on_mode.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import fnmatch
  2. from irc.modes import parse_channel_modes
  3. from common.networkservices import ChanServ
  4. from common import do_everything_to, userstatus, log
  5. from events.common import Aggressiveness, Lastact
  6. bold = "\x02"
  7. italic = "\x1D"
  8. underline = "\x1F"
  9. reverse = "\x16" # swap background and foreground colors ("reverse video")
  10. reset = "\x0F"
  11. blue = "\x0302"
  12. green = "\x0303"
  13. red = "\x0304"
  14. grey = "\x0314"
  15. def process_event(self, connection, event):
  16. log.info(event)
  17. # Update protectees.
  18. if event.target == self.homechannel: # Home channel
  19. if any(mode in event.arguments[0][-1:] for mode in ("q", "a", "o", "h")): # Atleast halfop.
  20. connection.who(event.arguments[1]) # Get whorepy to update protectees.
  21. # Update last act.
  22. Lastact.update(self, event.source.nick, "mode", lastact=event.target)
  23. # React.
  24. modes = parse_channel_modes(" ".join(event.arguments))
  25. behaviour = self.db.one("SELECT aggressiveness FROM channels WHERE name='" + event.target + "' AND network='" + self.network + "'")
  26. for idx, mode in enumerate(modes):
  27. # Report.
  28. if not event.target == self.homechannel: # Not in home channel.
  29. for protectee in self.protectees:
  30. if mode[1] == "b" and fnmatch.fnmatch(self.protectees[protectee]['ident'], mode[2]) and mode[0] == "+": # Protectee banned.
  31. connection.privmsg(self.homechannel, red + protectee + reset + " banned from " + red + event.target + reset + " by " + red + event.source.nick + reset + ": " + green + mode[2])
  32. if mode[1] == "e" and fnmatch.fnmatch(self.protectees[protectee]['ident'], event.arguments[idx + 1]) and mode[0] == "-": # Protectee's exception removed.
  33. connection.privmsg(self.homechannel, red + protectee + reset + " has had their exception removed from " + red + event.target + reset + " by " + red + event.source.nick + reset + ": " + green + event.arguments[idx + 1])
  34. # Track channel keys.
  35. if mode[1] == "k": # Channel key changed.
  36. if mode[0] == "+": # Key set.
  37. self.db.run("UPDATE channels SET key='" + mode[2] + "' WHERE name='" + event.target + "' AND network='" + self.network + "'")
  38. else: # Key removed.
  39. self.db.run("UPDATE channels SET key=NULL WHERE name='" + event.target + "' AND network='" + self.network + "'")
  40. # Unban if bot is banned from home channel
  41. try:
  42. if mode[1] == "b" and fnmatch.fnmatch(self.protectees[connection.get_nickname()]['ident'], mode[2]) and mode[0] == "+" and event.target == self.homechannel:
  43. connection.privmsg("ChanServ", "UNBAN")
  44. do_everything_to.unban(connection, event.target, connection.get_nickname(), mode[2])
  45. connection.mode(event.target, "-b " + mode[2])
  46. except:
  47. pass
  48. # Stop if not present in home channel.
  49. if not self.homechannel in self.channels:
  50. return
  51. # Stop if offender is bot or bot owner
  52. if event.source.nick == connection.get_nickname() or self.channels[self.homechannel].is_owner(event.source.nick):
  53. return
  54. for protectee in self.protectees:
  55. # Stop if offender is atleast halfop in the home channel and offended is not owner.
  56. if userstatus.atleast_halfop(self, event.source.nick, self.homechannel) and not self.channels[self.homechannel].is_owner(protectee):
  57. return
  58. try: # Had "IndexError: list index out of range" on "if modes[1] == "b" and mode[0] == "+": # Ban.".
  59. if behaviour == "passive": # Passive behaviour.
  60. return
  61. elif behaviour == "defense_only": # Defensive only behaviour.
  62. if mode[1] == "b" and mode[0] == "+": # Ban.
  63. if fnmatch.fnmatch(self.protectees[protectee]['ident'], mode[2]): # Protectee.
  64. do_everything_to.unban(connection, event.target, protectee, mode[2])
  65. elif mode[1] == "e" and mode[0] == "-": # Removed exception.
  66. if fnmatch.fnmatch(self.protectees[protectee]['ident'], event.arguments[idx + 1]): # Protectee.
  67. connection.mode(event.target, "+e " + mode[2])
  68. elif mode[0] == "-" and mode[1] in ["q", "a", "o", "h", "v"]: # Channel right taken.
  69. ChanServ.give_mode(connection, event.target, mode[2], mode[1])
  70. connection.mode(event.target, mode[0] + mode[1] + " " + mode[2])
  71. elif behaviour == "equal_retalliation": # Equal retaliatory behaviour.
  72. if modes[1] == "b" and mode[0] == "+": # Ban.
  73. if fnmatch.fnmatch(self.protectees[protectee]['ident'], mode[2]): # Protectee.
  74. do_everything_to.unban(connection, event.target, protectee, mode[2])
  75. if protectee == connection.get_nickname(): # Bot banned.
  76. ChanServ.ban(connection, event.target, event.source.nick, "Aggression channel function = equal_retalliation.")
  77. else:
  78. ChanServ.ban(connection, event.target, event.source.nick, "Aggression channel function = equal_retalliation: " + protectee + " is an operator of " + connection.get_nickname() + ".")
  79. connection.mode(event.target, "+b " + event.source)
  80. elif mode[1] == "e" and mode[0] == "-": # Removed exception.
  81. if fnmatch.fnmatch(self.protectees[protectee]['ident'], event.arguments[idx + 1]): # Protectee.
  82. connection.mode(event.target, "+e " + event.arguments[idx + 1])
  83. elif mode[0] == "-" and mode[1] in ["q", "a", "o", "h", "v"]: # Channel right taken.
  84. ChanServ.give_mode(connection, event.target, mode[2], mode[1])
  85. connection.mode(event.target, mode[0] + mode[1] + " " + mode[2])
  86. ChanServ.take_all_modes(connection, event.target, mode[2])
  87. connection.mode(event.target, "-vhoaq " + mode[2] + " " + mode[2]+ " " + mode[2]+ " " + mode[2]+ " " + mode[2])
  88. elif behaviour == "battlebot": # Battlebot behaviour.
  89. if mode[0] == "-" and mode[1] in ["q", "a", "o", "h", "v"]: # Channel right taken.
  90. ChanServ.give_mode(connection, event.target, mode[2], mode[1])
  91. connection.mode(event.target, mode[0] + mode[1] + " " + mode[2])
  92. do_everything_to.unban(connection, event.target, protectee, mode[2])
  93. do_everything_to.ban(connection, event.target, event.source.nick, event.source, Aggressiveness.retalliation_reason(self, connection, protectee, behaviour))
  94. connection.mode(event.target, "+e " + mode[2])
  95. ChanServ.akick_add(connection, event.target, event.source.nick)
  96. do_everything_to.kick(connection, event.target, event.source.nick, Aggressiveness.retalliation_reason(self, connection, protectee, behaviour))
  97. if mode[1] == "b" and mode[0] == "+": # Ban.
  98. if fnmatch.fnmatch(self.protectees[protectee]['ident'], mode[2]): # Protectee.
  99. do_everything_to.unban(connection, event.target, protectee, mode[2])
  100. do_everything_to.ban(connection, event.target, event.source.nick, event.source, Aggressiveness.retalliation_reason(self, connection, protectee, behaviour))
  101. connection.mode(event.target, "+e " + mode[2])
  102. ChanServ.akick_add(connection, event.target, event.source.nick)
  103. do_everything_to.kick(connection, event.target, event.source.nick, Aggressiveness.retalliation_reason(self, connection, protectee, behaviour))
  104. elif mode[1] == "e" and mode[0] == "-": # Removed exception.
  105. #for protectee in self.protectees:
  106. if fnmatch.fnmatch(self.protectees[protectee]['ident'], event.arguments[idx + 1]): # Protectee.
  107. do_everything_to.ban(connection, event.target, event.source.nick, event.source, Aggressiveness.retalliation_reason(self, connection, protectee, behaviour))
  108. connection.mode(event.target, "+e " + event.arguments[idx + 1])
  109. ChanServ.akick_add(connection, event.target, event.source.nick)
  110. do_everything_to.kick(connection, event.target, event.source.nick, Aggressiveness.retalliation_reason(self, connection, protectee, behaviour))
  111. except:
  112. pass