PtokaX forum

Development Section => HOW-TO's => Topic started by: WooshMan on 04 February, 2004, 16:01:31

Title: Table = Idiots guide
Post by: WooshMan on 04 February, 2004, 16:01:31
Hi,

I am after an idiots (WooshMan's) guide to tables and how to add / remove from them.

This is what I would like to do:

users = {}

function NewUserConnected(user)
get the username and the ip address of the user and put it in the table called users.
end

function UserDisconnects(user)
   remove the username and the ip address of the userfrom the table
end

Please can it be in plain english.. once I understand one table, it will help me with most of them.

Thanks]
WooshMan
Title:
Post by: NightLitch on 04 February, 2004, 16:10:35
simple:

users = {}

function NewUserConnected(user)
 --get the username and the ip address of the user and put it in the table called users.
 users[user.sName] = user.sIP  -- add user to table with name & ip
end

function UserDisconnects(user)
 users[user.sName] = nil -- delete user from table
 --remove the username and the ip address of the userfrom the table
end

writing & deleting from file can I explain later if you want or maybe someone else do that.
Title:
Post by: RobinHood on 04 February, 2004, 16:40:54
hi NightLitch,

your code is very simple ( i've the same problem)

let's take this as an example :-)

is there a possiblity to show ALL usernames with their IPs? (perhaps sorted by name if it's possible and anotherone sorted by IP)

is it possible to search f?r an IP? (perhaps more than 1 hint)?

and IF it's possible.... HOW can i script this? i want to avoid to create a file if the file is not necessary. and if it's necessary i will delete it after posting the message :-)
Title:
Post by: NightLitch on 04 February, 2004, 17:01:09
Well this table saves the nicks when logging in.

When restarting the script the table becomes emty becouse it is saved in memory and memory is erased when scripts restarted.

simple but maybe hard for some to "load" the table in a function:

function ShowLog(user,data)
user:SendData(Bot,"* * * User Log * * *")
user:SendData(Bot," "
-------------------------------
-- here is the calling lines
for nicks,ips in users do
user:SendData(Bot,"Nick: "..nicks.."        IP: "..ips)
end
-------------------------------
user:SendData(Bot," "
user:SendData(Bot,"* * * End of list * * *")
end

this is the simplest way calling the table in a function and viewing it.

fix this first before even think of sorting.

you want to learn so. learn this first.

/NL
Title:
Post by: WooshMan on 04 February, 2004, 17:47:13
Thanks NL

I got it working without knowing it.

I also looked at your new nxs bot and learned how to read / write the table to a file.

Excellent.... thanks :-)

Woosh
Title:
Post by: Typhoon on 04 February, 2004, 18:07:26
hello NL perhaps you can do me a favor then :) ....

i am trying to make a table for my prefix commands buti dont now how to do it ? ...  

example comming ..

prefix = { "+" , "!" , "-" }  --- you know ;)


command part now !


elseif cmd == prefix.."myip" then
      if tfind(pMYIP, user.iProfile) then
      user:SendData(BotName, "Your IP is *** "..user.sIP)
      return 0
      else user:SendData(pCOMMAND) return 0 end  

 how to make it work in the specific command then ??

i am quite a noob in tables and beginning to understand Lua  

Greetz  

   Typhoon?
Title:
Post by: NightLitch on 04 February, 2004, 18:15:53
Well my experiece tells me you can't do it that way.

you need to do it in the command capture.

If Am wrong anyone tell me.
Title:
Post by: kepp on 04 February, 2004, 18:33:40
The easist way to do that must be

Prefix = {"!","+","%"}

T = rawget(Prefix,1)

if you print T it will get you  "!"

rawget(TableName,Position_in_table)

The starts at 1, so if you want to get the + instead, you
change 1 to 2...
Title:
Post by: NightLitch on 04 February, 2004, 18:40:16
Well I think he wants to use all at the same time.
Title:
Post by: kepp on 04 February, 2004, 19:01:43
Well, wouldn't "or" be better there?

like

if cmd=="+help" or cmd=="!help"


Prefix = {"+","!","%"}

s,e,cmd = strfind(data,"%b<>%s+(%S)")

if cmd == rawget(Prefix,1) or cmd == rawget(Prefix,2) then

Maybe works, i don't know:

if cmd == cmd then
--//ToDo
end
Title:
Post by: plop on 04 February, 2004, 21:24:44
like this should work.
Tprefix = { ["+"]=1 , ["!"]=1 , ["-"]=1 } --- you know ;)


command part now !

s,e,prefix,cmd=strfind(data, "%b<>%s*(%S)(%S+)")
if Tprefix[prefix] then
   if cmd == "myip" then
      if tfind(pMYIP, user.iProfile) then
         user:SendData(BotName, "Your IP is *** "..user.sIP)
         return 0
      else
         user:SendData(pCOMMAND)
         return 0
      end  

plop
Title:
Post by: RobinHood on 05 February, 2004, 01:17:36
many thanks, NightLitch,

it works great!!!

and i've had a good idea to make it better :-))

if someone restarts the scripts the array will be empty.

