rotbot.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #! /usr/bin/env python
  2. import sys, random, string, ssl
  3. import irc.bot, irc.strings
  4. from irc.client import ip_numstr_to_quad#, ip_quad_to_numstr
  5. from postgres import Postgres
  6. import commands.public, commands.admin, commands.games
  7. import events.on_join
  8. from common.networkservices import NickServ
  9. bold = "\x02"
  10. italic = "\x1D"
  11. underline = "\x1F"
  12. reverse = "\x16" # swap background and foreground colors ("reverse video")
  13. reset = "\x0F"
  14. blue = "\x0302"
  15. green = "\x0303"
  16. red = "\x0304"
  17. grey = "\x0314"
  18. class PyRot(irc.bot.SingleServerIRCBot):
  19. def __init__(self, network, db, homechannel, nickname, username, password, host, port=6667, usessl=False, cmdchar="!", helpchar="@"):
  20. self.network = network
  21. self.db = db
  22. self.homechannel = homechannel
  23. self.password = password
  24. self.cmdchar = cmdchar
  25. self.helpchar = helpchar
  26. if usessl:
  27. factory = irc.connection.Factory(wrapper=ssl.wrap_socket)
  28. else:
  29. factory = irc.connection.Factory()
  30. print("Connecting to " + host + ":" + str(port) + "/" + self.homechannel)
  31. try:
  32. irc.bot.SingleServerIRCBot.__init__(self, [(host, port)], nickname, username, connect_factory=factory)
  33. except irc.client.ServerConnectionError:
  34. sys.stderr.write(sys.exc_info()[1])
  35. # Events.
  36. def on_nicknameinuse(self, connection, event):
  37. print("Nickname in use, attempting to recover: " + connection.nickname)
  38. connection.nick(connection.nickname + ''.join(random.choice(string.digits) for _ in range(3))) # Take temporary nick. Without this recovering via NickServ won't work.
  39. NickServ.recover_nick(connection, self.password)
  40. def on_nick(self, connection, event):
  41. if event.source.nick == connection.nickname: # If the nick boing changes is the bots prefered nickname.
  42. print("Assuming original nick.")
  43. NickServ.recover_nick(connection, self.password)
  44. def on_welcome(self, connection, event):
  45. print(event)
  46. if self.password:
  47. connection.privmsg("NickServ", "identify " + connection.nickname + " " + self.password) # Identify with NickServ.
  48. print("Joining " + self.homechannel)
  49. connection.join(self.homechannel)
  50. def on_join(self, connection, event):
  51. print(event)
  52. events.on_join.process_event(self, connection, event)
  53. def on_privmsg(self, connection, event):
  54. print(str(event))
  55. commands.public.do_command(self, connection, event)
  56. commands.admin.do_command(self, connection, event)
  57. commands.games.do_command(self, connection, event)
  58. def on_privnotice(self, connection, event):
  59. print(str(event))
  60. commands.public.do_command(self, connection, event)
  61. commands.admin.do_command(self, connection, event)
  62. commands.games.do_command(self, connection, event)
  63. if event.source.nick == NickServ and event.arguments[0].startswith("This nickname is registered"):
  64. connection.privmsg("NickServ", "identify " + connection.nickname + " " + connection.password) # Identify with NickServ.
  65. def on_pubmsg(self, connection, event):
  66. commands.public.do_command(self, connection, event)
  67. commands.admin.do_command(self, connection, event)
  68. try:
  69. games = self.db.one("SELECT games FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'")
  70. except:
  71. pass
  72. if games:
  73. commands.games.do_command(self, connection, event)
  74. if connection.get_nickname().lower() in event.arguments[0].lower() and event.source.nick is not connection.get_nickname(): # Bot's name was mentioned
  75. messages = [
  76. "Hello " + event.source.nick + ".",
  77. "How are you today " + event.source.nick + "?",
  78. "Piss off " + event.source.nick + "!",
  79. event.source.nick + ", what are you botherring me for?",
  80. "Go bother someone else...",
  81. "Is life treating you fair?",
  82. "What's up?",
  83. "Why are you talking to me?",
  84. "I'm not talking to you!",
  85. "What have you been up to?",
  86. "How is life?",
  87. "What do you wan't from me?",
  88. event.source.nick + ", why are you bothering me?",
  89. event.source.nick + ", when will you stop talking about me?",
  90. event.source.nick + " I hate you!",
  91. "Get bent!",
  92. "Go and cut yourself.",
  93. "Do you think i care about you?",
  94. "Stop nickalerting me " + event.source.nick + ", you wanker!",
  95. ]
  96. actions = [
  97. "hides!",
  98. "dies.",
  99. "runs away.",
  100. "is ignoring that.",
  101. "is not feeling like caring.",
  102. "is away",
  103. "will be ignoring that.",
  104. "is faggaliciouz!! <333",
  105. "likes you! <3",
  106. "looks the other way...",
  107. "does a little dance with " + event.source.nick + ".",
  108. "makes a little love.",
  109. "get's down tonight.",
  110. "thinks SAM Broadcaster sucks raw cocks in hell!",
  111. "is secretly in love with " + event.source.nick + ".",
  112. "tosses " + event.source.nick + "'s salad.",
  113. "tortures " + event.source.nick + " horribly!",
  114. "is smelling like tuna when looking at " + event.source.nick + ".",
  115. "sniffing armpits.. Eew! Smells like " + event.source.nick + ".",
  116. "rapes " + event.source.nick + ".",
  117. ]
  118. if random.randint(0, 1) == 0:
  119. connection.privmsg(event.target, random.choice(messages))
  120. else:
  121. connection.action(event.target, random.choice(actions))
  122. def on_dccmsg(self, c, e):
  123. # non-chat DCC messages are raw bytes; decode as text
  124. text = e.arguments[0].decode('utf-8')
  125. c.privmsg("You said: " + text)
  126. def on_dccchat(self, c, e):
  127. if len(e.arguments) != 2:
  128. return
  129. args = e.arguments[1].split()
  130. if len(args) == 4:
  131. try:
  132. address = ip_numstr_to_quad(args[2])
  133. port = int(args[3])
  134. except ValueError:
  135. return
  136. self.dcc_connect(address, port)
  137. def main():
  138. # Check system arguments.
  139. if len(sys.argv) != 2:
  140. print(sys.argv)
  141. print("Usage: rotbot <server ID from database>")
  142. sys.exit(1)
  143. # Check instance. Instance is the database network id.
  144. instance = sys.argv[1]
  145. db = Postgres("postgres://pyRot:4h8q(.@localhost/pyRot")
  146. try:
  147. network = db.one("SELECT * FROM networks WHERE id=" + str(instance))
  148. except:
  149. print("Invalid network ID.")
  150. sys.exit(1)
  151. if not network:
  152. print("Invalid network ID.")
  153. sys.exit(1)
  154. 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)
  155. bot.start()
  156. if __name__ == "__main__":
  157. main()