Page 1 of 1

IP-Range Gag Lua Script

Posted: Thu Mar 19, 2009 16:23
by TiTex

Code: Select all

-----------------------------------------
--    G A G R A N G E   S C R I P T    --
--	B Y   H U N G A R I S T A	--
--		2oo8.ll.22.		  --
-- Usage:					--
--  !gagrange <fromIP> <toIP> (!gr)    --
--  !ungagrange <fromIP> <toIP> (!ugr) --
--  !listgagranges (!lgr)		  --
-----------------------------------------

iMinClass = 2   -- Who can write, even if gagged (1 - regs and above;2 - vips and above, and so on)
bBlockPM = true -- Block PM messages? true/false
iBlockMode = 1  -- Sets the mode of gagging
		    -- 0 - nobody will see the message, user isn't notified
			    -- 1 - the user get his message, but he isn't notified, so he don't know the others didn't get his msg (best way)
			    -- 2 - nobody will see the message, user will be notified about the gag
bRC = true	-- Send right-click menu? true/false
iRCClass = 3    -- Class who can use the commands [and above]. They'll got the RC menu
sMenu = "Rangegag" -- The name of the menu. To make submenus, use \\ for ex. My Hub\\Penalities\\Rangegag

-- Settings end --

if loadfile("gagrange.dat") then
	dofile("gagrange.dat")
	if not tGaggedRanges then
		tGaggedRanges = {}
	end
else
	tGaggedRanges = {}
end
_,HubSecurity = VH:GetConfig("config","hub_security")

function VH_OnOperatorCommand(nick,data)
	tWords = Tokenize(data)
	if tWords[1] == "!gagrange" or tWords[1] == "!gr" then
		CheckClass(nick)
		return Gag(tWords[2],tWords[3],nick)
	elseif tWords[1] == "!ungagrange" or tWords[1] == "!ugr" then
		CheckClass(nick)
		return Ungag(tWords[2],tWords[3],nick)
	elseif tWords[1] == "!listgagrange" or tWords[1] == "!lgr" then
		CheckClass(nick)
		local sMsg = "Currently gagged IP ranges:\r\n"
		table.sort(tGaggedRanges,function(a,b) return a[1] > a[2] end)
		for i,v in ipairs(tGaggedRanges) do
			sMsg = sMsg.." ["..i.."]. "..DEC2IP(v[1]).." - "..DEC2IP(v[2]).."\r\n"
		end
		sMsg = sMsg.."To unban a range, use !ugr <IP from> <IP to> or !ugr <number> where number is the counter from here."
		VH:SendDataToUser("<"..HubSecurity.."> "..sMsg.."|",nick)
		return 0
	end
	return 1
end

function VH_OnParsedMsgChat(nick,data,bMe)
	local _,iClass = VH:GetUserClass(nick) if not _ then iClass = -1 end
	if iClass < iMinClass then
		local _,IP = VH:GetUserIP(nick)
		local iIP,bBlocked = IP2DEC(IP),false
		for i,v in ipairs(tGaggedRanges) do
			if iIP >= v[1] and iIP <= v[2] then bBlocked = true end
		end
		if bBlocked == true then
			if iBlockMode == 0 then
				return 0
			elseif iBlockMode == 1 then
				if bMe then
					VH:SendDataToUser("** "..nick.." "..string.sub(data,5).."|",nick)
				else
					VH:SendDataToUser("<"..nick.."> "..data.."|",nick)
				end
				return 0
			else
				local _,HubSecurity = VH:GetConfig("config","hub_security")
				VH:SendDataToUser("<"..HubSecurity.."> You have been gagged. Please wait while you'll be ungagged.|",nick)
				return 0
			end
		end
	end
	return 1
end

function VH_OnUserCommand(nick,data)
	if string.sub(data,1,3) == "+me" then
		return VH_OnParsedMsgChat(nick,data,true)
	end
	return 1
end

if bBlockPM == true then
	function VH_OnParsedMsgPM(from,data,to)
		return VH_OnParsedMsgChat(from,data)
	end
end

function VH_OnUserLogin(nick)
	if bRC then
		local _,userclass = VH:GetUserClass(nick)
		if not _ then userclass = -1 end
		if userclass >= iRCClass then
			VH:SendDataToUser("$UserCommand 1 3 "..sMenu.."\\Gag IP range$<%[mynick]> !gr %[line:from IP] %[line:to IP]&#124;|",nick)
			VH:SendDataToUser("$UserCommand 1 3 "..sMenu.."\\Ungag IP range$<%[mynick]> !ugr %[line:from IP] %[line:to IP]&#124;|",nick)
			VH:SendDataToUser("$UserCommand 1 3 "..sMenu.."\\List rangegags$<%[mynick]> !lgr&#124;|",nick)
		end
	end
end

