mIRC Home    About    Download    Register    News    Help

Print Thread
#255881 29/11/15 01:32 PM
Joined: Jan 2013
Posts: 10
F
Fabius Offline OP
Pikka bird
OP Offline
Pikka bird
F
Joined: Jan 2013
Posts: 10
I wrote a script that updates itself via socket when a new version is available, but i'm running into a couple of problems.
I use /sockread to store the data into a &binvar, and write it to a temp file.
It seems that the download is *really* slow (it takes more than 3 minutes to write 210kb) and also it stops writing the temp file at a random percentage (usually between 75-99%).

So i'm wondering what might be wrong with it since the script basically works, untill it just stops to write the file. And also i would like to know if it's normal that it takes so long for such a few kb of data.
Thanks in advance!

Fabius #255882 29/11/15 01:42 PM
Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
It's not normal, please post your script in the script & popoups section.


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Fabius #255883 29/11/15 01:42 PM
Joined: Dec 2008
Posts: 1,515
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2008
Posts: 1,515
This is actually an Scripts & Popups function and not Developers stuff but it would be nice to show us the code to help you further because now we cannot imagine where is the problem exactly.


Need Online mIRC help or an mIRC Scripting Freelancer? -> https://irc.chathub.org <-
westor #255885 29/11/15 03:12 PM
Joined: Jan 2013
Posts: 10
F
Fabius Offline OP
Pikka bird
OP Offline
Pikka bird
F
Joined: Jan 2013
Posts: 10
Originally Posted By: westor
This is actually an Scripts & Popups function and not Developers stuff but it would be nice to show us the code to help you further because now we cannot imagine where is the problem exactly.

Oh sorry, my mistake. Maybe a moderator will move the topic to the right section.
In the meanwhile, i made some more attempts and sometimes the download reaches 100% and the self update process ends succesfully, so this confusing me even more.

About the code...
i create a first socket on a small php file to check if a new update is available (it returns version number and script.ini size to make an integrity check later), then, if that's the case, i create another socket to download the .ini file, this way (some code not related to the problem stripped for convenience and readability):
Code:
alias startupdate {
    ; Open a dialog with a progress bar
    .write -c $script $+ .tmp
    .sockclose updatemyscript
    .sockopen updatemyscript my.website.url 80
}



on *:SOCKOPEN:updatemyscript:{
  if ($sockerr) {
    ; Report error
    .return
  }
  else {
    .sockwrite -n $sockname GET /subfolder/myscript.ini HTTP/1.0
    .sockwrite -n $sockname Host: my.website.url
    .sockwrite -n $sockname $crlf
  }
}



on *:SOCKREAD:updatemyscript:{
  if ($sockerr) {
    ; Report error
    .return
  }
  else {
    .sockread -fn &mybinvar
    if ($bvar(&mybinvar,$calc($bvar(&mybinvar,0) - 1),1) == 0) {
      .bwrite $script $+ .tmp -1 $calc($bvar(&mybinvar,0) - 2) &mybinvar
      .bwrite $script $+ .tmp -1 -1 $crlf
    }
    else {
      .bwrite $script $+ .tmp -1 $bvar(&mybinvar,0) &mybinvar
    }
    .var %downloaded.update.size $file($script $+ .tmp).size
    .var %perc.update $round($calc(%downloaded.update.size * 100 / %xdcc.newver.bytes),0)
    ; Update progress bar in a dialog
  }
}


on *:SOCKCLOSE:updatemyscript:{
  if ($sockerr) {
    ; Report error
    .return
  }
  else {
    ; Update progress bar in a dialog to ensure it reaches 100% (cause of approximation in "on SOCKREAD" $calc operation of %perc.update)
    ; Now strip headers by removing all lines before [script] line
    .var %i 1
    .var %script.first.line $chr(91) $+ script $+ $chr(93)
    while (%i < $lines($script $+ .tmp)) {
      if ($read($script $+ .tmp,n,1) != %script.first.line) {
        .write -dl1 $script $+ .tmp
      }
      else {
        .break
      }
      .inc %i
    }
    ; Close the dialog containing progress bar
    ; Now lets check if the file size matches
    if ($file($script $+ .tmp).size == %myscript.bytes) {
      ; Everything went ok, go on with other stuff
    }
    else {
      ; ERROR! Something went wrong and the download got interrupted
    }
  }
}

Last edited by Fabius; 29/11/15 03:14 PM.
Fabius #255886 29/11/15 03:16 PM
Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
Quote:
.sockread -fn &mybinvar
This is your problem, check the help file, this will read one line at a time, that's why it's so slow. You can use /sockread $sock($sockname).rq &mybinvar to read the full buffer available at the time.


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Wims #255887 29/11/15 03:31 PM
Joined: Jan 2013
Posts: 10
F
Fabius Offline OP
Pikka bird
OP Offline
Pikka bird
F
Joined: Jan 2013
Posts: 10
Originally Posted By: Wims
Quote:
.sockread -fn &mybinvar
This is your problem, check the help file, this will read one line at a time, that's why it's so slow. You can use /sockread $sock($sockname).rq &mybinvar to read the full buffer available at the time.

Thanks a lot, that fixes it! I tried that in one of my several attempts but i must have left "-fn" parameters set before [numbytes] and that made it still read line-by-line.