to get the data very fast add this:


function DataArrival(user,data)
   if users[user.sName]==nil and not(user.sName=="") and not(user.sName=="") then
      users[user.sName] = user.sIP
   end
end

Now it would be interesting to sort them by Nick or by IP.
And i will try to search Ips in this array - perhaps i can do this ;-)

thx
Robin
Title: Idiots Guide take 2
Post by: WooshMan on 05 February, 2004, 13:59:11
OK, so I have a table now called users and when a user connects to the hub the username and ip address is added, and when they leave the hub, that info is removed from the table.

Now my question(s) is:

1. What other things can I add to the table about the user when they connect?  i.e name, ip address, time coonected

2.  How do I add that info to the table so name, ip and time connected is in the table too?

I hope this makes sense.

Thanks

Woosh
Title:
Post by: NightLitch on 05 February, 2004, 16:35:55
QuoteNow my question(s) is:

1. What other things can I add to the table about the user when they connect? i.e name, ip address, time coonected

2. How do I add that info to the table so name, ip and time connected is in the table too?

I hope this makes sense.

Thanks

Woosh

Well m8 here is your problem, or not problem, its getting
a little bit harder scripting.

you will need to use strfind to get more from the table ex:

Table = {
["Nick"] = "IP",
}

this is standard.

-------------------------------------------------
this is a way with more info:

Table = {
["Nick"] = "IP#TIME#MYINFOSTRING",
}

or

Here's A simple solusion for storing both name & ip in same line & MyInfoString in the other.

Table = {
["Nick#IP"] = "MYINFOSTRING",
}

function GetInfo(user,data)
local _,_,nick = strfind(data,"%b<>%s%S%s(%S+)")
nick = GetItemByName(nick)
if nick == nil then
--Nick not found message
return 1
end
local vUser = ""
local vIP = ""
for vNick,vIp in Table do
local _,_Nick,Ip = stfind(vNick,"(%S+)#(%S+)")
if nick.sName == Nick then
vUser = Nick
vIP = Ip
end
end
user:SendData(Bot,"Nick: "..vUser.." with IP: "..vIP)
end

Hope This is of some use for you guys.
Title:
Post by: tezlo on 05 February, 2004, 17:27:25
nononono..
this is not exactly an efficient way of storing/retrieving user data

why not just use another table?
table lookup is way faster than strfind

the most obvious way of doing this would be..
Table = {
["somenick"] = {
  ["ip"] = "someip",
  ["time"] = "sometime",
  ["myinfo"] = "someinfo" }
}

but if you want to store info on a lot of users, you might want to use a number indexed table instead and save some memory that way..
Table = {
["somenick"] = { "someip", "sometime", "someinfo" },
}

ad the 'solution'..
associative tables are the ideal structure for storing user info because you can pull it out quick when you know the users nick

but when you index by "Nick#IP" (why?!) you have to go through all the items and do a strfind on each
which is no different from storing it in a number indexed table (very inefficient)

so..
Quotestoring both name & ip in same line & MyInfoString in the other
is really just making your job harder than it has to be

the code would then become..
Table = {
  ["somenick"] = { "someip", "sometime", "someinfo" },
}
function GetSomeInfo(user, nick)
  local tmp = table[nick]
  if tmp then
    user:SendData("somebot", "nick: "..nick.." ip: "..tmp[1])
  else -- there is no info on nick
    user:SendData("somebot", "no info for "..nick)
  end
end
which looks much easier and is much faster

also.. in your code you want to get some info on "nick"
so why do a GetItemByName? and why return when "nick" is not online?
isnt it the point that you want to be able to retrieve info on a user who is offline?
if "nick" were online you dont need to look up anything because the user object already has that info

and.. this just doesnt make sense
nick = GetItemByName(nick)
..
local _,_Nick,Ip = stfind(vNick,"(%S+)#(%S+)")
if nick.sName == Nick then -- whatever
nick.sName is the same nick you started with
Title:
Post by: NightLitch on 05 February, 2004, 18:47:40
THX Tezlo you opend my eyes for something better.

Only things is I use Serialize when handling table etc. Can I with that make your fine ex. That is what I have tried make.
but lack of knowledge I just put it aside for some time.

But gonna make over mine again.

/NL
Title:
Post by: WooshMan on 12 February, 2004, 14:39:29
OK this is what is in my table again:

{{
["WooshMan"]="Kicked for:  Testing.$192.168.1.5$02/12/04 12:45:39",
},
}

No I have tried NL's script to read a table and show the contents but it wont work.  And as tables are not yet my strong point......

How can I show everything that is in a table?

I have !showtbans as my command and it all works, but now I want that command to show the entire contents.

please help me again....

Thank you :-)
Title:
Post by: NightLitch on 12 February, 2004, 14:54:28
Woosh, skip that try on table.

do it like this when saving:

table[nick] = {
                      ["IP"] = nick.sIP
                      ["REASON"] = reason,
                      ["TIME"] = GetTime,
                      ["byOP"] = curUser.sName
                     }

and call it with this:

