mIRC Home    About    Download    Register    News    Help

Print Thread
Help with sockread #219623 23/03/10 05:11 PM
Joined: Jun 2009
Posts: 9
B
Borg8401 Offline OP
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
B
Joined: Jun 2009
Posts: 9
Hey all, trying to figure something out.
I am trying to pull information from this page: here.

This is my code so far, which works:
Code:
on *:text:!player*:#: {
if ($sock(player)) .sockclose player
set %chan $chan
set %nick $nick
sockopen player herald.uthgard-server.net 80
}
on *:SOCKOPEN:player: {
sockwrite -nt $sockname GET /herald.php?view=stats&p1=player&p2=Player&p3=DESC&p5=Player&p6=Rotbart HTTP/1.1
sockwrite -nt $sockname Host: herald.uthgard-server.net
sockwrite -nt $sockname $crlf
}
on *:SOCKREAD:player: {
var %sockreader
sockread %sockreader
if (*<a class="charname"* iswm %sockreader ) {
set %name $nohtml($remove(%sockreader,Player))

var %sockreader
sockread %sockreader
if (*<a class="guild"* iswm %sockreader ) {
set %guild $nohtml($remove(%sockreader,Guild))

msg %chan %name < $+ %guild $+ >
unset %chan
unset %nick
unset %name %guild
sockclose player
}
}
}
}

Which outputs:
Rotbart Laeuseimschritt <Anguish>

However, I'm needing to get more information from it, and when I try this:
Code:
on *:text:!player*:#: {
if ($sock(player)) .sockclose player
set %chan $chan
set %nick $nick
sockopen player herald.uthgard-server.net 80
}
on *:SOCKOPEN:player: {
sockwrite -nt $sockname GET /herald.php?view=stats&p1=player&p2=Player&p3=DESC&p5=Player&p6=Rotbart HTTP/1.1
sockwrite -nt $sockname Host: herald.uthgard-server.net
sockwrite -nt $sockname $crlf
}
on *:SOCKREAD:player: {
var %sockreader
sockread %sockreader
if (*<a class="charname"* iswm %sockreader ) {
set %name $nohtml($remove(%sockreader,Player))

var %sockreader
sockread %sockreader
if (*<a class="guild"* iswm %sockreader ) {
set %guild $nohtml($remove(%sockreader,Guild))

var %sockreader
sockread %sockreader
if (*<a class="realmrank"* iswm %sockreader ) {
set %realmrank $nohtml($remove(%sockreader,Realmrank))

msg %chan %name < $+ %guild $+ > %realmrank
unset %chan
unset %nick
unset %name %guild %realmpoints
sockclose player
}
}
}
}
}

I get no response from the bot at all, I've tried renaming the %sockreader to %sockreader2, %sockreader3, etc for each sockread but nothing seems to help. I'm trying to get a total of 7 lines of information from that page.

Any help would be greatly appreciated

Last edited by Borg8401; 23/03/10 05:13 PM.
Re: Help with sockread [Re: Borg8401] #219624 23/03/10 05:33 PM
Joined: Oct 2004
Posts: 8,330
Riamus2 Offline
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
You should only use one sockread. That section will loop until the entire page is read. Use IF statements to get all the information you need.

Code:
on *:text:!player*:#: {
  if ($sock(player)) .sockclose player
  set %chan $chan
  set %nick $nick
  sockopen player herald.uthgard-server.net 80
}
on *:SOCKOPEN:player: {
  sockwrite -nt $sockname GET /herald.php?view=stats&p1=player&p2=Player&p3=DESC&p5=Player&p6=Rotbart HTTP/1.1
  sockwrite -nt $sockname Host: herald.uthgard-server.net
  sockwrite -nt $sockname $crlf
}
on *:SOCKREAD:player: {
  var %sockreader
  sockread %sockreader
  if (*<a class="charname"* iswm %sockreader) {
    set %name $nohtml($remove(%sockreader,Player))
  }
  elseif (*<a class="guild"* iswm %sockreader) {
    set %guild $nohtml($remove(%sockreader,Guild))
  }
  elseif (*<a class="class2"* iswm %sockreader) {
    set %class $nohtml($remove(%sockreader,Class))
  }
  elseif (*<a class="race2"* iswm %sockreader) {
    set %race $nohtml($remove(%sockreader,Race))
  }
  if (</table>* iswm %sockreader) {
    msg %chan %name < $+ %guild $+ > %class %race
    unset %chan
    unset %nick
    unset %name %guild %class %race
    sockclose player
  }
}


