ChatStats v4 - An hell of offical release!
 

ChatStats v4 - An hell of offical release!

Started by Madman, 24 January, 2009, 00:13:27

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Madman

You people finnaly got me annoyed enough, that i wrote an offfical updated of ChatStatsv3.

This is NOT:
some half assed thing done by a converter
a version missing credits
a version with undocumented changes
a version with credits changed and undocumented changes.


This is:
an official release
a version with all the credits
a version with documented changes
a version converted by hand


And a side note, another ranking system, was written in another version 3.
But that featured actual regging of users, so this is a new ranking sytem.

-- ChatStats
-- Made By Optimus
-- Based on Tezlo chats
-- Version 3 by... alot of scripters
-- Version 4 - An offical version - Made by Madman

-- Version 3 changelog can be found at the end of this script

-- Version 4.0
-- Changed: All settings moved to tConfig table
-- Changed: 1/0 is now true/false
-- Changed: Some settings name
-- Added: CheckForFolder
-- Changed: tbl files now in ChatStats folder by default
-- Changed: Some API 2 updates
-- Changed: Code improvement for showing stats
-- Added: Ranking system

-- Version 4.1
-- Added: Rank in login msg, requested by Highlander Back
-- Added: Total in login msg
-- Fixed: Now sends login msg even when rightclick is disabled

-- Version 4.2
-- Fixed Bad SendToUser in UserConnected, reported by †StIfFLEr†™

tConfig = {
	Bot = SetMan.GetString(21), -- Name of Bot
	SendRC = true, -- Send UserCommands
	rcMenu = "ChatStats", -- Name of Menu
	Monthly = true, -- true/false = on/off
	Total = false,
	Rank = true,
	File = "chatstats.tbl", -- Add Total (char+words+post) in the chatstats, 1 = On  0 = Off
	Sortstats = 5, -- 2=posts / 3 = chars / 4 = words / 5 = Total
	-- Defaults back to posts if Total is disabeld but this is leaved on 5
	IgnoreTable = {
	-- 0=dont ignore/1=ignore
		["-=FakeKiller=-"] = true,
	},
	EnableChatStats = {
		[0] = true, -- Master
		[1] = true, -- Operators
		[2] = true, -- Vips
		[3] = true, -- Regs
		[-1] = true, -- Users (UnRegged)
	},
	AllowedProfiles = {
		[0] = true, -- Masters
		[1] = false, -- Operators
	},
	tRank = {
		["100"] = "Please give me some attenion",
		["200"] = "Newbie",
		["300"] = "Chatter",
		["400"] = "Almost Chatter",
		["500"] = "Chatter",
		["600"] = "Chat Slave",
		["700"] = "Uncontrollable Chatter",
		["800"] = "Unstopable Chatter",
		["900"] = "It's within my grasp!",
		["1000"] = "The Chat Master",
	}
}

Chatstats = {}
ChatstatsMonth = {}

---------- Warning! Do Not Edit! -----------
ChatStatsFileMonth = "chatstats - " ..os.date("%y-%m").. ".tbl"
---------- Warning! Do Not Edit! -----------

CheckForFolder = function()
	local wPath = string.gsub(Path,"/","\\")
	if os.execute('dir "'..wPath..'"') ~= 0 then
		os.execute('mkdir "'..wPath..'"')
	end
end

function CheckFile(File)
	local file = io.open(Path..File, "r")
	if file then
		file:close()
	else
		local file = io.open(Path..File, "w+")
		file:write()
		file:close()
	end
end

Path = Core.GetPtokaXPath().."scripts/ChatStats/"
CheckForFolder()

function OnStartup()
	Core.RegBot(tConfig.Bot,"ChatBot v4","",true)
	CheckFile(tConfig.File)
	dofile(Path..tConfig.File)
	if tConfig.Monthly then
		CheckFile(ChatStatsFileMonth)
		dofile(Path..ChatStatsFileMonth)
	end
	if not tConfig.Total then
		tConfig.SortStats = 2
	end
end

