Just because I'm bored, here's an alternative that can make future socket exploration a bit easier.

Code:
alias mysocket {
  if (www.?*.??* iswm $2) tokenize 32 $1 http:// $+ $2
  if (http://?*.??* iswm $2) || (https://?*.??* iswm $2) {
    var %e = $iif($gettok($2,1,47) == https:,-e),%a $gettok($2,2,47),%p $iif($gettok(%a,2,58) isnum 60-65535,$v1,$iif(%e,443,80)),%a $gettok(%a,1,58),%s $sha1($2,0) $+ .mysocket
    .remove %s
    sockclose %s
    hfree -w %s
    hmake %s
    hadd %s command $1
    hadd %s full $2
    hadd %s port %p
    hadd %s host %a
    hadd %s path $iif($gettok($2,3-,47),/ $+ $v1 $+ $iif($right($2,1) == /,/),/)
    hadd %s r 0
    sockopen %e %s %a %p
    .timermysocket.check -io 1 120 mysocket.check
    if ($isid) return %s
  }
  else $iif($isid,return,echo -a Invalid input, us as: /mysocket <command> <link>)
}

on *:start:noop $findfile($scriptdir,????????????????????????????????????????.mysocket,0,0,.remove $qt($1-))

alias -l mysocket.check {
  var %x = 1
  while ($hget(%x) != $null) { if (*.mysocket iswm $v1) hfree -w $v1 | else inc %x }
  while ($sock(*.mysocket,1)) sockclose $v1
}

on *:sockopen:*.mysocket: {
  tokenize 32 $sockname
  if ($sockerr) mysocket.e $1 open $v1 $sock($1).wsmsg
  else {
    sockwrite -tn $1 GET $hget($1,path) HTTP/1.1
    sockwrite -tn $1 Host: $hget($1,host)
    sockwrite -tn $1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:44.0) Gecko/20100101 Firefox/44.0
    sockwrite -tn $1 Accept: text/html
    sockwrite -tn $1 Connection: close
    sockwrite -t $1 $crlf
  }
}

on *:sockread:*.mysocket: {
  tokenize 32 $sockname
  if ($sockerr) mysocket.e $1 read 
  elseif ($hget($1,r)) mysocket.r $1
  else {
    sockread -f %c.t
    while ($sockbr > 2) { hadd $1 %c.t | sockread -f %c.t }
    if ($sockbr) { hadd $1 r $calc($sock($1).rcvd +$iif($hget($1,Content-Length:) <= 2097152,$v1,$v2)) | if ($sock($1).rq) mysocket.r $1 }
  }
}

on *:sockclose:*.mysocket:mysocket.d $sockname done

alias -l mysocket.r {
  sockread $sock($1).rq &b
  bwrite $1 -1 &b
  if ($sock($1).rcvd >= $hget($1,r)) mysocket.d $1 done
}

alias -l mysocket.e {
  $hget($1,command) $1 error $2 $sockerr $sock($1).wsmsg
  .remove $1
  hfree -w $1
  sockclose $1
}

alias -l mysocket.d {
  if ($hget($1,Transfer-Encoding:) == chunked) {
    var %y = 1
    bread $1 0 $file($1).size &f
    while ($bfind(&f,%y,$crlf).text) {
      var %v = $v1,%h $bvar(&f,%y,$calc(%v -%y)).text,%r $base(%h,16,10),%y $calc(%v +4+%r)
      if (%r == 0) break
      else bcopy &mysocket $calc(1+$bvar(&mysocket,0)) &f $calc(2+%v) %r
    }
  }
  else bread $1 0 $file($1).size &mysocket
  $hget($1,command) $1 done
  .remove $1
  hfree -w $1
  sockclose $1
}

All you need to do is to give the link and command you want it to execute after it has all the data.

In your case it would be: /mysocket mysocketdone http://paizo.com/pathfinderRPG/prd/spells/colorSpray

