mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Apr 2017
Posts: 14
K
Pikka bird
OP Offline
Pikka bird
K
Joined: Apr 2017
Posts: 14
I've tried to optimize my betting script posted previously and I've got a pretty good feeling about it, although there's one problem that I still face. Every time I execute a command to tell me which users entered their bets on a certain outcome, it'll tell me the name and points entered through Echo. As soon as I decide I want to have my script write the points, it'll tell me I have insufficient parameters and stop the script.

I'm guessing this is to do with the blank space, meaning the script can't write it as a parameter and therefore halts before I can finish the script.

The lay-out of the list. This simulates a situation where one of the people that bet on a match decided they didn't want to risk it and removed their entry. I'll either need a way to completely remove blanks altogether and shrink the file together , or to be able to skip this blank line.
Code:
User0
User1

User3


The code being used
Code:
on *:TEXT:!cmd:#: {
  var %i = 1, %l = $lines(Win.txt)
  while (%i <= %l) {
    echo 9 @Script Entry: $read(Win.txt,n,%i)
    echo 3 @Script Points: $readini(Bets.ini,n,$+(#), $read(Win.txt,n,%i))
    inc %i
  }
}


Code's outcome in @Script
Code:
Entry: User0
Points: 20
Entry: User1
Points: 2
Entry:
Points:
Entry: User3
Points: 4


Once I want to write points:
Code:
on *:TEXT:!cmd:#: {
  var %i = 1, %l = $lines(Win.txt)
  while (%i <= %l) {
    echo 9 @Script Entry: $read(Win.txt,n,%i)
    echo 3 @Script Points: $readini(Bets.ini,n,$+(#), $read(Win.txt,n,%i))
    writeini -n Points.ini $+(#) $read(Win.txt,n, %i) $calc($readini(Points.ini,$+(#),$read(Win.txt, n, %i)) + $round($calc($readini(Bets.ini,$+(#),$read(Win.txt,n, %i)) * 1.5) ,0))
    inc %i
  }
}


Outcome in Status and @Script

Code:
Status window:
* /writeini: insufficient parameters (line 75, remote.ini)

@Script window:
Entry: User0
Points: 20
Entry: User1
Points: 2
Entry:
Points:

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
You could write down an invalid value that you strip while reading it:

/writeini -n test.ini section item $iif($1-,$1-,dummy)

if ($remove($readini(test.ini,n,section,item),dummy)) blah blah

Or, more straightforward:

/writeini -n test.ini section item $iif($1-,$1-,$false)

if ( $readini(test.ini,n,section,item) ) blah blah

You could trim down your INI. It appears that User is always 1 token, so you could store the user and points together on the same line at the same time, then later you could read the joint line, and use $gettok(linetext,1,32) for the User and $gettok(linetext,2,32) for the Points if any.

Joined: Apr 2017
Posts: 14
K
Pikka bird
OP Offline
Pikka bird
K
Joined: Apr 2017
Posts: 14
Originally Posted By: maroon
You could write down an invalid value that you strip while reading it:

/writeini -n test.ini section item $iif($1-,$1-,dummy)

if ($remove($readini(test.ini,n,section,item),dummy)) blah blah

Or, more straightforward:

/writeini -n test.ini section item $iif($1-,$1-,$false)

if ( $readini(test.ini,n,section,item) ) blah blah

You could trim down your INI. It appears that User is always 1 token, so you could store the user and points together on the same line at the same time, then later you could read the joint line, and use $gettok(linetext,1,32) for the User and $gettok(linetext,2,32) for the Points if any.


I'm very unfamiliar with the more advanced things in MIRC to be honest. My entire betting script is based off a temporary text file system where every input gets registered into Text files and retrieved when needed. I'm having trouble trying to figure out how to get $gettok to work.

The name and the points are retrieved from 2 different files. The name is retrieved from the Win file and that is being used in $readini to look up how many points they entered in Bets.ini

Last edited by KevinSlice; 03/06/17 07:54 PM.
Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
$gettok is pretty simple, and a lot of the $XXXtok identifiers work similarly, so the learning curve is smaller for the others. When it's relevant, these identifiers have a case-sensitive variant for situations where hunting for a token needs to tell the difference between Nick and nick.

$gettok(text,N,C)
or
$gettok(STUFF,token-number,separator)

This assumes STUFF is a list of items that you can parse to grab part of it. Token-number lets you specify which token(s) you want. Token 0 is the total number of tokens, 1 is the 1st, etc. -1 is the last token, -2 is next-to-last, etc. You can use a range to grab several tokens. $gettok($1-,2-4,32) grabs the 2nd thru 4th words, $gettok($1-,2-,32) grabs the 2nd thru infinity tokens.

The last parameter is the ASCII character that separates your tokens from each other. If it's a normal sentence and you're wanting to grab the 2nd word, you use 2 as the token, and 32 is the ascii value for the space character. Comma is a common separator, so you often see 44 as the last parameter. You want to pick a separator that won't be part of any of your tokens, because unlike CSV format it doesn't let you put double-quotes around your token to allow the separator to be within the token. You can parse the foldernames of your c:\path\path\ by using 92 as your separator, because that's the ASCII value of "\".

So the userid name on the computer is likely to be the 2nd foldername in the path:

//echo -a $sysdir(desktop)

... so you can grab the username with:

//echo -a $gettok( $sysdir(desktop) , 3 , 92)

if you have a long list of tokens, and you just want the LAST token, you can get it 2 ways, you can use $numtok(STUFF,separator) or $gettok(STUFF,0,separator) to count the number of tokens and then use $calc() to subtract 1. Or you can use -1 as the token. -2 is the next-to-last, etc.

//echo -a mirc is installed into the $gettok( $mircexe , -2 , 92) folder.

When using tokens, you must always make sure to have 'something' as a token between your separators, because 2 consecutive separators doesn't treat this as being a $Null token, it treats the pair as a single separator.

//echo -a $gettok( a.b.c.d.e , 4 , 46)

... returns the value 'd'. If you replace the 'b' with a space the value is still 'd'. However if you delete the 'b' so you have 2 consecutive periods touching, the pair of periods becomes 1 separator, so 'c' becomes the 2nd token, and the above 4th token shifts from being 'd' to being 'e'.

The $XXXtok identifiers ignore leading or trailing separators, so a period in front of the 'a' or behind the 'e' won't change any of the answers. If you use $gettok($mircdir,1-,92) it always strips off the final backslash because there's no token following that final backslash. $gettok(LIST,1-,46) displays the same regardless whether LIST is a.c.d.e or a..c.d.e because it's stripping repeating, leading, or trailing separators.

You may sometimes see scripts doing things like

if ($event isin TEXT JOIN) do something

this is fine if you've controlled what $event could possibly be. However, if you've trapped the events CONNECT CONNECTFAIL DISCONNECT, this method will always trigger for CONNECT because it's "isin" the other words. For those cases, you can use $istok:

var %filetype $gettok($filename,-1,46)
; this grabs the last token following the last period, so it works for file.name.txt and file.txt, but returns the entire filename if there's no extension.

if ( $istok( jpg gif png bmp , %filetype , 32 ) echo -a this is a picture

Instead of a separate check for each filetype, you can do 1 check for everything.

Be careful when using $addtok, because this adds the token only if the token isn't already there. So if you're using $addtok to fill 20 slots in a list of bettors and fill 20 slots in a list of betting amounts, anyone who has multiple bets placed will have their user name only added the 1 time - while bet amounts will be added only if they're unique. Better would be using $puttok to oerwrite the Nth token. You'll have similar issues with tokens as you had with zapping an ITEM in your points.ini - you'd need to write $false or 0 to keep the token from being $null and dropping off the list.

If you store your list of 20 in a tokenized variable, you can avoid all those disk reads and writes. Instead of cycling through the list deleting the tokens 1 at a time you could deal with each of the 20 bets individually, then you can just wipe your bet list with:

/set %betlist 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0

or
set %betlist $str(0.,19) $+ 0

Joined: Apr 2017
Posts: 14
K
Pikka bird
OP Offline
Pikka bird
K
Joined: Apr 2017
Posts: 14
Originally Posted By: maroon
$gettok is pretty simple, and a lot of the $XXXtok identifiers work similarly, so the learning curve is smaller for the others. When it's relevant, these identifiers have a case-sensitive variant for situations where hunting for a token needs to tell the difference between Nick and nick.

$gettok(text,N,C)
or
$gettok(STUFF,token-number,separator)

This assumes STUFF is a list of items that you can parse to grab part of it. Token-number lets you specify which token(s) you want. Token 0 is the total number of tokens, 1 is the 1st, etc. -1 is the last token, -2 is next-to-last, etc. You can use a range to grab several tokens. $gettok($1-,2-4,32) grabs the 2nd thru 4th words, $gettok($1-,2-,32) grabs the 2nd thru infinity tokens.

The last parameter is the ASCII character that separates your tokens from each other. If it's a normal sentence and you're wanting to grab the 2nd word, you use 2 as the token, and 32 is the ascii value for the space character. Comma is a common separator, so you often see 44 as the last parameter. You want to pick a separator that won't be part of any of your tokens, because unlike CSV format it doesn't let you put double-quotes around your token to allow the separator to be within the token. You can parse the foldernames of your c:\path\path\ by using 92 as your separator, because that's the ASCII value of "\".

So the userid name on the computer is likely to be the 2nd foldername in the path:

//echo -a $sysdir(desktop)

... so you can grab the username with:

//echo -a $gettok( $sysdir(desktop) , 3 , 92)

if you have a long list of tokens, and you just want the LAST token, you can get it 2 ways, you can use $numtok(STUFF,separator) or $gettok(STUFF,0,separator) to count the number of tokens and then use $calc() to subtract 1. Or you can use -1 as the token. -2 is the next-to-last, etc.

//echo -a mirc is installed into the $gettok( $mircexe , -2 , 92) folder.

When using tokens, you must always make sure to have 'something' as a token between your separators, because 2 consecutive separators doesn't treat this as being a $Null token, it treats the pair as a single separator.

//echo -a $gettok( a.b.c.d.e , 4 , 46)

... returns the value 'd'. If you replace the 'b' with a space the value is still 'd'. However if you delete the 'b' so you have 2 consecutive periods touching, the pair of periods becomes 1 separator, so 'c' becomes the 2nd token, and the above 4th token shifts from being 'd' to being 'e'.

The $XXXtok identifiers ignore leading or trailing separators, so a period in front of the 'a' or behind the 'e' won't change any of the answers. If you use $gettok($mircdir,1-,92) it always strips off the final backslash because there's no token following that final backslash. $gettok(LIST,1-,46) displays the same regardless whether LIST is a.c.d.e or a..c.d.e because it's stripping repeating, leading, or trailing separators.

You may sometimes see scripts doing things like

if ($event isin TEXT JOIN) do something

this is fine if you've controlled what $event could possibly be. However, if you've trapped the events CONNECT CONNECTFAIL DISCONNECT, this method will always trigger for CONNECT because it's "isin" the other words. For those cases, you can use $istok:

var %filetype $gettok($filename,-1,46)
; this grabs the last token following the last period, so it works for file.name.txt and file.txt, but returns the entire filename if there's no extension.

if ( $istok( jpg gif png bmp , %filetype , 32 ) echo -a this is a picture

Instead of a separate check for each filetype, you can do 1 check for everything.

Be careful when using $addtok, because this adds the token only if the token isn't already there. So if you're using $addtok to fill 20 slots in a list of bettors and fill 20 slots in a list of betting amounts, anyone who has multiple bets placed will have their user name only added the 1 time - while bet amounts will be added only if they're unique. Better would be using $puttok to oerwrite the Nth token. You'll have similar issues with tokens as you had with zapping an ITEM in your points.ini - you'd need to write $false or 0 to keep the token from being $null and dropping off the list.

If you store your list of 20 in a tokenized variable, you can avoid all those disk reads and writes. Instead of cycling through the list deleting the tokens 1 at a time you could deal with each of the 20 bets individually, then you can just wipe your bet list with:

/set %betlist 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0

or
set %betlist $str(0.,19) $+ 0




I think I'll have to read through this multiple times to understand how to use tokens, although I believe it's something for later because the script works perfectly fine, even if it is in a different method. My main goal is to try and heavily reduce the amount of lines used in the code, because currently it's doing the exact same thing 20 times. I'm trying to use this loop and it works, I just need to find a way to skip or alter the blank lines

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
If you can identify 20 sections which are identical except for the line number, you can make that an alias which you pass the line number to it:

var %line 1

while (%line isnum 1-20) {
line_handling_alias %line
inc %line
}

alias line_handling_alias {
var %bet ($readini,bets.ini,n,section,bettor $+ $1)
etc
}

You can also made a pair of aliases for reading and writing each file, so that each .ini only needs to be mentioned twice in the entire script.


Link Copied to Clipboard