function UserConnected(user)
	if tConfig.EnableChatStats[user.iProfile] then
		if Chatstats[string.lower(user.sNick)] then
			Msg =  "Your ChatStats:  You made "..Chatstats[string.lower(user.sNick)]["post"].." posts in main used "..Chatstats[string.lower(user.sNick)]["chars"].." characters, and "..Chatstats[string.lower(user.sNick)]["words"].." words"
			if tConfig.Total then
				Msg = Msg..", with a total of " ..Chatstats[string.lower(user.sNick)]["tot"]
			end
			if tConfig.Rank then
				Msg = Msg..", and your rank is "..Chatstats[string.lower(user.sNick)]["rank"]
			end
			Core.SendToUser(user,"<" ..tConfig.Bot.. "> ---===[ " ..Msg.. " ]===---")
		end
		if tConfig.SendRC then
			Core.SendToNick(user.sNick,"$UserCommand 1 3 "..tConfig.rcMenu.."\\ChatStats$<%[mynick]> !chatstats&#124;")
			if tConfig.Monthly then
				Core.SendToNick(user.sNick,"$UserCommand 1 3 "..tConfig.rcMenu.."\\ChatStats Year-Month$<%[mynick]> !chatmonth %[line:YY-MM]&#124;")
			end
			Core.SendToNick(user.sNick,"$UserCommand 1 3 "..tConfig.rcMenu.."\\My ChatStats$<%[mynick]> !mystats&#124;")
			if tConfig.AllowedProfiles[user.iProfile] then
				Core.SendToNick(user.sNick,"$UserCommand 1 3 "..tConfig.rcMenu.."\\Op menu\\Del Chatter$<%[mynick]> !delchatter %[line:Nick]&#124;")
				Core.SendToNick(user.sNick,"$UserCommand 1 3 "..tConfig.rcMenu.."\\Op Menu\\Lower Chatter$<%[mynick]> !lowerchatter %[line:Nick] %[line:New posts]&#124;")
				Core.SendToNick(user.sNick,"$UserCommand 1 3 "..tConfig.rcMenu.."\\Op Menu\\Clear Chat Stats$<%[mynick]> !clearstats&#124;")
			end
			Core.GetUserData(user,11)
			if user.bOperator then
				Core.SendToNick(user.sNick,"$UserCommand 1 3 "..tConfig.rcMenu.."\\Op Menu\\TopChatters in Main$<%[mynick]> !topchat&#124;")
			end
		end
	end
end

OpConnected = UserConnected

function OnExit()
	if isEmpty(Chatstats) then
	else
		saveTableToFile(Path..tConfig.File, Chatstats, "Chatstats")
		if tConfig.Monthly then
			saveTableToFile(Path..ChatStatsFileMonth, ChatstatsMonth, "ChatstatsMonth")
		end
	end
end

function IsCmd(str)
	return string.sub(str, 1, 1) == "!" or string.sub(str, 1, 1) == "?" or string.sub(str, 1, 1) == "+" or string.sub(str, 1, 1) == "$"
end

function ChatArrival(user, data)
	if tConfig.EnableChatStats[user.iProfile] then
		local s,e,cmd = string.find(data,"%b<>%s+(%S+)")
		if IsCmd(cmd) then
		elseif tConfig.IgnoreTable[string.lower(user.sNick)] then
		else
			local s,e,str = string.find(data, "%b<>%s+(.*)%|")
			updStats(string.lower(user.sNick), str)
		end
	end
	local data = string.sub(data,1, -2)
	local s,e,cmd = string.find(data, "%b<>%s+[%!%+%?](%S+)")
	if cmd then
		cmd = string.lower(cmd)
		local tCmds = {
		["mystats"] = function(user, data)
			if Chatstats[string.lower(user.sNick)] then
				Core.SendToUser(user,"<" ..tConfig.Bot.. "> ---===[ Your Chat Stats:  You Made "..Chatstats[string.lower(user.sNick)]["post"].." Posts In Main Used "..Chatstats[string.lower(user.sNick)]["chars"].." Characters, And "..Chatstats[string.lower(user.sNick)]["words"].." Words ]===---")
			else
				Core.SendToUser(user,"<" ..tConfig.Bot.. "> *** No chat statics found!") 
			end
		end,
		["chatstats"] = function(user, data)
			Topic = "Current Top Chatters"
			Msg = Stats(Topic)
			Core.SendPmToUser(user,tConfig.Bot,Msg)
		end,
		["chatmonth"] = function(user,data)
			if tConfig.Monthly then
				local _,_,Y,M = string.find(data,"%b<>%s+%S+%s+(%d%d)%-(%d%d)")
				if Y and M then
					Topic = "Current Top Chatters of Month"
					Msg = Stats(Topic,Y,M)
					Core.SendPmToUser(user,tConfig.Bot,Msg)
				else
					Core.SendToUser(user,"<" ..tConfig.Bot.. "> Syntax: !chatmonth YY-MM i.e 07-02 for feb, 07")
				end
			else
				Core.SendToUser(user,"<" ..tConfig.Bot.. "> This function is disabled")
			end
		end,
		["topchat"] = function(user, data)
			Core.GetUserData(user,11)
			if user.bOperator then
				Topic = "Current Top Chatters"
				Msg = Stats(Topic)
				Core.SendToAll("<" ..tConfig.Bot.. "> " ..Msg)
			end
		end,
		["lowerchatter"] = function(user, data)
			if tConfig.AllowedProfiles[user.iProfile] then
				local s,e,name,chat = string.find(data, "%b<>%s+%S+%s+(%S+)%s+(%d+)")
				if name and chat then
					name = string.lower(name)
					if Chatstats[name] then
						chat = tonumber(chat)
						if Chatstats[name]["post"] <= chat then
							Core.SendToUser(user,"<" ..tConfig.Bot.. "> *** You can not raise the stats!")
						else
							local OldChat = Chatstats[name]["post"]
							Chatstats[name]["post"] = chat
							if tConfig.Rank then
								for posts,rank in pairs(tConfig.tRank) do
									-- Ugly fix, but if lowered bellow rank system, rank is removed
									if Chatstats[name]["post"] < tonumber(posts) then
										Chatstats[name]["rank"] = ""
										break
									-- Change rank
									elseif Chatstats[name]["post"] >= tonumber(posts) then
										Chatstats[name]["rank"] = rank
									end
								end
							end
							Core.SendToOps("<"..tConfig.Bot.. "> *** Chatstats posts for " ..name.. " has been lowered to " ..chat.. " from " ..OldChat.. " by " ..string.lower(user.sNick))
							saveTableToFile(Path..tConfig.File, Chatstats, "Chatstats")
						end
					else
						Core.SendToUser(user,"<" ..tConfig.Bot.. "> *** " ..name.. " is not in chatstats")
					end
				else
					Core.SendToUser(user,"<" ..tConfig.Bot.. "> *** Usage: !lowerchatter <name> <new posts>")
				end
			end
		end,
		["delchatter"] = function(user, data)
			if tConfig.AllowedProfiles[user.iProfile] then
				local s,e,name = string.find(data, "%b<>%s+%S+%s+(%S+)" )
				if name then
					if Chatstats[name] then
						Chatstats[name] = nil
						Core.SendToOps("<"..tConfig.Bot.. "> Chatstats from user "..name.." are now removed!")
						saveTableToFile(Path..tConfig.File, Chatstats, "Chatstats")
					else
						Core.SendToUser(user,"<" ..tConfig.Bot.. "> *** Chatstats from user "..name.." not found!")
					end
				else
					Core.SendToUser(user,"<" ..tConfig.Bot.. "> *** Usage: !delchatter <name>")
				end
			end
		end,
		["clearstats"] = function(user, data)
			if tConfig.AllowedProfiles[user.iProfile] then
				Chatstats = {}
				saveTableToFile(Path..tConfig.File, Chatstats, "Chatstats")
				Core.SendToAll("<" ..tConfig.Bot.. "> Chatstats are cleared by "..user.sNick)
			end
		end,
		}
		if tCmds[cmd] then
			return tCmds[cmd](user, data),true
		end
	end
end

function Stats(Topic,Y,M)
	if Chatstats then
		if Y and M then
			if loadfile("chatstats - " ..Y.. "-" ..M.. ".tbl") then
				loadTableFromFile("chatstats - " ..Y.. "-" ..M.. ".tbl")
				Table = ChatstatsMonth
			else
				return "That month has not been logged"
			end
		else
			Table = Chatstats
		end
		TCopy={}
		for i,v in pairs(Table) do
			table.insert(TCopy,{i,v.post,v.chars,v.words,v.tot,v.rank})
		end
		table.sort(TCopy,function(a,b) return (a[tConfig.Sortstats] > b[tConfig.Sortstats]) end)
		local chat = Topic..":\r\n\r\n"
		chat = chat.."\t ------------------------------------------------------------------------\r\n"
		---- Build order list, part 1
		chat = chat.."\t Nr.\tPosts:\tChars:\tWords:"
		if tConfig.Total then
			chat = chat.."\tTotalt:"
		end
		chat = chat.."\tName:"
		if tConfig.Rank then
			chat = chat.."\tRank:"
		end
		chat = chat.."\r\n"
		----
		chat = chat.."\t ------------------------------------------------------------------------\r\n"
		for i = 1,25 do 
			if TCopy[i] then
				---- Build order list, part 2
				chat = chat.."\t "..i..".\t "..TCopy[i][2].."\t "..TCopy[i][3].."\t "..TCopy[i][4] -- Nr, Posts,Chars,Words
				if tConfig.Total then
					chat = chat.."\t"..TCopy[i][5] -- Total
				end
				chat = chat.."\t"..TCopy[i][1] -- Name
				if tConfig.Rank then
					chat = chat.."\t"..TCopy[i][6] -- Rank
				end
				chat = chat.."\r\n"
				----
			end
		end
	return chat
	end
	TCopy={}
end


function updStats(nick, str)
	local tmp = Chatstats[nick] or {["post"]=0, ["chars"]=0, ["words"]=0, ["time"]=os.date("%x"),["tot"]=0,["rank"]=""}
	tmp["post"], tmp["chars"], tmp["words"], tmp["time"], tmp["tot"] = tmp["post"]+1, tmp["chars"]+string.len(str), tmp["words"]+cntargs(str,"(%a+)"), os.date("%x"), tmp["tot"]+string.len(str)+cntargs(str,"(%a+)")+1
	if tConfig.Rank then
		for posts,rank in pairs(tConfig.tRank) do
			if tmp["post"] == tonumber(posts) then
				tmp["rank"] = rank
				Core.SendToAll("<" ..tConfig.Bot.. "> " ..nick.. " is now at rank:" ..rank)
			end
		end
	end
	Chatstats[nick] = tmp
	saveTableToFile(Path..tConfig.File, Chatstats, "Chatstats")
	if tConfig.Monthly then
		local tmpM = ChatstatsMonth[nick] or {["post"]=0, ["chars"]=0, ["words"]=0, ["time"]=os.date("%x"),["tot"]=0,["rank"]=""}
		tmpM["post"], tmpM["chars"], tmpM["words"], tmpM["time"], tmpM["tot"] = tmpM["post"]+1, tmpM["chars"]+string.len(str), tmpM["words"]+cntargs(str,"(%a+)"), os.date("%x"), tmpM["tot"]+string.len(str)+cntargs(str,"(%a+)")+1
		if tConfig.Rank then
			for posts,rank in pairs(tConfig.tRank) do
				if tmpM["post"] == tonumber(posts) then
					tmpM["rank"] = rank
				end
			end
		end
		ChatstatsMonth[nick] = tmpM
		saveTableToFile(Path..ChatStatsFileMonth,ChatstatsMonth,"ChatstatsMonth")
	end
end


function cntargs(str, rule)
	local s,n = string.gsub(str, rule, "")
	return n
end

----------------------------------------------
-- load & save Tables
----------------------------------------------
function Serialize(tTable, sTableName, sTab)
	assert(tTable, "tTable equals nil");
	assert(sTableName, "sTableName equals nil");
	assert(type(tTable) == "table", "tTable must be a table!");
	assert(type(sTableName) == "string", "sTableName must be a string!");
	sTab = sTab or "";
	sTmp = ""
	sTmp = sTmp..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
			sTmp = sTmp..Serialize(value, sKey, sTab.."\t");
		else
			local sValue = (type(value) == "string") and string.format("%q",value) or tostring(value);
			sTmp = sTmp..sTab.."\t"..sKey.." = "..sValue
		end
		sTmp = sTmp..",\n"
	end
	sTmp = sTmp..sTab.."}"
	return sTmp
end

-----------------------------------------------------------
function saveTableToFile(file, table, tablename)
	local handle = io.open(file,"w+")
	handle:write(Serialize(table, tablename))
	handle:flush()
	handle:close()
end
-----------------------------------------------------------
function loadTableFromFile(file)
	local f = io.open(file)
	if f then
		local r = f:read("*a")
		f:flush()
		f:close()
		local func,err = loadstring(r)
		if func then x,err = pcall(func) end
	end
end

