Basic Python IRC Op/Flood Bot (Manual)

opbot.py

#!/usr/bin/python
import os
import re
import socket
import sys
import time
def outp(s, l):
	print(">%s<" % (l))
	s.send("%s\r\n" % (l))
def main():
	print("Usage: prog [server] [nick] [pass] [chans]")
	sockdata = ""
	sockline = []
	linenumb = 0
	sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	sockobjc.connect((sys.argv[1], 6667))
	outp(sockobjc, "NICK %s" % (sys.argv[2]))
	outp(sockobjc, "USER pyop * * :pyop")
	while (1):
		sockdata += sockobjc.recv(1024)
		templist = sockdata.split("\n")
		templeng = len(templist)
		if (templeng > 1):
			for x in range(0, templeng - 1):
				sockline.append(templist[x].strip())
			sockdata = templist[templeng - 1]
		while (len(sockline) > 0):
			print("["+sockline[0]+"]")
			testline = sockline[0].lower()
			if (testline[:6] == "ping :"):
				outp(sockobjc, "PONG :%s" % (sockline[0][6:]))
			if (linenumb == 8):
				for channame in sys.argv[4:]:
					outp(sockobjc, "JOIN #%s" % (channame))
				linenumb += 1
			regxobjc = re.match("^:(.+)!(.+)@(.+)[ ]+privmsg[ ]+([^#]+)[ ]+:[ ]*%s[ ]+(.+)$" % (sys.argv[3]), sockline[0], re.I)
			if (regxobjc):
				outp(sockobjc, str(regxobjc.group(5)))
			sockline.pop(0)
			if (linenumb < 8):
				linenumb = min(linenumb + 1, 8)
if (__name__ == "__main__"):
	main()

floobot.py

#!/usr/bin/python
import os
import re
import socket
import sys
import time
def outp(s, l):
	print(">%s<" % (l))
	s.send("%s\r\n" % (l))
def pban(n, u, h, b):
	d = {"bh":".", "b4":".", "b6":":", "un":""}
	t = "un"; l = [h]
	if (re.match("^[0-9A-Za-z.-]+$", h, re.I)):
		t = "bh"; l = h.split(d["bh"])
	ipvf = h.split(d["b4"])
	if (len(ipvf) == 4):
		flag = 1
		try:
			for i in ipvf:
				j = int(i)
				if ((j < 0x00) or (0xff < j)):
					flag = 0
		except:
			flag = 0
		if (flag == 1):
			t = "b4"; l = ipvf
	ipvs = h.split(d["b6"])
	if ((2 < len(ipvs)) and (len(ipvs) < 9)):
		flag = 1
		for i in ipvs:
			if (not re.match("^[0-9a-f]{0,4}$", i, re.I)):
				flag = 0
		if (flag == 1):
			t = "b6"; l = ipvs
	try:
		mask = b[t].split("@")
		if (mask[0] == "l"):
			x = 0; m = (len(l) - 1); a = 1; c = -1
		if (mask[0] == "r"):
			x = (len(l) - 1); m = 0; a = -1; c = 1
		i = int(mask[1]); k = 0; j = abs(i)
		if (not mask[2]):
			mask[2] = None
		while (x != m):
			if (i > 0):
				l[x] = mask[2]
				i -= 1
			if (i < 0):
				if ((a == 1) and (k < (m + 1 - j))):
					l[k] = mask[2]
				if ((a != 1) and (k > (j - 1))):
					l[k] = mask[2]
				k += 1
			x += a
		while (None in l):
			l.remove(None)
		if (mask[0] == "l"):
			return ("%s@%s%s" % (b["mk"] % {"n":n, "u":u}, mask[3], d[t].join(l)))
		if (mask[0] == "r"):
			return ("%s@%s%s" % (b["mk"] % {"n":n, "u":u}, d[t].join(l), mask[3]))
	except:
		pass
	return ("%s@%s" % (b["mk"] % {"n":n, "u":u}, d[t].join(l)))
