--[[
Chat History On Entry 1.07 LUA 5.1x [Strict][API 2]
By Mutor 01/15/07
Logs Main Chat and provides chat history
in private message at user connect.
-Provides manual history command
-Provides delete message command
-Provides delete all messages command
-Provides history by days command
-Provides chat history help command
-Provides context menu [right click]
-Optional max history entries
-Optional number of messages sent at connect
-Optional exclude pm at login per user
+Changes from 1.05
+Added Anti-advertisement options. Requested by sphinx
+Changes from 1.06 10/14/08
+Added command function for 'nick' history, requested by quicky2g
~ A few code optimizations
<BotName> Chat History Help
Command Description
????????????????????????????????????????????
+delchat Delete Single Chat Entry
+history Get Chat History
+togglehistory Toggle Chat History
+dayhistory Chat History By Days
+chathelp Chat History Help
+delete Delete Chat History
????????????????????????????????????????????
]]
Cfg = {
-- "Botname" ["" = hub bot]
Bot = "[Historian]",
-- Bot description
Desc = "I send a message to new users.",
-- Bot email address
Mail = "user@domain.com",
-- Admin's profile
AdminProf = 0,
-- Admins nick for status / error messages
OpNick = "Mutor",
-- File to save chat data to
File = "HubChat.dat",
-- File to save chat data to
UserFile = "ChatUsers.dat",
-- Maximum number of lines to display on user connect
History = 10,
-- Maximum number of lines to cache
MaxChat = 50,
-- Context Menu Title
Menu = SetMan.GetString(0),
-- Context Submenu Title
SubMenu = "Chat History",
-- Set your profiles permissions here.
-- profile_idx, history enabled [0=no 1=yes], "Profile Name"
Profiles = {
[-1] = {1,"Unregistered User"},
[0] = {1,"Master"},
[1] = {1,"Operator"},
[2] = {1,"Vip"},
[3] = {1,"Registered User"},
},
-- Block Advert Strings? 0 = disabled, 1 = From History, 2 = From History/Main Chat
AaBlock = 2,
-- Message to send to user when advert trigger was found. "" = disabled [(user) will be replaced with user nick]
AaReply = "(user), your chat was blocked, don't advertise here please.",
-- External File Advert Strings "" = disabled
AaFile = "AntiAd.txt",
-- Default Anti-Advertisement triggers, if not using external file
AaTrigs = {
"dchub:","http:","ftp:","hopto.org","myftp.biz","myftp.org","myvnc.com","no-ip.biz","no-ip.info","no-ip.org",
"redirectme.net","servebeer.com","serveblog.net","servecounterstrike.com","serveftp.com","servegame.com",
"servehalflife.com","servehttp.com","servemp3.com","servepics.com","servequake.com","sytes.net","mine.nu",
"zapto.org","blogsyte.com","cable-modem.org","ciscofreak.com","damnserver.com","ditchyourip.com","bounceme.net",
"dnsiskinky.com","geekgalaxy.com","homesecuritymac.com","homesecuritypc.com","myactivedirectory.com",
"mymediapc.net","mypsx.net","net-freaks.com","no-ip.ca","no-ip.co.uk","no-ip.com","no-ip.net","point2this.com",
"pointto.us","quicksytes.com","securityexploits.com","securitytactics.com","serveexchange.com","servehumour.com",
"servep2p.com","servesarcasm.com","stufftoread.com","unusualperson.com","workisboring.com","dns2go","myftpsite",
},
-- Replace characters < 32 and > 132 with this string. [Set: false, to disable]
RepChar = "?",
}
local r,sc = "?",0
OnStartup = function()
if _VERSION ~= "Lua 5.1" then return OnError("This script is incompatible with ".._VERSION),true end
Cfg.Script,Cfg.Pfx,Cfg.Path = "Chat History 1.07",SetMan.GetString(29):sub(1,1),Core.GetPtokaXPath().."scripts/"
if Cfg.Bot == "" then Cfg.Bot = SetMan.GetString(21) end
if Cfg.Bot ~= SetMan.GetString(21) then Core.RegBot(Cfg.Bot,Cfg.Desc.." PtokaX ".._VERSION, Cfg.Mail,true) end
if not Cfg.File:find("^"..Cfg.Path,1,true) then Cfg.File = Cfg.Path..Cfg.File end
if not Cfg.UserFile:find("^"..Cfg.Path,1,true) then Cfg.UserFile = Cfg.Path..Cfg.UserFile end
if loadfile(Cfg.File) then
dofile(Cfg.File)
local f,e = io.open(Cfg.File)
local size = f:seek("end")
size = FormatSize(size)
f:close()
OnError(Cfg.File.." was found and executed. File size: "..
size.." "..#Cfg.Chat.." entries.")
else
Cfg.Chat = {}
local t = {
tonumber(os.date("%Y") + os.date("%j")),
os.date("%m/%d/%y"),
os.date("%I:%M")..os.date("%p"):lower():sub(1,1),
--os.date("%I:%M")..string.sub(string.lower(os.date("%p")),1,1),
"<"..Cfg.Bot.."> Chat history file created "..
os.date("on: %B %d, %Y at: %I:%M")..string.sub(string.lower(os.date("%p")),1,1)
}
table.insert(Cfg.Chat,t)
SaveToFile(Cfg.File,Cfg.Chat,"Cfg.Chat")
OnError(Cfg.File.." was not found. This file has been created for you.")
end
if loadfile(Cfg.UserFile) then
dofile(Cfg.UserFile)
local f,e = io.open(Cfg.UserFile)
local size = f:seek("end")
size = FormatSize(size)
f:close()
OnError(Cfg.UserFile.." was found and executed. File size: "..
size.." "..#Cfg.Exclude.." entries.")
else
Cfg.Exclude = {}
SaveToFile(Cfg.UserFile,Cfg.Exclude,"Cfg.Exclude")
OnError(Cfg.UserFile.." was not found. This file has been created for you.")
end
if Cfg.AaFile ~= "" then
local Path = Core.GetPtokaXPath().."scripts/"
if not Cfg.AaFile:find("^"..Path,1,true) then Cfg.AaFile = Path..Cfg.AaFile end
if loadfile(Cfg.AaFile) then dofile(Cfg.File) end
end
OnError(Cfg.Script.." has been started. Memory usage: "..Mem())
end
OnExit = function()
SaveToFile(Cfg.File,Cfg.Chat,"Cfg.Chat")
OnError(Cfg.Script.." has been stopped, freeing "..Mem().." of memory.")
end
OnError = function(msg)
if Core.GetUser(Cfg.OpNick) then
Core.SendToNick(Cfg.OpNick,"<"..Cfg.Bot.."> "..msg.."|")
end
end
ChatArrival = function(user, data)
data = data:sub(1,-2)
local _,_,to = data:find("^$To: (%S+) From:")
local _,_,prefix = data:find("%b<> (["..SetMan.GetString(29).."])")
if not prefix and not to then
local ad,op = ChkAd(data)
if user.iProfile ~= -1 then op = ProfMan.GetProfile(user.iProfile).tProfilePermissions.bIsOP end
if not op and ad and Cfg.AaBlock > 0 then
if Cfg.AaReply ~= "" then
Core.SendToUser(user,"<"..Cfg.Bot.."> "..Cfg.AaReply:gsub("%(user%)",user.sNick).."|")
end
if Cfg.AaBlock == 2 then return true end
end
if Cfg.RepChar then
for c in data:gmatch(".") do
if c:byte() < 32 or c:byte() > 133 then data = data:gsub(c,Cfg.RepChar) end
end
end
if Cfg.AaBlock > 0 and ad then return end
local t = {
tonumber(os.date("%Y") + os.date("%j")),
os.date("%m/%d/%y"),
os.date("%I:%M")..string.sub(string.lower(os.date("%p")),1,1),
data,}
table.insert(Cfg.Chat,t)
sc = sc + 1
while #Cfg.Chat > Cfg.MaxChat do table.remove(Cfg.Chat,1) end
if sc > Cfg.History then sc = 0 SaveToFile(Cfg.File,Cfg.Chat,"Cfg.Chat") end
else
local _,_,cmd = data:find("%b<> %p(%w+)")
if cmd and Cmds[cmd] then
if Cfg.Profiles[user.iProfile] and Cfg.Profiles[user.iProfile][1] == 1 then
if to and to == Cfg.Bot then
return Core.SendPmToUser(user,Cfg.Bot,Cmds[cmd](user,data).."|"),true
else
return Core.SendToUser(user,"<"..Cfg.Bot.."> "..Cmds[cmd](user,data).."|"),true
end
else
if to and to == Cfg.Bot then
Core.SendPmToUser(user,Cfg.Bot,user.sNick..
" you dont have permission to use this command.|")
else
Core.SendToUser(user,"<"..Cfg.Bot.."> "..user.sNick..
" you dont have permission to use this command.|")
end
return true
end
end
end
end
ToArrival = ChatArrival
UserConnected = function(user)
if Cfg.Profiles[user.iProfile] and Cfg.Profiles[user.iProfile][1] == 1 then
local Exclude = CheckEx(user)
if not Exclude then
local add = "\n\n\tType "..Cfg.Pfx.."togglehistory to disable this message.\n\n"
Core.SendPmToUser(user,Cfg.Bot,add..GetChat(Cfg.History).."|")
end
end
if SendCmds(user) then
local Profile = ProfName(user)
Core.SendToUser(user,"<"..Cfg.Bot.."> "..Profile.."'s Chat History 1.07 "..
"commands enabled. Right click hub tab for command menu.|")
end
end
RegConnected,OpConnected = UserConnected,UserConnected
CheckEx = function(user)
for a,b in ipairs(Cfg.Exclude) do if b:lower() == user.sNick:lower() then return a end end
end
GetChat = function(lines)
local x = lines
lines = math.min(lines,#Cfg.Chat)
x = #Cfg.Chat - x
local str = "\r\n\r\n <"..r:rep(70).."[ Last ( "..(lines).." ) chat messages ]??????????>\r\n"
for i,v in ipairs(Cfg.Chat) do
if i > x then
str = str.."\r\n "..string.format("%"..string.len(#Cfg.Chat)..
"s",i).."] "..v[2].." "..v[3].." "..v[4]
end
end
return str.."\r\n\r\n <"..r:rep(70).."[ End of chat history ]"..
r:rep(4 + string.len(lines)).."??????????>\r\n\r\n"
end
DelChat = function(lines)
local count = lines
if lines > #Cfg.Chat then lines = #Cfg.Chat end
if lines == #Cfg.Chat then count = "all "..lines end
for x = 1, lines do table.remove(Cfg.Chat,1) end
if #Cfg.Chat == 0 then
local t = {
tonumber(os.date("%Y") + os.date("%j")),
os.date("%m/%d/%y"),
os.date("%I:%M")..string.sub(string.lower(os.date("%p")),1,1),
"<"..Cfg.Bot.."> Chat history cleared "..
os.date("on: %B %d %Y at: %I:%M")..string.sub(string.lower(os.date("%p")),1,1)
}
table.insert(Cfg.Chat,t)
end
SaveToFile(Cfg.File,Cfg.Chat,"Cfg.Chat")
return count.." messages deleted."
end
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 ipairs(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 SaveToFile(File , Table , Tablename)
local handle = io.open(File,"w")
handle:write(Serialize(Table, Tablename))
handle:flush()
handle:close()
Mem()
end
SendCmds = function(user)
if Cfg.Profiles[user.iProfile] and Cfg.Profiles[user.iProfile][1] == 1 then
for i,v in pairs(Cmds) do
local m,s,pfx = Cfg.Menu,Cfg.SubMenu,Cfg.Pfx
local c,n,pm,p = "$UserCommand 1","$<%[mynick]>","$$To: "..
Cfg.Bot.." From: %[mynick] ","||"
local d,a1,a2 = Cmds[i]()
Core.SendToUser(user,c.." 1 "..m.."\\"..s.."\\"..d..n.." "..pfx..i..a1..p)
Core.SendToUser(user,c.." 2 "..m.."\\"..s.."\\"..d..pm..n.." "..pfx..i..a2..p)
end
Mem()
return true
end
end
Mem = function() collectgarbage("collect") return string.format("%-.2f Kb.",collectgarbage("count")) end
FormatSize = function(int)
local i,u,x = tonumber(int) or 0,{"","K","M","G","T","P"},1
while i > 1024 do i,x = i/1024,x+1 end return string.format("%.2f %sB.",i,u[x])
end
ProfName = function(user)
local p,prof = user.iProfile,"Unregistered User"
if p ~= -1 then prof = ProfMan.GetProfile(p).sProfileName end
return prof
end
ChkAd = function(data)
for i,v in ipairs(Cfg.AaTrigs) do
if data:lower():find(v:lower(),1,1) or data:lower():find("%d+%.%d+%.%d+%.%d+") then return i end
end
end
Cmds = {
togglehistory = function(user,data)
if user then
local status,result = "removed from","You will now receive chat history at login."
local Exclude = CheckEx(user)
if not Exclude then
table.insert(Cfg.Exclude,user.sNick)
status,result = "added to","You will no "..
"longer receive chat history at login."
else
table.remove(Cfg.Exclude,Exclude)
end
SaveToFile(Cfg.UserFile,Cfg.Exclude,"Cfg.Exclude")
return "You have been "..status.." the exclusion table. "..result
else
return "Toggle Chat History","",""
end
end,
history = function(user,data)
local ChatLines = Cfg.MaxChat
if user then
local _,_,lines = data:find("%b<> %p%a+ (%d+)")
if not lines then lines = ChatLines else lines = tonumber(lines) end
return GetChat(lines)
else
return "Get Chat History",
" %[line:# of Lines or none for "..ChatLines.."]",
" %[line:# of Lines or none for "..ChatLines.."]"
end
end,
nickhistory = function(user,data)
if user then
local _,_,nick = data:find("%b<> %p%a+ (%S+)")
if nick then
local _,_,count = data:find("%b<> %p%a+ %S+ (%d+)")
count = tonumber(count) or #Cfg.Chat
local sn = "<"..nick:lower()..">"
local cnt,str = 0,""
for i,v in ipairs(Cfg.Chat) do
local _,_,n = v[4]:lower():find("^(%b<>) ")
if n and n == sn and cnt < count then
cnt,str = cnt + 1,str.."\r\n "..string.format("%"..
string.len(#Cfg.Chat).."s",i).."] "..v[2].." "..v[3].." "..v[4]
end
end
if cnt > 0 then
local pl = "s"
if cnt == 1 then pl = "" end
return "\r\n\r\n <"..r:rep(70).."[ Last ( "..tostring(cnt)..
" ) chat message"..pl.." for "..nick.." ]??????????>\r\n"..
str.."\r\n\r\n <"..r:rep(70).."[ End of "..nick.."'s chat history ]"..
r:rep(4 + string.len(cnt)).."??????????>\r\n\r\n"
else
return "Sorry "..user.sNick.." there where no entries found for "..nick.."."
end
else
return "Error! Usage: "..Cfg.Pfx.."nickhistory <nick>"
end
else
return "Get Chat History For Nick",
" %[line:User NickName] %[line:Number Of Messages (**None = All)]",
" %[nick] %[line:Number Of Messages (**None = All)]"
end
end,
dayhistory = function(user,data)
local today = tonumber(os.date("%Y") + os.date("%j"))
if user then
local _,_,days = data:find("%b<> %p%a+ (%d+)")
if days then
local past = today - tonumber(days)
OnError(past)
local str = "\r\n\r\n <"..string.rep("?",70)..
"[ Last ( "..days.." ) days of chat ]??????????>\r\n"
for i,v in ipairs(Cfg.Chat)do
if v[1] > past then str = str.."\r\n ["..i.."] "..v[2].." "..v[3].." "..v[4] end
end
str = str.."\r\n\r\n <"..string.rep("?",70).."[ End of chat history ]"..
string.rep("?",string.len(days)).."??????????>\r\n\r\n"
return str
else
return "You must specify how many days"
end
else
return "Chat History By Days",
" %[line:How Many Days of Chat Do You Want to See?]",
" %[line:How Many Days of Chat Do You Want to See?]"
end
end,
delete = function(user,data)
local ChatLines = #Cfg.Chat
if user then
if user.iProfile == Cfg.AdminProf then
local _,_,lines = data:find("%b<> %p%a+ (%d+)")
if not lines then lines = ChatLines else lines = tonumber(lines) end
return DelChat(lines)
else
return "Sorry "..user.sNick..", this command is for "..
ProfMan.GetProfile(Cfg.AdminProf).sProfileName.."'s only."
end
else
return "Delete Chat History",
" %[line:# of Lines **None = All ("..ChatLines..") messages ]",
" %[line:# of Lines **None = All ("..ChatLines..") messages ]"
end
end,
delchat = function(user,data)
local ChatLines = #Cfg.Chat
if user then
if user.iProfile == Cfg.AdminProf then
local _,_,line = data:find("%b<> %p%a+ (%d+)")
if line then
line = tonumber(line)
if Cfg.Chat[line] then
local str = Cfg.Chat[line][4]
table.remove(Cfg.Chat,line)
SaveToFile(Cfg.File,Cfg.Chat,"Cfg.Chat")
return "Chat entry "..line.." deleted has been deleted.\r\n"..
"Deleted Entry: "..string.format("%q",str)
else
return line.." is not a valid entry."..GetChat(Cfg.History)
end
else
return "You must specify an entry to delete."
end
else
return "Sorry "..user.sNick..", this command is for "..
ProfMan.GetProfile(Cfg.AdminProf).sProfileName.."'s only."
end
else
return "Delete Single Chat Entry",
" %[line:Delete Which Entry?]",
" %[line:Delete Which Entry?]"
end
end,
chathelp = function(user,data,to)
if user then
local reply = "Chat History Help\n\n\tCommand\t\tDescription\r\n"..
"\t"..string.rep("?",40).."\r\n"
for i,v in pairs(Cmds) do
local desc,args = Cmds[i]()
reply = reply.."\t"..Cfg.Pfx..string.format("%-15s",i).."\t"..desc.."\r\n"
end
return reply.."\n\t"..string.rep("?",40).."\r\n\r\n"
else
return "Chat History Help","",""
end
end,
}
Hello ... I have a problem with this script ... I would be concerned if he can solve ...
Input script more often than not recognize the nick ascii o some messages ... replacing them with dots of blacks ... would be possible to find a solution to this problem?
Thanks ... Best regards ...
Maximilian
for exmple ...
<??????????????????????????????????????????????????????????????????????[ Last ( 10 ) chat messages ]??????????>
41] 05/25/10 08:25p <][V][?????> sera a tutti ;)
42] 05/25/10 09:56p <][V][?nm???> ????? $??? H?b
43] 05/25/10 11:02p <pisi_for_you3> fav/
44] 05/25/10 11:56p <!!!??++??????Mirijo> notteee
45] 05/26/10 03:22a <ParrotFish> the used
46] 05/26/10 08:35a <!!!??++??????L???> ????~? Augura A Tutti Una Buona Giornata ?~???? ??
47] 05/26/10 09:17a <!!??++?????????Mk???????> ?h? J???? K??? ? Heaven & Hell - Bible Black ? \m/ ? 06:26..??? t? n?v?? n?v?? l?n?..?.?.?
48] 05/26/10 09:17a <!!??++?????????Mk???????> Don't go on, put it back ! You're reading from the Bible Black !!!
49] 05/26/10 09:37a <!!??++?????????Mk???????> a mare
50] 05/26/10 09:37a <!!??++?????????Mk???????> xD
<??????????????????????????????????????????????????????????????????????[ End of chat history ]????????????????>
Thanks ;D :P
Maximilian