There's just a quick example. It shows a couple extra pieces of information. Just repeat that format for anything else that you need. The main reason you ran into trouble is having the extra sockread's in there. Doing that will cause lines to be skipped.


Invision Support
#Invision on irc.irchighway.net
Re: Help with sockread [Re: Riamus2] #219626 23/03/10 05:44 PM
Joined: Jun 2009
Posts: 9
B
Borg8401 Offline OP
Nutrimatic drinks dispenser
OP Offline
Nutrimatic drinks dispenser
B
Joined: Jun 2009
Posts: 9
Wow, thanks for the quick reply... Works perfectly! Thank you for your time and help.

Re: Help with sockread [Re: Borg8401] #219631 23/03/10 06:13 PM
Joined: Nov 2006
Posts: 1,559
H
Horstl Offline
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
Riamus2 beat me to it, but here's another approach (parsing all the data, no global variables) - maybe it's of use.
Code:
on *:TEXT:!player*:#: {
  if ($sock(player)) .sockclose player
  sockopen player herald.uthgard-server.net 80
  ; you can mark the socket instead of putting $chan and $nick into global variables
  sockmark player $chan $nick
}

on *:SOCKOPEN:player: {
  sockwrite -nt $sockname GET /herald.php?view=stats&p1=player&p2=Player&p3=DESC&p5=Player&p6=Rotbart HTTP/1.1
  sockwrite -nt $sockname Host: herald.uthgard-server.net
  sockwrite -nt $sockname $crlf
}

on *:SOCKREAD:player: {
  var %read

  ; goto-loop of sockread
  :read
  sockread %read

  ; if there was data left to read and the data matched " <tr class="TBLmid"><td>SOMETHING HERE</td><td> "
  ; then set a local variable named "%SOMETHING_HERE" (spaces replaced with underscores)
  ; which holds the data of $remove($nohtml(sockread),SOMETHING HERE)
  if ($sockbr) {
    if ($regex(read,%read,/\<tr class="TBLmid"><td>([^<]+)<\/td><td>/)) { set -l % $+ $replace($regml(read,1),$chr(32),_) $remove($nohtml(%read),$regml(read,1)) }
    goto read
  }

  ; this means you can now use EACH of
  ; %player %guild %class %race %level %realmrank %dragon_kills %legion_kills %kills %realmpoints %last_week _RPs

  ; convert sockmark back to local variables 
  var %chan = $gettok($sock($sockname).mark,1,32), %nick = $gettok($sock($sockname).mark,2,32)

  msg %chan %player < $+ %guild $+ > Rank: %realmrank Pts: %realmpoints
  sockclose $sockname
}

alias -l nohtml {
  var %x, %i = $regsub($1-,/(^[^<]*>|<[^>]*>|<[^>]*$)/g,$null,%x), %x = $remove(%x,&nbsp;,$chr(9))
  return %x
}

Re: Help with sockread [Re: Horstl] #219632 23/03/10 06:18 PM
Joined: Oct 2004
Posts: 8,330
Riamus2 Offline
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
Someday, I really need to learn regex. I like that approach, though it's not as easily adjusted when doing other socket scripts. It works great on this one since all the important lines use the same format. The only thing that may not (I can't test it here) is how race2 and class2 are used in the HTML... but you're removing Race and Class respectively. That would leave Race and Class in the %race2 and %class2 variables if I'm understanding the regex correctly. Maybe I'm not since I really don't know regex, but that seems to be the case?

EDIT: Nevermind. I realized that it wasn't looking at the URL section that included race2 and class2.