function Serialize(tTable, sTableName, hFile, sTab)
assert(tTable, "tTable equals nil");
assert(sTableName, "sTableName equals nil");
assert(hFile, "hFile equals nil");

assert(type(tTable) == "table", "tTable must be a table!");
assert(type(sTableName) == "string", "sTableName must be a string!");

sTab = sTab or "";

write(hFile, sTab..sTableName.." = {\n" );

for key, value in tTable do
local sKey = (type(key) == "string") and format("[%q]",key) or format("[%d]",key);

if(type(value) == "table") then
Serialize(value, sKey, hFile, sTab.."\t");
else
local sValue = (type(value) == "string") and format("%q",value) or tostring(value);
write(hFile, sTab.."\t"..sKey.." = "..sValue);
end

write(hFile, ",\n");
end

write(hFile, sTab.."}");
end

function SaveToFile(file , table , tablename)
local hFile = openfile(file, "w");
Serialize(table, tablename, hFile);
closefile(hFile);
end

function LoadFromFile (file)
assert(readfrom(file),file.." is not found.Generating new "..file..". All is fine. Don't panic.")
dostring(read("*all"))
readfrom()
end

ex. on SaveToFile & Loading:

SaveToFile(KickFile,KickTable,"KickTable")

LoadFromFile(KickFile)

and when opening the in script for viewing:

local tmp = table[curUser.sName]
if tmp then
local IP = tmp["IP"]
local REASON = tmp["REASON"]
local TIME = tmp["TIME"]
local BYOP = tmp["byOP"]
end

Msg = "Nick: "..tmp..", IP: "..IP..", Reason: "..REASON..", Time: "..TIME..", By OP: "..BYOP.."."

hope this help some.
Title:
Post by: WooshMan on 15 February, 2004, 15:31:24
Currently being thick again:

Here is my table:

user = {
   ["WooshMan"] = {
      ["MYINFO"] = "$MyINFO $ALL WooshMan The other half of WooshMan<++ V:0.251,M:P,H:0/1/0,S:2>$ $DSL$$17753879$|",
      ["PROFILE"] = 4,
      ["ONLINE"] = "YES",
      ["IP"] = "192.168.1.6",
      ["TIME"] = "14:27:24",
   },
}

And here is my code:

function userinfo (user,data)

s,e,cmd,who,msg =strfind( data, "%b<>%s+(%S+)%s+(%S+)%s*(.*)" )

LoadFromFile(onlinepath)
if users[who.sName] ~= nil then
SendToAll("something happened")
else
SendToAll("did not find " ..user.sName .." in the table")
end

return 1

end

But I get this error....

Syntax error: attempt to index global `who' (a string value)

Why?????

If I use users[user.sName] ~= nill then

And I am on the table it finds me.. so why not who when i have done a strfind???

Please help.. these tables are killing me :-(

Woosh
Title:
Post by: NightLitch on 16 February, 2004, 00:24:15
you fogot calling the user in userlist.

put in:  
local vUser = GetItemByName(who)
if vUser==nil then
   -- User not found line here
    return 1
end
Title:
Post by: tezlo on 16 February, 2004, 04:16:33
no.. should be
if users[who] then

but the regexp may not pass so youll want to check that
and LoadFromFile on script start
Title:
Post by: NightLitch on 16 February, 2004, 16:33:29
yes that works but...  who is the way he types it...

if he typ UsEr and in file User then it's not taken... my experience... or user and it is USER or otherway.
Title:
Post by: WooshMan on 17 February, 2004, 14:26:44
Yes NL that worked TY... but I am trying to read the data from the table without checking if the user is online first and getting NOT getting who from GetItemByName(who).

OK..... lets say I have a table which holds information on every user that has visted.

If I make a command !userinfo, I want it to look in the table for the user specified and show the information stored. Not check if the user is online first.


        s,e,cmd,who =strfind( data, "%b<>%s+(%S+)" )

-- code for  Search users table  for who goes here
vUser = who ---- this doesn't work...
--  ends here

if users[vUser.sName] then
ip = users[vUser.sName].IP
time = users[vUser.sName].TIME
profile = users[vUser.sName].PROFILE
online = users[vUser.sName].ONLINE
myinfo = users[vUser.sName].MYINFO

s,e,share = strfind(myinfo, "%$(%d+)%$")
s,e,speed = strfind(myinfo,"([%a%d%%.(%)]+)")

SendPmToNick(user.sName, botname, vUser.sName .." Details:")
SendPmToNick(user.sName, botname, "Connected at: " ..time)
SendPmToNick(user.sName, botname, "IP address is: " ..ip)
SendPmToNick(user.sName, botname, " Still on line: " ..online)
SendPmToNick(user.sName, botname, "Share Size is: " ..share)
SendPmToNick(user.sName, botname, "Connection is: " ..speed)
return 1
else
SendPmToNick(user.sName, botname, "Sorry, there is no info for that user at present.")
return 1
end
end

I hope this makes sense?

Woosh
Title:
Post by: tezlo on 17 February, 2004, 15:12:08
not really.. i tried to explain before
you already have the users nick (in your code "who")
you dont need to get the user object (with GetItemByName) since you already have all you need to get that user's info (the nick!)

so..
local s,e,cmd,who =strfind(data, "%b<>%s+(%S+)")
if s then
  local info = users[who]
  if info then
    ip = info.IP
    -- and so on
Title:
Post by: NightLitch on 17 February, 2004, 15:25:12
this is the way I have it some way in my getinfo:

function DoUserInfo(user,data)
s,e,cmd,who =strfind( data, "%b<>%s+(%S+)" )

if who==nil
SendPmToNick(user.sName, botname, "Syntax: !getinfo ")
return 1
end

local vUser = GetItemByName(who)

------( Check if User is online then Get Online info about user. )-----

if vUser then

ip = vUser.sIP
time = GetTime -- Current Time --
profile = user.iProfile
online = "Yes"
myinfo = vUser.sMyInfoString

s,e,share = strfind(myinfo, "%$(%d+)%$")
s,e,speed = strfind(myinfo,"([%a%d%%.(%)]+)")

SendPmToNick(user.sName, botname, vUser.sName .." Details:")
SendPmToNick(user.sName, botname, "Connected at: " ..time)
SendPmToNick(user.sName, botname, "IP address is: " ..ip)
SendPmToNick(user.sName, botname, " Still on line: " ..online)
SendPmToNick(user.sName, botname, "Share Size is: " ..share)
SendPmToNick(user.sName, botname, "Connection is: " ..speed)
return 1

else

-----( If user NOT Online then get Offline Info about user if exist. )-----

local vUser = "" --( For storing name if found in memory
for Nick,Info in Table do --( Open User Table
if strlower(Nick)==strlower(who) then --( compare the given nick(who) with nicks in Table
vUser = Nick --( If nick found the added to vUser "memory"

--------------------------------------------------------
--( Unsure if the ends should be here or after the grabbed data down below, try.

end
end
--------------------------------------------------------
if users[vUser] then
ip = users[VUser].IP
time = users[vUser.sName].TIME
profile = users[vUser.sName].PROFILE
online = users[vUser.sName].ONLINE
myinfo = users[vUser.sName].MYINFO

s,e,share = strfind(myinfo, "%$(%d+)%$")
s,e,speed = strfind(myinfo,"([%a%d%%.(%)]+)")

SendPmToNick(user.sName, botname, vUser.sName .." Details:")
SendPmToNick(user.sName, botname, "Connected at: " ..time)
SendPmToNick(user.sName, botname, "IP address is: " ..ip)
SendPmToNick(user.sName, botname, " Still on line: " ..online)
SendPmToNick(user.sName, botname, "Share Size is: " ..share)
SendPmToNick(user.sName, botname, "Connection is: " ..speed)
return 1
else
SendPmToNick(user.sName, botname, "Sorry, there is no info for that user at present.")
return 1
end
end
end

Hope this clear some more.

/NL
Title:
Post by: NightLitch on 17 February, 2004, 15:26:33
your way is shorter Tezlo I know. BUT! if you type the:

who = nicker

and it is stored Nicker with big N then it will not find it.
Title:
Post by: tezlo on 17 February, 2004, 15:27:34
same can be done with..
local info = Table[user.sName] or Table[strlower(user.sName)]

but they may well be two different users
Title:
Post by: NightLitch on 17 February, 2004, 15:46:11
yes, but here he was out for getting the offline data.

so he need to compare the table nicks with the who(nick) he has typed.

and then check with strlower(Nick)==strlower(who)

But this you already know Tezlo, I hope m8 :-)
Title:
Post by: nErBoS on 24 February, 2004, 01:15:47
Hi,

I'm new on working with tables give a hint why this is not working..

info = {
["IP"] = {}
}

function NewUserConnected(user, data)
info[user.sName].IP = user.sIP

user:SendData(Bot, info[user.sName].IP)

end

It gives me this error in the editor..

Syntax Error: attempt to index a nil value

Best regards, nErBoS
Title:
Post by: Stravides on 14 May, 2004, 22:38:05
Sorry if I am being thick here, but I reall am losing it on tables...

I have a table

table[player] = {
["XP"] = 1,
["LEVEL"] = 1,
["HP"] = 1,
["INITIATIVE"] = 1,
["SPEED"] = 30,
["AC"] = 10,
["GRAPPLE"] = 1,
["MELEE"] = 1,
["RANGED"] = 1,
["FORT"] = 1,
["WILL"] = 1,
["REF"] = 1
}
all in the top variable section of my bot.

In the func main I have
SaveToFile(players,players,"players")
LoadFromFile(players)

the functions for these (and your serialize funcs are
function Serialize(tTable, sTableName, hFile, sTab)
assert(tTable, "tTable equals nil");
assert(sTableName, "sTableName equals nil");
assert(hFile, "hFile equals nil");

assert(type(tTable) == "table", "tTable must be a table!");
assert(type(sTableName) == "string", "sTableName must be a string!");

sTab = sTab or "";

write(hFile, sTab..sTableName.." = {\n" );

for key, value in tTable do
local sKey = (type(key) == "string") and format("[%q]",key) or format("[%d]",key);

if(type(value) == "table") then
Serialize(value, sKey, hFile, sTab.."\t");
else
local sValue = (type(value) == "string") and format("%q",value) or tostring(value);
write(hFile, sTab.."\t"..sKey.." = "..sValue);
end

write(hFile, ",\n");
end

write(hFile, sTab.."}");
end

function SaveToFile(file , table , tablename)
local hFile = openfile(file, "w");
Serialize(table, tablename, hFile);
closefile(hFile);
end

function LoadFromFile (file)
assert(readfrom(file),file.." is not found.Generating new "..file..". All is fine. Don't panic.")
dostring(read("*all"))
readfrom()
end

And in the DataArrival I have

elseif (cmd == prefix.."players") then
local tmp = table[curUser.sName]
if tmp then
local XP = tmp["XP"]
local LEVEL = tmp["LEVEL"]
local HP = tmp["HP"]
local INITIATIVE = tmp["INITIATIVE"]
local SPEED = tmp["SPEED"]
local AC = tmp["AC"]
local GRAPPLE = tmp["GRAPPLE"]
local MELEE = tmp["MELEE"]
local RANGED = tmp["RANGED"]
local FORT = tmp["FORT"]
local WILL = tmp["WILL"]
local REF = tmp["REF"]

end
Msg = "Nick: "..tmp..", XP: "..XP..", Level: "..LEVEL..", HP: "..HP..", INIT: "..INITIATIVE.."."
SendToAll(BOTName,Msg)

I get the error message
Syntax Error: attempt to index global `table' (a nil value)

any Ideas ??
Title:
Post by: pHaTTy on 14 May, 2004, 23:22:40
yep

table = {
         player. = {
["XP"] = 1,
["LEVEL"] = 1,
["HP"] = 1,
["INITIATIVE"] = 1,
["SPEED"] = 30,
["AC"] = 10,
["GRAPPLE"] = 1,
["MELEE"] = 1,
["RANGED"] = 1,
["FORT"] = 1,
["WILL"] = 1,
["REF"] = 1
       }
}

hmm never tried but also try

table.player. = {
["XP"] = 1,
["LEVEL"] = 1,
["HP"] = 1,
["INITIATIVE"] = 1,
["SPEED"] = 30,
["AC"] = 10,
["GRAPPLE"] = 1,
["MELEE"] = 1,
["RANGED"] = 1,
["FORT"] = 1,
["WILL"] = 1,
["REF"] = 1
}
Title:
Post by: Stravides on 15 May, 2004, 00:33:48
i take it the players. should be players no dot

??
Title:
Post by: Stravides on 15 May, 2004, 01:47:01
PART 1.....

Ok I've completely lost the plot here..

I want to hold data on multiple users.  now I have thought about ammending the tables and loads from the function.cfg, but I still do not understand tables...

Would it be possible to do this problem for me as I am slowly running out of time to get this online and am just banging my head against a brick wall

so here goes... Consider the dataset

PLAYER  (this is a users login name)
XP
LEVEL
HP
INITIATIVE
SPEED
AC
GRAPPLE
MELEE
RANGED
FORT
WILL
REF

please can you help me add this table to write to a file
and update, also to add the user via an !addnewplayer details go here kind of action

many thanks as I'm completely lost here again...

ver = "4.14"
revdate = "23rd April 2004"
-----------------------------------  Begin Variables used ----------------------------------------

configfile = "dm/data.cfg"
functionfile = "dm/functions.cfg"
kickfunctions = "dm/kickfunctions.cfg"

dofile(configfile);  
dofile(functionfile);  
dofile(kickfunctions);

opchatName = frmHub:GetOpChatName()
HubDesc = frmHub:GetHubDescr()
Time = ""..date("%d").."/"..date("%m").."/"..date("%Y").." * "..date("%H")..":"..date("%M")..""

logindef = "RPGBooks Cymru welcomes a New User"
logoutdef = "RPGBooks Cymru bids farewell to a New User"
botdef =  BOTName
OpChatBOTInfo = "$MyINFO $ALL "..opchatName.." <++V:0.401 Operators ChatRoom $ $Slug"..strchar( 1 ).."$Stravides@RPGBooks-cymru.no-ip.org$"


------------------------------------  Begin Tables used  -----------------------------------------
tabTimers = {n=0}

UserBotTable = { };
LogInTable = { };
LogOutTable = { };

usrKicks = {}
BanTable = {}
KickTable = {}

aNicks = {
["Stravides"] = 1,
["Malevolence"] = 1,
["Blumpy"] = 1,
["GromEyefist"] = 1,
}



-----------------------------------   End Variables used  ----------------------------------------
-- --
-----------------------------------  Begin Constants used ----------------------------------------
ptokaxcommands = {
op = 1, drop = 1, ban = 1, unban = 1, nickban = 1, getbanlist = 1,
getinfo = 1, gag = 1, ungag = 1, banip = 1, ipinfo = 1, iprangeinfo = 1,
userinfo = 1, clrtempban = 1, stat = 1 }

ptokax2commands = {
clrpermban = 1, topic = 1, reloadtxt = 1 }

function Main()
frmHub:RegBot(BOTName)
frmHub:EnableSearchData(1)
frmHub:EnableFullData(1)
SendToAll(BOTNameInfo)
SendToAll(OpChatBOTInfo)
UseTables(log_in,LogInTable)
UseTables(log_out,LogOutTable)
UseTables(botsfile,UserBotTable)
botLen = strlen( BOTName )
RegTimer(ForumTimer, 4*Hour)
RegTimer(LocalTimer, 1*Min)
SetTimer(TmrFreq)
StartTimer()
end

function OpConnected(user)
local BotIn = ""
if UserBotTable[user.sName] then
BotIn = UserBotTable[user.sName]
else
BotIn = BOTName
end
if LogInTable[user.sName] then
SendToAll(BotIn,LogInTable[user.sName])
else    
SendToAll("DungeonMaster", "[DM] "..user.sName.." has Entered the Realm")
end
-- user:SendPM(BOTName,rules)
end

function OpDisconnected(user)
if UserBotTable[user.sName] then
BotIn = UserBotTable[user.sName]
else
BotIn = "DungeonMaster"
end
if LogOutTable[user.sName] then
SendToAll(BotIn,LogOutTable[user.sName])
elseif user.iProfile == 1 then
SendToAll("DungeonMaster", "[DM] "..user.sName.." Has Left the Realm")  
end
end

function NewUserConnected(user)
SendToAll("DungeonMaster", ""..user.sName..", has Entered the Realm" )
end

function UserDisconnected(user)
SendToAll("DungeonMaster", ""..user.sName..", Has Left the Realm" )
end

function DataArrival(user,data)
if (strsub(data, 1, 1) == "$" and strfind(data, "ConnectToMe") and not aNicks[curUser.sName]) then
curUser:SendData("*** You are not allowed to download in this Realm I suggest you remove the filelist from your downloads.")
curUser:SendData("*** For downloading goto rpgbooks-cymru.no-ip.org ")
return 1
end
    if (strsub(data,1,1) == "<") then
local s, e, cmd, args = strfind(data, "^%b<> %!(%a+)%s*(.*)|$")
if user.bOperator then
local s,e,starter,cmd = strfind(data, "%b<>%s+(%S+)(%S+)")
if starter == "!clockoff" then
StopTimer()
frmHub:UnregBot(startchrs ..current ..endchrs)
return 1
elseif starter == "!clockon" then
current = date("%H:%M")
StartTimer()
frmHub:RegBot(startchrs ..current ..endchrs)
return 1
end
end
data=strsub(data,1,strlen(data)-1)
s,e,cmd = strfind(data,"%b<>%s+(%S+)")
cmd = strlower(cmd)

if (cmd == prefix.."rules") then
user:SendPM(BOTName,rules)
return 1
elseif (cmd == prefix.."mmop" ) then
_,_,cmd,message = strfind( data, "%b<>%s+(%S+)%s+(.*)" )
if user.iProfile == 1 or user.iProfile == 0 or user.iProfile == 4 then
SendPmToOps(user.sName, message)
return 1
end
elseif (cmd=="!say") then
if user.iProfile == 1 or user.iProfile == 0 or user.iProfile == 2 then
local s,e,cmd,From,Text = strfind( data, "%b<>%s+(%S+)%s+(%S+)%s*(.*)" )
SendToAll(From,Text)
To="ALL"
LogWhoUsed(To,user,From,Text)
return 1
end
elseif (cmd=="!saypm") then
if user.iProfile == 1 or user.iProfile == 0 or user.iProfile == 2 then
local s,e,cmd,From,To,Text = strfind(data, "%b<>%s+(%S+)%s+(%S+)%s+(%S+)%s+(.*)")
SendPmToNick(To,From,Text)
LogWhoUsed(To,user,From,Text)
return 1
end
elseif (cmd == prefix.."pmip") then
if user.iProfile == 1 or user.iProfile == 0 or user.iProfile == 2 then
local s,e,cmd,username = strfind( data, "%b<>%s+(%S+)%s+(.*)" )
local vUser = GetItemByName(username)
user:SendPM(BOTName,"IP Address of: "..vUser.sName.." is "..vUser.sIP)
return 1
end
elseif (cmd == prefix.."setmaxdice") then
s,e,cmd,qty = strfind( data, "%b<>%s+(%S+)%s+(.*)" )
if user.iProfile == 1 or user.iProfile == 0 or user.iProfile == 2 then
maxdiceroll=qty
return 1
end
elseif (cmd == prefix.."roll") then
local s,e,cmd,qty,type,sign,n = strfind( data, "%b<>%s+(%S+)%s+(%d+)d(%d+)([%+%-]?)(%d*)" )
if  tonumber(qty) > tonumber(maxdiceroll) then
SendToAll(BOTName,user.sName.." Is trying to crash the server rolling "..qty.." dice - Max "..maxdiceroll.." Please")
else
local subtot=0
local scoretable={}
local value = 0
type = tonumber(type)
for i = 1, tonumber(qty) do
randomgen=dice(type)
subtot=subtot + randomgen
SendToAll(BOTName,user.sName.." Roll Number "..i.." was "..randomgen)
end
num = tonumber(n) or 0
if sign == "+" then
subtot = subtot + num
elseif sign == "-" then
subtot = subtot - num
end
SendToAll(BOTName,user.sName.." Rolled "..qty.."d"..type..sign..n.." and got "..subtot)
return 1
end
elseif (cmd == prefix.."d4") then
singledie(user,4)
return 1
elseif (cmd == prefix.."d6") then
singledie(user,6)
return 1
elseif (cmd == prefix.."d8") then
singledie(user,8)
return 1
elseif (cmd == prefix.."d10") then
singledie(user,10)
return 1
elseif (cmd == prefix.."d12") then
singledie(user,12)
return 1
elseif (cmd == prefix.."d20") then
singledie(user,20)
return 1
elseif (cmd == prefix.."d100") then
singledie(user,100)
return 1
elseif (cmd=="!addnewplayer") then

