I have been using this script to send frequently requested information to main chat, and thought it was time to share it with anyone else who might need it. I know there are probably many similar scripts out there, but maybe it's a help to someone. :)
Currently all commands and triggers need to be sent to the bot by private message. This could easily be changed. Have fun, let me know if anyone has any questions. Also, let me know if you find it useful...
Will put in the following two posts:
--********************************************************
-- Info bot 1.0 by MaynardK
-- (Credit to those who developed the utility functions I used.)
--
-- Script Usage: (all private commands)
-- !help
-- !infoadd
-- !infodel #
-- !infotrig # trigger1 trigger2 trigger3
-- !infomod #
-- !infolist
-- !rule #
-- !rulelist
--
-- Note: I initially wanted to allow all users to fire information, but added
-- flood protection so they could only fire six messages per minute. Adding a user
-- rule allows you to customize this for individuals. The variable timePerMinuteAllowed
-- is applied to all users that do not have a rule.
-- (Example of allowing user JohnDoe 3 message triggers in one minute: !rule JohnDoe 3)
--********************************************************
infoFile = "infoTriggers.dat"
infoFileUsers = "infoTriggersUsers.dat"
infoElementsTable={}
userLastTriggeredTime={}
infoElementsUsersTable={}
sBot = "infobot"
timePerMinuteAllowed = 6 -- Change to 0 to allow ONLY users with a rule to trigger info
function Main()
frmHub:RegBot(sBot)
LoadFromFile(infoFile)
LoadFromFile(infoFileUsers)
SetTimer(300000) StartTimer()
end
function OnExit()
SaveToFile(infoFile , infoElementsTable , "infoElementsTable")
SaveToFile(infoFileUsers , infoElementsUsersTable , "infoElementsUsersTable")
end
OnTimer = function()
SaveToFile(infoFile , infoElementsTable , "infoElementsTable")
SaveToFile(infoFileUsers , infoElementsUsersTable , "infoElementsUsersTable")
end
--*************************************************************
function ToArrival(User, Data)
local data = string.sub(Data,1,string.len(Data)-1)
local s, e, cmd, args = string.find(Data, "%b<>%s+(%S+)%s*([^%|]*)%|$");
local ss,ee,to,fromm,msgg = string.find(Data,"%$To:%s+(%S+)%s+From:%s+(%S+)%s+%$%b<>%s+(.*)%|")
if(to ~= sBot) then
return
end
--*************************************************************
if( cmd == "!help" ) then
local helpText = "\r\n-------- Private Message Commands ---------\r\n"
helpText = helpText .. "\t \t\t -> Trigger a info.\r\n"
helpText = helpText .. "\t !infolist \t -> list all Information and triggers.\r\n"
helpText = helpText .. "\r\n"
if(User.bOperator) then
helpText = helpText .. "\r\n--- Operator Commands ---\r\n"
helpText = helpText .. "\t !infoadd \t -> Add a new info.\r\n"
helpText = helpText .. "\t !infotrig # \t -> Add a trigger to a info number.\r\n"
helpText = helpText .. "\t !infodel # \t\t -> Delete info number.\r\n"
helpText = helpText .. "\t !infomod # \t -> Modify an existing info number.\r\n"
end
SendPmToNick(User.sName, sBot,helpText)
end
--*************************************************************
if( cmd == "!infoadd" ) then
if( User.bOperator ) then
for x=1,table.getn(infoElementsTable) do
if("<<< "..args.." >>>" == infoElementsTable SendPmToNick(User.sName, sBot," Sound already exists...")
return 1
end
end
local usedNumberToInsert = infoElementsTable[1][2]
for i=1,table.getn(infoElementsTable) do
if(usedNumberToInsert > infoElementsTable[2]) then
usedNumberToInsert = infoElementsTable[2]
end
end
infoElementsTable[table.getn(infoElementsTable)+1] = {"<<< "..args.." >>>", usedNumberToInsert,User.sName,"",infoElementsTable[table.getn(infoElementsTable)][5]+1,{}}
SaveToFile(infoFile , infoElementsTable , "infoElementsTable")
LoadFromFile(infoFile)
SendPmToNick(User.sName, sBot," Info learned... (position: "..infoElementsTable[table.getn(infoElementsTable)][5].." )")
else
SendPmToNick(User.sName, sBot," Access Denied...")
end
return 1
end
--*************************************************************
if( cmd == "!infodel" ) then
local text = cmd.." "..args
local id = string.sub(text,11)
local addedByUser = ""
for i=1,table.getn(infoElementsTable) do
if(trim(infoElementsTable[5]) == trim(id)) then
addedByUser = trim(infoElementsTable[3])
pos = i
break
end
end
if( User.bOperator ) then
table.remove(infoElementsTable,pos)
local MySaveData = Serialize(infoElementsTable, "infoElementsTable", "")
SaveToFile(infoFile , infoElementsTable , "infoElementsTable")
SendPmToNick(User.sName, sBot," Sound deleted... ")
return 1
end
SendPmToNick(User.sName, sBot," Access Denied...")
return 1
end
--*************************************************************
if( cmd == "!infomod" ) then
local text = cmd.." "..args
local idStart = string.find(text," ")+1
local idEnd = string.find(string.sub(text,11)," ")+9
local id = string.sub(text,idStart,idEnd)
local addedByUser = ""
local pos = 0
for i=1,table.getn(infoElementsTable) do
if(trim(infoElementsTable[5]) == trim(id)) then
addedByUser = trim(infoElementsTable[3])
pos = i
break
end
end
if( User.bOperator ) then
local modText = string.sub(text,idEnd+2)
if(addedByUser ~= "") then
if(trim(infoElementsTable[pos][5]) == trim(id)) then
infoElementsTable[pos] = {modText, infoElementsTable[pos][2], infoElementsTable[pos][3],User.sName,infoElementsTable[pos][5],infoElementsTable[pos][6]}
local MySaveData = Serialize(infoElementsTable, "infoElementsTable", "")
SaveToFile(infoFile , infoElementsTable , "infoElementsTable")
SendPmToNick(User.sName, sBot," Phrase modified... ")
return 1
end
end
SendPmToNick(User.sName, sBot," Modified failed!!! ")
return 1
end
SendPmToNick(User.sName, sBot," Access Denied...")
return 1
end
--*************************************************************
if( cmd == "!infotrig" ) then
if( User.bOperator ) then
local text = cmd.." "..args
local idStart = string.find(text," ")+1
local idEnd
local id
if ( string.find(string.sub(text,13)," ") ~= nil ) then
idEnd = string.find(string.sub(text,13)," ")+11
id = string.sub(text,idStart,idEnd)
else
id = string.sub(text,idStart)
end
local addedByUser = ""
local pos = 0
for i=1,table.getn(infoElementsTable) do
if(trim(infoElementsTable[5]) == trim(id)) then
addedByUser = trim(infoElementsTable[3])
pos = i
break
end
end
if(pos == 0) then
SendPmToNick(User.sName, sBot," Trigger(s) add failed!!! ")
return 1
end
if( User.bOperator ) then
local modtext = ""
if( idEnd ~= nil ) then
modtext = string.lower(string.sub(text,idEnd+2))
end
if(trim(infoElementsTable[pos][5]) == trim(id)) then
--ADD local triggers = infoElementsTable[pos][6]
local triggers = {}
for trigger in string.gfind(modtext, "%S+") do
triggers[table.getn(triggers)+1] = trigger
end
infoElementsTable[pos] = {infoElementsTable[pos][1], infoElementsTable[pos][2], infoElementsTable[pos][3],User.sName,infoElementsTable[pos][5],triggers}
local MySaveData = Serialize(infoElementsTable, "infoElementsTable", "")
SaveToFile(infoFile , infoElementsTable , "infoElementsTable")
SendPmToNick(User.sName, sBot," Trigger(s) added... ")
return 1
end
SendPmToNick(User.sName, sBot," Trigger(s) add failed!!! ")
return 1
end
SendPmToNick(User.sName, sBot," Access Denied...")
return 1
else
SendPmToNick(User.sName, sBot," Access Denied...")
return 1
end
end
if( cmd == "!infolist" ) then
local listText = ""
local totalTriggered=0
listText = listText.."\n---- I know the following Information ----\n"
for i=1,table.getn(infoElementsTable) do
if( infoElementsTable[1] ~= nil ) then
listText = listText..infoElementsTable[5]..": "..infoElementsTable[1]
for j=1, table.getn(infoElementsTable[6]) do
if(j==1) then
listText = listText.."\n\t[ Triggers: "
end
listText = listText..infoElementsTable[6][j].." "
if(j==table.getn(infoElementsTable[6])) then
listText = listText.."]"
end
end
listText = listText.."\n(Added by: "..infoElementsTable[3].." - Modified by: "..infoElementsTable[4].." - Count:"..infoElementsTable[2]..")\n\n"
totalTriggered = totalTriggered + infoElementsTable[2]
end
end
listText = listText.."\n-------------------------------------------------------------\n"
listText = listText.." Total: "..table.getn(infoElementsTable).." Used Total: "..totalTriggered
SendPmToNick(User.sName, sBot,listText)
return 1
end
--*************************************************************
if( cmd == "!rule" ) then
if( User.bOperator ) then
local text = cmd.." "..args
local idStart = string.find(text," ")+1
local idEnd
local id
if ( string.find(string.sub(text,13)," ") ~= nil ) then
idEnd = string.find(string.sub(text,13)," ")+11
id = string.sub(text,idStart,idEnd)
else
id = string.sub(text,idStart)
end
local pos = 0
for i=1,table.getn(infoElementsUsersTable) do
if(string.lower(trim(infoElementsUsersTable[1])) == string.lower(trim(id))) then
pos = i
break
end
end
if(pos == 0) then
pos = table.getn(infoElementsUsersTable) + 1
end
if( User.bOperator ) then
local num = ""
if( idEnd ~= nil ) then
num = string.lower(string.sub(text,idEnd+2))
end
local numtest = tonumber(num)
if numtest then -- operand is numeric?
infoElementsUsersTable[pos] = {trim(id), num}
local MyUserSaveData = Serialize(infoElementsUsersTable, "infoElementsUsersTable", "")
SaveToFile(infoFileUsers , infoElementsUsersTable , "infoElementsUsersTable")
SendPmToNick(User.sName, sBot," Flood rule added... ")
return 1
else
SendPmToNick(User.sName, sBot," Flood rule failed... (syntax example: !rule MaynardK 10)")
return 1
end
end
SendPmToNick(User.sName, sBot," Access Denied...")
return 1
else
SendPmToNick(User.sName, sBot," Access Denied...")
return 1
end
end
--*************************************************************
if( cmd == "!rulelist" and User.bOperator) then
local ruleListText = ""
ruleListText = ruleListText.."\n---- Information Rules ----\n"
for i=1,table.getn(infoElementsUsersTable) do
if( infoElementsUsersTable[1] ~= nil ) then
ruleListText = ruleListText..infoElementsUsersTable[1].."\t - "..infoElementsUsersTable[2].."\n"
end
end
ruleListText = ruleListText.."\n-------------------------------------------------------------\n"
SendPmToNick(User.sName, sBot,ruleListText)
return 1
end
--*************************************************************
--*************************************************************
local text = cmd.." "..args
for trigger in string.gfind(text, "%S+") do
local temp = {}
local temp = getTriggerPositions(string.gsub(trigger,"%p",""))
if(table.getn(temp) > 0) then
--******************************************
if floodProtect(User) == 1 then
return 1
end
--******************************************
local n = math.random(table.getn(temp))
local freshSounds={}
for i=1,table.getn(temp) do
if(infoElementsTable[temp][2] < infoElementsTable[temp[n]][2]) then
freshSounds[table.getn(freshSounds)+1] = {infoElementsTable[temp][1],temp}
end
end
local info
local origPosition
if( table.getn(freshSounds) > 0 ) then
r = math.random(table.getn(freshSounds))
info = freshSounds[r][1]
origPosition = freshSounds[r][2]
else
info = infoElementsTable[temp[n]][1]
origPosition = temp[n]
end
SendToAll(info)
infoElementsTable[origPosition][2] = infoElementsTable[origPosition][2] + 1
SaveToFile(infoFile , infoElementsTable , "infoElementsTable")
end
end
--*************************************************************
--*************************************************************
end
--//**********************************************************
-- Utility functions
--//**********************************************************
function floodProtect(User)
for i=1,table.getn(infoElementsUsersTable) do
if(string.lower(trim(infoElementsUsersTable[1])) == string.lower(trim(User.sName))) then
timePerMinuteAllowed = infoElementsUsersTable[2]
break
end
end
if (timePerMinuteAllowed == "0") then
return 1
end
local userInLastTriggeredTimeTable = false
for i=1, table.getn(userLastTriggeredTime) do
if(trim(User.sName) == trim(userLastTriggeredTime[1])) then
if( os.difftime(os.time(),userLastTriggeredTime[2]) < 60) then
if( userLastTriggeredTime[4] > timePerMinuteAllowed-1) then
if(User.bOperator) then
return 0
end
if( userLastTriggeredTime[3] == false ) then
SendPmToNick(User.sName, sBot," Stop flooding ...")
return 1
end
userLastTriggeredTime[2] = os.time()+300
userLastTriggeredTime[3] = true
return 1
else
userLastTriggeredTime[2] = os.time()
userLastTriggeredTime[4] = userLastTriggeredTime[4] + 1
end
else
userLastTriggeredTime[2] = os.time()
userLastTriggeredTime[3] = false
userLastTriggeredTime[4] = 1
userInLastTriggeredTimeTable = true
end
end
end
if( userInLastTriggeredTimeTable == false) then
userLastTriggeredTime[table.getn(userLastTriggeredTime)+1] = { User.sName, os.time(), false, 1 }
end
return 0
end
function getTriggerPositions(trig)
matchingTrigs = {}
for i=1,table.getn(infoElementsTable) do
for j=1, table.getn(infoElementsTable[6]) do
if(trim(trig) == trim(infoElementsTable[6][j])) then
matchingTrigs[table.getn(matchingTrigs)+1] = i
end
end
end
return matchingTrigs
end
function getUserPosition(userName)
for i=1, table.getn(usersTable) do
if(string.lower(trim(usersTable)) == string.lower(trim(userName))) then
return i
end
end
return 0
end
--//**********************************************************************************************
-- I wish I could give prper credit to the original authors of the below functions.
-- Thanks... I am sure when you see this you'll know who you are.
--//**********************************************************************************************
--////////////////////////////////////////////////////////
function trim (s)
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
end
--////////////////////////////////////////////////////////
function Serialize(tTable, sTableName, sTab)
sTab = sTab or "";
sTmp = ""
sTmp = sTmp..sTab..sTableName.."={"
local tStart = 0
for key, value in tTable do
if tStart == 1 then
sTmp = sTmp..",\r\n"
else
sTmp = sTmp.."\r\n"
tStart = 1
end
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
end
sTmp = sTmp.."\r\n"..sTab.."}"
return sTmp
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 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()
end
function LoadFromFile(file)
local handle = io.open(file,"r")
if (handle ~= nil) then
dofile(file)
handle:flush()
handle:close()
end
end
--///////////////////////////////////////////////////////
function GetTime()
a = os.date("%a")
I = os.date("%I")
M = os.date("%M")
S = os.date("%S")
b = os.date("%b")
d = os.date("%d")
z = os.date("%z")
y = os.date("%y")
p = os.date("%p")
Date = a..", "..I..":"..M..":"..S.." "..p..", "..b.."/"..d.."/"..y.." "..z
return Date
end
QuoteOriginally posted by MaynardK
I have been using this script to send frequently requested information to main chat, and thought it was time to share it with anyone else who might need it. I know there are probably many similar scripts out there, but maybe it's a help to someone. :)
Currently all commands and triggers need to be sent to the bot by private message. This could easily be changed. Have fun, let me know if anyone has any questions. Also, let me know if you find it useful...
Will put in the following two posts:
Why not upload to the script database instead of flooding the forum? And, please use CODE tags.