mirror of
https://github.com/jlu5/PyLink.git
synced 2024-11-27 21:19:31 +01:00
Many fixes
- Move _nicktoUid to utils.py - Make _sendFromUser arguments more consistent (irc, sendfrom, message) instead of (irc, message, sendfrom=None) - Add admin only kickclient, partclient, and nickclient commands - proto.joinClient: take UIDs instead of an IrcUser object, in order to be more consistent Closes #4, Closes #12.
This commit is contained in:
parent
8bbf4ba387
commit
43a46d3d99
@ -31,19 +31,19 @@ def spawnclient(irc, source, args):
|
|||||||
proto.spawnClient(irc, nick, ident, host)
|
proto.spawnClient(irc, nick, ident, host)
|
||||||
|
|
||||||
@utils.add_cmd
|
@utils.add_cmd
|
||||||
def removeclient(irc, source, args):
|
def quitclient(irc, source, args):
|
||||||
checkauthenticated(irc, source)
|
checkauthenticated(irc, source)
|
||||||
try:
|
try:
|
||||||
nick = args[0].lower()
|
nick = args[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
utils.msg(irc, source, "Error: not enough arguments. Needs 1: nick.")
|
utils.msg(irc, source, "Error: not enough arguments. Needs 1: nick.")
|
||||||
return
|
return
|
||||||
u = _nicktoUid(nick)
|
if irc.pseudoclient.uid == utils._nicktoUid(irc, nick):
|
||||||
if u is None or u not in irc.server[irc.sid].users:
|
utils.msg(irc, source, "Error: cannot quit the main PyLink PseudoClient!")
|
||||||
utils.msg(irc, source, "Error: user %r not found." % nick)
|
|
||||||
return
|
return
|
||||||
_sendFromUser(irc, u, "QUIT :Client Quit")
|
u = utils._nicktoUid(irc, nick)
|
||||||
proto.removeClient(irc, nick, ident, host)
|
quitmsg = ' '.join(args[1:]) or 'Client quit'
|
||||||
|
proto.quitClient(irc, u, quitmsg)
|
||||||
|
|
||||||
@utils.add_cmd
|
@utils.add_cmd
|
||||||
def joinclient(irc, source, args):
|
def joinclient(irc, source, args):
|
||||||
@ -56,12 +56,56 @@ def joinclient(irc, source, args):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
utils.msg(irc, source, "Error: not enough arguments. Needs 2: nick, comma separated list of channels.")
|
utils.msg(irc, source, "Error: not enough arguments. Needs 2: nick, comma separated list of channels.")
|
||||||
return
|
return
|
||||||
u = _nicktoUid(nick)
|
u = utils._nicktoUid(irc, nick)
|
||||||
if u is None or u not in irc.server[irc.sid].users:
|
|
||||||
utils.msg(irc, source, "Error: user %r not found." % nick)
|
|
||||||
return
|
|
||||||
for channel in clist:
|
for channel in clist:
|
||||||
if not channel.startswith('#'):
|
if not channel.startswith('#'):
|
||||||
utils.msg(irc, source, "Error: channel names must start with #.")
|
utils.msg(irc, source, "Error: channel names must start with #.")
|
||||||
return
|
return
|
||||||
joinClient(irc, ','.join(clist))
|
proto.joinClient(irc, u, channel)
|
||||||
|
|
||||||
|
@utils.add_cmd
|
||||||
|
def nickclient(irc, source, args):
|
||||||
|
checkauthenticated(irc, source)
|
||||||
|
try:
|
||||||
|
nick = args[0]
|
||||||
|
newnick = args[1]
|
||||||
|
except IndexError:
|
||||||
|
utils.msg(irc, source, "Error: not enough arguments. Needs 2: nick, newnick.")
|
||||||
|
return
|
||||||
|
u = utils._nicktoUid(irc, nick)
|
||||||
|
proto.nickClient(irc, u, newnick)
|
||||||
|
|
||||||
|
@utils.add_cmd
|
||||||
|
def partclient(irc, source, args):
|
||||||
|
checkauthenticated(irc, source)
|
||||||
|
try:
|
||||||
|
nick = args[0]
|
||||||
|
clist = args[1].split(',')
|
||||||
|
reason = ' '.join(args[2:])
|
||||||
|
except IndexError:
|
||||||
|
utils.msg(irc, source, "Error: not enough arguments. Needs 2: nick, comma separated list of channels.")
|
||||||
|
return
|
||||||
|
u = utils._nicktoUid(irc, nick)
|
||||||
|
for channel in clist:
|
||||||
|
if not channel.startswith('#'):
|
||||||
|
utils.msg(irc, source, "Error: channel names must start with #.")
|
||||||
|
return
|
||||||
|
proto.partClient(irc, u, channel, reason)
|
||||||
|
|
||||||
|
@utils.add_cmd
|
||||||
|
def kickclient(irc, source, args):
|
||||||
|
checkauthenticated(irc, source)
|
||||||
|
try:
|
||||||
|
nick = args[0]
|
||||||
|
channel = args[1]
|
||||||
|
target = args[2]
|
||||||
|
reason = ' '.join(args[3:])
|
||||||
|
except IndexError:
|
||||||
|
utils.msg(irc, source, "Error: not enough arguments. Needs 3-4: nick, channel, target, reason (optional).")
|
||||||
|
return
|
||||||
|
u = utils._nicktoUid(irc, nick)
|
||||||
|
targetu = utils._nicktoUid(irc, target)
|
||||||
|
if not channel.startswith('#'):
|
||||||
|
utils.msg(irc, source, "Error: channel names must start with #.")
|
||||||
|
return
|
||||||
|
proto.kickClient(irc, u, channel, targetu, reason)
|
||||||
|
74
proto.py
74
proto.py
@ -9,15 +9,8 @@ from classes import *
|
|||||||
def _sendFromServer(irc, msg):
|
def _sendFromServer(irc, msg):
|
||||||
irc.send(':%s %s' % (irc.sid, msg))
|
irc.send(':%s %s' % (irc.sid, msg))
|
||||||
|
|
||||||
def _sendFromUser(irc, msg, user=None):
|
def _sendFromUser(irc, numeric, msg):
|
||||||
if user is None:
|
irc.send(':%s %s' % (numeric, msg))
|
||||||
user = irc.pseudoclient.uid
|
|
||||||
irc.send(':%s %s' % (user, msg))
|
|
||||||
|
|
||||||
def _nicktoUid(irc, nick):
|
|
||||||
for k, v in irc.users.items():
|
|
||||||
if v.nick == nick:
|
|
||||||
return k
|
|
||||||
|
|
||||||
def spawnClient(irc, nick, ident, host, *args):
|
def spawnClient(irc, nick, ident, host, *args):
|
||||||
uid = next_uid(irc.sid)
|
uid = next_uid(irc.sid)
|
||||||
@ -30,12 +23,19 @@ def spawnClient(irc, nick, ident, host, *args):
|
|||||||
return u
|
return u
|
||||||
|
|
||||||
def joinClient(irc, client, channel):
|
def joinClient(irc, client, channel):
|
||||||
# Channel list can be a comma-separated list of channels, per the
|
# One channel per line here!
|
||||||
# IRC specification.
|
|
||||||
if not isInternalClient(irc, client):
|
if not isInternalClient(irc, client):
|
||||||
raise LookupError('No user/PyLink PseudoClient %r exists.' % client)
|
raise LookupError('No such PyLink PseudoClient exists.')
|
||||||
_sendFromUser(irc, "JOIN {channel} {ts} +nt :,{uid}".format(sid=irc.sid,
|
_sendFromServer(irc, "FJOIN {channel} {ts} + :,{uid}".format(
|
||||||
ts=int(time.time()), uid=client.uid, channel=channel))
|
ts=int(time.time()), uid=client, channel=channel))
|
||||||
|
|
||||||
|
def partClient(irc, client, channel, reason=None):
|
||||||
|
if not isInternalClient(irc, client):
|
||||||
|
raise LookupError('No such PyLink PseudoClient exists.')
|
||||||
|
msg = "PART %s" % channel
|
||||||
|
if reason:
|
||||||
|
msg += " :%s" % reason
|
||||||
|
_sendFromUser(irc, client, msg)
|
||||||
|
|
||||||
def removeClient(irc, numeric):
|
def removeClient(irc, numeric):
|
||||||
"""<irc object> <client numeric>
|
"""<irc object> <client numeric>
|
||||||
@ -60,34 +60,36 @@ def isInternalClient(irc, numeric):
|
|||||||
"""
|
"""
|
||||||
return numeric in irc.servers[irc.sid].users
|
return numeric in irc.servers[irc.sid].users
|
||||||
|
|
||||||
def quitClient(irc, numeric):
|
def quitClient(irc, numeric, reason):
|
||||||
"""<irc object> <client numeric>
|
"""<irc object> <client numeric>
|
||||||
|
|
||||||
Quits a PyLink PseudoClient."""
|
Quits a PyLink PseudoClient."""
|
||||||
if isInternalClient(irc, numeric):
|
if isInternalClient(irc, numeric):
|
||||||
_sendFromUser(irc, numeric, "QUIT :Client quit")
|
_sendFromUser(irc, numeric, "QUIT :%s" % reason)
|
||||||
|
removeClient(irc, numeric)
|
||||||
else:
|
else:
|
||||||
raise LookupError("No user %r exists. If you're trying to remove "
|
raise LookupError("No such PyLink PseudoClient exists. If you're trying to remove "
|
||||||
"a user that's not a PyLink PseudoClient from "
|
"a user that's not a PyLink PseudoClient from "
|
||||||
"the internal state, use removeClient() instead.")
|
"the internal state, use removeClient() instead.")
|
||||||
|
|
||||||
def kickClient(irc, channel, numeric, target, reason=None):
|
def kickClient(irc, numeric, channel, target, reason=None):
|
||||||
"""<irc object> <kicker client numeric>
|
"""<irc object> <kicker client numeric>
|
||||||
|
|
||||||
Sends a kick from a PyLink PseudoClient."""
|
Sends a kick from a PyLink PseudoClient."""
|
||||||
if not isInternalClient(irc, numeric):
|
if not isInternalClient(irc, numeric):
|
||||||
raise LookupError('No user/PyLink PseudoClient %r exists.' % numeric)
|
raise LookupError('No such PyLink PseudoClient exists.')
|
||||||
if reason is None:
|
if not reason:
|
||||||
reason = irc.users[target].nick
|
reason = 'No reason given'
|
||||||
_sendFromUser(irc, numeric, 'KICK %s %s :%s' % (channel, target, reason))
|
_sendFromUser(irc, numeric, 'KICK %s %s :%s' % (channel, target, reason))
|
||||||
|
|
||||||
def nickClient(irc, numeric, newnick, reason=None):
|
def nickClient(irc, numeric, newnick):
|
||||||
"""<irc object> <client numeric> <new nickname>
|
"""<irc object> <client numeric> <new nickname>
|
||||||
|
|
||||||
Changes the nick of a PyLink PseudoClient."""
|
Changes the nick of a PyLink PseudoClient."""
|
||||||
if not isInternalClient(irc, numeric):
|
if not isInternalClient(irc, numeric):
|
||||||
raise LookupError('No user/PyLink PseudoClient %r exists.' % numeric)
|
raise LookupError('No such PyLink PseudoClient exists.')
|
||||||
_sendFromUser(irc, numeric, 'NICK %s' % newnick)
|
_sendFromUser(irc, numeric, 'NICK %s %s' % (newnick, int(time.time())))
|
||||||
|
irc.users[numeric].nick = newnick
|
||||||
|
|
||||||
def connect(irc):
|
def connect(irc):
|
||||||
irc.start_ts = ts = int(time.time())
|
irc.start_ts = ts = int(time.time())
|
||||||
@ -110,7 +112,8 @@ def connect(irc):
|
|||||||
# +ACKNOQcdfgklnoqtx :Craig Edwards
|
# +ACKNOQcdfgklnoqtx :Craig Edwards
|
||||||
irc.pseudoclient = spawnClient(irc, 'PyLink', 'pylink', host)
|
irc.pseudoclient = spawnClient(irc, 'PyLink', 'pylink', host)
|
||||||
f(':%s ENDBURST' % (irc.sid))
|
f(':%s ENDBURST' % (irc.sid))
|
||||||
joinClient(irc, irc.pseudoclient, ','.join(irc.serverdata['channels']))
|
for chan in irc.serverdata['channels']:
|
||||||
|
joinClient(irc, irc.pseudoclient.uid, chan)
|
||||||
|
|
||||||
# :7NU PING 7NU 0AL
|
# :7NU PING 7NU 0AL
|
||||||
def handle_ping(irc, servernumeric, command, args):
|
def handle_ping(irc, servernumeric, command, args):
|
||||||
@ -143,7 +146,8 @@ def handle_kill(irc, source, command, args):
|
|||||||
removeClient(irc, killed)
|
removeClient(irc, killed)
|
||||||
if killed == irc.pseudoclient.uid:
|
if killed == irc.pseudoclient.uid:
|
||||||
irc.pseudoclient = spawnClient(irc, 'PyLink', 'pylink', irc.serverdata["hostname"])
|
irc.pseudoclient = spawnClient(irc, 'PyLink', 'pylink', irc.serverdata["hostname"])
|
||||||
joinClient(irc, irc.pseudoclient, ','.join(irc.serverdata['channels']))
|
for chan in irc.serverdata['channels']:
|
||||||
|
joinClient(irc, irc.pseudoclient.uid, chan)
|
||||||
|
|
||||||
def handle_kick(irc, source, command, args):
|
def handle_kick(irc, source, command, args):
|
||||||
# :70MAAAAAA KICK #endlessvoid 70MAAAAAA :some reason
|
# :70MAAAAAA KICK #endlessvoid 70MAAAAAA :some reason
|
||||||
@ -151,7 +155,7 @@ def handle_kick(irc, source, command, args):
|
|||||||
kicked = args[1]
|
kicked = args[1]
|
||||||
irc.channels[channel].users.discard(kicked)
|
irc.channels[channel].users.discard(kicked)
|
||||||
if kicked == irc.pseudoclient.uid:
|
if kicked == irc.pseudoclient.uid:
|
||||||
joinClient(irc, irc.pseudoclient, channel)
|
joinClient(irc, irc.pseudoclient.uid, channel)
|
||||||
|
|
||||||
def handle_part(irc, source, command, args):
|
def handle_part(irc, source, command, args):
|
||||||
channel = args[0]
|
channel = args[0]
|
||||||
@ -211,11 +215,24 @@ def handle_nick(irc, numeric, command, args):
|
|||||||
newnick = args[0]
|
newnick = args[0]
|
||||||
irc.users[numeric].nick = newnick
|
irc.users[numeric].nick = newnick
|
||||||
|
|
||||||
|
def handle_save(irc, numeric, command, args):
|
||||||
|
# This is used to handle nick collisions. Here, the client Derp_ already exists,
|
||||||
|
# so trying to change nick to it will cause a nick collision. On InspIRCd,
|
||||||
|
# this will simply set the collided user's nick to its UID.
|
||||||
|
|
||||||
|
# <- :70MAAAAAA PRIVMSG 0AL000001 :nickclient PyLink Derp_
|
||||||
|
# -> :0AL000001 NICK Derp_ 1433728673
|
||||||
|
# <- :70M SAVE 0AL000001 1433728673
|
||||||
|
user = args[0]
|
||||||
|
irc.users[user].nick = user
|
||||||
|
|
||||||
|
'''
|
||||||
def handle_fmode(irc, numeric, command, args):
|
def handle_fmode(irc, numeric, command, args):
|
||||||
# <- :70MAAAAAA FMODE #chat 1433653462 +hhT 70MAAAAAA 70MAAAAAD
|
# <- :70MAAAAAA FMODE #chat 1433653462 +hhT 70MAAAAAA 70MAAAAAD
|
||||||
# Oh god, how are we going to handle this?!
|
# Oh god, how are we going to handle this?!
|
||||||
channel = args[0]
|
channel = args[0]
|
||||||
modestrings = args[3:]
|
modestrings = args[3:]
|
||||||
|
'''
|
||||||
|
|
||||||
def handle_squit(irc, numeric, command, args):
|
def handle_squit(irc, numeric, command, args):
|
||||||
# :70M SQUIT 1ML :Server quit by GL!gl@0::1
|
# :70M SQUIT 1ML :Server quit by GL!gl@0::1
|
||||||
@ -238,8 +255,7 @@ def handle_idle(irc, numeric, command, args):
|
|||||||
# -> :1MLAAAAIG IDLE 70MAAAAAA 1433036797 319
|
# -> :1MLAAAAIG IDLE 70MAAAAAA 1433036797 319
|
||||||
sourceuser = numeric
|
sourceuser = numeric
|
||||||
targetuser = args[0]
|
targetuser = args[0]
|
||||||
_sendFromUser(irc, 'IDLE %s %s 0' % (sourceuser, irc.start_ts),
|
_sendFromUser(irc, targetuser, 'IDLE %s %s 0' % (sourceuser, irc.start_ts))
|
||||||
user=targetuser)
|
|
||||||
|
|
||||||
def handle_events(irc, data):
|
def handle_events(irc, data):
|
||||||
# Each server message looks something like this:
|
# Each server message looks something like this:
|
||||||
|
7
utils.py
7
utils.py
@ -19,10 +19,15 @@ def next_uid(sid, level=-1):
|
|||||||
|
|
||||||
def msg(irc, target, text, notice=False):
|
def msg(irc, target, text, notice=False):
|
||||||
command = 'NOTICE' if notice else 'PRIVMSG'
|
command = 'NOTICE' if notice else 'PRIVMSG'
|
||||||
proto._sendFromUser(irc, '%s %s :%s' % (command, target, text))
|
proto._sendFromUser(irc, irc.pseudoclient.uid, '%s %s :%s' % (command, target, text))
|
||||||
|
|
||||||
def add_cmd(func, name=None):
|
def add_cmd(func, name=None):
|
||||||
if name is None:
|
if name is None:
|
||||||
name = func.__name__
|
name = func.__name__
|
||||||
name = name.lower()
|
name = name.lower()
|
||||||
bot_commands[name] = func
|
bot_commands[name] = func
|
||||||
|
|
||||||
|
def _nicktoUid(irc, nick):
|
||||||
|
for k, v in irc.users.items():
|
||||||
|
if v.nick == nick:
|
||||||
|
return k
|
||||||
|
Loading…
Reference in New Issue
Block a user