|
Joined: Dec 2014
Posts: 40
Ameglian cow
|
OP
Ameglian cow
Joined: Dec 2014
Posts: 40 |
Okay! So I've spent the past four hours trying to wrap my head around SOCKOPEN and SOCKCLOSE and I attempted to reverse engineer and follow guides on using RAW EVENTS to get what I want done. But all to no end. All I want is to have a command "!spell*" that then opens up http://paizo.com/pathfinderRPG/prd/spells/colorSpray for example with !spell colorspray and then display the description the page offers. I've given up.
|
|
|
|
Joined: Dec 2008
Posts: 1,515
Hoopy frood
|
Hoopy frood
Joined: Dec 2008
Posts: 1,515 |
Try use this code:
ON *:TEXT:!spell *:#: { .msg $chan http://paizo.com/pathfinderRPG/prd/spells/ $+ $$2 }
|
|
|
|
Joined: Dec 2014
Posts: 40
Ameglian cow
|
OP
Ameglian cow
Joined: Dec 2014
Posts: 40 |
This might work for some spells but I definitely plan on working up a sockopen raw event for spells that might be spelt differently or ones with spaces or hyphens. But thank you. I thought right over this quick fix.
Edit: I also want it to actually message the chat with the content rather than just the link. Which is precisely why I need to work on it to be a sockopen and sockclose raw event.
Last edited by Feyl0rd; 25/02/16 07:31 PM.
|
|
|
|
Joined: Nov 2013
Posts: 22
Ameglian cow
|
Ameglian cow
Joined: Nov 2013
Posts: 22 |
be forewarned when you start scraping content off webpages, you're gonna have to deal with handling the content as it exists in <HTML> form. in your case this might not be much of an issue the page you linked seems pretty straightforward. here is a rough idea of a working example that has lots of notes so you can figure out what's going on. note that the user needs to have the proper case (e.g. colorSpray, chillTouch) with the search query.. or else the server will throw an error. this is by no means rock solid code but you can get some ideas about how the sockets are working with it.
on *:text:!spell*:#: {
getpaizocontent $chan $2
}
alias noHTML return $regsubex($1, /<[^>]+(?:>|$)|^[^<>]+>/g, $null)
alias getpaizocontent {
;; get content from "http://paizo.com/pathfinderRPG/prd/spells/"
;
; usage: /getpaizocontent $chan <searchquery>
;
; input: $1 %paizochan
; $2 %paizomark
;
; output: null => .msg $chan <result>
; let %paizochan be the room your nick is listening for !spell
set %paizochan $1
; let %paizomark be the spell name in: !spell <spellname>
set %paizomark $2
; close the <paizo> socket if it is already open
sockclose paizo
; open a <paizo> socket
sockopen paizo paizo.com 80
}
on *:sockopen:paizo: {
; write to the socket your HTTP header request...
sockwrite -nt $sockname GET /pathfinderRPG/prd/spells/ $+ %paizomark $+ .html HTTP/1.1
sockwrite -nt $sockname Connection: keep-alive
sockwrite -nt $sockname Host: paizo.com
sockwrite $sockname $crlf
}
on *:sockread:paizo: {
var %read
; let %startfind be the line of html right before your content starts
var %startfind class="stat-block-title"><b>
; let %endfind be the line of html where your content ends
; ..caution: this mIRCscript will break if this html changes..
var %endfind <div class = "footer">
sockread %read
; there was a weird quirk in the HTML of the paizo site resulting in
; a blank newline with the text '368' ... not really sure why this is
; happening. resolved with the below commands:
if ( $len(%read) < 10 ) && ( %paizofound = 1 ) {
unset %paizofound
unset %paizochan
unset %paizomark
sockclose paizo
halt
}
; typically if you wanted to close the socket you would listen for
; a string which would terminate your socket.. as shown below:
if ( %endfind isin %read ) {
sockclose paizo
unset %paizofound
unset %paizochan
unset %paizomark
halt
}
; %paizofound is defined underneath this - the %startfind was found on
; the previous line, so start dumping the contents of the page to your channel..
; defined initially as %paizochan
if ( %paizofound = 1 ) {
msg %paizochan $noHTML(%read)
}
; %startfind was found so set %paizofound to 1
if ( %startfind isin %read ) {
set %paizofound 1
}
}
|
|
|
|
Joined: Dec 2015
Posts: 148
Vogon poet
|
Vogon poet
Joined: Dec 2015
Posts: 148 |
Just because I'm bored, here's an alternative that can make future socket exploration a bit easier.
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:
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):
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:
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.
|
|
|
|
Joined: Dec 2014
Posts: 40
Ameglian cow
|
OP
Ameglian cow
Joined: Dec 2014
Posts: 40 |
Thank you for your reply! I will now begin digesting this and another comment on the thread now.
|
|
|
|
Joined: Dec 2014
Posts: 40
Ameglian cow
|
OP
Ameglian cow
Joined: Dec 2014
Posts: 40 |
Holy wall of text bat-man! Thanks for posting! I will begin the process of reading yours and others posts. Thank you!
|
|
|
|
|