def handle(s, nick, ident, host, cmd, data): if cmd == "PING": meta.send(s, "PONG %s\r\n" % data) return True elif cmd == "001": if meta.conf['pass']: print("Sending NickServ Password\n") meta.sendMsg(s, "NickServ", "IDENTIFY %s" % meta.conf['pass']) print("Joining Channel %s\n" % meta.conf['channel']) meta.send(s, "MODE %s +B\r\nJOIN %s\r\nUSERHOST %s\r\n" % (meta.conf['nick'], meta.conf['channel'], meta.conf['ident'])) return True elif cmd == "353": # Create our user list on channel join (353: user list) #print(data) listStart = data.find(':') cfind = data.find('=') if cfind == -1: #secret cfind = data.find('*') if cfind == -1: #private cfind = data.find('@') channel = data[cfind+2 : listStart-1] userlist = data[listStart+1 :].split() #print("userlist:",userlist) for u in userlist: #print(u) if u[0] == '&': user = u[1 :] meta.users[channel][user] = meta.User(user, channel, ident, host) meta.users[channel][user].protected = True elif u[0] == '~': user = u[1 :] meta.users[channel][user] = meta.User(user, channel, ident, host) meta.users[channel][user].owner = True elif u[0] == '@': user = u[1 :] meta.users[channel][user] = meta.User(user, channel, ident, host) meta.users[channel][user].op = True elif u[0] == '%': user = u[1 :] meta.users[channel][user] = meta.User(user, channel, ident, host) meta.users[channel][user].halfOp = True elif u[0] == '+': user = u[1 :] meta.users[channel][user] = meta.User(user, channel, ident, host) meta.users[channel][user].voice = True else: #print("channel:", channel) #print("U:", u) meta.users[channel][u] = meta.User(u, channel, ident, host) meta.parseMuteTimers(s, channel) elif cmd == "MODE": #return True mode = data.split() if len(mode) < 3: return True print(nick, ident, mode) channel = mode[0] user = mode[2] mode = mode[1] if not meta.isUser(channel, user): return True add = True for char in mode: if char == "+": add = True elif char == "-": add = False elif char == "v": if add: meta.users[channel][user].voice = True #clears mute timers meta.users[channel][user].unmute(s) #take them off the pig watch list (mute until list) removePig(user, channel) else: meta.users[channel][user].voice = False elif char == "o": if add: meta.users[channel][user].op = True else: meta.users[channel][user].op = False elif char == "a": if add: meta.users[channel][user].protected = True else: meta.users[channel][user].protected = False elif char == "h": if add: meta.users[channel][user].halfOp = True else: meta.users[channel][user].halfOp = False elif char == "q": if add: meta.users[channel][user].owner = True else: meta.users[channel][user].owner = False return True elif cmd == "KICK": # remove the user from our list when they are kicked kick = data.split() if meta.isUser(kick[0], kick[1]): del meta.users[kick[0]][kick[1]] removePig(kick[1], kick[0]) return True elif cmd == "JOIN": channel = data[1 :] if nick == meta.conf['nick']: #:[email protected] JOIN :#joey #when jobot joins a channel, add that channel to its list meta.users[ channel ] = dict() meta.send(s, "WHO {0}\r\n".format(channel)) else: #:[email protected] JOIN :#xkcd meta.users[channel][nick] = meta.User(nick, channel, ident, host) # mute the person if wally has a timer ready and waiting for them muted = meta.parseMuteTimers(s, channel, nick) # dont autovoice if they are on a mute timer if not muted and meta.conf['autovoice']:# and meta.canMute(channel, meta.conf['nick']) and meta.conf['autovoice']: meta.users[channel][nick].unmute(s) if nick not in meta.userInfo: meta.userInfo[nick] = {} meta.userInfo[nick]["ident"] = ident meta.userInfo[nick]["host"] = host return True elif cmd == "PART": meta.delUser(data, nick) removePig(nick, data) return True # WHO #channel reply #:colobus.foonetic.net 352 Joey #xkcd-robotics ~Jobot hide-54ECEB19.tampabay.res.rr.com colobus.foonetic.net wally HrB% :0 Joey #:colobus.foonetic.net 352 Joey #xkcd-robotics ~Joey hide-54ECEB19.tampabay.res.rr.com colobus.foonetic.net Joey Hr& :0 Joey elif cmd == "352": x = data.split() if x[5] not in meta.userInfo: meta.userInfo[x[5]] = {} meta.userInfo[x[5]]["ident"] = x[2] meta.userInfo[x[5]]["host"] = x[3] meta.userInfo[x[5]]["server"] = x[4] meta.userInfo[x[5]]["realname"] = x[8] return True # Handle nick changes. No channel is given because nicks are unique for that server. elif cmd == "NICK": for channel in meta.users.keys(): if nick in meta.users[channel]: meta.users[channel][data[1:]] = meta.users[channel][nick] del meta.users[channel][nick] piggy = findPig(nick, channel) if piggy: removePig(nick, channel) groundPig(data[1:], channel, piggy[2], piggy[3]) m = meta.delMuteTimer(nick, channel) if m: meta.saveMuteTimers(*m) return True elif cmd == "QUIT": #:[email protected] QUIT :Ping timeout for channel in meta.users.keys(): if nick in meta.users[channel]: del meta.users[channel][nick] removePig(nick, channel) return True
def run(self): if not meta.conf['autostart']: meta.prompt('\nPress Enter to connect.\n') print("Connecting to:", HOST, PORT) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #ssl_s = ssl.wrap_socket(s) s.connect((HOST, PORT)) meta.send(s, "NICK %s\r\nUSER %s \"%s\" \"%s\" :%s\r\n" % (meta.conf['nick'], meta.conf['ident'], meta.conf['ident'], meta.conf['ident'], meta.conf['realname'])) meta.send(s, "MODE %s +B\r\n" % meta.conf['nick']) # This is for plugins that require objects to be created # in the calling thread. for plugin in plugins: if 'init' in plugin.__dict__: plugin.init(s) while not meta.quit: readbuffer = "" while True: temp = decode(s.recv(4096))#.decode("utf-8", "ignore") #temp = decode(ssl_s.read(4096))#.decode("utf-8", "ignore") readbuffer = readbuffer + temp if len(temp) < 4096: break # unexpected socket close if not readbuffer: break readbuffer = readbuffer.split("\r\n") for line in readbuffer: #line = line.rstrip() # dont mess with empty lines if not line: continue parseMsg(s, line) # quit was issued print("Shutting Down...\n") # run all closing module functions for plugin in plugins: if 'close' not in plugin.__dict__: continue try: plugin.close(s) except: traceback.print_exc() meta.send(s, "QUIT :Goodbye\r\n") try: s.close() print("Connection closed.") except: print("Connection alread closed.") #stdin.stderr.write("Socket already closed!") for plugin in plugins: if 'shutdown' not in plugin.__dict__: continue try: plugin.shutdown() except: traceback.print_exc()
def notice(s, sender, ident, host, channel, text): # Don't parse anything from nick or chan server. They wont be telling us # to do things. senderLower = sender.lower() if senderLower == 'chanserv' or senderLower == 'nickserv': return True authd = meta.isAuthor(sender, ident, host) textLower = text.lower() if textLower.find('join ') == 0 and authd: meta.send(s, "JOIN %s\r\n" % textLower[5:].strip()) return False elif textLower.find('part ') == 0 and authd: meta.send(s, "PART %s\r\n" % textLower[5:].strip()) return False elif textLower.find('nick ') == 0 and authd: meta.send(s, "NICK %s\r\n" % text[5:].strip()) meta.conf['nick'] = text[5:].strip() return False elif textLower.find('nickpass ') == 0 and authd: meta.sendMsg(s, "NickServ", "IDENTIFY %s" % textLower[9:].strip()) return False elif textLower.find('reload ') == 0 and authd: print("Reloading Module:", textLower[7:].strip()) meta.reload.append(textLower[7:].strip()) return False elif textLower.find('test ') == 0 and authd: meta.sendMsg(s, "Joey", "asdf1456") return False elif textLower.find('raw ') == 0 and authd: meta.send(s, "%s\r\n" % textLower[4:]) return False elif textLower.find('msg ') == 0 and authd: rest = text[4:].strip() x = rest.find(' ') if not x: return False meta.sendMsg(s, rest[:x].rstrip(), rest[x+1:].lstrip()) return False params = text[4:].strip().split() if len(params) < 2: return False meta.sendMsg(s, params[0], text[4+strlen(params[0]):].strip()) return False elif textLower.find('notice ') == 0 and authd: rest = text[4:].strip() x = rest.find(' ') if not x: return False meta.sendMsg(s, rest[:x].rstrip(), rest[x+1:].lstrip()) return False params = text[7:].strip().split() if len(params) < 2: return False meta.sendMsg(s, params[0], text[4+strlen(params[0]):].strip()) return False elif textLower == 'mode?': if meta.conf['autovoice']: meta.sendNotice(s, sender, "Mode: AutoVoice is On.") else: meta.sendNotice(s, sender, "Mode: AutoVoice is Off.") # continue through to the other modules. # This command should return all the modules state to the requesting # user. return True noBlock = True # break down our text into commands to be processed by cmds = text.split() while(cmds): #print(cmds[0]) if cmds[0] == '-autovoice' and authd: if not meta.conf['autovoice']: meta.sendNotice(s, sender, "Confirm - AutoVoice is already Off.") else: meta.sendNotice(s, sender, "Confirm - AutoVoice is now Off.") meta.conf['autovoice'] = False noBlock = False elif cmds[0] == '+autovoice' and authd: if meta.conf['autovoice']: meta.sendNotice(s, sender, "Confirm - AutoVoice is already On.") else: meta.sendNotice(s, sender, "Confirm - AutoVoice is now On.") meta.conf['autovoice'] = True noBlock = False elif cmds[0] == '+auth': # This command takes 1 parameter that should immediatly follow it. # pop off the current command (+auth) so that we can grab the pass cmds.pop(0) # grab the pass upass = cmds[0] if upass == meta.conf['auth']: # save the authors exact identity meta.setAuthor(sender, ident, host) meta.sendNotice(s, sender, "Confirm - You are now Authorized.") print(sender, "is now authorized.") # set the local authorized variable so that the user is # authorized for the rest of the commands. authd = True # no other modules should ever get their hands on the password noBlock = False else: print("FAILED AUTHORIZATION BY", sender, ident, host) elif cmds[0] == '-auth': if authd: # un auth the sender meta.unsetAuthor() meta.sendNotice(s, sender, "Confirm - Authorization Removed.") print(sender, "has been deauthorized.") noBlock = False else: print("FAILED DEAUTH BY", sender, ident, host) elif cmds[0] == '+loud' and authd: if meta.conf['loud']: meta.sendNotice(s, sender, "CONFIRM - I WAS ALREADY REALLY REALLY ANNOYING.") else: meta.conf['loud'] = True meta.sendNotice(s, sender, "CONFIRM - I AM NOW REALLY REALLY ANNOYING.") elif cmds[0] == '-loud' and authd: if not meta.conf['loud']: meta.sendNotice(s, sender, "Confirm - Loud was already Off.") else: meta.conf['loud'] = False; meta.sendNotice(s, sender, "Confirm - Loud is now Off.") elif cmds[0] == '+tenso' and authd: if meta.conf['tenso']: meta.sendNotice(s, sender, "CONFIRM - TENSO was already On.") else: meta.conf['tenso'] = True meta.sendNotice(s, sender, "CONFIRM - TENSO") elif cmds[0] == '-tenso' and authd: if not meta.conf['tenso']: meta.sendNotice(s, sender, "Confirm - TENSO was already Off.") else: meta.conf['tenso'] = False; meta.sendNotice(s, sender, "Confirm - TENSO is now Off.") #elif cmds[0] == '+reload' and authd: # cmds.pop(0) # print("trying to reload:", cmds[0]) # print(__main__.__dict__) # for plugin in __main__.plugins: # print(" plugin:", plugin.__name__) # if plugin.__name__ == cmds[0]: # plugin = imp.reload(plugin) # break elif cmds[0] == '-quit' and authd: meta.quit = True noBlock = False elif cmds[0] == '-restart' and authd: meta.quit = True meta.restart = True noBlock = False # if the first command fails dont continue trying to process commands # This is useful in situations where the notice is something like a # talk command and this module shouldn't process anything in that # message. if noBlock: return True # pop the old command that we just worked on, off the queue cmds.pop(0) return noBlock