"mysocketdone" is the custom alias that you need to create:
Code:
alias mysocketdone {

  ;Let's catch the errors here, first one checks for generic errors that happen sometimes and second one checks if it received any data.
  if ($2 == error) echo -a An error occurred with $qt($1) socket during $qt($3) process: $4-
  elseif (!$bvar(&mysocket,0)) echo -a No data received!
  else {

    ;%s = where the desired content starts, %e = where it ends.
    var %s = $bfind(&mysocket,1,<div class = "body">),%e $bfind(&mysocket,%s,<div class = "footer">)

    ;Just to be sure it picked the right spots, let's check %e's value is higher than %s'.
    if (%e > %s) {

      ;$bvar(&mysocket,%s,$calc(%e -%s)).text gives you everything between "<div class = "body">" and "<div class = "footer">", so let's make it easy and set it to its own binary variable: &mydata
      bcopy &mydata 1 &mysocket %s $calc(%e -%s)

      ;%start is where the "A vivid cone of clashing colors..." line starts and %end is where it stops.
      var %start = $bfind(&mydata,1,<p>),%end $bfind(&mydata,%start,</p>)

      ;Pukes out the whole line, and thanks to funfare's $nohtml, you don't need to deal with the included HTML code.
      echo -a $nohtml($bvar(&mydata,%start,$calc(%end -%start)).text)
    }
    else echo -a Something went wrong!
  }
}

alias noHTML return $regsubex($1,/<[^>]+(?:>|$)|^[^<>]+>/g,$null)



Just to explain a bit more:

Basically all you need to do with it, is to give it a link and a command. It will execute the command when it's done or when it encounters an error. If everything goes right, it will do the following: "<your command> <socket name> done"

If it encounters an error, it will do: "<your command> <socket name> error <the event where it happened (open/read)> <error code> <error message>"

Your custom alias should always start a bit like this (use this to test new links/sites/whatever):
Code:
alias mysockettest {
  if ($2 == error) echo -a An error occurred with $qt($1) socket during $qt($3) process: $4-
  elseif (!$bvar(&mysocket,0)) echo -a No data received!
  else {
    echo -a &mysocket contains the whole page/file: $bvar(&mysocket,0) characters (mysocket.txt)
    .remove mysocket.txt
    bwrite mysocket.txt 0 -1 &mysocket
    echo -a $1 hash table contains all the relevant information, like the header: $hget($1,0).item items (mysocket.ini)
    .remove mysocket.ini
    hsave -i $1 mysocket.ini mysocket
    echo -a $1 file contains the whole page/file: $bytes($file($1).size).suf (it will be deleted when this alias finishes.)
    echo -a $1 is the socket's name: $sock($1) (it will be closed when this alias finishes.)
  }
}

It will create a "<sha1 hash of the link>.mysocket" socket, hash table and a file. The hash table contains relevant information, like the header. The file will contain the whole page/file. All three of these are destroyed after your custom command finishes.

The best thing is, you don't have to deal with any of the above, all the data will be in &mysocket binary variable. Just use $bvar and $bfind and do whatever you want, or just do whatever you want with the hash table/file/socket.

If you use the command as an identifier ($mysocket(command,link)), it will either return the name (valid input) or $null (invalid input). This can be handy if you use it in a text event and you want it to spam some information to the channel/whatever. You can store the channel/user name in the hash table and retrieve when it executes your command.


As an example the original request:
Code:
on *:text:!spell *:#:if ($mysocket(myspell,http://paizo.com/pathfinderRPG/prd/spells/ $+ $replacex($2-,$chr(32),% $+ 20))) hadd $v1 channel #

alias myspell {
  if ($2 == error) msg $hget($1,channel) An error occurred with $qt($1) socket during $qt($3) process: $4-
  elseif (!$bvar(&mysocket,0)) msg $hget($1,channel) No data received!
  else {
    var %s = $bfind(&mysocket,1,<div class = "body">),%e $bfind(&mysocket,%s,<div class = "footer">)
    if (%e > %s) {
      bcopy &mydata 1 &mysocket %s $calc(%e -%s)
      var %start = $bfind(&mydata,1,<p>),%end $bfind(&mydata,%start,</p>)
      if ($nohtml($bvar(&mydata,%start,$calc(%end -%start)).text)) msg $hget($1,channel) $v1
      else msg $hget($1,channel) Something went wrong!
    }
    else msg $hget($1,channel) Something went wrong!
  }
}

alias noHTML return $regsubex($1,/<[^>]+(?:>|$)|^[^<>]+>/g,$null)

Just to be safe: you also need the first code thing.

Last edited by Dazuz; 03/03/16 09:29 AM.