SendToAll(BOTName,"Add New Players goes here :)")

elseif (cmd == "!ban") and user.bOperator then
ComFunc(user,data,"!ban",BanLog,BanTable)
return 1
elseif (cmd == "!kick") and user.bOperator then
ComFunc(user,data,"!kick",KickLog,KickTable)
return 1
elseif (cmd == "!time") and user.bOperator then
SendToAll(BOTName,"Current Server Time is: ".."<"..date("%d").."/"..date("%m").."/"..date("%Y").."  "..date("%H")..":"..date("%M").." GMT >")
return 1
end
elseif strsub(data, 1, 5) == "$To: " then
RightKick2(user, data)
elseif strsub(data,1,6) == "$Kick " then
RightKick1(user, data)
return 1
end
end

Title:
Post by: Stravides on 15 May, 2004, 01:48:14
Part 2....

function.cfg is
function UseTables(filename,table)
local handle = openfile(filename, "r")
if (handle) then
local line = read(handle)
while line do
s,e,username,text = strfind(line, "(.+)|(.+)")
if username ~= nil and text ~= nil  then
table[username]=text
end
line = read(handle)
end
closefile(handle)
end
end

function checkvalue(randomgen,max)
if randomgen==1 then
SendToAll(BOTName," F U M B L E    F U M B L E    F U M B L E    F U M B L E    F U M B L E   ")
elseif randomgen==max then
SendToAll(BOTName," C R I T I C A L     C R I T I C A L     C R I T I C A L     C R I T I C A L    ")
end
end

function singledie(user,die)
if user.iProfile == 1 or user.iProfile == 0 then
local randomgen=dice(tonumber(die))
SendToAll(BOTName,user.sName.." Rolled a d"..die.." and got a "..randomgen)
checkvalue(randomgen,tonumber(die))
return 1
end
end

function dice(type)
randomSeed = random(type)
return randomSeed
end

function CountTableRows(table,rows)
rows=0
for key, value in table do
rows=rows+1
end
return rows
end

function DoRead(curUser)
while 1 do
line = read()
if line == nil then break end
curUser:SendData(BOTName, line)
end
readfrom()
end


function LocalTimer()
frmHub:UnregBot(startchrs ..current ..endchrs)
time = date("%H:%M")
current = time
frmHub:RegBot(startchrs ..current ..endchrs)
end

function RegTimer(f, Interval)
local tmpTrig = Interval / TmrFreq
assert(Interval >= TmrFreq , "RegTimer(): Please Adjust TmrFreq")
local Timer = {n=0}
Timer.func=f
Timer.trig=tmpTrig
Timer.count=1
tinsert(tabTimers, Timer)
end

function OnTimer()
for i=1, getn(tabTimers) do
tabTimers[i].count = tabTimers[i].count + 1
if tabTimers[i].count > tabTimers[i].trig then
tabTimers[i].count=1
tabTimers[i]:func()
end
end
end


function tfind(table, item)
for key, value in table do
if value == item then return key end
end
end

function UseTables(filename,table)
local handle = openfile(filename, "r")
if (handle) then
local line = read(handle)
while line do
s,e,username,text = strfind(line, "(.+)|(.+)")
if username ~= nil and text ~= nil  then
table[username]=text
end
line = read(handle)
end
closefile(handle)
end
end

function SaveTable(filename,table)
writeto(filename)
for key, value in table do
table[key]=value
write(key.."|"..value.."\n")
end
    writeto()
end

function SaveKeyTable(filename,table)
writeto(filename)
keynum=1
for key, value in table do
table[key]=value
write(keynum.."|"..value.."\n")
keynum=keynum+1
end
    writeto()
end

function LoadKeyTable(filename,table)
local handle = openfile(filename, "r")
if (handle) then
local line = read(handle)
while line do
s,e,keynum,username = strfind(line, "(.+)|(.+)")
if username ~= nil then
table[keynum]=username
end
line = read(handle)
end
closefile(handle)
end
end

