-
Notifications
You must be signed in to change notification settings - Fork 4
/
handler.py
144 lines (128 loc) · 5.44 KB
/
handler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import signal
from oyoyo.cmdhandler import DefaultCommandHandler
from oyoyo import helpers
from constants import VERSION, HELP_URL
from kevinbot import KevinBotGM
class KevinBotCommandHandler(DefaultCommandHandler):
def __abort(self):
for chan in self.channels:
self.client.send('MODE %s -m' % chan)
def __init__(self, client, settings):
self.client = client
self.settings = settings
self.my_nick = self.settings['nick']
self.users = {} # users[association.
self.channels = {} # This stores the channel->game association.
self.busy = 1 # Wait for RPL_WELCOME.
for chan in self.settings['channels']:
self.channels[chan] = None
for i in range(1, signal.NSIG):
try:
signal.signal(i, lambda *args: self.__sighandler(*args))
except RuntimeError:
pass
def __sighandler(self, signalnum, *args):
self.__abort()
self.client.send('QUIT :Caught signal %d' % signalnum)
exit(1)
def channelmodeis(self, host, nick, chan, modestr, *args):
self.channels[chan]._cmode(modestr)
def endofnames(self, host, nick, chan, msg):
self.channels[chan]._endofnames()
def invite(self, nickhost, target, chan):
nick, host = nickhost.split('!')
if nick in self.settings['admins']:
if target == self.my_nick and not chan in self.channels:
self.channels[chan] = KevinBotGM(self, chan)
else:
pass # TODO: figure out whether this can happen
else:
helpers.msg(self.client, nick, 'Only a kevinbot admin can ' +
'add channels.')
def join(self, nickhost, chan):
nick, host = nickhost.split('!')
self.channels[chan]._join(nick) # Delegate
def kick(self, nickhost, chan, target, msg):
if target == self.my_nick:
del self.channels[chan]
else:
self.channels[chan]._kick(nick)
'''
You may notice there is no kill handler. This is because when other users
get killed, we see it as a quit, but when we get killed, there is no point
in trying to continue anyway.
'''
def mode(self, nickhost, target, modestr, *args):
if target != self.my_nick: # Ignore user modes.
self.channels[target]._mode(modestr, *args)
def namreply(self, host, nick, chanmode, chan, users):
nice = []
for user in users.split():
mode = ' '
if user[0] in '@%+':
mode, user = user[0], user[1:]
nice.append((user, mode))
self.channels[chan]._namreply(nice) # delegate
def nick(self, origin, newnick):
oldnick, host = origin.split('!')
# If this is us, it means a nick change was forced
if oldnick == self.my_nick:
self.my_nick = newnick
# Propagate this change to all channels.
for chan in self.channels:
self.channels[chan]._nick(oldnick, newnick)
def part(self, nickhost, chan, *args):
nick, host = nickhost.split('!')
self.channels[chan]._part(nick)
def privmsg(self, nickhost, chan, msg):
if self.busy:
return
nick, host = nickhost.split('!')
if chan == self.my_nick: # user private message
# Always respond to !version, !help, !die directly
if msg == '!version':
helpers.msg(self.client, nick, VERSION)
elif msg == '!help' or msg.startswith('!help '):
helpers.msg(self.client, nick, HELP_URL)
elif msg == '!die':
if nick in self.settings['admins']:
self.__abort()
self.client.send('QUIT :Killed by admin')
exit(0)
else:
helpers.msg(self.client, nick, 'Not authorized!')
else:
# The !abort and !kick commands require a channel argument.
# The !quit and !role commands do not.
args = msg.split()
if len(args) == 0:
return
if args[0] == '!abort' or args[0] == '!kick':
if len(args) >= 2:
if args[1] in self.channels:
self.channels[args[1]]._usermsg(
nick, ' '.join([args[0]] + args[2:])
)
else:
helpers.msg(
self.client,
nick,
'Channel %s does not exist!' % args[1]
)
else:
for game in self.channels.values():
if nick in game.players:
game._usermsg(nick, msg)
else: # channel message; dispatch to appropriate GM
self.channels[chan]._chanmsg(nick, msg)
def quit(self, nickhost, msg, *args):
nick, host = nickhost.split('!')
for chan in self.channels:
self.channels[chan]._quit(nick)
def welcome(self, *args):
'''Wait for the RPL_WELCOME before joining channels.'''
self.busy -= 1
# We don't really care whether this succeeds.
helpers.ns(self.client, 'IDENTIFY', self.settings['password'])
for chan in self.channels:
self.channels[chan] = KevinBotGM(self, chan)