-------------table checker by herodes
--- for an associative table, like ["smth"] = "smth else",
function isEmpty(t)
	for i,v in pairs(t) do
		return false;
	end
	return true;
end;

-- Added Send Commands By TiMeTrAVelleR
-- Madman fixed some in commands
-- Converted to lua5 by Madman with very little help by Jelf
-- with some help by ?
-- fixed stats saving on exit by jiten
---- Modded by Madman
-- Added so it's creates ChatStatsFile, if it's missing
-- Fixed so it dont counts commands
-- Added a IgnoreTable, users in that wont be counted
---- Madman Return's
-- Changed: New ChatArrival
-- Changed: Some Commands
-- Changed: Some small code...
-- Changed: Modded 4 my hub
---- Madman strikes again
-- Added: a lowerchatter cmd, use it to lower someones chatstats post
-- Changed to lua 5.1 by TT
-- Added: chatter of Month, Madman, requested by BrotherBear
-- Added: not case senastive, all nicks will be loged in lower case, Madman, requested by Yahoo
-- Madman does it again
-- Added: Total (char+words+post), request by -SkA-
-- Adedd: Option for Total
-- Changed: Cleaned up code, chatstats,chatmonth and topchat now use same function
-- Added: Sorting by Total, request by -SkA-
-- Changed: Shortstats Option
---- Updated again, by Madman
-- Added: UseMonthStats, so you don't have to use the month stats

We suffer in silence, we lurk in the shadows, we kill in the night
Site currently down, ETA of returning online is 2099 ;p

CrazyGuy


Highlander Back

Nice script 2 requests do if posible

1.
when logging in   that you see rank aswel  ---===[ Your Chat Stats:  You Made 1 Posts In Main Used 1 Characters, And 0 Words Youre current chatrank is newby ]===---
2.
Instead of just lowering stats from a user   change  if its lower ore higher

Greetz Highlander

Madman

Quote from: Highlander Back on 24 January, 2009, 09:10:01
Nice script 2 requests do if posible

1.
when logging in   that you see rank aswel  ---===[ Your Chat Stats:  You Made 1 Posts In Main Used 1 Characters, And 0 Words Youre current chatrank is newby ]===---
Done, script updated
Quote from: Highlander Back on 24 January, 2009, 09:10:01
2.
Instead of just lowering stats from a user   change  if its lower ore higher
If i'm understanding you right. NO!
I'm not going to lett you raise a users chat. That would be cheating...
If users get lowered... well shit happens...
We suffer in silence, we lurk in the shadows, we kill in the night
Site currently down, ETA of returning online is 2099 ;p

?StIfFLEr??

LOL madman,
i never thought my repeated request for conversion would make you this angry.
But its the best who finishes it in style :P
And its you.
Thanks a lot for making this script.


Madman

Not your post specific.
Its just that, there are like 10 diffrent v3, and all of them is called v3
Only diffrent is the changelog in the begining. And all version isn't modded after latest fixes in script.

It's a shitload of versions, that are just messy and maybe maybe the changes are documented
We suffer in silence, we lurk in the shadows, we kill in the night
Site currently down, ETA of returning online is 2099 ;p

?StIfFLEr??

no problem madman
i would like to thank for making it official atleast the script isn't orphan anymore :P
would surely like to share some more thoughts regarding the script sooner.
I have been back after a long time on the forum so trying to go through all the scripts.
Madman there is one more request could you please make some tutorials if you be free anytime for people to learn scripting on your site.

Madman

We suffer in silence, we lurk in the shadows, we kill in the night
Site currently down, ETA of returning online is 2099 ;p

?StIfFLEr??

Madman small error i came accross would like to share it with you.
The script line number 114 showed following line
QuoteCore.SendToUser(user,)"<" ..tConfig.Bot.. "> ---===[ " ..Msg.. " ]===---"
which i suppose will give error on ptokax 4.1 and the script would not start.
can it be updated with.
Core.SendToUser(user,"<" ..tConfig.Bot.. "> ---===[ " ..Msg.. " ]===---")

So that it will work for everyone in ptokax 4.1
Hope you dont mind.
Thanks a lot for making the script.

Madman

I don't mind, beacuse it is suposed to work on px 0.4.1.1.
So that was a bug...
Script updated
We suffer in silence, we lurk in the shadows, we kill in the night
Site currently down, ETA of returning online is 2099 ;p

?StIfFLEr??


SMF spam blocked by CleanTalk