-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathirc_client.py
More file actions
162 lines (119 loc) · 5.48 KB
/
Copy pathirc_client.py
File metadata and controls
162 lines (119 loc) · 5.48 KB
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import functools
from twisted.internet import protocol, reactor
from twisted.python import log
from twisted.web import client
from twisted.words.protocols import irc
import commands
PREFIXES = '!.@'
CHANNEL_DELIM = '\xf0'
class HMIRCClient(irc.IRCClient):
max_per_msg = 450
def __init__(self):
self.commands = {
'servers': self.__command_servers,
'stats': self.__command_stats,
}
def __command_servers(self, write, **_):
servers = map(lambda x: x['client'].factory, filter(lambda x: x.get('client'), self.factory.controller.servers.itervalues()))
servers = map(lambda x: x.formatted_name, sorted(servers, key=lambda x: x.name))
write('Servers: ' + ', '.join(servers or ('none!',)))
def __command_stats(self, write, args, **_):
url = self.factory.stats_url + '&player=' + args
if url:
client.getPage(url).addCallback(write)
def connectionMade(self):
irc.IRCClient.connectionMade(self)
self.factory.controller.irc_client = self
self.admins = set()
def signedOn(self):
self.lineRate = self.factory.controller.irc_identity.get('line_rate')
if self.factory.controller.irc_identity['nickserv']['service_name'] and self.factory.controller.irc_identity['nickserv']['password']:
self.msg(self.factory.controller.irc_identity['nickserv']['service_name'], 'IDENTIFY %s' % self.factory.controller.irc_identity['nickserv']['password'])
for i in self.factory.controller.irc_identity.get('admin_channels', ()):
self.join(i)
for i in self.factory.controller.irc_identity['channels']:
self.join(i)
def noticed(self, user, channel, msg):
pass
def joined(self, channel):
log.msg('Joined %s' % channel)
def left(self, channel):
log.msg('Left %s' % channel)
def ctcpQuery(self, user, channel, messages):
pass
def irc_RPL_NAMREPLY(self, prefix, params):
chantype, channel, users = params[1:]
self.admins |= set([user[1:] for user in users.split() if user[0] == '@'])
def userLeft(self, user, channel):
self.admins.discard(user)
def userQuit(self, user, channel):
self.admins.discard(user)
def userKicked(self, user, channel, kicker, message):
self.admins.discard(user)
def userRenamed(self, oldname, newname):
if oldname in self.admins:
self.admins.remove(oldname)
self.admins.add(newname)
def modeChanged(self, user, channel, set, modes, args):
for n, mode in enumerate(modes):
if mode == 'o' and args[n] != self.nickname:
(self.admins.discard, self.admins.add)[set](args[n])
def write(self, message, admin_channel=False):
if not message:
return
if admin_channel:
for channel in self.factory.controller.irc_identity.get('admin_channels', ()):
self.msg(channel, message)
else:
for channel in self.factory.controller.irc_identity['channels']:
self.msg(channel, message)
def msg(self, channel, message):
for line in message.splitlines():
irc.IRCClient.msg(self, channel, line)
def privmsg(self, user, channel, msg):
global servers
servers = dict([(a,b) for a,b in self.factory.controller.servers.iteritems() if b.get('client')])
if msg[0] in PREFIXES:
no_prefix = msg.lstrip(PREFIXES)
command, _, args = no_prefix.partition(' ')
command = command.lower()
nickname = user.split('!')[0]
target = nickname if channel == self.nickname else channel
command_args = {
'args': args,
'channel': target,
'write': functools.partial(self.msg, target),
}
if command in self.commands:
reactor.callLater(0.0, self.commands[command], **command_args)
return
log.msg('%s -> %s: %s' % (user, command, args))
for server_name in servers:
if user.split('!')[0] in self.admins and (command == server_name or command == 'all'):
server_command, _, n_args = args.partition(' ')
if server_command in commands.server:
command_args['nickname'] = nickname
command_args['args'] = n_args
cmd = """def server_write(message):
servers['%s']['client'].sendLine(('%%s%%s %%s' %% (CHANNEL_DELIM, '%s', message)).replace('\\n', ' '))""" % (server_name, target)
exec cmd
command_args['server_write'] = server_write
reactor.callLater(0.0, commands.server[server_command], **command_args)
if channel[0] != '#':
log.msg('%s: %s' % (user, msg))
class HMIRCFactory(protocol.ClientFactory):
protocol = HMIRCClient
def __init__(self, controller, nickname):
self.controller = controller
self.nickname = nickname
def buildProtocol(self, addr):
p = self.protocol()
p.nickname = self.nickname
p.factory = self
return p
def clientConnectionLost(self, connector, reason):
connector.connect()
def clientConnectionFailed(self, connector, reason):
reactor.stop()
def __repr__(self):
return 'HMIRCFactory "%s"' % self.nickname