another script i m tryin my hands on
 

another script i m tryin my hands on

Started by satya, 04 July, 2008, 11:11:03

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

satya

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

Eyes says everything,
Its on you how u read em...

satya

Hey guyss

i figured out the mistake


;D

Eyes says everything,
Its on you how u read em...

satya

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

Eyes says everything,
Its on you how u read em...

CrazyGuy

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

satya

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

Eyes says everything,
Its on you how u read em...

CrazyGuy

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 ?

satya

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


Eyes says everything,
Its on you how u read em...

Snooze

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

satya

snooze thanks a lot for the reference will b great if u can help with with an example


thanks satz

Eyes says everything,
Its on you how u read em...

satya

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

Eyes says everything,
Its on you how u read em...

CrazyGuy

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


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

Yada

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"



CrazyGuy

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

Yada

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

satya

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

Eyes says everything,
Its on you how u read em...

satya

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

Eyes says everything,
Its on you how u read em...

CrazyGuy

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.

satya

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

Eyes says everything,
Its on you how u read em...

CrazyGuy

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

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+)|")

satya

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

Eyes says everything,
Its on you how u read em...

CrazyGuy

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 ?

satya

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

Eyes says everything,
Its on you how u read em...

satya

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

Eyes says everything,
Its on you how u read em...

CrazyGuy

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


satya

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



Eyes says everything,
Its on you how u read em...

SMF spam blocked by CleanTalk