|
Joined: Mar 2007
Posts: 139
Vogon poet
|
OP
Vogon poet
Joined: Mar 2007
Posts: 139 |
Hi people I have a socket bot. I want to follow user modes correctly and am having difficulty with it. I am getting user modes on joining a channel from the names list but when mode changes happen in a channel i have trouble following them. I want to add these mode changes to a hash table so if solo has +v and then gets +o the hash table should show +vo. Additionally i want to cater if someone sets /mode #test +oo-v solo solo123 otheruser so it should show that solo1 and solo123 having +o and otheruser -v etc. I have pasted the raw message my server sends and the deficient code idea i am using now. ;server raw example :Solo!solo@hhx-C0087967.dsl.in-add.orange.co.uk MODE #test +o Solo;my code example if ($2 == mode) && (+ isin $4) {
hadd -m temp $+($3,_,$5) users mode
} as you can see it wont keep track of complex mode changes etc. What is the best way of doing this? Many Thanks
|
|
|
|
Joined: Aug 2004
Posts: 7,252
Hoopy frood
|
Hoopy frood
Joined: Aug 2004
Posts: 7,252 |
While you could script a lot of events for this, ON JOIN, ON PART, ON QUIT, ON KICK, ON BAN, etc,. etc. etc. You could also use the ON RAWMODE event With this event, the line /mode #test +oo-v solo solo123 otheruser would return +oo-v solo solo123 otheruser as $1- As I'm not familiar with socket bots, this may not be applicable to your usage, but from a mIRC scripting aspect, this should be ideal.
|
|
|
|
Joined: Mar 2007
Posts: 139
Vogon poet
|
OP
Vogon poet
Joined: Mar 2007
Posts: 139 |
Hi I am aware of that event but it won't help me as i am using sockets as i mentioned.
|
|
|
|
Joined: Oct 2005
Posts: 1,741
Hoopy frood
|
Hoopy frood
Joined: Oct 2005
Posts: 1,741 |
I'm not entirely familiar with raw MODE changes, but I believe you have to check any and all modes in the MODE raw against the list of user/channel modes given by the server when you first connect (I don't know the RAW of that list, probably 001-005). That will tell you whether each mode (character) needs to use one of the arguments provided after the mode characters. ie
:nick!ident@host MODE #channel +os-v targetnick1 targetnick2
= mode characters = arguments
In the example, mode +o (ops) requires an argument and consumes the first nickname provided. Mode +s (secret channel) doesn't require an argument, so it doesn't use up one from the list. Mode -v (devoice) requires an argument, so it consumes the remaining argument given.
The server I am presently on, doesn't use this method (precisely). Instead, it arranges the mode characters so that if n arguments are provided, the mode characters associated with those arguments are last in the string of mode characters. Example:
/mode #channel -hC+Rv targetnick1 targetnick2 :nick!ident@host MODE #channel +R-Ch+v genius_at_work genius_at_work
You can see that the server rearranged the modes so that the two requiring arguments (-h and +v) were last in the mode character string. Because of the modes I chose to set and unset, the server had to do + modes twice.
Your script should take these two possibilities into account if you plan on using it on more than one server.
-genius_at_work
|
|
|
|
Joined: Mar 2007
Posts: 139
Vogon poet
|
OP
Vogon poet
Joined: Mar 2007
Posts: 139 |
Hi Genius at work Thanks for your reply
Basically it does not matter how the server changes the modes, i want to correctly parse whatever the socket sees. For example i just did the following
/mode #test +oo-v Adam comperr decay Solo the socket saw this :Solo!solo@hhx-C0087967.dsl.in-addr.orange.co.uk MODE #test +oo-v Adam comperr decay
Basically i want to track save all user modes and add it to a temp hash table in this format $+(#channel_username) usersmodes hence the hadd -m temp $+($3,_,$5) users mode example i pasted before. Trouble is it only caters in an event one users mode changes it will correctly track but if say a few users modes are changed in one command it will not correctly track all the changes.
p.s The socket sees basically what one would see in a debug window /debug @debug
Last edited by Solo1; 19/08/08 03:14 PM.
|
|
|
|
Joined: Oct 2007
Posts: 214
Fjord artisan
|
Fjord artisan
Joined: Oct 2007
Posts: 214 |
This is what I use, I tend to stay away from raw data from sockets as it can be really messy, but for ease of use im sharing this with you. You can format it to your own needs.
on ^*:RAWMODE:*: {
var %p = $left($nick($chan,$nick).pnick,1) | if (%p == $left($nick,1)) { unset %p }
if ($regex($1,/^[\+-]?[ifmstplk]$/)) { echo $color(mode) -ti2 $chan 3› %p $+ $replace($nick,>,Guest_) sets mode: 14 $+ $chr(91) $+ 14 $+(3,$1,3) $2- 14 $+ $chr(93) 143 $+(14,«,3) $chan $+(14,»3) | haltdef }
else {
echo $color(mode) -ti2 $chan 3› %p $+ $replace($nick,>,Guest_) sets mode: 14 $+ $chr(91) $+ 14 $+(3,$regsubex($1,/([oqQvh])\1+/g,\t),3) 14 $+ $chr(93) 143 $replace($2-,$chr(32),$+($chr(44),$chr(32)))
haltdef
}
}
|
|
|
|
Joined: Mar 2007
Posts: 139
Vogon poet
|
OP
Vogon poet
Joined: Mar 2007
Posts: 139 |
Hi Am not sure this would work for me as am using sockets i would not be able to use $nick or $nick(#,1).pnick properties.
|
|
|
|
Joined: Jan 2003
Posts: 2,523
Hoopy frood
|
Hoopy frood
Joined: Jan 2003
Posts: 2,523 |
Here's something that should get you going: alias parseusermodes {
/*
* Fill the two variables below accordingly.
* When connected normally, mirc provides
* this information via $nickmode and $chanmodes
* but you can't use those in sockets. Ideally you
* should be getting them from the 005 raw, if supplied
*/
var %nickmode = $nickmode
var %chanmodes = $chanmodes
hfree -w usermodes
hmake usermodes 10
var %i = 1, %sign
while $mid($1,%i,1) != $null {
if ($v1 isin +-) %sign = $v1
else {
var %mode = $v1
if $2 != $null && %mode isincs %nickmode {
var %oppsign = $mid(-+,%sign $+ 1,1)
hadd usermodes %sign $+ %mode $addtok($hget(usermodes,%sign $+ %mode),$2,32)
hadd usermodes %oppsign $+ %mode $remtok($hget(usermodes,%oppsign $+ %mode),$2,32)
tokenize 32 $1 $3-
}
elseif ($matchtokcs(%chanmodes,%mode,1,44) != $null && $&
($findtokcs(%chanmodes,$v1,44) isnum 1-2 || ($v1 %sign == 3 +))) $&
tokenize 32 $1 $3-
}
inc %i
}
; done parsing, now just display the user modes
%i = 1
while $hget(usermodes,%i).item {
%mode = $v1
if ($hget(usermodes,$v1) != $null) {
var %nicks = $v1
echo -a %mode : %nicks
}
inc %i
}
hfree usermodes
} You can test it like this: /parseusermodes +ooim-lv Adam comperr decay
/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
|
|
|
|
Joined: Oct 2005
Posts: 1,741
Hoopy frood
|
Hoopy frood
Joined: Oct 2005
Posts: 1,741 |
What I'm trying to say is that it DOES matter how the server parses the data. Not every mode that is set in a channel is related to specific users. IE. you cannot set /mode #channel +s nickname because +s sets a channel to secret, and thus doesn't have anything to do with a specific user. Here is another sample code that may help you:
alias parsemodes {
;$1=channel, $2=modestring, $3-=arguments
var %numargs = $numtok($3-,32)
var %nummodes = $len($remove($2,+,-))
var %sign, %char, %arg
var %mcount = 0, %acount = 0
var %i = 0, %ii = $len($2)
while (%i < %ii) {
inc %i
%char = $mid($2,%i,1)
if (%char isin +-) { %sign = %char | continue }
inc %mcount
if (%mcount <= $calc(%nummodes - %numargs)) { continue }
inc %acount
%arg = $gettok($3-,%acount,32)
if ($ison(%arg,$1)) {
;echo -a $+(%sign,%char) %arg
%cmodes = $hget(usermodes,$+($1,_,%arg))
if ((%sign == +) && (%char !isin %cmodes)) { hadd -m usermodes $+($1,_,%arg) $sortmodes($+(%cmodes,%char)) }
elseif ((%sign == -) && (%char isin %cmodes)) { hadd -m usermodes $+($1,_,%arg) $sortmodes($removecs(%cmodes,%char)) }
}
}
;;; Display usermodes hash
var %x = 0, %xx = $hfind(usermodes,*,0,w)
while (%x < %xx) {
inc %x
echo -a $hfind(usermodes,*,%x,w) $hget(usermodes,$hfind(usermodes,*,%x,w))
}
}
;Don't change this alias
alias sortmodes { return $remove($sorttok($regsubex($1,/([a-z])/gi,\1.),46),.) }
;This alias should return $true if $1 ison channel $2
alias ison { return $true }
Syntax: /parsemodes #channel +Cov nickname1 nickname2 /parsemodes #channel +Co-v nickname1 nickname2 /parsemodes #channel +C-ov nickname1 nickname2 /parsemodes #channel +R-Ch+v nickname1 nickname2 The alias $ison needs to be altered to return $true if the nickname ($1) is on the channel ($2). You probably already keep track of this somehow in your script. Don't change the $sortmodes alias. I added a portion of code to display what is in the usermodes hash table for debug purposes. -genius_at_work
|
|
|
|
Joined: Mar 2007
Posts: 139
Vogon poet
|
OP
Vogon poet
Joined: Mar 2007
Posts: 139 |
Hi Geniusatwork This looks really good. I will play with it a little to try and mod it for my script. Thanks edit: After some work i have modded it to my script and it does exactly what i need. But i have tried to make it work with 353 names event on joining a channel and since i dont properly understand the format of this code i have not been successful. I wonder if you could help me with that? if ($2 == 353) {
get usermodes of names in the #channel and add it to the hash table
} Thanks :Second EditOk i have managed to do something that gets the modes on a join event. Please let me know if there is a more efficient way of doing this. if ($2 == 353) {
var %i = 1,%line = $remove($6-,:)
while $gettok(%line,%i,32) {
var %mode = $left($v1,1)
if ($regex(%mode,/(@|&|~|%|v)/g)) { hadd -m usermodes $+($5,_,$remove($gettok(%line,%i,32),@,&,~,%)) $replace(%mode,&,a,@,o,%,h,~,q) }
inc %i
}
}
Last edited by Solo1; 20/08/08 11:43 AM.
|
|
|
|
Joined: Oct 2005
Posts: 1,741
Hoopy frood
|
Hoopy frood
Joined: Oct 2005
Posts: 1,741 |
One correction for my above code:
if ((%sign == +) && (%char !isin %cmodes)) { hadd -m usermodes $+($1,_,%arg) $sortmodes($+(%cmodes,%char)) }
elseif ((%sign == -) && (%char isin %cmodes)) { hadd -m usermodes $+($1,_,%arg) $sortmodes($removecs(%cmodes,%char)) }
should be:
if ((%sign == +) && (%char !isincs %cmodes)) { hadd -m usermodes $+($1,_,%arg) $sortmodes($+(%cmodes,%char)) }
elseif ((%sign == -) && (%char isincs %cmodes)) { hadd -m usermodes $+($1,_,%arg) $sortmodes($removecs(%cmodes,%char)) }
When you connect to the IRC server, you are sent a RAW that contains the PREFIX settings for that server. Example: PREFIX=(ohv)@%+ . The characters inside the brackets correspond to the characters outside the brackets in the same order. o -> @, h -> %, v -> +. You need to store that information when your bot connects, and then use it later. And here is a code to read the PREFIX from RAW 005 and user modes from RAW 353:
alias 005 {
var %pre = $gettok($matchtok($2-,PREFIX=,1,32),2,61)
var %prec = $remove($gettok(%pre,1,41),$chr(40))
var %pres = $gettok(%pre,2,41)
hadd -m server pre_symb %pres
hadd -m server pre_char %prec
}
alias 353 {
var %pres = $hget(server,pre_symb)
var %prec = $hget(server,pre_char)
var %temp, %nick, %symb, %char
var %i = 0, %ii = $numtok($5-,32)
while (%i < %ii) {
inc %i
%temp = $gettok($5-,%i,32)
%symb = $left(%temp,1)
%char = $null
%nick = %temp
if (%symb isin %pres) {
%char = $mid(%prec,$pos(%pres,%symb,1),1)
%nick = $mid(%temp,2)
}
;You can store the nicknames to a list here. $3=chan, %nick=nick
hadd -m userlist $+($3,_,%nick) $ctime
var %cmodes = $hget(usermodes,$+($3,_,%nick))
if (%char !isincs %cmodes) { hadd -m usermodes $+($3,_,%nick) $sortmodes($+(%cmodes,%char)) }
;echo -a > %symb : %char : %nick : %temp
}
}
These aliases respond to the standard format for their respective RAWs. Samples from my server: RAW 005: YourNick MAP KNOCK SAFELIST HCN WATCH=128 SILENCE=5 MODES=13 MAXCHANNELS=25 MAXBANS=120 NICKLEN=30 TOPICLEN=307 KICKLEN=307 CHANTYPES=# PREFIX=(ohv)@%+ are supported by this server RAW 353: YourNick @ #channel UserNick1 @UserNick2 %UserNick3 +UserNick4 The code adds the modes to the same hash as my previous code. -genius_at_work
|
|
|
|
|