Table = Idiots guide
 

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

Table = Idiots guide

Started by WooshMan, 04 February, 2004, 16:01:31

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

WooshMan

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
WooshMan

Creator of
originaltimebot.lua
www hubstats

Thanks to Plop, Kepp and NightLitch

NightLitch

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.
//NL

RobinHood

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 :-)

NightLitch

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
//NL

WooshMan

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
WooshMan

Creator of
originaltimebot.lua
www hubstats

Thanks to Plop, Kepp and NightLitch

Typhoon

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?



NightLitch

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.
//NL

kepp

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...
Guarding    

NightLitch

Well I think he wants to use all at the same time.
//NL

kepp

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
Guarding    

plop

#10
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
http://www.plop.nl lua scripts/howto\'s.
http://www.thegoldenangel.net
http://www.vikingshub.com
http://www.lua.org

>>----> he who fights hatred with hatred, drives the spreading of hatred <----<<

RobinHood

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

WooshMan

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
WooshMan

Creator of
originaltimebot.lua
www hubstats

Thanks to Plop, Kepp and NightLitch

NightLitch

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.
//NL

tezlo

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

NightLitch

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
//NL

WooshMan

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 :-)
WooshMan

Creator of
originaltimebot.lua
www hubstats

Thanks to Plop, Kepp and NightLitch

NightLitch

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.
//NL

WooshMan

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
WooshMan

Creator of
originaltimebot.lua
www hubstats

Thanks to Plop, Kepp and NightLitch

NightLitch

#19
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
//NL

tezlo

no.. should be
if users[who] then

but the regexp may not pass so youll want to check that
and LoadFromFile on script start

NightLitch

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.
//NL

WooshMan

#22
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
WooshMan

Creator of
originaltimebot.lua
www hubstats

Thanks to Plop, Kepp and NightLitch

tezlo

#23
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

NightLitch

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
//NL

SMF spam blocked by CleanTalk