Btw i'm still curious about the strange behavior occurring when reading line-by-line, which makes the writing randomly stop at a random point. I also tried to measure if it stopped after a specific amount of time (maybe there was some sort of timeout) but i've seen it stop after quite different timings.

Fabius #255888 29/11/15 03:36 PM
Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
-n reads a line but won't read anything if there is not a terminated line in the buffer (a $crlf, or just $lf)
-f force the read of whatever is in the buffer so with -fn, it reads a line in priority, but if no line is found, it will still read whatever is in the buffer, so from that point, you're good, it should read everything.

Now, the on sockread event:
Originally Posted By: /help on sockread
Note: A single /sockread may not be enough to read the entire buffer. You should keep reading until $sockbr (bytes read) is set to zero. This is far faster than letting mIRC re-trigger the event. If your script does not read the whole buffer, the on sockread event is re-triggered if:

a) you were reading into a &binvar.

b) you were reading into a %var and there is still a $crlf terminated line in the buffer waiting to be read.
since you're reading into a binvar, it should always retrigger, it's hard to tell, only debugging the script would help at this point


Also, can you explain what you're doing with this?
Quote:
if ($bvar(&mybinvar,$calc($bvar(&mybinvar,0) - 1),1) == 0) {
.bwrite $script $+ .tmp -1 $calc($bvar(&mybinvar,0) - 2) &mybinvar
.bwrite $script $+ .tmp -1 -1 $crlf
}
else {
.bwrite $script $+ .tmp -1 $bvar(&mybinvar,0) &mybinvar
}

Last edited by Wims; 29/11/15 03:42 PM.

#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Wims #255889 29/11/15 04:39 PM
Joined: Jan 2013
Posts: 10
F
Fabius Offline OP
Pikka bird
OP Offline
Pikka bird
F
Joined: Jan 2013
Posts: 10
Originally Posted By: Wims
-n reads a line but won't read anything if there is not a terminated line in the buffer (a $crlf, or just $lf)
-f force the read of whatever is in the buffer so with -fn, it reads a line in priority, but if no line is found, it will still read whatever is in the buffer, so from that point, you're good, it should read everything.

Now, the on sockread event:
Originally Posted By: /help on sockread
Note: A single /sockread may not be enough to read the entire buffer. You should keep reading until $sockbr (bytes read) is set to zero. This is far faster than letting mIRC re-trigger the event. If your script does not read the whole buffer, the on sockread event is re-triggered if:

a) you were reading into a &binvar.

b) you were reading into a %var and there is still a $crlf terminated line in the buffer waiting to be read.
since you're reading into a binvar, it should always retrigger, it's hard to tell, only debugging the script would help at this point


Also, can you explain what you're doing with this?
Quote:
if ($bvar(&mybinvar,$calc($bvar(&mybinvar,0) - 1),1) == 0) {
.bwrite $script $+ .tmp -1 $calc($bvar(&mybinvar,0) - 2) &mybinvar
.bwrite $script $+ .tmp -1 -1 $crlf
}
else {
.bwrite $script $+ .tmp -1 $bvar(&mybinvar,0) &mybinvar
}

when writing from binvar of sockread performed line-by-line it misses empty lines, so i had to use this trick to make it keep stuff like:
[code]
...

...
[code]
and make it not become:
[code]
...
...
[code]

Thanks again for you help and explanations!

Last edited by Fabius; 29/11/15 04:40 PM.
Fabius #255890 29/11/15 04:55 PM
Joined: Jul 2006
Posts: 4,145
W
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 4,145
Ok, although it works, it's more or less incorrect.
mIRC/sockread isn't missing the line, it sees it but since it reads line by line, the $crlf is removed on purpose.
your $calc() is going to always give -1 whenever the binvar is empty, and $bvar(&,-1,1) does give 0.
Note that you're checking the penultimate character with your $calc, if for some reasons you had a nul byte 0, your $bvar could return 0 and it would make it fail, although it's probably ok to guess you'll never have a nul byte there lol.

But you should be checking that the binvar itself is empty with if ($bvar(&mybinvar,0) == 0)

As a matter of fact, your on sockread event is *wrong* as well, because you're asking for a line, but if no line is present, you request the data anyway, in your situation it's not a problem, because in any case you're going to write whatever you have to the file, but if you were looking for a specific line in the response, like it's often the case with socket script, if you were lagging for example, only a small portion of the line you want would be available, so your script wouldn't match that line, and you would then read the rest of the line later, ending up never having the full line being checked, I described this here: http://en.wikichip.org/wiki/mirc/commands/sockread
in your situation above you can make sure you read an empty line by checking $sockbr, which should be 2 while $bvar(,0) is 0, but you did read 2 bytes.


#mircscripting @ irc.swiftirc.net == the best mIRC help channel
Wims #255891 29/11/15 07:35 PM
Joined: Jan 2013
Posts: 10
F
Fabius Offline OP
Pikka bird
OP Offline
Pikka bird
F
Joined: Jan 2013
Posts: 10
This was my first time using sockets and i'm not much familiar with that. Your post and the link you provided to wikichip (which i didnt know) are really comprehensive, so thanks for your explanation and for pointing out also a possible bug of my code!


Link Copied to Clipboard