function LogWhoUsed(To,user,From,Text)
Msg = user.sName.." * "..To.." * "..From.." * "..Text.." * "..date("%d").."/"..date("%m").."/"..date("%Y").." * "..date("%H")..":"..date("%M")..""
local handle = openfile(SayLog, "a")
write(handle,Msg.."\n")
closefile(handle)
end

function AddBlanksToTables(uName,filename,table,textstring)
UseTables(filename,table)
writeto(filename)
for key, value in table do
table[key]=value
write(key.."|"..value.."\n")
end
write(uName.."|"..textstring.."\n")
writeto()
end

data.cfg is

------------------------------------------Begin Credits ------------------------------------------
-- --
-- Bot Name : Smeagol --
-- Home : RPGBooks-Cymru.no-ip.org --
--     Credits : Developed By Stravides, --
-- Copyright : There's no problem taking and ammending this config, but --
-- please leave in this Credit Section --
-- --
------------------------------------------ End Credits -------------------------------------------
-- --
--------------------------------------  Variables used -------------------------------------------
BOTName = "DungeonMaster"
HubAdress = "RPGBooks-Cymru-rpg.no-ip.org"
addredirect = "RPGBooks-Cymru.no-ip.org:411"
BOTNameInfo = "$MyINFO $ALL "..BOTName.." <++V:0.306 DungeonMaster $ $Etherial Plane"..strchar( 1 ).."$DungeonMaster@RPGBooks-Cymru.no-ip.org$"
version = BOTName.." "..ver
prefix = "!"
ReverseKick = "Stravides"
mb = 1024 * 1024
gb = 1024 * mb
maxKicks = 3

disconnectUser = nil -- disconnect the user, nil = don't
useTimer = 1
counter = 1

rows = 0
Count = {}

startchrs = "Local: "   -- shows before clock
endchrs = " GMT"    -- shows after clock
current = date("%H:%M:%S")
-------------------------------------  Time Definition -------------------------------------------
Sec = 1000
Min = 60*Sec
Hour = 60*Min
Day = 24*Hour
Week = 7*Day
Month = 4*Week
Year = 365*Day
TmrFreq = 10*Sec
-------------------------------------  Begin Files used ------------------------------------------
BanLog = "dm/banlog.txt"
KickLog = "dm/kicklog.txt"
SayLog = "dm/saylog.txt"
log_in = "dm/logintext.txt"
log_out = "dm/logouttext.txt"
botsfile = "dm/botstext.txt"
fil_block = "dm/blockedusers.txt"
-------------------------------------   End Files used  ------------------------------------------
maxdiceroll = 15

rules = "\r\n"..
"                                   Rules \r\n"..
"\r\n"..
"Failure to comply with these rules will mean permanent exclusion from the Realm.\r\n"..
"\r\n"..
"1.  This realm is for Roleplaying... If you wanna download goto my other hub RPGBooks-Cymru.no-ip.org.  Not Here.\r\n"..
"2.  Keep it clean and nice - I will not tolerate Rants, offensive or distractive players\r\n"..
"3.  Any Offences will result in the loss of XP and Temp Stasis\r\n"..
"4.  3 Stasis' will lead to an automatic and permanent death of your character.\r\n"..
"5.  The DM is Always Right - there will be no rules lawyers tolerated. \r\n"..
"6.  Characters are to be created in E-Tools ver 1.4.1 and e-mailed to [EMAIL]Stravides@RPGBooks-Cymru.no-ip.org[/EMAIL]\r\n"..
"7.  Dice rolls are Public and Only the 1st roll will be accepted.\r\n"..
"8.  You will be asked to roll by the DM, only then should you use the dice rolling engine\r\n"..
"9.  No Munchkins - Read the definition on the web !!!\r\n"..
"\r\n"

helpstart= "\r\n"..
"                                   Starting package \r\n"..
"\r\n"..
"Create a 1st Level char from 3Ed PHB, any other mods must be run by the DM.\r\n"..
"Character has 750 starting gold\r\n"..
"Characters may be of any alignment.\r\n"..
"Characters must not have offensive names, and your Nick must be that of your character\r\n"..
"Ascii names will not be tolerated.\r\n"..
"\r\n"

helpdice= "\r\n"..
"                                   Dice Rolling \r\n"..
"\r\n"..
"Dice rolls can be made by typing !d then the number of sides of the dice you\r\n"..
"wish to throw ie !d4 !d6 !d8 !d10 !d12 !d20 !d100\r\n"..
"If you wish to roll multiple die ie 4d6+3 you type\r\n"..
"!roll 4d6+3  where 4 is the qty 6 is the sides of the dice 3 is added to the score\r\n"..
"\r\n"

ForumAd = "\r\n"..
"=========================== FORUM ============================ \r\n"..
"          Please visit the RPGBooks Cymru Forum @ \r\n"..
"          [URL]http://rpgbooks-cymru.no-ip.org/forum/[/URL] \r\n"..
"    News, Requests, RPG Checklists, & General Discussions \r\n"..
"============================================================== \r\n"