Advertisement
Guest User

Untitled

a guest
May 12th, 2017
564
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.32 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import sys, socket, shelve, time, traceback, random
  5.  
  6. #EDIT the lines that follow
  7. #Also remember to create two files in the same directory as the script. They should be named 'passwd' and 'owners'. 'passwd' should contain the password #for the nick the bot will be using. If you didn't register the nick, please still create a file and in there put (secret) WITH the parenthesis.
  8. #On the 'owners' file, put a single nickname that will have the abilities of owner. To add other owners it is recommended to do it via IRC.
  9. HOST="irc.freenode.net"
  10. PORT=6667
  11. NICK="FailBot"
  12. USERNAME="FailBot"
  13. REALNAME="PedroBot"
  14. CHANNEL="##pedro3005"
  15. max_factoids=50 # this is the limit of factoids. set 0 for no limit.
  16. #COMMENT (add a # to the beginning) the two following lines. they are here to warn a user if he didn't edit the lines properly."
  17. #print "Open the script and edit the first few lines accordingly. Instructions are provided in it."
  18. #exit()
  19. #editing beyond this line is NOT necessary
  20.  
  21.  
  22. tries = 0 #this is related to the roulette function.
  23. recv="" #this is the variable that will receive from the socket
  24. bot_is_opped = 0
  25. passwd = open("passwd", "r")
  26. PASSWORD = passwd.read().split("\n")[0]
  27. owners = []
  28. owners_get = open("owners", "r")
  29. for line in owners_get :
  30.     owners.append(line.split('\n')[0])
  31. log_enabled = 0
  32. factoids = shelve.open("factoids", writeback=True)
  33.  
  34. def parsemsg(s) :
  35.     # this function takes a normal IRC message such as :
  36.     # :pedro3005!~pedro@xxx.xxx.xxx.xxx PRIVMSG ##pedro3005 :yay
  37.     #and defines:
  38.     #prefix = pedro3005!~pedro@xxx.xxx.xxx.xxx
  39.     #command = PRIVMSG
  40.     #args = ['##pedro3005', 'yay']
  41.     #the actual message will always be args[-1], but don't worry since we define that later. use the variable 'message'. also don't worry about the variable trailing.
  42.     trailing = 0
  43.     prefix = 0
  44.     if s[0] == ":" :
  45.         s = s[1:].split(' ', 1)
  46.         prefix = s[0]
  47.         s = s[1]
  48.     if " :" in s :
  49.         s = s.split(" :")
  50.         trailing = s[1]
  51.         s = s[0]
  52.     args = s.split()
  53.     command = args.pop(0)
  54.     if trailing != 0 :
  55.         args.append(trailing)
  56.     return prefix, command, args
  57.  
  58. def chanmsg(msg) : #use this whenever you want to send a message to the chan
  59.     socket.send("PRIVMSG %s :%s\r\n" % (CHANNEL, msg))
  60.  
  61. def chanact(act) : #same as above but a /me
  62.     socket.send("PRIVMSG %s :\x01ACTION %s\x01\r\n" % (CHANNEL, act))
  63.  
  64. def say(*msg) :
  65.     msg = " ".join(msg)
  66.     loadowners()
  67.     if nick in owners :
  68.         chanmsg(msg)
  69.  
  70. def act(*msg) :
  71.     msg = " ".join(msg)
  72.     loadowners()
  73.     if nick in owners :
  74.         chanact(act)
  75.  
  76. def kill(nick) :
  77.     if not nick in owners :
  78.         chanact("kills %s unmercifully!" % (nick))
  79.     else :
  80.         chanmsg("I shall not kill my master.")
  81.  
  82. def read_factoids() :
  83.     fact_list = []
  84.     for item in factoids :
  85.         fact_list.append(item[1:]) #this simply takes out the '!' from the name
  86.     chanmsg("Available factoids: %s" % (", ".join(fact_list)))
  87.  
  88. def new_factoid(name, nothing, *definitions) :
  89.     if not name.startswith("!") : #avoids someone trying to create a factoid with ! on the beginning (could confuse the bot)
  90.         if "!" + name in factoids and nick not in owners :
  91.             chanmsg("Permission denied.")
  92.         elif len(factoids) == max_factoids and max_factoids != 0 and nick not in owners :
  93.             chanmsg("Maximum number of factoids reached. Contact an owner.")
  94.         else :
  95.             definition = " ".join(definitions)
  96.             factoids["!" + name] = definition
  97.             chanmsg("Factoid %s added successfuly" % (name))
  98.     else :
  99.         chanmsg("You're not going to break me")
  100. def del_factoid(*names) :
  101.     factoids_deleted = []
  102.     factoids_notfound = []
  103.     name = " ".join(names).split()
  104.     if nick in owners :
  105.         for factoid in name :
  106.             try :
  107.                 del factoids["!" + factoid]
  108.             except :
  109.                 factoids_notfound.append(factoid)
  110.             else :
  111.                 factoids_deleted.append(factoid)
  112.         if len(factoids_deleted) > 0 :
  113.             chanmsg("Successfuly deleted factoids: %s" % (", ".join(factoids_deleted)))
  114.         if len(factoids_notfound) > 0 :
  115.             chanmsg("Factoids not found: %s" % (", ".join(factoids_notfound)))
  116.     else :
  117.         chanmsg("Permission denied.")
  118.  
  119. def add_owner(name) :
  120.     if nick in owners :
  121.         owners.append(name)
  122.         write = open("owners", "a")
  123.         write.write(name + '\n')
  124.     if name in owners :
  125.         chanmsg("Owner %s added successfuly." % (name))
  126.  
  127. def read_owners() :
  128.     loadowners()
  129.     rowners = ", ".join(owners) #rowners is from r(ead)owners :P
  130.     chanmsg("Owners: %s" % (rowners))
  131.  
  132. def kick(name, *reasons) :
  133.     reason = " ".join(reasons)
  134.     if nick in owners :
  135.         socket.send("KICK %s %s :%s\r\n" % (CHANNEL, name, reason))
  136.         if not bot_is_opped == 1 :
  137.             chanmsg("I'm not an OP.")
  138.     else :
  139.         chanmsg("Permission denied.")
  140.  
  141. def ismsg(msg) :
  142.     if command == "PRIVMSG" and args[0] == CHANNEL : #see the parsemsg function if in doubt
  143.         return True
  144.  
  145. def log_on() :
  146.     global log_enabled, log #necessary to work with functions defined elsewhere inside a function
  147.     if nick in owners :
  148.         if log_enabled == 0 : #checks if it isn't already logging
  149.             log = open(CHANNEL, "a")
  150.             log.write(time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()) + '\n' + '----------------------------' + '\n')
  151.             log_enabled = 1
  152.             chanmsg("Logging started")
  153.             log.flush()
  154.         else :
  155.             chanmsg("I am already logging.")
  156.     else :
  157.         chanmsg("Permission denied.")
  158. def log_off() :
  159.     global log_enabled, log
  160.     if nick in owners :
  161.         if log_enabled == 1 :
  162.             log_enabled = 0
  163.             log.write("-------END OF LOG-----\n")
  164.             log.flush()
  165.             chanmsg("Stopped logging")
  166.         else :
  167.             chanmsg("I am not logging anything.")
  168.  
  169. def ircroulette() :
  170.     global tries
  171.     chance = random.choice(range(1, 5)) #the range is (1, 5) but the possible numbers are [1, 2, 3, 4]. you can increase the range, i'm not sure which is correct
  172.     if tries == 4 or chance == 4 :
  173.         kick(nick, "because", "*BAM*")
  174.         tries = 0
  175.     else :
  176.         tries = tries + 1
  177.         chanmsg("*tick*")
  178.  
  179. def loadowners() : #this re-reads the owners from the file, to update the list of owners.
  180.     global owners
  181.     owners = []
  182.     owners_get = open("owners", "r")
  183.     for line in owners_get :
  184.         owners.append(line.split('\n')[0])
  185.  
  186. def topic(*ntpcs) : #ntpcs is from n(ew)t(o)p(i)cs
  187.     ntpc = " ".join(ntpcs)
  188.     if nick in owners :
  189.         socket.send("TOPIC %s :%s\r\n" % (CHANNEL, ntpc))
  190.         if not bot_is_opped == 1 :
  191.             chanmsg("I'm not an OP.")
  192.     else :
  193.         chanmsg("Permission denied.")
  194.  
  195. def ban(mode, *user) :
  196.     b = ""
  197.     user = " ".join(user)
  198.     for _ in (range(len(user.split()))) :
  199.         b = b + "b"
  200.     if len(b) > 4 :
  201.         chanmsg("Only 4 bans per command.")
  202.     if mode == "add" and nick in owners :
  203.         socket.send("MODE %s +%s %s\r\n" % (CHANNEL, b, user))
  204.         for x in user :
  205.             kick(user, "Banned!")
  206.     elif nick not in owners :
  207.         chanmsg("Permission denied.")
  208.     elif mode == "remove" and nick in owners :
  209.         socket.send("MODE %s -%s %s\r\n" % (CHANNEL, b, user))
  210.  
  211. def sendraw(*msg) :
  212.     print msg
  213.     msg = " ".join(msg)
  214.     if nick in owners :
  215.         print msg
  216.         socket.send("%s\r\n" % (msg))
  217.     else :
  218.         chanmsg("Permission denied.")
  219.  
  220. commands = { #this dict is extremely important. in here, assign a command which preceded by ! on irc will call the function. ex: "a": a -> if someone types !a it'll call the function a
  221.     "kill": kill,
  222.     "factoids": read_factoids,
  223.     "add": new_factoid,
  224.     "del": del_factoid,
  225.     "add_owner": add_owner,
  226.     "owners": read_owners,
  227.     "kick": kick,
  228.     "log": log_on,
  229.     "log_off": log_off,
  230.     "roulette": ircroulette,
  231.     "say": say,
  232.     "act": act,
  233.     "topic": topic,
  234.     "ban": ban,
  235.     "sendraw": sendraw
  236. }
  237.  
  238.  
  239. socket = socket.socket()
  240. socket.connect((HOST, PORT))
  241. if PASSWORD != "(secret)" : #this is to check if the person actually set a password
  242.     socket.send("PASS %s\r\n" % (PASSWORD))
  243. socket.send("NICK %s\r\n" % (NICK))
  244. socket.send("USER %s * * :%s\r\n" % (USERNAME, REALNAME))
  245. socket.send("JOIN %s\r\n" % (CHANNEL))
  246.  
  247. while True :
  248.     recv = recv + socket.recv(4096)
  249.     s = recv.split("\r\n")
  250.     recv = s.pop() #this simply takes the part before the \r\n
  251.     for msg in s :
  252.         loadowners()
  253.         print msg
  254.         prefix, command, args = parsemsg(msg)
  255.         try : #here we assign some basic variables. message is whatever someone typed. if someone typed !kill, bot_cmd will be kill. bot_cmd_args will be a list of whatever is after bot_cmd. nick will be the person's nick.
  256.             message = args[-1]
  257.             bot_cmd = message.split()[0][1:]
  258.             bot_cmd_args = message.split()[1:]
  259.             nick = prefix.split("!")[0]
  260.         except :
  261.             pass
  262.         if command == "MODE" and "+o" in args and NICK in args : #detect ops and deops of the bot
  263.             bot_is_opped = 1
  264.         elif command == "MODE" and "-o" in args and NICK in args :
  265.             bot_is_opped = 0
  266.         if command == "KICK" and NICK in args : #detects kicks
  267.             socket.send("JOIN %s\r\n" % (CHANNEL))
  268.         if log_enabled == 1 and ismsg(msg) : #if logging is enabled and the msg is a real message by someone, it writes to the log life.
  269.             log.write("%s: %s\n" % (nick, message))
  270.             log.flush()
  271.         if command == "PING" : #this is to respond for pings, necessary or you will get kicked out of the network eventually.
  272.             socket.send("PONG\r\n")
  273.         elif bot_cmd in commands and message.startswith("!") :
  274.             try :
  275.                 commands[bot_cmd](*bot_cmd_args) #this is necessary or someone can give too many arguments for a function and break the bot
  276.             except :
  277.                 chanmsg("Error encountered. You probably didn't provide enough or provided too much arguments for a function. Try again")
  278.         elif message.startswith("!") and "!" + bot_cmd in factoids.keys() :
  279.             socket.send("PRIVMSG %s :%s\r\n" % (CHANNEL, factoids["!" + bot_cmd]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement