|
|
@@ -1,56 +1,141 @@
|
|
|
#! /usr/bin/env python
|
|
|
-#
|
|
|
-# Example program using irc.bot.
|
|
|
-#
|
|
|
-# Joel Rosdahl <joel@rosdahl.net>
|
|
|
|
|
|
-"""A simple example bot.
|
|
|
-This is an example bot that uses the SingleServerIRCBot class from
|
|
|
-irc.bot. The bot enters a channel and listens for commands in
|
|
|
-private messages and channel traffic. Commands in channel messages
|
|
|
-are given by prefixing the text by the bot name followed by a colon.
|
|
|
-It also responds to DCC CHAT invitations and echos data sent in such
|
|
|
-sessions.
|
|
|
-The known commands are:
|
|
|
- stats -- Prints some channel information.
|
|
|
- disconnect -- Disconnect the bot. The bot will try to reconnect
|
|
|
- after 60 seconds.
|
|
|
- die -- Let the bot cease to exist.
|
|
|
- dcc -- Let the bot invite you to a DCC CHAT connection.
|
|
|
-"""
|
|
|
-
|
|
|
-import irc.bot
|
|
|
-import irc.strings
|
|
|
-#from irc.bot import Channel
|
|
|
-from irc.client import ip_numstr_to_quad, ip_quad_to_numstr
|
|
|
-
|
|
|
-class RotBot(irc.bot.SingleServerIRCBot):
|
|
|
- def __init__(self, channel, nickname, server, port=6667):
|
|
|
- print("Connecting")
|
|
|
- irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)
|
|
|
- print("Joining channel")
|
|
|
- self.channel = channel
|
|
|
-
|
|
|
- def on_nicknameinuse(self, c, e):
|
|
|
- c.nick(c.get_nickname() + "_")
|
|
|
-
|
|
|
- def on_welcome(self, c, e):
|
|
|
- print("Joining channel")
|
|
|
- c.join(self.channel)
|
|
|
+import sys, random, string, ssl
|
|
|
+import irc.bot, irc.strings
|
|
|
+from irc.client import ip_numstr_to_quad#, ip_quad_to_numstr
|
|
|
+from postgres import Postgres
|
|
|
+import commands.public, commands.admin, commands.games
|
|
|
+import events.on_join
|
|
|
+from common.networkservices import NickServ
|
|
|
+bold = "\x02"
|
|
|
+italic = "\x1D"
|
|
|
+underline = "\x1F"
|
|
|
+reverse = "\x16" # swap background and foreground colors ("reverse video")
|
|
|
+reset = "\x0F"
|
|
|
+blue = "\x0302"
|
|
|
+green = "\x0303"
|
|
|
+red = "\x0304"
|
|
|
+grey = "\x0314"
|
|
|
|
|
|
+class PyRot(irc.bot.SingleServerIRCBot):
|
|
|
+ def __init__(self, network, db, homechannel, nickname, username, password, host, port=6667, usessl=False, cmdchar="!", helpchar="@"):
|
|
|
+ self.network = network
|
|
|
+ self.db = db
|
|
|
+ self.homechannel = homechannel
|
|
|
+ self.password = password
|
|
|
+ self.cmdchar = cmdchar
|
|
|
+ self.helpchar = helpchar
|
|
|
+
|
|
|
+ if usessl:
|
|
|
+ factory = irc.connection.Factory(wrapper=ssl.wrap_socket)
|
|
|
+ else:
|
|
|
+ factory = irc.connection.Factory()
|
|
|
+
|
|
|
+ print("Connecting to " + host + ":" + str(port) + "/" + self.homechannel)
|
|
|
+ try:
|
|
|
+ irc.bot.SingleServerIRCBot.__init__(self, [(host, port)], nickname, username, connect_factory=factory)
|
|
|
+ except irc.client.ServerConnectionError:
|
|
|
+ sys.stderr.write(sys.exc_info()[1])
|
|
|
+
|
|
|
+ # Events.
|
|
|
+ def on_nicknameinuse(self, connection, event):
|
|
|
+ print("Nickname in use, attempting to recover: " + connection.nickname)
|
|
|
+ connection.nick(connection.nickname + ''.join(random.choice(string.digits) for _ in range(3))) # Take temporary nick. Without this recovering via NickServ won't work.
|
|
|
+ NickServ.recover_nick(connection, self.password)
|
|
|
+
|
|
|
+ def on_nick(self, connection, event):
|
|
|
+ if event.source.nick == connection.nickname: # If the nick boing changes is the bots prefered nickname.
|
|
|
+ print("Assuming original nick.")
|
|
|
+ NickServ.recover_nick(connection, self.password)
|
|
|
+
|
|
|
+ def on_welcome(self, connection, event):
|
|
|
+ print(event)
|
|
|
+ if self.password:
|
|
|
+ connection.privmsg("NickServ", "identify " + connection.nickname + " " + self.password) # Identify with NickServ.
|
|
|
+ print("Joining " + self.homechannel)
|
|
|
+ connection.join(self.homechannel)
|
|
|
+
|
|
|
+
|
|
|
+ def on_join(self, connection, event):
|
|
|
+ print(event)
|
|
|
+ events.on_join.process_event(self, connection, event)
|
|
|
+
|
|
|
+
|
|
|
def on_privmsg(self, connection, event):
|
|
|
- self.do_command(connection, event)
|
|
|
+ print(str(event))
|
|
|
+ commands.public.do_command(self, connection, event)
|
|
|
+ commands.admin.do_command(self, connection, event)
|
|
|
+ commands.games.do_command(self, connection, event)
|
|
|
+
|
|
|
+ def on_privnotice(self, connection, event):
|
|
|
+ print(str(event))
|
|
|
+ commands.public.do_command(self, connection, event)
|
|
|
+ commands.admin.do_command(self, connection, event)
|
|
|
+ commands.games.do_command(self, connection, event)
|
|
|
+ if event.source.nick == NickServ and event.arguments[0].startswith("This nickname is registered"):
|
|
|
+ connection.privmsg("NickServ", "identify " + connection.nickname + " " + connection.password) # Identify with NickServ.
|
|
|
|
|
|
def on_pubmsg(self, connection, event):
|
|
|
- self.do_command(connection, event)
|
|
|
-
|
|
|
+ commands.public.do_command(self, connection, event)
|
|
|
+ commands.admin.do_command(self, connection, event)
|
|
|
+ try:
|
|
|
+ games = self.db.one("SELECT games FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'")
|
|
|
+ except:
|
|
|
+ pass
|
|
|
+ if games:
|
|
|
+ commands.games.do_command(self, connection, event)
|
|
|
|
|
|
- #def on_pubmsg(self, c, e):
|
|
|
- # a = e.arguments[0].split(":", 1)
|
|
|
- # if len(a) > 1 and irc.strings.lower(a[0]) == irc.strings.lower(self.connection.get_nickname()):
|
|
|
- # self.do_command(e, a[1].strip())
|
|
|
- # return
|
|
|
-
|
|
|
+ if connection.get_nickname().lower() in event.arguments[0].lower() and event.source.nick is not connection.get_nickname(): # Bot's name was mentioned
|
|
|
+
|
|
|
+ messages = [
|
|
|
+ "Hello " + event.source.nick + ".",
|
|
|
+ "How are you today " + event.source.nick + "?",
|
|
|
+ "Piss off " + event.source.nick + "!",
|
|
|
+ event.source.nick + ", what are you botherring me for?",
|
|
|
+ "Go bother someone else...",
|
|
|
+ "Is life treating you fair?",
|
|
|
+ "What's up?",
|
|
|
+ "Why are you talking to me?",
|
|
|
+ "I'm not talking to you!",
|
|
|
+ "What have you been up to?",
|
|
|
+ "How is life?",
|
|
|
+ "What do you wan't from me?",
|
|
|
+ event.source.nick + ", why are you bothering me?",
|
|
|
+ event.source.nick + ", when will you stop talking about me?",
|
|
|
+ event.source.nick + " I hate you!",
|
|
|
+ "Get bent!",
|
|
|
+ "Go and cut yourself.",
|
|
|
+ "Do you think i care about you?",
|
|
|
+ "Stop nickalerting me " + event.source.nick + ", you wanker!",
|
|
|
+ ]
|
|
|
+ actions = [
|
|
|
+ "hides!",
|
|
|
+ "dies.",
|
|
|
+ "runs away.",
|
|
|
+ "is ignoring that.",
|
|
|
+ "is not feeling like caring.",
|
|
|
+ "is away",
|
|
|
+ "will be ignoring that.",
|
|
|
+ "is faggaliciouz!! <333",
|
|
|
+ "likes you! <3",
|
|
|
+ "looks the other way...",
|
|
|
+ "does a little dance with " + event.source.nick + ".",
|
|
|
+ "makes a little love.",
|
|
|
+ "get's down tonight.",
|
|
|
+ "thinks SAM Broadcaster sucks raw cocks in hell!",
|
|
|
+ "is secretly in love with " + event.source.nick + ".",
|
|
|
+ "tosses " + event.source.nick + "'s salad.",
|
|
|
+ "tortures " + event.source.nick + " horribly!",
|
|
|
+ "is smelling like tuna when looking at " + event.source.nick + ".",
|
|
|
+ "sniffing armpits.. Eew! Smells like " + event.source.nick + ".",
|
|
|
+ "rapes " + event.source.nick + ".",
|
|
|
+ ]
|
|
|
+ if random.randint(0, 1) == 0:
|
|
|
+ connection.privmsg(event.target, random.choice(messages))
|
|
|
+ else:
|
|
|
+ connection.action(event.target, random.choice(actions))
|
|
|
+
|
|
|
+
|
|
|
def on_dccmsg(self, c, e):
|
|
|
# non-chat DCC messages are raw bytes; decode as text
|
|
|
text = e.arguments[0].decode('utf-8')
|
|
|
@@ -68,113 +153,27 @@ class RotBot(irc.bot.SingleServerIRCBot):
|
|
|
return
|
|
|
self.dcc_connect(address, port)
|
|
|
|
|
|
- def do_command(self, connection, event):
|
|
|
- cmdchar = "!"
|
|
|
- helpchar = "@"
|
|
|
- trigger = event.arguments[0]
|
|
|
-
|
|
|
- #Check command prefix
|
|
|
- if trigger.startswith(cmdchar) or trigger.startswith(helpchar): #Do nothing if it's not a command.
|
|
|
- command = trigger[1:] #Without prefix.
|
|
|
- help = False
|
|
|
- if trigger.startswith(helpchar): #It's a help requist.
|
|
|
- help = True
|
|
|
-
|
|
|
- # Set replyto variable for output to multiple protocols
|
|
|
- if event.type == "pubmsg":
|
|
|
- replyto = event.target
|
|
|
- elif event.type == "privmsg":
|
|
|
- replyto = event.source.nick
|
|
|
- else:
|
|
|
- return
|
|
|
-
|
|
|
- if command == "cmd":
|
|
|
- if help:
|
|
|
- connection.privmsg(replyto, "Displays a list of commands.")
|
|
|
- else:
|
|
|
- connection.privmsg(replyto, "!cmd, !test, !msg")
|
|
|
-
|
|
|
- elif command == "test":
|
|
|
- if help:
|
|
|
- connection.privmsg(replyto, "Strictly for testing purposes only!")
|
|
|
- else:
|
|
|
- connection.privmsg(replyto, str(connection) + " | " + str(event))
|
|
|
-
|
|
|
- #elif command == "channel":
|
|
|
- #channel = Channel()
|
|
|
- #print("aaa")
|
|
|
- #print(replyto)
|
|
|
- #connection.privmsg(replyto, event.source.nick)
|
|
|
- #connection.privmsg(replyto, str(channel.users(replyto)))
|
|
|
- #connection.privmsg(replyto, is_admin(event.source.nick))
|
|
|
- #connection.privmsg(replyto, "A: " + self.channels[0].is_admin(event.source.nick))
|
|
|
-
|
|
|
- elif command.split(maxsplit=1)[0] == "msg":
|
|
|
- print(1)
|
|
|
- if help:
|
|
|
- print(2)
|
|
|
- connection.privmsg(replyto, "Message a user or channel.")
|
|
|
- connection.privmsg(replyto, "\x0314Usage: \x0300!msg \x1Dname message")
|
|
|
- else:
|
|
|
- try:
|
|
|
- connection.privmsg(command.split()[1], command.split(maxsplit=2)[2])
|
|
|
- except IndexError:
|
|
|
- connection.privmsg(replyto, "Nothing")
|
|
|
-
|
|
|
- #else: #Parrot mode
|
|
|
- # connection.privmsg("#[CP]Specifer", str(trigger.arguments[0].split(maxsplit=1)[0]))
|
|
|
-# def do_command(self, e, cmd):
|
|
|
-# nick = e.source.nick
|
|
|
-# c = self.connection
|
|
|
-#
|
|
|
-# if cmd == "disconnect":
|
|
|
-# self.disconnect()
|
|
|
-# elif cmd == "die":
|
|
|
-# self.die()
|
|
|
-# elif cmd == "stats":
|
|
|
-# for chname, chobj in self.channels.items():
|
|
|
-# c.notice(nick, "--- Channel statistics ---")
|
|
|
-# c.notice(nick, "Channel: " + chname)
|
|
|
-# users = sorted(chobj.users())
|
|
|
-# c.notice(nick, "Users: " + ", ".join(users))
|
|
|
-# opers = sorted(chobj.opers())
|
|
|
-# c.notice(nick, "Opers: " + ", ".join(opers))
|
|
|
-# voiced = sorted(chobj.voiced())
|
|
|
-# c.notice(nick, "Voiced: " + ", ".join(voiced))
|
|
|
-# elif cmd == "dcc":
|
|
|
-# dcc = self.dcc_listen()
|
|
|
-# c.ctcp("DCC", nick, "CHAT chat %s %d" % (
|
|
|
-# ip_quad_to_numstr(dcc.localaddress),
|
|
|
-# dcc.localport))
|
|
|
-# else:
|
|
|
-# c.notice(nick, "Not understood: " + cmd)
|
|
|
-
|
|
|
def main():
|
|
|
- #import sys
|
|
|
- #if len(sys.argv) != 4:
|
|
|
- # print(sys.argv)
|
|
|
- # print("Usage: testbot <server[:port]> <channel> <nickname>")
|
|
|
- # sys.exit(1)
|
|
|
-
|
|
|
- #s = sys.argv[1].split(":", 1)
|
|
|
- #server = s[0]
|
|
|
- #if len(s) == 2:
|
|
|
- # try:
|
|
|
- # port = int(s[1])
|
|
|
- # except ValueError:
|
|
|
- # print("Error: Erroneous port.")
|
|
|
- # sys.exit(1)
|
|
|
- #else:
|
|
|
- # port = 6667
|
|
|
- #channel = sys.argv[2]
|
|
|
- #nickname = sys.argv[3]
|
|
|
-
|
|
|
- channel = "#[CP]Specifer"
|
|
|
- nickname = "pyRotBot"
|
|
|
- server = "irc.gtanet.com"
|
|
|
- port = 6667
|
|
|
- bot = RotBot(channel, nickname, server, port)
|
|
|
- print("Starting bot")
|
|
|
+
|
|
|
+ # Check system arguments.
|
|
|
+ if len(sys.argv) != 2:
|
|
|
+ print(sys.argv)
|
|
|
+ print("Usage: rotbot <server ID from database>")
|
|
|
+ sys.exit(1)
|
|
|
+
|
|
|
+ # Check instance. Instance is the database network id.
|
|
|
+ instance = sys.argv[1]
|
|
|
+ db = Postgres("postgres://pyRot:4h8q(.@localhost/pyRot")
|
|
|
+ try:
|
|
|
+ network = db.one("SELECT * FROM networks WHERE id=" + str(instance))
|
|
|
+ except:
|
|
|
+ print("Invalid network ID.")
|
|
|
+ sys.exit(1)
|
|
|
+ if not network:
|
|
|
+ print("Invalid network ID.")
|
|
|
+ sys.exit(1)
|
|
|
+
|
|
|
+ bot = PyRot(network.name, db, network.home_channel, network.nickname, network.username, network.password, network.host, network.port, network.use_ssl, network.command_character, network.help_character)
|
|
|
bot.start()
|
|
|
|
|
|
if __name__ == "__main__":
|