Advertisement
Guest User

Untitled

a guest
May 13th, 2017
603
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 11.43 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import sys, socket, shelve, time, random, fun
  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. CHANNELS="##pedro3005, ##devil" #separate by comma AND space
  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. CHANNELS = CHANNELS.split(", ")
  23. tries = 0 #this is related to the roulette function.
  24. recv="" #this is the variable that will receive from the socket
  25. bot_is_opped = 0
  26.  
  27. passwd = open("passwd", "r")
  28. PASSWORD = passwd.read().split("\n")[0]
  29.  
  30. log_enabled = 0
  31. factoids = shelve.open("factoids", writeback=True)
  32.  
  33. def parsemsg(s) :
  34.     # this function takes a normal IRC message such as :
  35.     # :pedro3005!~pedro@xxx.xxx.xxx.xxx PRIVMSG ##pedro3005 :yay
  36.     #and defines:
  37.     #prefix = pedro3005!~pedro@xxx.xxx.xxx.xxx
  38.     #command = PRIVMSG
  39.     #args = ['##pedro3005', 'yay']
  40.     #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.
  41.     trailing = 0
  42.     prefix = 0
  43.     if s[0] == ":" :
  44.         s = s[1:].split(' ', 1)
  45.         prefix = s[0]
  46.         s = s[1]
  47.     if " :" in s :
  48.         s = s.split(" :", 1)
  49.         trailing = s[1]
  50.         s = s[0]
  51.     args = s.split()
  52.     command = args.pop(0)
  53.     if trailing != 0 :
  54.         args.append(trailing)
  55.     return prefix, command, args
  56.  
  57. def chanmsg(channel, msg) : #use this whenever you want to send a message to the chan. call it as chanmsg(channel, message). the channel will normally be the variable chan.
  58.     socket.send("PRIVMSG %s :%s\r\n" % (channel, msg))
  59.  
  60. def chanact(channel, act) : #same as above but a /me
  61.     socket.send("PRIVMSG %s :\x01ACTION %s\x01\r\n" % (channel, act))
  62.  
  63. def say(*msg) :
  64.     msg = " ".join(msg)
  65.     loadowners()
  66.     if nick in owners :
  67.         chanmsg(chan, msg)
  68.     else :
  69.         chanmsg(chan, "Permission denied.")
  70.  
  71. def act(*msg) :
  72.     msg = " ".join(msg)
  73.     loadowners()
  74.     if nick in owners :
  75.         chanact(chan, msg)
  76.     else :
  77.         chanmsg(chan, "Permission denied.")
  78.  
  79. def kill(nick) :
  80.     loadowners()
  81.     if not nick in owners :
  82.         chanact(chan, "kills %s unmercifully!" % (nick))
  83.     else :
  84.         chanmsg(chan, "I shall not kill my master.")
  85.  
  86. def read_factoids() :
  87.     fact_list = []
  88.     for item in factoids :
  89.         fact_list.append(item[1:]) #this simply takes out the '!' from the name
  90.     chanmsg(chan, "Available factoids: %s" % (", ".join(fact_list)))
  91.  
  92. def new_factoid(name, nothing, *definitions) :
  93.     loadowners()
  94.     if not name.startswith("!") : #avoids someone trying to create a factoid with ! on the beginning (could confuse the bot)
  95.         if "!" + name in factoids and nick not in owners :
  96.             chanmsg(chan, "Permission denied.")
  97.         elif len(factoids) == max_factoids and max_factoids != 0 and nick not in owners :
  98.             chanmsg(chan, "Maximum number of factoids reached. Contact an owner.")
  99.         else :
  100.             definition = " ".join(definitions)
  101.             factoids["!" + name] = definition
  102.             chanmsg(chan, "Factoid %s added successfuly." % (name))
  103.     else :
  104.         chanmsg(chan, "You're not going to break me.")
  105. def del_factoid(*names) :
  106.     loadowners()
  107.     factoids_deleted = []
  108.     factoids_notfound = []
  109.     if nick in owners :
  110.         for factoid in names :
  111.             try :
  112.                 del factoids["!" + factoid]
  113.             except :
  114.                 factoids_notfound.append(factoid)
  115.             else :
  116.                 factoids_deleted.append(factoid)
  117.         if len(factoids_deleted) > 0 :
  118.             chanmsg(chan, "Successfuly deleted factoids: %s" % (", ".join(factoids_deleted)))
  119.         if len(factoids_notfound) > 0 :
  120.             chanmsg(chan, "Factoids not found: %s" % (", ".join(factoids_notfound)))
  121.     else :
  122.         chanmsg(chan, "Permission denied.")
  123.  
  124. def add_owner(name) :
  125.     loadowners()
  126.     if nick in owners :
  127.         owners.append(name)
  128.         write = open("owners", "a")
  129.         write.write(name + '\n')
  130.         write.flush()
  131.     else :
  132.         chanmsg(chan, "Permission denied.")
  133.     loadowners()
  134.     if name in owners :
  135.         chanmsg(chan, "Owner %s added successfuly." % (name))
  136.  
  137. def read_owners() :
  138.     loadowners()
  139.     rowners = ", ".join(owners) #rowners is from r(ead)owners :P
  140.     chanmsg(chan, "Owners: %s" % (rowners))
  141.  
  142. def kick(name, *reasons) :
  143.     loadowners()
  144.     if bot_is_opped == 0 :
  145.         chanmsg(chan, "I'm not an OP.")
  146.     else :
  147.         reason = " ".join(reasons)
  148.         if nick in owners :
  149.             socket.send("KICK %s %s :%s\r\n" % (chan, name, reason))
  150.         else :
  151.             chanmsg(chan, "Permission denied.")
  152.  
  153. def ismsg(msg) :
  154.     if command == "PRIVMSG" and chan in CHANNELS : #see the parsemsg function if in doubt
  155.         return True
  156.  
  157. def log_on() :
  158.     loadowners()
  159.     global log_enabled, log #necessary to work with functions defined elsewhere inside a function
  160.     if nick in owners :
  161.         if log_enabled == 0 : #checks if it isn't already logging
  162.             log = open(chan, "a")
  163.             log.write(time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()) + '\n' + '----------------------------' + '\n')
  164.             log_enabled = 1
  165.             chanmsg(chan, "Logging started")
  166.             log.flush()
  167.         else :
  168.             chanmsg(chan, "I am already logging.")
  169.     else :
  170.         chanmsg(chan, "Permission denied.")
  171. def log_off() :
  172.     global log_enabled, log
  173.     loadowners()
  174.     if nick in owners :
  175.         if log_enabled == 1 :
  176.             log_enabled = 0
  177.             log.write("-------END OF LOG-----\n")
  178.             log.flush()
  179.             chanmsg(chan, "Stopped logging")
  180.         else :
  181.             chanmsg(chan, "I am not logging anything.")
  182.  
  183. def ircroulette() :
  184.     if bot_is_opped == 1 :
  185.         global tries
  186.         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
  187.         if tries == 4 or chance == 4 :
  188.             kick(nick, "*BAM*")
  189.             tries = 0
  190.         else :
  191.             tries = tries + 1
  192.             chanmsg(chan, "*tick*")
  193.     else :
  194.         chanmsg(chan, "I'm not an OP.")
  195.  
  196. def loadowners() : #this re-reads the owners from the file, to update the list of owners.
  197.     global owners
  198.     owners = []
  199.     owners_get = open("owners", "r")
  200.     for line in owners_get :
  201.         owners.append(line.split('\n')[0])
  202.  
  203. def topic(*ntpcs) : #ntpcs is from n(ew)t(o)p(i)cs
  204.     loadowners()
  205.     if bot_is_opped == 1 :
  206.         ntpc = " ".join(ntpcs)
  207.         if nick in owners :
  208.             socket.send("TOPIC %s :%s\r\n" % (chan, ntpc))
  209.         else :
  210.             chanmsg(chan, "Permission denied.")
  211.     else :
  212.         chanmsg(chan, "I'm not an OP.")
  213.  
  214. def ban(mode, *user) :
  215.     loadowners()
  216.     if bot_is_opped == 0 :
  217.         chanmsg(chan, "I'm not an OP.")
  218.     else :
  219.         b = ""
  220.         user = " ".join(user)
  221.         for _ in (range(len(user.split()))) : #this makes a range according to how many users there are to be kicked and creates a string with as many b's as that number is.
  222.             b = b + "b"
  223.         if len(b) > 4 :
  224.             chanmsg(chan, "Only 4 bans per command.")
  225.         if mode == "add" and nick in owners :
  226.             socket.send("MODE %s +%s %s\r\n" % (chan, b, user))
  227.             for x in user :
  228.                 kick(user, "Banned!")
  229.         elif nick not in owners :
  230.             chanmsg(chan, "Permission denied.")
  231.         elif mode == "remove" and nick in owners :
  232.             socket.send("MODE %s -%s %s\r\n" % (chan, b, user))
  233.         elif not mode == "add" and not mode == "remove" :
  234.             chanmsg(chan, "Mode unknown. Use !ban add <user> or !ban remove <user>.")
  235.  
  236. def sendraw(*msg) : #with this function you can send a raw commands via irc with !sendraw. Ex: !sendraw PRIVMSG ##pedro3005 :hey #makes the bot say hey.
  237.     loadowners()
  238.     msg = " ".join(msg)
  239.     if nick in owners :
  240.         socket.send("%s\r\n" % (msg))
  241.     else :
  242.         chanmsg(chan, "Permission denied.")
  243.  
  244. def join(chan) :
  245.     loadowners()
  246.     if nick in owners :
  247.         socket.send("JOIN %s\r\n" % (chan))
  248.     else :
  249.         chanmsg(chan, "Permission denied.")
  250.  
  251. def leave() :
  252.     loadowners()
  253.     global chan
  254.     if nick in owners :
  255.         socket.send("PART %s\r\n" % (chan))
  256.     else :
  257.         chanmsg(chan, "Permission denied.")
  258.  
  259. def quit() :
  260.     loadowners()
  261.     if nick in owners :
  262.         exit()
  263.     else :
  264.         chanmsg(chan, "Permission denied.")
  265.  
  266. def op(usr) :
  267.     if bot_is_opped == 1 :
  268.         loadowners()
  269.         if nick in owners :
  270.             socket.send("MODE %s +o %s\r\n" % (chan, usr))
  271.         else :
  272.             chanmsg(chan, "Permission denied.")
  273.     else :
  274.         chanmsg(chan, "I'm not an OP.")
  275.  
  276. def deop(usr) :
  277.     if bot_is_opped == 1 :
  278.         loadowners()
  279.         if nick in owners :
  280.             socket.send("MODE %s -o %s\r\n" % (chan, usr))
  281.         else :
  282.             chanmsg(chan, "Permission denied.")
  283.     else :
  284.         chanmsg(chan, "I'm not an OP.")
  285.  
  286. 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
  287.     "kill": kill,
  288.     "factoids": read_factoids,
  289.     "add": new_factoid,
  290.     "del": del_factoid,
  291.     "add_owner": add_owner,
  292.     "owners": read_owners,
  293.     "kick": kick,
  294.     "log": log_on,
  295.     "log_off": log_off,
  296.     "roulette": ircroulette,
  297.     "say": say,
  298.     "act": act,
  299.     "topic": topic,
  300.     "ban": ban,
  301.     "sendraw": sendraw,
  302.     "join": join,
  303.     "leave": leave,
  304.     "quit": quit,
  305.     "op": op,
  306.     "deop": deop
  307. }
  308. commands = fun.load_fun(commands)
  309.  
  310. socket = socket.socket()
  311. socket.connect((HOST, PORT))
  312. if PASSWORD != "(secret)" : #this is to check if the person actually set a password
  313.     socket.send("PASS %s\r\n" % (PASSWORD))
  314. socket.send("NICK %s\r\n" % (NICK))
  315. socket.send("USER %s * * :%s\r\n" % (USERNAME, REALNAME))
  316. for channel in CHANNELS :
  317.     socket.send("JOIN %s\r\n" % (channel))
  318.  
  319. loadowners()
  320. while True :
  321.     recv = recv + socket.recv(4096)
  322.     s = recv.split("\r\n")
  323.     recv = s.pop() #this simply takes the part before the \r\n
  324.     for msg in s :
  325.         loadowners()
  326.         print msg
  327.         prefix, command, args = parsemsg(msg)
  328.         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. chan is the channel the message was sent on.
  329.             message = args[-1]
  330.             bot_cmd = message.split()[0][1:]
  331.             bot_cmd_args = message.split()[1:]
  332.             nick = prefix.split("!")[0]
  333.             chan = args[0]
  334.         except :
  335.             pass
  336.         if command == "MODE" and "+o" in args and NICK in args : #detect ops and deops of the bot
  337.             bot_is_opped = 1
  338.         elif command == "MODE" and "-o" in args and NICK in args :
  339.             bot_is_opped = 0
  340.         if command == "KICK" and NICK in args : #detects kicks
  341.             socket.send("JOIN %s\r\n" % (chan))
  342.         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.
  343.             log.write("%s: %s\n" % (nick, message))
  344.             log.flush()
  345.         if command == "PING" : #this is to respond for pings, necessary or you will get kicked out of the network eventually.
  346.             socket.send("PONG\r\n")
  347.         elif bot_cmd in commands and message.startswith("!") :
  348.             #try :
  349.             commands[bot_cmd](*bot_cmd_args) #this is necessary or someone can give too many arguments for a function and break the bot
  350.             #except SystemExit :
  351.             #   raise
  352.             #except :
  353.             #   chanmsg(chan, "Error encountered. You probably didn't provide enough or provided too much arguments for a function. Try again.")
  354.         elif message.startswith("!") and "!" + bot_cmd in factoids.keys() :
  355.             socket.send("PRIVMSG %s :%s\r\n" % (chan, factoids["!" + bot_cmd]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement