Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- import sys, socket, shelve, time, random, fun
- #EDIT the lines that follow
- #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.
- #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.
- HOST="irc.freenode.net"
- PORT=6667
- NICK="FailBot"
- USERNAME="FailBot"
- REALNAME="PedroBot"
- CHANNELS="##pedro3005, ##devil" #separate by comma AND space
- max_factoids=50 # this is the limit of factoids. set 0 for no limit.
- #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."
- #print "Open the script and edit the first few lines accordingly. Instructions are provided in it."
- #exit()
- #editing beyond this line is NOT necessary
- CHANNELS = CHANNELS.split(", ")
- tries = 0 #this is related to the roulette function.
- recv="" #this is the variable that will receive from the socket
- bot_is_opped = 0
- passwd = open("passwd", "r")
- PASSWORD = passwd.read().split("\n")[0]
- log_enabled = 0
- factoids = shelve.open("factoids", writeback=True)
- def parsemsg(s) :
- # this function takes a normal IRC message such as :
- # :pedro3005!~pedro@xxx.xxx.xxx.xxx PRIVMSG ##pedro3005 :yay
- #and defines:
- #prefix = pedro3005!~pedro@xxx.xxx.xxx.xxx
- #command = PRIVMSG
- #args = ['##pedro3005', 'yay']
- #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.
- trailing = 0
- prefix = 0
- if s[0] == ":" :
- s = s[1:].split(' ', 1)
- prefix = s[0]
- s = s[1]
- if " :" in s :
- s = s.split(" :", 1)
- trailing = s[1]
- s = s[0]
- args = s.split()
- command = args.pop(0)
- if trailing != 0 :
- args.append(trailing)
- return prefix, command, args
- 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.
- socket.send("PRIVMSG %s :%s\r\n" % (channel, msg))
- def chanact(channel, act) : #same as above but a /me
- socket.send("PRIVMSG %s :\x01ACTION %s\x01\r\n" % (channel, act))
- def say(*msg) :
- msg = " ".join(msg)
- loadowners()
- if nick in owners :
- chanmsg(chan, msg)
- else :
- chanmsg(chan, "Permission denied.")
- def act(*msg) :
- msg = " ".join(msg)
- loadowners()
- if nick in owners :
- chanact(chan, msg)
- else :
- chanmsg(chan, "Permission denied.")
- def kill(nick) :
- loadowners()
- if not nick in owners :
- chanact(chan, "kills %s unmercifully!" % (nick))
- else :
- chanmsg(chan, "I shall not kill my master.")
- def read_factoids() :
- fact_list = []
- for item in factoids :
- fact_list.append(item[1:]) #this simply takes out the '!' from the name
- chanmsg(chan, "Available factoids: %s" % (", ".join(fact_list)))
- def new_factoid(name, nothing, *definitions) :
- loadowners()
- if not name.startswith("!") : #avoids someone trying to create a factoid with ! on the beginning (could confuse the bot)
- if "!" + name in factoids and nick not in owners :
- chanmsg(chan, "Permission denied.")
- elif len(factoids) == max_factoids and max_factoids != 0 and nick not in owners :
- chanmsg(chan, "Maximum number of factoids reached. Contact an owner.")
- else :
- definition = " ".join(definitions)
- factoids["!" + name] = definition
- chanmsg(chan, "Factoid %s added successfuly." % (name))
- else :
- chanmsg(chan, "You're not going to break me.")
- def del_factoid(*names) :
- loadowners()
- factoids_deleted = []
- factoids_notfound = []
- if nick in owners :
- for factoid in names :
- try :
- del factoids["!" + factoid]
- except :
- factoids_notfound.append(factoid)
- else :
- factoids_deleted.append(factoid)
- if len(factoids_deleted) > 0 :
- chanmsg(chan, "Successfuly deleted factoids: %s" % (", ".join(factoids_deleted)))
- if len(factoids_notfound) > 0 :
- chanmsg(chan, "Factoids not found: %s" % (", ".join(factoids_notfound)))
- else :
- chanmsg(chan, "Permission denied.")
- def add_owner(name) :
- loadowners()
- if nick in owners :
- owners.append(name)
- write = open("owners", "a")
- write.write(name + '\n')
- write.flush()
- else :
- chanmsg(chan, "Permission denied.")
- loadowners()
- if name in owners :
- chanmsg(chan, "Owner %s added successfuly." % (name))
- def read_owners() :
- loadowners()
- rowners = ", ".join(owners) #rowners is from r(ead)owners :P
- chanmsg(chan, "Owners: %s" % (rowners))
- def kick(name, *reasons) :
- loadowners()
- if bot_is_opped == 0 :
- chanmsg(chan, "I'm not an OP.")
- else :
- reason = " ".join(reasons)
- if nick in owners :
- socket.send("KICK %s %s :%s\r\n" % (chan, name, reason))
- else :
- chanmsg(chan, "Permission denied.")
- def ismsg(msg) :
- if command == "PRIVMSG" and chan in CHANNELS : #see the parsemsg function if in doubt
- return True
- def log_on() :
- loadowners()
- global log_enabled, log #necessary to work with functions defined elsewhere inside a function
- if nick in owners :
- if log_enabled == 0 : #checks if it isn't already logging
- log = open(chan, "a")
- log.write(time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime()) + '\n' + '----------------------------' + '\n')
- log_enabled = 1
- chanmsg(chan, "Logging started")
- log.flush()
- else :
- chanmsg(chan, "I am already logging.")
- else :
- chanmsg(chan, "Permission denied.")
- def log_off() :
- global log_enabled, log
- loadowners()
- if nick in owners :
- if log_enabled == 1 :
- log_enabled = 0
- log.write("-------END OF LOG-----\n")
- log.flush()
- chanmsg(chan, "Stopped logging")
- else :
- chanmsg(chan, "I am not logging anything.")
- def ircroulette() :
- if bot_is_opped == 1 :
- global tries
- 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
- if tries == 4 or chance == 4 :
- kick(nick, "*BAM*")
- tries = 0
- else :
- tries = tries + 1
- chanmsg(chan, "*tick*")
- else :
- chanmsg(chan, "I'm not an OP.")
- def loadowners() : #this re-reads the owners from the file, to update the list of owners.
- global owners
- owners = []
- owners_get = open("owners", "r")
- for line in owners_get :
- owners.append(line.split('\n')[0])
- def topic(*ntpcs) : #ntpcs is from n(ew)t(o)p(i)cs
- loadowners()
- if bot_is_opped == 1 :
- ntpc = " ".join(ntpcs)
- if nick in owners :
- socket.send("TOPIC %s :%s\r\n" % (chan, ntpc))
- else :
- chanmsg(chan, "Permission denied.")
- else :
- chanmsg(chan, "I'm not an OP.")
- def ban(mode, *user) :
- loadowners()
- if bot_is_opped == 0 :
- chanmsg(chan, "I'm not an OP.")
- else :
- b = ""
- user = " ".join(user)
- 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.
- b = b + "b"
- if len(b) > 4 :
- chanmsg(chan, "Only 4 bans per command.")
- if mode == "add" and nick in owners :
- socket.send("MODE %s +%s %s\r\n" % (chan, b, user))
- for x in user :
- kick(user, "Banned!")
- elif nick not in owners :
- chanmsg(chan, "Permission denied.")
- elif mode == "remove" and nick in owners :
- socket.send("MODE %s -%s %s\r\n" % (chan, b, user))
- elif not mode == "add" and not mode == "remove" :
- chanmsg(chan, "Mode unknown. Use !ban add <user> or !ban remove <user>.")
- 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.
- loadowners()
- msg = " ".join(msg)
- if nick in owners :
- socket.send("%s\r\n" % (msg))
- else :
- chanmsg(chan, "Permission denied.")
- def join(chan) :
- loadowners()
- if nick in owners :
- socket.send("JOIN %s\r\n" % (chan))
- else :
- chanmsg(chan, "Permission denied.")
- def leave() :
- loadowners()
- global chan
- if nick in owners :
- socket.send("PART %s\r\n" % (chan))
- else :
- chanmsg(chan, "Permission denied.")
- def quit() :
- loadowners()
- if nick in owners :
- exit()
- else :
- chanmsg(chan, "Permission denied.")
- def op(usr) :
- if bot_is_opped == 1 :
- loadowners()
- if nick in owners :
- socket.send("MODE %s +o %s\r\n" % (chan, usr))
- else :
- chanmsg(chan, "Permission denied.")
- else :
- chanmsg(chan, "I'm not an OP.")
- def deop(usr) :
- if bot_is_opped == 1 :
- loadowners()
- if nick in owners :
- socket.send("MODE %s -o %s\r\n" % (chan, usr))
- else :
- chanmsg(chan, "Permission denied.")
- else :
- chanmsg(chan, "I'm not an OP.")
- 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
- "kill": kill,
- "factoids": read_factoids,
- "add": new_factoid,
- "del": del_factoid,
- "add_owner": add_owner,
- "owners": read_owners,
- "kick": kick,
- "log": log_on,
- "log_off": log_off,
- "roulette": ircroulette,
- "say": say,
- "act": act,
- "topic": topic,
- "ban": ban,
- "sendraw": sendraw,
- "join": join,
- "leave": leave,
- "quit": quit,
- "op": op,
- "deop": deop
- }
- commands = fun.load_fun(commands)
- socket = socket.socket()
- socket.connect((HOST, PORT))
- if PASSWORD != "(secret)" : #this is to check if the person actually set a password
- socket.send("PASS %s\r\n" % (PASSWORD))
- socket.send("NICK %s\r\n" % (NICK))
- socket.send("USER %s * * :%s\r\n" % (USERNAME, REALNAME))
- for channel in CHANNELS :
- socket.send("JOIN %s\r\n" % (channel))
- loadowners()
- while True :
- recv = recv + socket.recv(4096)
- s = recv.split("\r\n")
- recv = s.pop() #this simply takes the part before the \r\n
- for msg in s :
- loadowners()
- print msg
- prefix, command, args = parsemsg(msg)
- 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.
- message = args[-1]
- bot_cmd = message.split()[0][1:]
- bot_cmd_args = message.split()[1:]
- nick = prefix.split("!")[0]
- chan = args[0]
- except :
- pass
- if command == "MODE" and "+o" in args and NICK in args : #detect ops and deops of the bot
- bot_is_opped = 1
- elif command == "MODE" and "-o" in args and NICK in args :
- bot_is_opped = 0
- if command == "KICK" and NICK in args : #detects kicks
- socket.send("JOIN %s\r\n" % (chan))
- 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.
- log.write("%s: %s\n" % (nick, message))
- log.flush()
- if command == "PING" : #this is to respond for pings, necessary or you will get kicked out of the network eventually.
- socket.send("PONG\r\n")
- elif bot_cmd in commands and message.startswith("!") :
- #try :
- commands[bot_cmd](*bot_cmd_args) #this is necessary or someone can give too many arguments for a function and break the bot
- #except SystemExit :
- # raise
- #except :
- # chanmsg(chan, "Error encountered. You probably didn't provide enough or provided too much arguments for a function. Try again.")
- elif message.startswith("!") and "!" + bot_cmd in factoids.keys() :
- socket.send("PRIVMSG %s :%s\r\n" % (chan, factoids["!" + bot_cmd]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement