PtokaX forum

Lua 5.3/5.2/5.1 Scripts (for PtokaX 0.4.0.0 and newer) => Help with scripts => Topic started by: satya on 04 July, 2008, 11:11:03

Title: another script i m tryin my hands on
Post by: satya on 04 July, 2008, 11:11:03
Here is a script wich i m trying hand on


local MsgPrefix = "\n\n\n\t\t\t\t\tUsers IP List\r\n"
MsgPrefix = MsgPrefix.."\t\tTHIS IS A CONFIDENTIAL MATTER WICH IS BEIN SENT TO U BY ADMIN\r\n"
MsgPrefix = MsgPrefix.."\t\tCONTENTS IN HERE SHOULD NOT B SHARED WITH ANY USERS IN ANY CASE\r\n"
MsgPrefix = MsgPrefix.."\t\tFOR FUTHER MORE DETAILS CONTACT THE ADMIN [P0RNISTAN?]\r\n\r\n"
MsgPrefix = MsgPrefix..string.rep("?",150).."\r\n"



local MsgSuffix = "\r\n"..string.rep("?",150).."\r\n"
MsgSuffix = MsgSuffix.."\t\t\t\t\t\t\t\t\t\t\t\t\tAdmin"


local File = "ip list.txt"
local Msgs




OnStartup = function()
File = Core.GetPtokaXPath().."scripts/"..File
local f,e = io.open(File)
Msgs = f:read("*a") f:close()
Msgs = MsgPrefix ..Msgs ..MsgSuffix

End

--OpConnected = function(users)

UserConnected = function(user)
Core.SendToUser(user,Msgs)
Core.SendPmToUser(user, SetMan.GetString(1), Msgs)
End


Well the script is pretty simple, wen a operator logs in this sends a PM with the contents of the file


n now this is the error which i get

[14:58] Syntax [string "..."]:30: '=' expected near 'UserConnected'



can ne1 help me out with this
Title: Re: another script i m tryin my hands on
Post by: satya on 04 July, 2008, 12:10:46
Hey guyss

i figured out the mistake


;D
Title: Re: another script i m tryin my hands on
Post by: satya on 04 July, 2008, 12:21:49
hey guyss


If u know in C we have some thing called structures. so using structures we can store n retrieve records of nething.

similarly do we have such provision in LUA. if yes then wat is it! n can i have a small example for the same


thanks
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 04 July, 2008, 14:57:54
not sure that this is what you meant but LUA uses tables.

Example usage

table.field = value
table["field"] = value
table = { value, value, value, value, }     <== all fields get a numeric indici starting at 1
table = { field = value, newtable = { value, value, }, field = value, }

table.maxn(table)  returns number of index
#table      returns number of inidex (works only on numeric index)
table.insert(table [,position] , value)
table.remove(table [,position] , value)


this is what a table can look like when saved to file

Quote
tLogintable = {
   ["[NHA™]CrazyGuy"] = {
      [6] = 217,
      [2] = "Online",
      [8] = 2,
      [3] = "07/02/08 16:11:56",
      [1] = "06/28/08 22:37:52 (script start)",
      [4] = 500,
      [5] = "06/30/08 01:39:44",
      [7] = "06/15/08 17:30:09",
   },
}


or the same table with named fields

tLogintable = {
   ["[NHA™]CrazyGuy"] = {
      ["PM"] = 217,
      ["Status"] = "Online",
      ["Search"] = 2,
      ["Last Search"] = "07/02/08 16:11:56",
      ["Last Login"] = "06/28/08 22:37:52 (script start)",
      ["Mainchat"] = 500,
      ["Last PM"] = "06/30/08 01:39:44",
      ["Last Mainchat"] = "06/15/08 17:30:09",
   },
}

For more information about tables see LUA Manual Chapter 5, Par 5 (http://www.lua.org/manual/5.1/manual.html#5.5)
Title: Re: another script i m tryin my hands on
Post by: satya on 05 July, 2008, 16:27:32
CG thanks for dat


but in C lang wich i know very well.. this is wat we can do with the help of structures:


I can Accept the records from the user and save it in a file and later on wen ever required i can retrieve it back from the same file.

here is an example:

struct emp             //Creating a structure to hold record of employee
{
char name[30];
int age;
} e;

FILE *fp;                                //Creating a pointer variable to point to the file
fp=fopen("emp.txt","w+");         //openin the file in the write mode


scanf("%s%d",&e.name,&e.age);    //Accepting the records from the user and storing it in the struct var e
fprintf(fp,"%s %d\n",e.name,e.age);     //Writing the Values in the var e into the file pointed by fp



Now the above code in a C lang will accept a single record n store it in the file..

now later using the following code i retrive it too one by one


struct emp             //Creating a structure to hold record of employee
{
char name[30];
int age;
} e;

FILE *fp;                                //Creating a pointer variable to point to the file
fp=fopen("emp.txt","r");         //openin the file in the read mode


fscanf(fp, "%s%d",&e.name,&e.age);    //Reading the records from the file and storing it in the struct var e
printf("%s %d",e.name,e.age);     //Printing the Values in the var e


Such kind of file operations are very help full to search for a particular thing. Like if i want to know the age of employee 'xyz', i wud read records one by one and compare with the name 'xyz' once match will print the same.

This is want i wanna do and want to know..


No doubt the thing wich u suggested is good but this is wat i m lookin for, ne suggestion for this

it will be very helpfull if u can help me with and example as u did in the last one wich was an xcellent one for a novice like me to understand.


thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 06 July, 2008, 02:11:56


emp = {} -- creating a table to hold record of employee
-- no definition of keys/values needed in lua
-- Assuming Employer object with fields .Name and .Age

sFilename = "myfile.tbl" -- creating global var holding the file name


AddRecord = function(Employer) -- function to store employer name and age in table
emp[Employer.Name] = Employer.Age
end

GetRecord = function(Name) -- function to return age by name (or 0 if employer not found)
if emp[Name] then
return emp[Name]
else
return 0
end
end

DelRecord = function(Name) -- function to remove employer by name
if emp[Name] then
emp[Name] = nil
return true -- return true on success
else
return false -- return false, employer not found
end
end

LoadRecords = function() -- function to load file data into table
local hFile = io.open(sFilename)
if hFile then
hFile:close()
emp.items = dofile(sFilename)
end
end

SaveRecords = function() -- function to store table data into file
local hFile = io.open(sFilename, "w+")
if hFile then
hFile:write(Serialize(emp,"emp"))
hFile:flush()
hFile:close()
end
end

Serialize = function(tTable, sTableName, sTab)
--function to transform table data into readable file structure
sTab = sTab or "";
sTmp = ""
sTmp = sTmp..sTab..sTableName.." = {\n"
for key, value in pairs(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


Is this example of any help ?
Title: Re: another script i m tryin my hands on
Post by: satya on 06 July, 2008, 08:38:54
Thanks CG will take sometime for me to understand this thing as i told u dat i have started the LUA scripting.

but thanks a lot for this example will surely help me a lot!

and one more thing can u help with menu thing..

Like how to add a menu in the hub with the commands n how to write the function to execute them!


and also if we are using menu driven command then for an user ip a input box appears how do we get daT!

thanks
satz

Title: Re: another script i m tryin my hands on
Post by: Snooze on 06 July, 2008, 09:48:57
Hey satya,

This might help you get started.
http://www.thenighthawk.biz/smf/index.php?topic=52.0

You can find tons of examples on the board on the usage of these.

Let us know if you need a small example..

/Snooze
Title: Re: another script i m tryin my hands on
Post by: satya on 06 July, 2008, 10:47:34
snooze thanks a lot for the reference will b great if u can help with with an example


thanks satz
Title: Re: another script i m tryin my hands on
Post by: satya on 08 July, 2008, 09:10:07
hey CG abt the table thing i m still not able to understand it.


Can u help in this way:

can u show a small function wich will take the arguments as Name And Age and store them in a file

and also another funtion wich will show the entire contents of the file using table!

thanks
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 08 July, 2008, 11:23:22
Quote from: satya on 08 July, 2008, 09:10:07
hey CG abt the table thing i m still not able to understand it.


Can u help in this way:

can u show a small function wich will take the arguments as Name And Age and store them in a file

and also another funtion wich will show the entire contents of the file using table!

thanks

Well, my code above does already take the arguments as Name and Age and stores them to file (if you call the Save function)
The table file created will look like this:

Quote
emp = {
   ["Peter"] = 20,
   ["John"] = 25,
   ["Albert"] = 18,
}


showing the entire contents of the table can be done on several ways.
In lua we'd use  for <iterator> in pairs(table) do  to iterate through the table.
This iteration however is in a random order so the output may not always look the same, eventhough the data the output contains does.
If a table has numeric keys (the place where it not says the Name), we could use a different iterator
for k = 1,#table do
This will iterate in order starting at index 1, continuing to the last with an increment of 1.
More information about for loops can be found here (http://www.lua.org/manual/5.1/manual.html#2.4.5)


So let's take the previous code i wrote, and output the table contents as a whole with print


PrintTable = function()
local output = ""
for k in pairs(emp) do
output = output.."Employer name: "..k.."\tage: "..emp[k].."\n"
end
print(output)
end



This may output as follows
Quote
Employer name: John   age: 25
Employer name: Peter   age: 20
Employer name: Albert   age: 18


Mind you that LUA does not output directly from file in such way as your example did.
We read the file contents first and store them in a variable, often on script start.
Then we use that variable to add/remove/search for records and output results
Title: Re: another script i m tryin my hands on
Post by: Yada on 08 July, 2008, 14:01:23
Quote from: CrazyGuy on 08 July, 2008, 11:23:22

for k in pairs(emp) do
output = output.."Employer name: "..k.."\tage: "..emp[k].."\n"


Is there any increase/decrease in performance or memory doing like this?
for k,v in pairs(emp) do
output = output.."Employer name: "..k.."\tage: "..v.."\n"


Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 08 July, 2008, 21:30:09
the extra looping of v may make the whole loop a bit slower. Since all keys only have one value in the example table layout, there's no advantage to iterating through all 1 of them.
To be honest, I do not have a single script in which i've iterated through values, not even when the structures become multiple levels deep. But in that situation, there may be a small advantage to it, who knows.
But since iterating is random and having multiple values per key, they may get mixed up.

Here's an example of how that may cause trouble

local emp = { ["Peter"] = { 20, "streetname",}, ["John"] = { 18, "his address",},}

for k,v in pairs(emp) do
     output = output.."Employer name: "..k
     if v == 1 then
          output = output.."\tage: "..v.."\n"
     else
          output = output.."\'taddress: "..v.."\n"
     end
end


the extra if clause needed to see which v is the one currently being processed, slows things down.
I'd prefer to write the above code like this

local emp = { ["Peter"] = { 20, "streetname",}, ["John"] = { 18, "his address",},}

for k in pairs(emp) do
     output = output.."Employer name: "..k.."\tage: "..emp[k][1].."\taddress: "..emp[k][2].."\n"
end


Maybe other scripters can give you other (and better) examples of that, but like I said, I don't use it because I don't find it handy  :)
Title: Re: another script i m tryin my hands on
Post by: Yada on 09 July, 2008, 00:20:25
I see your point. there is no need to do a other loop if it's not needed :)
Hopefully other scripters have some input on this :)
Title: Re: another script i m tryin my hands on
Post by: satya on 09 July, 2008, 11:10:43
Well dats makes my work easier....

now i understood it, thanks buddy now i can go ahead with my script once i completed i will let ya know


thanks alot u always helped me wen i was stucked
Title: Re: another script i m tryin my hands on
Post by: satya on 09 July, 2008, 12:06:16
Thanks CG alot atlast i got the script working in a way i wanted

here is something wich i m still not able to understand

wat is the job of the serialize function????


tHnks for all ur help
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 09 July, 2008, 13:09:55
The serialize function writes the data in a readable form to file.
This way, when you open a file containing a table with a texteditor such as Notepad, you can easily read the contents.
Title: Re: another script i m tryin my hands on
Post by: satya on 10 July, 2008, 12:06:40
Hey CG some help againn :D


wat we need to do if we want to get all the text after a keyword say for example

+request The Hancock movie

how can i get thing after +request into a var in the above example "The Hancock movie"

thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 10 July, 2008, 14:18:34
You'd have to use string.find for that.


ChatArrival = function(tUser,sData)
local _,_,sCmd,sText = sData:find("%b<>%s%p(%S+)%s(.*)|")
if sCmd == "request" then
Core.SendToAll("<"..SetMan.GetString(21).."> "..sText.."|")
return true
end
end


The complete message a user writes is
Quote<nickname> +request The Hancock movie|

the first 2 return values of string.find return the position and the length of the searched string.
We don't need those, so we store them in _ twice
%b<> captures everything between the characters < and > , which is the nickname
%s is a space character, which will be there after the nickname
%p captures amongst other things, the symbols we use for commands !,+,- etc.
then comes our command, which is a string. %S  , the + indicates it has a length > 1 characters.
And because we want to store that value, we place brackets around it.
between the command and the rest of the text is another space %s
Then the rest of the line, except for the endpipe | we want to see what's requested.
. reads over every character. * indicated (the longest possible) and again, because we want to use that, we place brackets around it.
and last, the endpipe. we don't capture that but we put it in our pattern to indicate how long the .* should go on.

The above script will return the text requested in mainchat
In this example
Quote<PtokaX> The Hancock movie
will be seen in chat

string patterns can be tricky, and it will take some time to learn them.
But read more about it here in the LUA Manual (http://www.lua.org/manual/5.1/manual.html#5.4.1)

What i found handy when i wasn't so familiar with string.find, is to send all incoming data to mainchat.
Core.SendToAll(sData)
That gives you a good overview of what exactly is being send. (Note that endpipes will not show, but every protocol command ends with one !)
Then when you see it in mainchat, try to break it up in parts such as nickname, spaces, special characters, strings, numbers etc.
Write a pattern that will indicate all the parts , and after that , place brackets around the parts you want to save in variables. And name the variables before the = sign in the code.

Quote<CrazyGuy> !set language english

<CrazyGuy> %b<>
%s
! %p
set %S+
%s
language %S+
%s
english %S+

local _,_ = sData:find("%b<>%s%p%S+%s%S+%s%S+|") -- don't forget to add the endpipe

-- let's capture all the parts
local _,_,sNickname,cCommand,sCommand,sVariable,sValue = sData:find("(%b)<>%s(%p)(%S+)%s(%S+)%s(%S+)|")
Title: Re: another script i m tryin my hands on
Post by: satya on 11 July, 2008, 08:09:09
Cool man CG dats was some kind of xplaination wich i needed, the manual wich i had refered to didn had such simple and understanding xplanation with such xamples

thanks a lot buddy u surely helpin me alot in this lua scripting thanks to u now i can make scripts for my hub as i want and i can bug u netime if i m stuck :D

one more thing CG the above +request thing if i want to add a menu for this for registered users how can i do dat, i have gone thru this menu thing but has not helped me in any ways will b great if u can xplain me dat too..


thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 11 July, 2008, 13:59:26
you're welcome  :)
I rather spend time explaining people like you how things work, then fill requests by those that want one to do the stuff for them  ;D

What kind of menu's do you exactly mean ?
Title: Re: another script i m tryin my hands on
Post by: satya on 11 July, 2008, 18:38:15
Hey thanks alot CG

by menu i mean the one wich we get by doin a right click on the hub tab, well in one script wich i found here in the hub wich is used for change the nick of the user, there are context menus provided wich a user can get by doin a right clik on the hubs tab name..


Does this help???

Thanks Satz
Title: Re: another script i m tryin my hands on
Post by: satya on 12 July, 2008, 09:27:22
Thanks mutor but i have seen this explanation b4 too wich was of no use, i m lookin forward for a xplanation for a kind wich CG gave me other day!


thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 12 July, 2008, 14:55:14
I'm not sure if I can be more specific then Mutor.
But I can try to add some more examples.

Let's assume you are an operator and when you rightclick on a user in the userlist, you want options to gag,ungag,drop and kick the user. We shall group these commands in a menu called "User Admin", so when you rightclick you'll see this menu:
Quote
User Admin
   Gag this user
   Ungag this user
   -------------------------
   Drop this user
   Kick this user

A UserCommand gives a user an option to click, instead of typing the command. But the command must still exist, and all the parameters needed for the command must be included in the UserCommand.
For simplicity, we shall use the inbuild commands PtokaX has.
The commands in the example are
Quote
!gag <nickname>
!ungag <nickname>
!drop <nickname>
$Kick <nickname>|

PtokaX does not have a !kick command (actually it's function is taken over by !drop) but we can use the protocol command $Kick.
Sending protocol commands is called sending raw commands.
As Mutor pointed out, the type identifier for raw commands, is the number 1 in a $UserCommand

Quote from: Mutor$UserCommand <type> <context> <details>|

or we can write it like this..
Quote
$UserCommand

<type>

<context>

<details>
|

Let's start with the kick option, continuing from above we can fill in.
Quote$UserCommand 1 <context> <details>|

Since this is gonna be a command performed on a user in the userlist, we only need that command there, and not on the hub tab.
So our context will be 2 (User List)

Quote$UserCommand 1 2 <details>|

<details> include the commands name, the menu name, and the actual command send to the hub with all parameters to make the command work.
We said our menu was called User Admin, and we named the command "Kick this user"
Menu's and names are split by \\ in UserCommands

Quote$UserCommand 1 2 User Admin\\Kick this User|

Now we need to add the command syntax.
$ is used as a delimiter to indicate the end of the menu naming and the beginning of the command.
Everything to the right of the $ will be send to the hub when a user clicks on the command.

Quote$UserCommand 1 2 User Admin\\Kick this User$|

The syntax for the protocol $Kick command is $Kick <nickname>|
the $ and | need to be escaped as they are special chars used in the protocol to indicate beginning and end of a command.
If we'd send them like $ and | in the UserCommand to the client, the client will misinterpret them.
Quote
$ is escaped with &#36;
| is escpaed with &#124;

so $Kick <nickname>| becomes &#36;Kick <nickname>&#124;


Quote$UserCommand 1 2 User Admin\\Kick this User$&#36;Kick <nickname>&#124;|

Now it is almost complete, but we have 1 variable we need to replace: <nickname>
There's been added a few rules to UserCommands so all clients know how to replace variables with current values.
Quote
%[mynick]  will be replaced with the nick of the one clicking the command
%[nick]      will be replaced with the nickname of the user the command is used on (selected user in userlist)
%[ip]         will be replaced with the IP of the user the command is used on (if known)

and there are many more, which are listed in most clients Settings menu under UserCommands

So , we need to replace <nickname> with %[nick]

Quote$UserCommand 1 2 User Admin\\Kick this User$&#36;Kick %[nick]&#124;|

UserCommands are added to a client in the order they are received. So send them in order (top to bottom)

Let's do the Gag User option the same way.
The menu naming and such i won't repeat, but the command is different

Quote$UserCommand 1 2 User Admin\\Gag this User$|

We're using the command !gag <nickname> for this.
Normally, this command would be typed in mainchat and send by the client as chat.
Quote<CrazyGuy> !gag idiot|

As explained above, the | needs to be replaced with &#124;
My nickname needs to be replaced with %[mynick]
and the nickname of the one the command is used on with %[nick]
Note that %[mynick] does not place the < and > brackets around my nick, so we'll have to include them in the command.
Quote<%[mynick]> !gag %[nick]&#124;
Also not that the spaces must be added correctly as if it was a normal chat message.
That is namely how the hub will receive it when it's used.


Now our command is complete
Quote$UserCommand 1 2 User Admin\\Gag this User$<%[mynick]> !gag %[nick]&#124;|

The other commands all go the same way.

Quote
$UserCommand 1 2 User Admin\\Gag this User$<%[mynick]> !gag %[nick]&#124;|
$UserCommand 1 2 User Admin\\Ungag this User$<%[mynick]> !ungag %[nick]&#124;|

$UserCommand 1 2 User Admin\\Drop this User$<%[mynick]> !drop %[nick]&#124;|
$UserCommand 1 2 User Admin\\Kick this User$&#36;Kick %[nick]&#124;|

The only thing still missing is the seperator after the Ungag command.
As Mutor pointed out, this is $UserCommand of type 0
and we want that in the User List as well, so context is 2.
Since it doesn't do anything, there are no details.

Quote
$UserCommand 1 2 User Admin\\Gag this User$<%[mynick]> !gag %[nick]&#124;|
$UserCommand 1 2 User Admin\\Ungag this User$<%[mynick]> !ungag %[nick]&#124;|
$UserCommand 1 2|
$UserCommand 1 2 User Admin\\Drop this User$<%[mynick]> !drop %[nick]&#124;|
$UserCommand 1 2 User Admin\\Kick this User$&#36;Kick %[nick]&#124;|

Title: Re: another script i m tryin my hands on
Post by: satya on 13 July, 2008, 10:15:18
Hey CG that made some sense

now here is wat i want to do,
If u rem i was workin on a script wich takes the request from the user for wich u xpained me dat string.find().

So this is wat i want to do
i want to provide a menu for the RegUser to leave a request.
so wen the user cliks on it, how can he enter the Request i mean i have seen those pop up box coming up and askin the user to enter the required arguements. so how to get those input box.

Thanks Satz


Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 13 July, 2008, 13:23:18
an input box can be added with %[line:<title>]

So you're UserCommand will be
Quote$UserCommand 1 3 RegUser Menu\\Add a request$<%[mynick]> +request %[line:Title]&#124;|

Before sending UserCommands to users, make sure their clients support that.
A Client sends $Supports UserCommands during login.
PtokaX stores if this has been send or not.
You can check this with
if Core.GetUserValue(User,12) == true then
Title: Re: another script i m tryin my hands on
Post by: satya on 14 July, 2008, 12:48:50
Hey CG thanks a lot for dat..
i will very soon try dat and will let ya know abt the out comes

thanks Satz
Title: Re: another script i m tryin my hands on
Post by: satya on 17 July, 2008, 10:36:24
Quote from: CrazyGuy on 06 July, 2008, 02:11:56


emp = {} -- creating a table to hold record of employee
-- no definition of keys/values needed in lua
-- Assuming Employer object with fields .Name and .Age

sFilename = "myfile.tbl" -- creating global var holding the file name


AddRecord = function(Employer) -- function to store employer name and age in table
emp[Employer.Name] = Employer.Age
end

GetRecord = function(Name) -- function to return age by name (or 0 if employer not found)
if emp[Name] then
return emp[Name]
else
return 0
end
end

DelRecord = function(Name) -- function to remove employer by name
if emp[Name] then
emp[Name] = nil
return true -- return true on success
else
return false -- return false, employer not found
end
end

LoadRecords = function() -- function to load file data into table
local hFile = io.open(sFilename)
if hFile then
hFile:close()
emp.items = dofile(sFilename)
end
end

SaveRecords = function() -- function to store table data into file
local hFile = io.open(sFilename, "w+")
if hFile then
hFile:write(Serialize(emp,"emp"))
hFile:flush()
hFile:close()
end
end

Serialize = function(tTable, sTableName, sTab)
--function to transform table data into readable file structure
sTab = sTab or "";
sTmp = ""
sTmp = sTmp..sTab..sTableName.." = {\n"
for key, value in pairs(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


Is this example of any help ?


this is how u xplained me table, with wich i have made a script wich keeps record of the userip at the time of registration.

Now a normal table say

user = {
   ["Peter"] = 10.40.181.225,
   ["John"] = 10.40.181.226,
   ["Albert"] = 10.40.181.227,
}


wud have the contents as shown above, now this time i want to store date and also time along with the user ip,

wich i wud use to show the user wen he logs in wen he was online in the hub last time. Wich is a common trend these days in the websites.

So i want to store Date and Time along with the IP

the content might be like this:
user = {
   ["Peter"] = {10.40.181.225,7/12/2008,15.36.53}
   ["John"] = 10.40.181.226,7/12/2008,15.36.53}
   ["Albert"] = 10.40.181.227,7/12/2008,15.36.53}
}

This is wat i think i wud look like, if i m wrong then pls help me out with dat.

but this is wat i want, u gave me function Serialize wich is used to store this in the file, so wat wud be the changes to be done to store such table in the same file, with the user table is ready with records in it.


thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 17 July, 2008, 16:00:01
you are almost right, this is what it will look like

Quote
user = {
   ["Peter"] = {"10.40.181.225","7/12/2008","15.36.53",},
   ["John"] = {"10.40.181.226","7/12/2008","15.36.53",},
   ["Albert"] = {"10.40.181.227","7/12/2008","15.36.53",},
}

But when you add values to a table like that, LUA will automatically generate keys and you have a table within a table.


user = {
["Peter"] = {
[1] = "10.40.181.225",
[2] = "7/12/2008",
[3] = "15.36.53",
},
["John"] = {
[1] = "10.40.181.226",
[2] = "7/12/2008",
[3] = "15.36.53",
},
["Albert"] = {
[1] = "10.40.181.227",
[2] = "7/12/2008",
[3] = "15.36.53",
},
}


If you'd use the Serialize function, that is how it will be written to disk.

Suppose Peter logs in and you want to show him his info, the code would be.
Core.SendToUser(User,"<Login info> Hello "..User.sNick..". This is your info\n\n\tYour IP:\t\t"..user[User.sNick][1].."\n\tDate you logged in:\t"..user[User.sNick][2].."\n\tTime you logged in:\t"..user[User.sNick][3].."|")

Resulting in
Quote
<Login info> Hello Peter. This is your info

   Your IP:      10.40.181.225
   Date you logged in:   7/12/2008
   Time you logged in:   15.36.53
Title: Re: another script i m tryin my hands on
Post by: satya on 17 July, 2008, 18:02:45
Hey CG thanks a lot for dat but still if u can xplain me in short like the way u did last time it will be more helpful for me.


Let me make it simpler for u..
from the last time lesson i know how to retrive the contents of the file into the table in the script, So lets say dat table user holds all the record


user
{
["ABC"]={"10.40.181.225","17/7/2008","15.03.56"}
["XYZ"]={"10.40.181.225","17/7/2008","15.03.56"}
}

Let the above be the user table contents wich are read from the file and are in the table in the script
so now help me with this

I want to show a Message to the user wen he connects to the hub with this msg


Welcome nick
You are logged in the hub with the IP: user.sIP, your ip at the registration time was (here i want to show the ip from the table user)
Last time u logged in the hub on (DATE FROM THE TABLE) at (TIME FROM THE TABLE)


So in short all i want to know is how to access ie display or compare all the members from the table, as of last time there was a single member in the table ie for each user there was his ip, but this time we have more than one value for each user nick.
I think i have made some sense :D

thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 18 July, 2008, 12:54:08
Read my previous post again a bit more closely.  ;)
Although i send a different message then you , i do use the information in the table and send that to the user.
Check the [1], [2] and [3] indicators i use in the message.

I'm actually not quite sure how to make that example more clear.
If it doesn't help you, can you specify exactly on what point you get stuck ?
Title: Re: another script i m tryin my hands on
Post by: satya on 19 July, 2008, 09:28:41
Hey CG thanks a lot but i m really gettin no where with dat here is a small script wich i tried


usr = {}
OpConnected = function(user)
usr[user.sNick][1]=user.sIP
usr[user.sNick][2]=os.date("%A").." the "..os.date("%d").." of "..os.date("%B").." "os.date("%Y")
usr[user.sNick][3]=os.date("%T")
usr[user.sNick][4]=2014008




x="Welcome "..user.sNick.."\n"..
"Last time u where online on "..usr[user.sNick][2].." "..user[user.sNick][3].."\n\n"..
"Some of your important information: "..
"\tYour referal id: "..usr[user.sNick][4]..
"\tYour registered ip: "..usr[user.sNick][1]
Core.SendPmToUser(user, "INFO", x)
end


See the above code i have tried once but its not helping me in any ways :(
i don understand where i m worng, wud u please tell me a small code just like u did last time.

thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 19 July, 2008, 13:08:35
Well, there's nothing really wrong with your code, but there's a few things you could have a look at.
Not all, but some of these in the list can cause that you do not get a message (i assume that is what the problem is ?)


local x =
UserConnected = OpConnected
Setusr[user.sNick] = {} before you use usr[user.sNick][1]=user.sIP


I'm not fully awake yet, so I may have missed something but i'm pretty sure that created a new table for the current user and registering the sender of pm (or change it to SetMan.GetString(21)  the default bot) will do the trick.
Other then that, I see no reason why it shouldn't work, you have the principles right :)

Title: Re: another script i m tryin my hands on
Post by: satya on 20 July, 2008, 13:54:33
Hey CG thanks a lot its workin fine

heres one more:

from the user nick i want to find wats inside the []

for ex: [123]Alen

so i have written the following code for dat
local id=user.sNick:find("(%b)[]")

and its says dat its a nil value

nething missing with my codin????

thanks Satz
Title: Re: another script i m tryin my hands on
Post by: satya on 20 July, 2008, 19:07:33
well mutor i have done dat as many times as u wud have imagined but its of no use, there is no example wat so ever in dat manual and also there are no simple and xact xplanation as ne1 need.

once again mutor this is something between me and CG, if he says dat i m bugin him its fine i will stop, but i never asked u in this thread any single time it was CG who came forward n helped me as i wantd, and i thank him every single time. And if readin Manuals wud had done a great deal then we shud have these help or how-to forums

thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 21 July, 2008, 13:56:39
Quote from: satya on 20 July, 2008, 13:54:33
Hey CG thanks a lot its workin fine

heres one more:

from the user nick i want to find wats inside the []

for ex: [123]Alen

so i have written the following code for dat
local id=user.sNick:find("(%b)[]")

and its says dat its a nil value

nething missing with my codin????

thanks Satz

Quote from: Mutor%bxy Matches the balanced string from character x to character y (e.g. nested parenthesis).


You want to find what is within the square brackets [ and ].
So that'll be %b[]    ( although i'm not 100% sure if the brackets are counted as special chars and need to be escapded with \ )

Also, I'm pretty sure i've explained before that the first 2 return values of find are the index and length of the pattern you are looking for. As you want to know what is between the brackets and not where in the string the pattern is, your variable 'id' should be the third variable after keyword 'local'
local _,_,id=user.sNick:find("(%b[])")

Give that a try, I'm not sure it works though.



Quote from: MutorSomething between you and he? This is a public forum.
It is, he is right. And I'd welcome other scripters to join this post with questions and answers.
I'm not all knowing :P


Quote from: satyawell mutor i have done dat as many times as u wud have imagined but its of no use, there is no example wat so ever in dat manual and also there are no simple and xact xplanation as ne1 need.
Actually everything can be found in the manual, but I can understand why it can be hard to see it all the first few times.
Especially string patterns have given me a headache for the longest time when learning lua.
Often I simply tried things in code and once I got it working and figured out why it worked, I read back in the manual and was like "aha, so that's how they meant that".


Either way, I wanna use this topic to help explain principles, not to code for someone. There's 1000 topics for that in the Request sections ;)
Personally I find it easier to explain using examples and I get the impression satya finds it easier to learn by watching examples.
I do think there's progress though, certainly if you consider we started with C  ;D

I was gonna write something else, but I forgot. Will add when I remember :P
Title: Re: another script i m tryin my hands on
Post by: satya on 24 July, 2008, 19:04:33
Hey CG thanks a lot for dat.

Quote from: CrazyGuyAlso, I'm pretty sure i've explained before that the first 2 return values of find are the index and length of the pattern you are looking for.
Hey i had forgotten dat :D well now i rem but using dat manual i found my way out my self, instead of string.find i used string.sub

id=user.sNick
id=id:sub(1,8)


Now the above code will return string from position 1 to 8, wich is wat i wanted cos the id is 7 digit long :D

Here take a look at the code wich i made by myself
I run a hub at my place these days it been rockin so now i have got an idea of doin the referral registration system wich we see these days on many site, so this is a script wich checks the ref id and if its valid then lets the user to enter the hub else it disconnects it


usref = {}
local refFile=Core.GetPtokaXPath().."scripts/table/usref.txt"

UserConnected = function(user)
LoadRecords()
local flag=0
local id=user.sNick
local nik
id=id:sub(2,8)


for k in pairs(usref) do
if usref[k] == id then
flag=1
nik=k
end
end

if flag == 1 then
x="\n\t\t\t\tWelcome "..user.sNick.."\n"..
"\t\t YOU HAVE PROVIDED A VALID USER ID:"..id.."\n"..
"\t\t NOW YOU CAN ENTER THE HUB BUT U WONT B ABLE TO DOWNLOAD ANYTHING FROM THE HUB\n"..
"\t\t VERY SOON U WILL B CONTACTED BY ONE OF THE OPERATORS FOR U REGISTRATION PROCESS\n"..
"\t\t PLEASE BE ACTIVE"
Core.SendPmToUser(user,"Stifler",x)
x="\n\n\t\t\t\t\tATTENTION OPERATOR\n"..
"\tA USER HAS LOGGED IN THE HUB WITH THE ID: "..id.." which from our records is valid for the user: "..nik
Core.SendPmToOps("REFERAL",x)
else
x="\n\tRegistration for the hub has been closed\n"..
"\tRegistration for the hub has been closed\n"..
"\tRegistration for the hub has been closed\n"..
"\tRegistration for the hub has been closed\n"..
"\tRegistration for the hub has been closed\n"..
"\tRegistration for the hub has been closed\n"..
"\tRegistration for the hub has been closed\n"..
"\tNOW REGISTRATION ONLY ON REFERRAL BASIS U CAN ENTER THE HUB WITH A REFERRAL ID OF A REGISTERED USER,\n"..
"\tEVERY USER HAS A REFERAL ID, YOU CAN ASK FOR ONE\n\n"..
"\tAFTER U GET THE ID U CAN PREFIX THE ID IN UR NICK AS FOLLOWS\n"..
"\t\t\tIF ALEN IS THE NICK AND THE REF ID IS 1025555 THIS IS HOW U HAVE TO ENTER IT: [1025555]Alen\t\t\t\t\n"
Core.SendToUser(user, "<Stifler>"..x)
Core.Disconnect(user)
end

end


LoadRecords = function() -- function to load file data into table THE SAME ONE WICH U HELPED ME FOR THE TABLE CODE
local hFile = io.open(refFile)
if hFile then
hFile:close()
usref.items = dofile(refFile)
end
return
end



Well CG thanks a lot for been kind and helping me with those explanation and most importantly those examples wich helped me a lot.

Quote from: CrazyGuyI get the impression satya finds it easier to learn by watching examples.

U are absolutely right buddy and this is the reason why i always asked u for an example never the full coding except for dat table thing which was entirely new thing for me. And about the manual ya it helpful in many ways but the string and the os functions needed to have some examples for users like me.

Well CG i want to show u some scripts wich i made after u explained me stuffs.

1st i made rather i shud say i changed ur example code wich u showed to me for dat emp :D

but i learnt a lot from it and i have made a script with 4 tables
one for ip another for date of last login another for time of last login and last one holds the REF ID wich i was talkin abt a while ago

2nd rem once i asked abt those command and all

Quote from: SatyaHey CG some help againn Cheesy


wat we need to do if we want to get all the text after a keyword say for example

Code:

+request The Hancock movie


how can i get thing after +request into a var in the above example "The Hancock movie"

thanks Satz

rem this ???
to which u gave such an awesome reply dude, this kind of explanation shud be in the manual simple with examples. ;)

ok so using dat i have made few commands for my hub operators and hub registered members, take a look


request = function(user,data,cmd)
local _,_,uReq = data:find("%b<> %p"..cmd.."%s(.*)|")

local msg="\r\n\r\n\t\t\tATTENTION OPERATOR\r\n"..
"\t\t"..user.sNick.." has submitted a request:\r\n"..
"\t\t\t"..uReq

Core.SendPmToOps("UserReq", msg)
Core.SendPmToUser(user, "UserReq" , "Your request has been submitted to the operators")
end

suggest = function(user,data,cmd)
local _,_,cs,uSug = data:find("%b<> %p"..cmd.."%s(%S+)%s(.*)|")
cs=cs:lower()
if cs =="cs" then
local msg="\r\n\r\n\t\t\tATTENTION OPERATOR\r\n"..
"\t\t"..user.sNick.." has submitted a suggestion for the Counter Strike Game:\r\n"..
"\t\t\t"..uSug
Core.SendPmToOps("UserReq", msg)
Core.SendPmToUser(user, "UserReq" , "Your suggestion has been submitted to the operators")
else
local _,_,uSug = data:find("%b<> %p"..cmd.."%s(.*)|")
local msg="\r\n\r\n\t\t\tATTENTION OPERATOR\r\n"..
"\t\t"..user.sNick.." has submitted a suggestion:\r\n"..
"\t\t\t"..uSug
Core.SendPmToOps("UserReq", msg)
Core.SendPmToUser(user, "UserReq" , "Your suggestion has been submitted to the operators")
end
end

There are lot more :D

And dats all buddy now i can think abt a script and make it myself all credit goes to u for helping me always and wenever i was in need it.

Hey one more thing buddy with the new version of the ptokax they provide those HTML files with functions and useful scripting information, using dat i have developed a HUB auto shutdown script check it out and do suggest any improvements u think of.


OnStartup=function()
Timer = TmrMan.AddTimer(60000)
OnTimer(Timer)

end

OnTimer = function()
time=os.date("%T")
tx=time:sub(1,2)
if tx == "5" then
Core.Shutdown()
end
end

OpConnected = function(user)
local x="\n\n\t\t\tWELCOME "..user.sNick.."\n"..
"\t This is the night session of the hub where there will be not operator in the hub\n"..
"\t The will remain active throught the night till morning at 5.00 AM\n"..
"\t And in the morning the hub will AUTO SHUTDOWN\n"
Core.SendPmToUser(user, "Stifler", x)
end

RegConnected=OpConnected


Thanks Satz
Title: Re: another script i m tryin my hands on
Post by: CrazyGuy on 24 July, 2008, 21:07:21
Hey Satya,

Good to hear you're enjoying scripting that much  8)
The more experienced you'll get, the easier it will be and more fun it will be.
Then complicated ideas will arise and scripts get of such size that they'll be hard to follow.
But, if you succeed even with that, and place scripts here, peope will start bugging you for scripts.
And then the fun is over.......  :P  just kidding  ;D

Had 2 small things in your code I'd like to point out.
In the first code
local nik

That doesn't do anything in LUA. ( i think that's a C thingy ?)
if you want to reserve a variable 'nik' for later usage, you'll have to equal it to something.
Depending on what it will hold, you could use this.

You can't see it in your code, but when you actually use 'nik' later on in your code, it will become a global variable,instead of a local var. Assigning it a base value assures the local keyword is honoured.


The second thing i saw was in your last code, regarding the OnTimer function.
Wether you are working with 1 or mutliple timers, it's a good idea to check if the timer triggering the event actually is the timer you are looking for. What i mean is, check the timer ID.

Timer = TmrMan.AddTimer(60000)

What you did there is you stored the timerID returned by the function AddTimer into variable Timer.
So you have this info, why not use it ?
The OnTimer function has a parameter nTimerID.
When the function is called, you can check if that parameter matches yours.
If so, execute the code. Else, do nothing.


OnTimer = function(nTimerID)
if nTimerID == Timer then
-- code
end
end


If you'd keep that as a habit, you'll have it easier later on when you use multiple timers in one script.


Keep up the good work  :D