Info Bot - lua 5
 

News:

29 December 2022 - PtokaX 0.5.3.0 (20th anniversary edition) released...
11 April 2017 - PtokaX 0.5.2.2 released...
8 April 2015 Anti child and anti pedo pr0n scripts are not allowed anymore on this board!
28 September 2015 - PtokaX 0.5.2.1 for Windows 10 IoT released...
3 September 2015 - PtokaX 0.5.2.1 released...
16 August 2015 - PtokaX 0.5.2.0 released...
1 August 2015 - Crowdfunding for ADC protocol support in PtokaX ended. Clearly nobody want ADC support...
30 June 2015 - PtokaX 0.5.1.0 released...
30 April 2015 Crowdfunding for ADC protocol support in PtokaX
26 April 2015 New support hub!
20 February 2015 - PtokaX 0.5.0.3 released...
13 April 2014 - PtokaX 0.5.0.2 released...
23 March 2014 - PtokaX testing version 0.5.0.1 build 454 is available.
04 March 2014 - PtokaX.org sites were temporary down because of DDOS attacks and issues with hosting service provider.

Main Menu

Info Bot - lua 5

Started by MaynardK, 21 August, 2005, 05:05:47

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

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:

MaynardK

--********************************************************
-- 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[x][1]) then
            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

MaynardK

--*************************************************************
   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

bastya_elvtars

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.
Everything could have been anything else and it would have just as much meaning.

SMF spam blocked by CleanTalk