def main():
	print("Usage: prog [server] [nick] [pass] [chans]")
	sockdata = ""
	sockline = []
	linenumb = 0
	# note: the number order relates to: amount, time
	floorate = {"ki":[10, 30], "bk":[2, 90], "un":[9999, 3600]}
	# note: the ban mask should include: direction@depth@replacement@postfix
	banmasks = {"mk":"*!*", "bh":"l@-6@@*", "b4":"r@0@*@", "b6":"r@0@*@", "un":""}
	flootime = {}
	floocmds = {"ki":["KICK %(chan)s %(nick)s :kick-flood-trigger"], "bk":["MODE %(chan)s +b %(mask)s", "KICK %(chan)s %(nick)s :ban-flood-trigger"], "un":["MODE %(chan)s -b %(mask)s"]}
	sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	sockobjc.connect((sys.argv[1], 6667))
	outp(sockobjc, "NICK %s" % (sys.argv[2]))
	outp(sockobjc, "USER pyop * * :pyop")
	while (1):
		sockdata += sockobjc.recv(1024)
		templist = sockdata.split("\n")
		templeng = len(templist)
		if (templeng > 1):
			for x in range(0, templeng - 1):
				sockline.append(templist[x].strip())
			sockdata = templist[templeng - 1]
		prestime = int(time.time())
		while (len(sockline) > 0):
			print("["+sockline[0]+"]")
			testline = sockline[0].lower()
			if (testline[:6] == "ping :"):
				outp(sockobjc, "PONG :%s" % (sockline[0][6:]))
			if (linenumb == 8):
				for channame in sys.argv[4:]:
					outp(sockobjc, "JOIN #%s" % (channame))
				linenumb += 1
			regxobjc = re.match("^:(.+)!(.+)@(.+)[ ]+privmsg[ ]+([^#]+)[ ]+:[ ]*%s[ ]+(.+)$" % (sys.argv[3]), sockline[0], re.I)
			if (regxobjc):
				comdlist = str(regxobjc.group(5)).split(" ")
				comdleng = len(comdlist)
				comdflag = 0
				if (comdleng > 2):
					for flootype in floorate.keys():
						if (comdlist[0] == flootype):
							try:
								floorate[flootype] = [int(comdlist[1]), int(comdlist[2])]
								outp(sockobjc, "PRIVMSG %s :SET: %s" % (str(regxobjc.group(1)), comdlist))
							except:
								pass
							comdflag = 1
				if (comdleng > 1):
					for masktype in banmasks.keys():
						if (comdlist[0] == masktype):
							try:
								banmasks[masktype] = comdlist[1]
								outp(sockobjc, "PRIVMSG %s :SET: %s" % (str(regxobjc.group(1)), comdlist))
							except:
								pass
							comdflag = 1
				if (comdflag == 0):
					outp(sockobjc, str(regxobjc.group(5)))
			regxobjc = re.match("^:(.+)!(.+)@(.+)[ ]+privmsg[ ]+(#.+)[ ]+.*$", sockline[0], re.I)
			if (regxobjc):
				nickname = str(regxobjc.group(1))
				username = str(regxobjc.group(2))
				hostname = str(regxobjc.group(3))
				channame = str(regxobjc.group(4))
				bmaskstr = pban(nickname, username, hostname, banmasks)
				objckeyn = ("%s %s" % (channame, bmaskstr))
				if (not objckeyn in flootime.keys()):
					flootime[objckeyn] = {"ki":[0, -1], "bk":[0, -1], "un":[0, -1], "list":{}, "last":prestime}
				if (not nickname in flootime[objckeyn]["list"]):
					flootime[objckeyn]["list"][nickname] = {"nick":nickname, "user":username, "host":hostname, "chan":channame, "mask":bmaskstr}
				l = ["ki", "bk", "un"]; m = len(l)
				for x in range(0, m):
					t = l[x]
					# note: if the time from the last one of these has passed then clear the counters
					if (flootime[objckeyn][t][1] > 0):
						if ((prestime - flootime[objckeyn][t][1]) >= floorate[t][1]):
							flootime[objckeyn][t][0] = 0
							flootime[objckeyn][t][1] = -1
							if ((x + 1) < m):
								flootime[objckeyn][l[x+1]][0] = 0
								flootime[objckeyn][l[x+1]][1] = -1
					# note: increase the first counter to begin our monitoring
					if (x == 0):
						flootime[objckeyn][t][0] += 1
						if (flootime[objckeyn][t][1] < 0):
							flootime[objckeyn][t][1] = prestime
					# note: if the rate is exceeded then perform some action and notify the next counter
					if (flootime[objckeyn][t][0] >= floorate[t][0]):
						flootime[objckeyn][t][0] = 0
						flootime[objckeyn][t][1] = -1
						if ((x + 1) < m):
							u = l[x+1]
							flootime[objckeyn][u][0] += 1
							if (flootime[objckeyn][u][1] < 0):
								flootime[objckeyn][u][1] = prestime
							if (flootime[objckeyn][u][0] >= floorate[u][0]):
								t = u
						if (t == l[x]):
							for k in flootime[objckeyn]["list"].keys():
								for floocomd in floocmds[t]:
									outp(sockobjc, floocomd % flootime[objckeyn]["list"][k])
				flootime[objckeyn]["last"] = prestime
			sockline.pop(0)
			if (linenumb < 8):
				linenumb = min(linenumb + 1, 8)
		# note: undo a given action after a certain amount of time
		for k in flootime.keys():
			if ((prestime - flootime[k]["last"]) >= floorate["un"][1]):
				if (flootime[k]["un"][1] > 0):
					for l in flootime[k]["list"].keys():
						for floocomd in floocmds["un"]:
							outp(sockobjc, floocomd % flootime[k]["list"][l])
				del flootime[k]
if (__name__ == "__main__"):
	main()

Basic Python IRC Op/Flood Bot (Manual)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s