Код
--[[
Chat History On Entry 1.08 LUA 5.11 [Strict][API 2]
By Mutor Modified by Nafanya (translated by CJay) 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
<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 = {
-- Имя бота
Bot = "Дворецкий",
-- Описание бота
Desc = "Я не злопамятный, поэтому записываю",
-- Bot email address
Mail = "Top Secret",
-- Номер профиля админа
AdminProf = 0,
-- Ник для получения месаг об ошибках
OpNick = SetMan.GetString(24),
-- File to save chat data to
File = "ChatHistory.dat",
-- File to save chat data to
UserFile = "ChatUsers.dat",
-- Максимум строк истории чата для показа при подключении юзера. Поставил 11, так как первая строка <[История_чата]> Chat history file created on:
History = 20,
-- Максимум строк истории чата для хранения
MaxChat = 100,
-- Название меню
Menu = "Сообщения",
-- Название подменю
SubMenu = "Меню администрации\\Логи чата",
-- Установить каким профилям будет доступна история чата.
-- profile_idx, история доступна [0=нет, 1=да], "Profile Name"
Profiles = {
[-1] = {0,"Unregistered User"},
[0] = {1,"Master"},
[1] = {0,"Operator"},
[2] = {0,"Moderator"},
[3] = {0,"Reg"},
},
-- Установить каким профилям будут показыватся история чата при входе на хаб.
ShowHistoty = {
[-1] = {0,"Unregistered User"},
[0] = {1,"Master"},
[1] = {1,"Operator"},
[2] = {1,"Moderator"},
[3] = {1,"Reg"},
},
-- Включить антирекламу? 0 = отключено, 1 = включить для истории, 2 = включить для истории и главного чата
AaBlock = 0,
-- Сообщение которое будет отправлено юзеру при попытке рекламы. "" = отключено [(user) will be replaced with user nick]
AaReply = " • (user), не пишите прямые линки пожалуйста.",
-- Внешний файл "плохих слов". "" = не использовать
AaFile = "",
-- Список "плохих слов" по умолчанию, если не используется внешний файл
AaTrigs = {
"dchub://",
"хуй",
},
}
local bot_reg = 0
local r,sc = "=",0
OnStartup = function()
local LuaVer = _VERSION:sub(1,7)
if LuaVer ~= "Lua 5.1" then
return OnError("Данный скрипт не совместим с версией ".._VERSION),true
end
Cfg.Script = "Chat History 1.08 for PtokaX ".._VERSION.." by Mutor (Modified by Nafanya)"
Cfg.Pfx = SetMan.GetString(29):sub(1,1)
if bot_reg==1 then
Core.RegBot(Cfg.Bot,Cfg.Desc,Cfg.Mail,true)
end
Cfg.Path = string.gsub(Core.GetPtokaXPath().."scripts/","/","\\")
Cfg.File = Cfg.Path..Cfg.File
Cfg.UserFile = Cfg.Path..Cfg.UserFile
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.." был найден и выполнен. Размер файла: "..
size.." Записываются "..#Cfg.Chat.." юзера(ов).")
else
Cfg.Chat = {}
local t = {
tonumber(os.date("%Y") + os.date("%j")),
os.date(" ---"),
os.date("[%H:%M:%S]")..string.sub(string.lower(os.date("%R")),0,0),
"<"..Cfg.Bot.."> Файл истории чата создан "..
os.date("от: %m:%d:%Y")..string.sub(string.lower(os.date("%R")),0,0)
}
table.insert(Cfg.Chat,t)
SaveToFile(Cfg.File,Cfg.Chat,"Cfg.Chat")
OnError(Cfg.File.." не найден. Этот файл может быть создан вами.")
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.." был найден и выполнен. Размер файла: "..
size.." Записываются "..#Cfg.Exclude.." юзера(ов).")
else
Cfg.Exclude = {}
SaveToFile(Cfg.UserFile,Cfg.Exclude,"Cfg.Exclude")
OnError(Cfg.UserFile.." не найден. Этот файл может быть создан вами.")
end
if Cfg.AaFile ~= "" and loadfile(Cfg.AaFile) then
dofile(Cfg.File)
end
OnError(Cfg.Script.." загружен. Использовано памяти: "..CleanMem())
end
OnExit = function()
OnError(Cfg.Script.." остановлен, освобождено "..CleanMem().." памяти.")
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 data:match"%b<> is kicking " then
data = data:gsub("kicking", "kiсking")
end
if not prefix and not to then
local op = user.iProfile
if (op < 3) and (op > -1) and ChkAd(data) 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
else
return false
end
end
local t = {
tonumber(os.date("%Y") + os.date("%j")),
os.date(" ---"),
os.date("[%H:%M:%S]")..string.sub(string.lower(os.date("%R")),0,0),
data,
}
table.insert(Cfg.Chat,t)
for x = 1, #Cfg.Chat - Cfg.MaxChat do
table.remove(Cfg.Chat,1)
end
SaveToFile(Cfg.File,Cfg.Chat,"Cfg.Chat")
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..
" вы не имеете доступа к использованию этой команды.|")
else
Core.SendToUser(user,"<"..Cfg.Bot.."> "..user.sNick..
" вы не имеете доступа к использованию этой команды.|")
end
return true
end
end
end
end
ToArrival = ChatArrival
UserConnected = function(user)
if Cfg.Profiles[user.iProfile] and Cfg.ShowHistoty[user.iProfile][1] == 1 then
local Exclude = CheckEx(user)
if not Exclude then
local add = ""
Core.SendToUser(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.06 "..
--"команд доступно. Правый клик по вкладке хаба для меню команд.|")
end
end
RegConnected,OpConnected = UserConnected,UserConnected
CleanMem = function()
collectgarbage("collect")
Cfg.Mem = string.format("%-.2f Kb.",collectgarbage("count"))
return Cfg.Mem
end
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
if lines > #Cfg.Chat then
x,lines = #Cfg.Chat,#Cfg.Chat
end
x = #Cfg.Chat - x
local str = ""..string.rep(" ",0).."Последние ( "..(lines).." ) сообщений чата!\r\n"
for i,v in ipairs(Cfg.Chat) do
if i > x then
str = str.."\r\n "..v[2].." "..v[3].." "..v[4]..""
end
end
return str.."\r\n"..string.rep(" ",0)..""
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(" ---"),
os.date("[%H:%M:%S]")..string.sub(string.lower(os.date("%R")),0,0),
"<"..Cfg.Bot.."> Лог чата очищен "..
os.date("от: %m:%d:%Y")..string.sub(string.lower(os.date("%R")),0,0)
}
table.insert(Cfg.Chat,t)
end
SaveToFile(Cfg.File,Cfg.Chat,"Cfg.Chat")
return "Удалено "..count.." messages."
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()
CleanMem()
end
SendCmds = function(user)
if Cfg.Profiles[user.iProfile] and (Cfg.Profiles[user.iProfile][1] == 1 or Cfg.Profiles[user.iProfile][1] == 2) then
local m,s,pfx = Cfg.Menu,Cfg.SubMenu,Cfg.Pfx
local c,n,pm,p = "$UserCommand 1","$<%[mynick]>","$$To: "..
Cfg.Bot.." From: %[mynick] ","||"
for i,v in pairs(Cmds) do
local d,a1,a2 = Cmds[i]()
Core.SendToUser(user,c.." 1 "..s.."\\"..d..n.." "..pfx..i..a1..p)
Core.SendToUser(user,c.." 2 "..s.."\\"..d..pm..n.." "..pfx..i..a2..p)
end
CleanMem()
return true
end
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
if p and p ~= -1 then
prof = ProfMan.GetProfile(p).sProfileName
else
prof = "Незарегистрированный пользователь"
end
return prof
end
ChkAd = function(data)
for i,v in ipairs(Cfg.AaTrigs or {}) 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 = "удалены из","Теперь вы будете получать историю чата при входе в хаб."
local Exclude = CheckEx(user)
if not Exclude then
table.insert(Cfg.Exclude,user.sNick)
status,result = "добавлены в","Вы больше не "..
"будете получать историю чата при входе в хаб."
else
table.remove(Cfg.Exclude,Exclude)
end
SaveToFile(Cfg.UserFile,Cfg.Exclude,"Cfg.Exclude")
return "Вы были "..status.." в таблицу исключений. "..result
else
return "Включить/выключить историю чата","",""
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
local x = lines
x = #Cfg.Chat - x
local str = "\r\n <"..r:rep(4).."[ Последние ( "..(lines).." ) сообщений чата ]"..r:rep(38)..">\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(45 + string.len(lines)).."[ Конец истории чата ]"..r:rep(4)..">\r\n"
-- return GetChat(lines)
else
return "История чата",
" %[line:"..ChatLines..")]",
" %[line:Число строк (** пусто = "..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:rep(4).."[ Последние ( "..tostring(cnt).." ) сообщений чата для "..
nick.." ]"..r:rep(31)..">\r\n"..str.."\r\n\r\n <"..
r:rep(41 + string.len(cnt)).."[ Конец истории чата "..nick.." ]"..
r:rep(4)..">\r\n"
else
return "Извините, "..user.sNick..", записей для ника "..nick.." не найдено."
end
else
return "Ошибка! Использовать: "..Cfg.Pfx.."nickhistory <nick>"
end
else
return "Запросить историю чата для ника",
" %[line:Ник пользователя] %[line:Число сообщений (**пусто = все)]",
" %[nick] %[line:Число сообщений (**пусто = все)]"
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 <"..r:rep(4)..
"[ Последние ( "..days.." ) дней чата ]"..r:rep(43)..">\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 <"..r:rep(46 + days:len())..
"[ Конец истории чата ]"..r:rep(4)..">\r\n\r\n"
return str
else
return "Вы должны указать количество дней"
end
else
return "История чата за дни",
" %[line:Сколько дней чата показать?]",
" %[line:Сколько дней чата показать?]"
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 "Извините, "..user.sNick..", эта команда для "..
ProfMan.GetProfile(Cfg.AdminProf).sProfileName.." только."
end
else
return "Удалить историю чата",
" %[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 "Удалить строку",
" %[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\tКоманды\t\tОписание\r\n"..
"\t"..r: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"..r:rep(40).."\r\n\r\n"
else
return "Подсказка по командам для истории чата","",""
end
end,
}