3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-01 09:19:23 +01:00

Merge branch 'usermode-handling'

This commit is contained in:
James Lu 2015-06-20 22:05:01 -07:00
commit 0a1754dd4b
3 changed files with 69 additions and 15 deletions

View File

@ -1,7 +1,7 @@
class IrcUser(): class IrcUser():
def __init__(self, nick, ts, uid, ident='null', host='null', def __init__(self, nick, ts, uid, ident='null', host='null',
realname='PyLink dummy client', realhost='null', realname='PyLink dummy client', realhost='null',
ip='0.0.0.0'): ip='0.0.0.0', modes=set()):
self.nick = nick self.nick = nick
self.ts = ts self.ts = ts
self.uid = uid self.uid = uid
@ -10,6 +10,7 @@ class IrcUser():
self.realhost = realhost self.realhost = realhost
self.ip = ip self.ip = ip
self.realname = realname self.realname = realname
self.modes = modes
self.identified = False self.identified = False

View File

@ -3,12 +3,12 @@ import time
import sys import sys
import os import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from utils import * import utils
from copy import copy from copy import copy
import traceback import traceback
from classes import * from classes import *
uidgen = TS6UIDGenerator() uidgen = utils.TS6UIDGenerator()
def _sendFromServer(irc, msg): def _sendFromServer(irc, msg):
irc.send(':%s %s' % (irc.sid, msg)) irc.send(':%s %s' % (irc.sid, msg))
@ -16,14 +16,19 @@ def _sendFromServer(irc, msg):
def _sendFromUser(irc, numeric, msg): def _sendFromUser(irc, numeric, msg):
irc.send(':%s %s' % (numeric, msg)) irc.send(':%s %s' % (numeric, msg))
def spawnClient(irc, nick, ident, host, *args): def spawnClient(irc, nick, ident, host, modes=[], *args):
uid = uidgen.next_uid(irc.sid) uid = uidgen.next_uid(irc.sid)
ts = int(time.time()) ts = int(time.time())
if not isNick(nick): if modes:
modes = utils.joinModes(modes)
else:
modes = '+'
if not utils.isNick(nick):
raise ValueError('Invalid nickname %r.' % nick) raise ValueError('Invalid nickname %r.' % nick)
_sendFromServer(irc, "UID {uid} {ts} {nick} {host} {host} {ident} 0.0.0.0 {ts} +o +" _sendFromServer(irc, "UID {uid} {ts} {nick} {host} {host} {ident} 0.0.0.0 "
" :PyLink Client".format(ts=ts, host=host, "{ts} {modes} + :PyLink Client".format(ts=ts, host=host,
nick=nick, ident=ident, uid=uid)) nick=nick, ident=ident, uid=uid,
modes=modes))
u = irc.users[uid] = IrcUser(nick, ts, uid, ident, host, *args) u = irc.users[uid] = IrcUser(nick, ts, uid, ident, host, *args)
irc.servers[irc.sid].users.append(uid) irc.servers[irc.sid].users.append(uid)
return u return u
@ -32,7 +37,7 @@ def joinClient(irc, client, channel):
# One channel per line here! # One channel per line here!
if not isInternalClient(irc, client): if not isInternalClient(irc, client):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
if not isChannel(channel): if not utils.isChannel(channel):
raise ValueError('Invalid channel name %r.' % channel) raise ValueError('Invalid channel name %r.' % channel)
_sendFromServer(irc, "FJOIN {channel} {ts} + :,{uid}".format( _sendFromServer(irc, "FJOIN {channel} {ts} + :,{uid}".format(
ts=int(time.time()), uid=client, channel=channel)) ts=int(time.time()), uid=client, channel=channel))
@ -41,7 +46,7 @@ def partClient(irc, client, channel, reason=None):
if not isInternalClient(irc, client): if not isInternalClient(irc, client):
raise LookupError('No such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
msg = "PART %s" % channel msg = "PART %s" % channel
if not isChannel(channel): if not utils.isChannel(channel):
raise ValueError('Invalid channel name %r.' % channel) raise ValueError('Invalid channel name %r.' % channel)
if reason: if reason:
msg += " :%s" % reason msg += " :%s" % reason
@ -98,7 +103,7 @@ def nickClient(irc, numeric, newnick):
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 such PyLink PseudoClient exists.') raise LookupError('No such PyLink PseudoClient exists.')
if not isNick(newnick): if not utils.isNick(newnick):
raise ValueError('Invalid nickname %r.' % nick) raise ValueError('Invalid nickname %r.' % nick)
_sendFromUser(irc, numeric, 'NICK %s %s' % (newnick, int(time.time()))) _sendFromUser(irc, numeric, 'NICK %s %s' % (newnick, int(time.time())))
irc.users[numeric].nick = newnick irc.users[numeric].nick = newnick
@ -122,7 +127,7 @@ def connect(irc):
# :751 UID 751AAAAAA 1220196319 Brain brainwave.brainbox.cc # :751 UID 751AAAAAA 1220196319 Brain brainwave.brainbox.cc
# netadmin.chatspike.net brain 192.168.1.10 1220196324 +Siosw # netadmin.chatspike.net brain 192.168.1.10 1220196324 +Siosw
# +ACKNOQcdfgklnoqtx :Craig Edwards # +ACKNOQcdfgklnoqtx :Craig Edwards
irc.pseudoclient = spawnClient(irc, 'PyLink', 'pylink', host) irc.pseudoclient = spawnClient(irc, 'PyLink', 'pylink', host, modes=set(["+o"]))
f(':%s ENDBURST' % (irc.sid)) f(':%s ENDBURST' % (irc.sid))
for chan in irc.serverdata['channels']: for chan in irc.serverdata['channels']:
joinClient(irc, irc.pseudoclient.uid, chan) joinClient(irc, irc.pseudoclient.uid, chan)
@ -142,15 +147,15 @@ def handle_privmsg(irc, source, command, args):
except IndexError: except IndexError:
cmd_args = [] cmd_args = []
try: try:
func = bot_commands[cmd] func = utils.bot_commands[cmd]
except KeyError: except KeyError:
msg(irc, source, 'Unknown command %r.' % cmd) utils.msg(irc, source, 'Unknown command %r.' % cmd)
return return
try: try:
func(irc, source, cmd_args) func(irc, source, cmd_args)
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
msg(irc, source, 'Uncaught exception in command %r: %s: %s' % (cmd, type(e).__name__, str(e))) utils.msg(irc, source, 'Uncaught exception in command %r: %s: %s' % (cmd, type(e).__name__, str(e)))
return return
def handle_kill(irc, source, command, args): def handle_kill(irc, source, command, args):
@ -207,6 +212,9 @@ def handle_uid(irc, numeric, command, args):
uid, ts, nick, realhost, host, ident, ip = args[0:7] uid, ts, nick, realhost, host, ident, ip = args[0:7]
realname = args[-1] realname = args[-1]
irc.users[uid] = IrcUser(nick, ts, uid, ident, host, realname, realhost, ip) irc.users[uid] = IrcUser(nick, ts, uid, ident, host, realname, realhost, ip)
parsedmodes = utils.parseModes(args[8:9])
print('Applying modes %s for %s' % (parsedmodes, uid))
irc.users[uid].modes = utils.applyModes(irc.users[uid].modes, parsedmodes)
irc.servers[numeric].users.append(uid) irc.servers[numeric].users.append(uid)
def handle_quit(irc, numeric, command, args): def handle_quit(irc, numeric, command, args):
@ -246,6 +254,15 @@ def handle_fmode(irc, numeric, command, args):
modestrings = args[3:] modestrings = args[3:]
''' '''
def handle_mode(irc, numeric, command, args):
# In InspIRCd, MODE is used for setting user modes and
# FMODE is used for channel modes:
# <- :70MAAAAAA MODE 70MAAAAAA -i+xc
target = args[0]
modestrings = args[1:]
changedmodes = utils.parseModes(modestrings)
irc.users[numeric].modes = utils.applyModes(irc.users[numeric].modes, changedmodes)
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
split_server = args[0] split_server = args[0]

View File

@ -57,3 +57,39 @@ def isNick(s, nicklen=None):
def isChannel(s): def isChannel(s):
return bool(s.startswith('#')) return bool(s.startswith('#'))
def parseModes(args):
"""['+mitl-o', '3', 'person'] => ['+m', '+i', '+t', '-o']
TODO: handle modes with extra arguments (mainly channel modes like +beIqlk)
"""
modes = args[0]
extramodes = args[1:]
if not modes:
return ValueError('No modes supplied in parseModes query: %r' % modes)
res = []
for mode in modes:
if mode in '+-':
prefix = mode
else:
res.append(prefix + mode)
return res
def applyModes(modelist, changedmodes):
modelist = modelist.copy()
print('Initial modelist: %s' % modelist)
print('Changedmodes: %r' % changedmodes)
for mode in changedmodes:
if mode[0] == '+':
# We're adding a mode
modelist.add(mode)
print('Adding mode %r' % mode)
else:
# We're removing a mode
modelist.discard(mode)
print('Removing mode %r' % mode)
print('Final modelist: %s' % modelist)
return modelist
def joinModes(modes):
return '+' + ''.join(mode[1] for mode in modes)