function CheckClass(nick)
	local _,userclass = VH:GetUserClass(nick)
	if not _ then userclass = -1 end
	if userclass < iRCClass then
		VH:SendDataToUser("<"..HubSecurity.."> Unknown command. Try !help.|",nick)
		return
	end
end

function Gag(sFromIP,sToIP,nick)
	local iFromIP,iToIP = IP2DEC(sFromIP),IP2DEC(sToIP)
	if iFromIP > -1 and iToIP > -1 then
		if iFromIP < iToIP then
			for i,v in ipairs(tGaggedRanges) do
				if iFromIP >= v[1] and iToIP <= v[2] then
					VH:SendDataToUser("<"..HubSecurity.."> A larger IP range ("..DEC2IP(v[1]).." - "..DEC2IP(v[2])..") already has been gagged.|",nick)
					return
				end
			end
			table.insert(tGaggedRanges,{tonumber(iFromIP),tonumber(iToIP)})
			local f = io.open("gagrange.dat","w+");
			Serialize(tGaggedRanges,"tGaggedRanges",f)
			f:close()
			VH:SendDataToUser("<"..HubSecurity.."> IP range "..sFromIP.." - "..sToIP.." has been successfully gagged.|",nick)
		else
			VH:SendDataToUser("<"..HubSecurity.."> First IP must be lower than the second one.|",nick)
		end
	else
		VH:SendDataToUser("<"..HubSecurity.."> Command usage: !gagrange <fromIP> <toIP>|",nick)
	end
	return 0
end

function Ungag(sFromIP,sToIP,nick)
	if sFromIP then
		if sFromIP:find("^%d+$") then
			if tonumber(sFromIP) <= table.getn(tGaggedRanges) then
				local v = table.remove(tGaggedRanges,tonumber(sFromIP))
				local f = io.open("gagrange.dat","w+");
				Serialize(tGaggedRanges,"tGaggedRanges",f)
				f:close()
				VH:SendDataToUser("<"..HubSecurity.."> IP range "..DEC2IP(v[1]).." - "..DEC2IP(v[2]).." has been successfully ungagged.|",nick)
			end
		elseif sToIP ~= "" then
			local iFromIP,iToIP = IP2DEC(fromIP),IP2DEC(toIP)
			local iAdded = nil
			for i,v in ipairs(tGaggedRanges) do
				if v[1] == iFromIP and v[2] == iToIP then iAdded = i break end
			end
			if bAdded then
				table.remove(tGaggedRanges,iAdded)
				local f = io.open("gagrange.dat","w+");
				Serialize(tGaggedRanges,"tGaggedRanges",f)
				f:close()
				VH:SendDataToUser("<"..HubSecurity.."> IP range "..sFromIP.." - "..sToIP.." has been successfully ungagged.|",nick)
			else
				VH:SendDataToUser("<"..HubSecurity.."> Sorry, this range is not on the list.|",nick)
			end
		else
			VH:SendDataToUser("<"..HubSecurity.."> Command usage: !ungagrange <fromIP> <toIP> or !ungagrange <num>|",nick)
		end
	else
		VH:SendDataToUser("<"..HubSecurity.."> Command usage: !ungagrange <fromIP> <toIP> or !ungagrange <num>|",nick)
	end
	return 0
end
	
function DEC2IP(iNum)
	local sIP = ""
	if iNum < 0 then return "Not valid IPv4 address" end
	for i=3,1,-1 do
		if iNum>256^i then
			sIP = iNum-(math.floor(iNum/256)*256).."."..sIP
			iNum = math.floor(iNum/256)
		end
	end
	return iNum.."."..sIP:sub(1,-2)
end

function IP2DEC(sIP)
	if not sIP then return -1 end
   local iDec,iNum = 0,0
	for num in sIP:gmatch("(%d+)") do
		iNum = iNum + 1
		if tonumber(num) < 0 or tonumber(num) > 255 then return -1 end
		iDec = iDec + num*256^(4-iNum)
	end
	if iNum ~= 4 then return -1 end
	return iDec
end

function Tokenize(text)
	local tRet = {}
	text:gsub("(%S+)",function(s) table.insert(tRet, s) end)
	return tRet
end

function Serialize(tTable, sTableName, hFile, sTab)
	sTab = sTab or "";
	hFile:write(sTab..sTableName.." = {\n" );
	for key, value in pairs(tTable) do
		local sKey = (type(key) == "string") and string.format("[%q]",key) or string.format("[%d]",key);
		if(type(value) == "table") then
			Serialize(value, sKey, hFile, sTab.."\t");
		else
			local sValue = (type(value) == "string") and string.format("%q",value) or tostring(value);
			hFile:write(sTab.."\t"..sKey.." = "..sValue);
		end
		hFile:write(",\n");
	end
	hFile:write(sTab.."}");
end