|
Joined: Jun 2009
Posts: 9
Nutrimatic drinks dispenser
|
OP
Nutrimatic drinks dispenser
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: 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: 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.
|
|
|
|
Joined: Oct 2004
Posts: 8,330
Hoopy frood
|
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.
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
|
|
|
|
Joined: Jun 2009
Posts: 9
Nutrimatic drinks dispenser
|
OP
Nutrimatic drinks dispenser
Joined: Jun 2009
Posts: 9 |
Wow, thanks for the quick reply... Works perfectly! Thank you for your time and help.
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
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. 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, ,$chr(9))
return %x
}
|
|
|
|
Joined: Oct 2004
Posts: 8,330
Hoopy frood
|
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
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
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 
|
|
|
|
Joined: Feb 2009
Posts: 133
Vogon poet
|
Vogon poet
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 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 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 alias -l nohtml return $remove($regsubex($1-,/(^[^<]*>|<[^>]*>|<[^>]*$)/g,), ,$chr(9))
WorldDMT
|
|
|
|
Joined: Jul 2007
Posts: 1,129
Hoopy frood
|
Hoopy frood
Joined: Jul 2007
Posts: 1,129 |
I think the $remove can be omitted: alias -l nohtml return $regsubex($1-,/(^[^<]*>|<[^>]*>|<[^>]*$|\46nbsp\73|\t)/g,) I haven't tested this but it should work to strip $chr(9) and too.
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
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. 
|
|
|
|
Joined: Feb 2009
Posts: 133
Vogon poet
|
Vogon poet
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
|
|
|
|
|