Last edited by Riamus2; 23/03/10 06:25 PM.

Invision Support
#Invision on irc.irchighway.net
Re: Help with sockread [Re: Riamus2] #219634 23/03/10 06:30 PM
Joined: Nov 2006
Posts: 1,559
H
Horstl Offline
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
The regex matches every collumn of the chart ( e.g. <tr class="TBLmid"><td>Race</td> ) and captures word with ([^<]+) aka "one or more chars being no "<"-char" to name the variables. The variable thus will be named "%Race". And yep - this approach will be of little use in other cases smile

Re: Help with sockread [Re: Horstl] #219646 23/03/10 09:42 PM
Joined: Feb 2009
Posts: 133
C
chacha Offline
Vogon poet
Offline
Vogon poet
C
Joined: Feb 2009
Posts: 133
hi
i think no need for goto loop and i prefer to add "wx" only to unset the global variable and replace the sockmark by set %wxchan # and %wxnick $nick
Code:
on *:sockread:player:{
  var %read | sockread %read
  if ($regex(read,%read,/\<tr class="TBLmid"><td>([^<]+)<\/td><td>/)) set -l %wx $+ $replace($regml(read,1),$chr(32),_) $remove($nohtml(%read),$regml(read,1))
}

then u use ON SOCKCLOSE event to send msg if exist result something like

Code:
on *:sockclose:player:{
  if %var here {
    msg %wxchan %wxplayer $+(<,%wxguild,>) Rank: %wxrealmrank Pts: %wxrealmpoints
    unset %wx*
  }
}


and for the alias nohtml u can use $regsubex

Code:
alias -l nohtml return $remove($regsubex($1-,/(^[^<]*>|<[^>]*>|<[^>]*$)/g,),&nbsp;,$chr(9))


WorldDMT
Re: Help with sockread [Re: chacha] #219658 24/03/10 07:15 AM
Joined: Jul 2007
Posts: 1,129
T
Tomao Offline
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
I think the $remove can be omitted:
Code:
alias -l nohtml return $regsubex($1-,/(^[^<]*>|<[^>]*>|<[^>]*$|\46nbsp\73|\t)/g,)
I haven't tested this but it should work to strip $chr(9) and
Code:
&nbsp;
too.

Re: Help with sockread [Re: chacha] #219677 25/03/10 01:15 PM
Joined: Nov 2006
Posts: 1,559
H
Horstl Offline
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
(late reply)

- I used /sockmark especially to show that one may relay data to socket events with other means.
- Set -l sets local variables - they dont need any unset. That said, I usually try to avoid global variables wherever possible - especially if the data isn't required in further sessions. Global vars may persist (even with -e in case of a crash; if you forget adding an unload event etc). It depends on the situation and is a personal preference though (I like a clean vars section).
- You're right about $nohtml, I simpliy ripped the first alias I found from an existing thread, as (to my surprise) I didn't needed one in any script of mine so far.
- Of course you can trigger the output not after !$sockbr but on sockclose. However I don't see any advantage in this particular case... The $sockbr-loop is again a habbit of mine (but mandatory in some other socket situations).
- Yep, the OP could check first whether or not his variables actually hold [valid] data. However the script won't get stuck, issue invalid commands or the like without the check. And no output at all might cause more confusion than an output with missing values...
- Besides a small (and inconsequential) typo in the regex of my post, the expression could capture the data right away for a $regml(read,2) instead of using $nohtml and $remove on the whole line. That aside, the current construct can actually be improved with "$mid($nohtml(%read),$calc($len($regml(read,1)) +1))" instead of "$remove($nohtml(%read),$regml(read,1))": It won't strip "guild" out of a guild's name for example.
smile

Re: Help with sockread [Re: Horstl] #219692 25/03/10 08:27 PM
Joined: Feb 2009
Posts: 133
C
chacha Offline
Vogon poet
Offline
Vogon poet
C
Joined: Feb 2009
Posts: 133
about /set -l it's like /var i only copy paste and remove something but i didnt look at all :p


WorldDMT