# Useful Functions, Commands and Code Snippets

## Recommended Posts

Because I could not find any Thread like this on the Forums I decided to start one on myself.

You may post your Useful Functions, Commands and Code Snippets here so that the others can use them and don't have to script on their own.

int GetTimestamp([int year, int month, int day, int hour, int minute, int second])

Returns the UNIX Timestamp of any Date after 1st January of 1970 ignoring Summertime(!) (of course as an Integer)

All Arguments are optional, GetTimestamp() returns the UNIX Timestamp of the actual Datetime.

```function GetTimestamp(year, month, day, hour, minute, second)
local i
local timestamp = 0
local time = getRealTime()
local monthDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }

if (not year or year < 1970) then
year = time.year + 1900
month = time.month + 1
day = time.monthday
hour = time.hour
minute = time.minute
second = time.second
else
month = month or 1
day = day or 1
hour = hour or 0
minute = minute or 0
second = second or 0
end

for i=1970, year-1, 1 do
timestamp = timestamp + 60*60*24*365
if (IsYearALeapYear(i)) then
timestamp = timestamp + 60*60*24
end
end

if (IsYearALeapYear(year)) then
monthDays[2] = monthDays[2] + 1
end

for i=1, month-1, 1 do
timestamp = timestamp + 60*60*24*monthDays[i]
end

timestamp = timestamp + 60*60*24 * (day - 1) + 60*60 * hour + 60 * minute + second

return timestamp
end
```

table GetDateTime(int timestamp)

Needs the IsYearALeapYear() Function!

Complement to GetTimestamp. Returns a Table like GetRealTime does but without yearday and isdst.

Note: It returns a year like 2008, you will not have to add 1900 like in getRealTime()! Also the Months start at 1 and end at 12!

```function GetDateTime(timestamp)
local i
local time = {}
local monthDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }

time.year = 1970
while (timestamp >= 60*60*24*365) do
timestamp = timestamp - 60*60*24*365
time.year = time.year + 1

if (IsYearALeapYear(time.year - 1)) then
if timestamp >= 60*60*24 then
timestamp = timestamp - 60*60*24
else
timestamp = timestamp + 60*60*24*365
time.year = time.year - 1
break
end
end
end

if (IsYearALeapYear(time.year)) then
monthDays[2] = monthDays[2] + 1
end

local month, daycount
for month, daycount in ipairs(monthDays) do
time.month = month
if (timestamp >= 60*60*24*daycount) then
timestamp = timestamp - 60*60*24*daycount
else
break
end
end

time.monthday = math.floor(timestamp / (60*60*24)) + 1
timestamp = timestamp - 60*60*24 * (time.monthday - 1)

time.hour = math.floor(timestamp / (60*60))
timestamp = timestamp - 60*60 * time.hour

time.minute = math.floor(timestamp / 60)
timestamp = timestamp - 60 * time.minute

time.second = timestamp

local monthcode = time.month - 2
local year = time.year
local yearcode

if (monthcode < 1) then
monthcode = monthcode + 12
year = year - 1
end
monthcode = math.floor(2.6 * monthcode - 0.2)

yearcode = year % 100
time.weekday = time.monthday + monthcode + yearcode + math.floor(yearcode / 4)
yearcode = math.floor(year / 100)
time.weekday = time.weekday + math.floor(yearcode / 4) - 2 * yearcode
time.weekday = time.weekday % 7

return time
end
```

boolean IsYearALeapYear(int year)

Returns true if the year was/is/will be a Leapyear, else false.

```function IsYearALeapYear(year)
if ((year % 4 == 0 and year % 100 ~= 0) or year % 400 == 0) then
return true
else
return false
end
end
```

You may also post feedback.

Greetz, Neon

Edited by Guest

Because I could not find any Thread like this on the Forums I decided to start one on myself.

You may post your Useful Functions, Commands and Code Snippets here so that the others can use them and don't have to script on their own.

int GetTimestamp([int year, int month, int day, int hour, int minute, int second])

Returns the UNIX Timestamp of any Date after 1st January of 1970 ignoring Summertime(!) (of course as an Integer)

All Arguments are optional, GetTimestamp() returns the UNIX Timestamp of the actual Datetime.

`function GetTimestamp(year, month, day, hour, minute, second)    local i    local timestamp = 0    local time = getRealTime()    local monthDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }        if (not year or year < 1970) then        year = time.year + 1900        month = time.month + 1        day = time.monthday        hour = time.hour        minute = time.minute        second = time.second    else        month = month or 1        day = day or 1        hour = hour or 0        minute = minute or 0        second = second or 0    end        for i=1970, year-1, 1 do        timestamp = timestamp + 60*60*24*365        if (IsYearALeapYear(i)) then            timestamp = timestamp + 60*60*24        end    end        if (IsYearALeapYear(year)) then        monthDays[2] = monthDays[2] + 1    end        for i=1, month-1, 1 do        timestamp = timestamp + 60*60*24*monthDays[i]    end        timestamp = timestamp + 60*60*24 * (day - 1) + 60*60 * hour + 60 * minute + second        return timestampend`

table GetDateTime(int timestamp)

Needs the IsYearALeapYear() Function!

Complement to GetTimestamp. Returns a Table like GetRealTime does but without yearday and isdst.

Note: It returns a year like 2008, you will not have to add 1900 like in getRealTime()! Also the Months start at 1 and end at 12!

`function GetDateTime(timestamp)    local i    local time = {}    local monthDays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }        time.year = 1970    while (timestamp >= 60*60*24*365) do        timestamp = timestamp - 60*60*24*365        time.year = time.year + 1                if (IsYearALeapYear(time.year - 1)) then            if timestamp >= 60*60*24 then                timestamp = timestamp - 60*60*24            else                timestamp = timestamp + 60*60*24*365                time.year = time.year - 1                break            end        end    end        if (IsYearALeapYear(time.year)) then        monthDays[2] = monthDays[2] + 1    end        local month, daycount    for month, daycount in ipairs(monthDays) do        time.month = month        if (timestamp >= 60*60*24*daycount) then            timestamp = timestamp - 60*60*24*daycount        else            break        end    end        time.monthday = math.floor(timestamp / (60*60*24)) + 1    timestamp = timestamp - 60*60*24 * (time.monthday - 1)        time.hour = math.floor(timestamp / (60*60))    timestamp = timestamp - 60*60 * time.hour        time.minute = math.floor(timestamp / 60)    timestamp = timestamp - 60 * time.minute        time.second = timestamp        local monthcode = time.month - 2    local year = time.year    local yearcode        if (monthcode < 1) then        monthcode = monthcode + 12        year = year - 1    end    monthcode = math.floor(2.6 * monthcode - 0.2)        yearcode = year % 100    time.weekday = time.monthday + monthcode + yearcode + math.floor(yearcode / 4)    yearcode = math.floor(year / 100)    time.weekday = time.weekday + math.floor(yearcode / 4) - 2 * yearcode    time.weekday = time.weekday % 7        return timeend`

boolean IsYearALeapYear(int year)

Returns true if the year was/is/will be a Leapyear, else false.

`function IsYearALeapYear(year)    if ((year % 4 == 0 and year % 100 ~= 0) or year % 400 == 0) then        return true    else        return false    endend`

You may also post feedback.

Greetz, Neon

Edited by Guest

These are useful, they may be better placed on the wiki somewhere, though I'm not sure where. You could create a page or category for them. They're probably a bit too 'off topic' to be examples... Good job

These are useful, they may be better placed on the wiki somewhere, though I'm not sure where. You could create a page or category for them. They're probably a bit too 'off topic' to be examples... Good job

More Functions. This time for Strings and formatting Numbers.

int Encrypt(string string)

Returns a Hash (Integer). For Example used to save Passwords so that nobody can read them. I used the Adler-32 Algorithm.

```function Encrypt(string)
local length = #string
local s1, s2 = 0, 1

for n=1, length do
s1 = (s1 + string.byte(string:sub(n, n))) % 65521
s2 = (s2 + s1) % 65521
end

return (s2 * 2^16) + s1
end
```

table Explode(string separator, string ensemble)

Splits ensemble at all Occurrences of separator and stores the Pieces in a Table, which is returned.

```function Explode(separator, ensemble)
local i, j = 1, ensemble:find(separator)
local pieces = {}

while (i) do
if (j) then j = j - 1 end
table.insert(pieces, ensemble:sub(i, j))
if (j) then
i = j + #separator
j = ensemble:find(separator, i)
else break end
end

return pieces
end
```

string FormatNumber(number number, [int digits=0, int decimals=0, string komma=".", string milsep])

Needs the Explode() Function!

Formats any Number and returns the formatted Number as a String. If digits is greater than the Number of digits of number it will fill up with Zeroes. If it's smaller the Number of Digits won't be changed. decimals sets the Number of Digits after the Comma, if it's greater than the Number of Decimals of number it will fill up with Zeroes, else it will cut off the Rest without rounding. komma sets the String that shall replace the Decimal Point. Useful for People like me who come from Germany, where a "," is used to separate floating Point Numbers. Finally milsep sets the String that should separate Thousands. If you leave this nil Thousands won't be separated.

```function FormatNumber(number, digits, decimals, komma, milsep)
digits = digits or 0
decimals = decimals or 0
komma = komma or "."

local strNumber = Explode("%.", tostring(number))
strNumber[2] = strNumber[2] or "0"

if (milsep) then
local revint = strNumber[1]:reverse()
strNumber[1] = ""
for block in revint:gmatch("%d%d%d") do
strNumber[1] = strNumber[1]..block..milsep
end
strNumber[1] = strNumber[1]..revint:sub(-(#revint % 3))
strNumber[1] = strNumber[1]:reverse()
if (#strNumber[1] % 4 == 0) then
strNumber[1] = strNumber[1]:sub(2)
end
end

if (digits > #strNumber[1]) then
strNumber[1] = string.rep("0", digits - #strNumber[1])..strNumber[1]
end

if (decimals == 0) then return strNumber[1] end

if (decimals < #strNumber[2]) then
strNumber[2] = strNumber[2]:sub(1, decimals)
else
strNumber[2] = strNumber[2]..string.rep("0", decimals - #strNumber[2])
end

return strNumber[1]..komma..strNumber[2]
end
```

Greetz, Neon

PS.: All of my Functions may have Bugs. If you finde some, report them in this Thread please.

Edited by Guest

iterator explode2( string str, string separator )

It returns an iterator just like ipairs and pairs. See an example below to see how it works and how to use it.

```function explode2( str, separator )
local start = 1
local ret = nil
return function( )
local s, e = string.find( str, separator, start, true )
if s then
local retrn = string.sub( str, start, s-1 )
start = e + 1
return retrn, start-1, e
else
local retrn = string.sub( str, start, -1 )
if #retrn > 0 then
start = start + #retrn
return retrn
end
return nil
end
end
end
```

Example of usage:

```
for word, s, e in explode2( "hello,from,lua", "," ) do
print( word, s, e )
end

```

the result will be:

```hello    6    6
from     11   11
lua      nil  nil
```

the first variable is a string found between separators or whole string before the separator (in the first call), the 1st number is where the separator was found and the 2nd number is where it ends. You don't have to use those numbers, you can use a simple for loop w/o them like so:

```for word in explode2( "hello,from,lua", "," ) do
print( word )
end
```

Respawn a Destroyed Vehicle Whit timer

```function respawnDetroyedVehicle()
setTimer(respawnVehicle, 4000, 1, source)
end
```

Define a Pickup

```
house = createPickup(-2333.90234375, -1588.9066162109, 483.16543579102,3,1273)

function expedicion(playerSource)
setPlayerSkin(playerSource, 123)
setPlayerMoney (playerSource, 50000)
setPlayerArmor ( playerSource, 20 )
end
```

Edited by Guest

Define a Pickup

```
house = createPickup(-2333.90234375, -1588.9066162109, 483.16543579102,3,1273)

function expedicion(playerSource)
setPlayerSkin(playerSource, 123)
setPlayerMoney (playerSource, 50000)
setPlayerArmor ( playerSource, 20 )
end
```

I can see an error on line 9.

NOTE: Test your code before you post it here!

change

```addEventHandler("onPickupHit", expedicion1, house)
```

to

```addEventHandler("onPickupHit", getRootElement(), house)
```

change
```addEventHandler("onPickupHit", expedicion1, house)
```

to

```addEventHandler("onPickupHit", getRootElement(), house)
```

sorry i change the title of house for translade spanish to english.

i fix the code sorry

NOTE: Who ever used my Explode Function before 27th June 2008 should get the new Version! The old one has a bad Bug! I edited the Explode Function.

I was tired of creating a new Event for every Function I wanted to call from Client to Server or vice versa, so I made a CallClientFunction and CallServerFunction Handler.

You'll have to add this Script server-side:

```function CallClientFunction(client, funcname, ...)
triggerClientEvent(client, "OnServerCallsClientFunction", getRootElement(), funcname, unpack(arg))
end

function CallServerFunction(funcname, ...)
_G[funcname](unpack(arg))
end

```

And this Script must be added client-side:

```function CallClientFunction(funcname, ...)
_G[funcname](unpack(arg))
end

function CallServerFunction(funcname, ...)
triggerServerEvent("OnClientCallsServerFunction", getRootElement(), funcname, unpack(arg))
end

```

Then you can use

void CallClientFunction(element player, string function, [arguments...]) SERVER-SIDE

and

void CallServerFunction(string function, [arguments...]) CLIENT-SIDE

NOTE: Neither CallClientFunction nor CallServerFunction return Anything! This is, no Data is passed by returning something if you use one of these Functions!

And here also the Complement to FormatNumber:

number UnformatNumber(string formattedNumber, string comma, string milsep)

```function UnformatNumber(formattedNumber, comma, milsep)
if (milsep) then
formattedNumber = formattedNumber:gsub(milsep, "")
end
if (comma) then
formattedNumber = formattedNumber:gsub(comma, ".")
end
end
```

This topic need to be sticky!

build_query(queryType, sql_array)

Note: This can only be at the server side system, against security reason's

Code:

```function build_query(queryType, sql_array)
if type(sql_array) ~= "table" then
return false
end

local queryString = ""

if queryType == "INSERT" or queryType == "INSERT_SELECT" then
local keyTable = {}
local valTable = {}

for k, v in pairs(sql_array) do
v = string.format("SHA1('%s')", v)
v = string.format("LOWER('%s')", v)
else
v = string.format("'%s'", v)
end

table.insert(keyTable, k)
table.insert(valTable, v)
end

if queryType == "INSERT" then
queryString = " (" .. table.concat(keyTable, ", ") .. ") VALUES (" .. table.concat(valTable, ", ") .. ") "
elseif queryType == "INSERT_SELECT" then
queryString = " (" .. table.concat(keyTable, ", ") .. ") SELECT " .. table.concat(valTable, ", ") .. " "
end
elseif queryType == "UPDATE" or queryType == "SELECT" then
local valueTable = {}

for k, v in pairs(sql_array) do
v = string.format("SHA1('%s')", v)
v = string.format("LOWER('%s')", v)
else
v = string.format("'%s'", v)
end
table.insert(valueTable, k .. " = " .. v)
end

if queryType == "UPDATE" then
queryString = table.concat(valueTable, ", ")
elseif queryType == "SELECT" then
queryString = table.concat(valueTable, " AND ")
end
end

return queryString
end
```

Example

```data = {
}

query = mysql_query("INSERT_INTO users " .. build_query("INSERT", data)

```

queryTypes:

INSERT

INSERT_SELECT

UPDATE

SELECT

username_clean will be automatically has a LOWER function of mysql.

password will be hashed to SHA1 automatically.

You need the mysql module. You can find it here

Good luck with it.

ConvertXYToRelative

```function ConvertXYToRelative(Resx, Resy, x, y)
local Rx = (1/Resx)*x
local Ry = (1/Resy)*y
return Rx,Ry
end
```

Converts an XY co-ordinate to a relative size requires the resolution you tested it on (you can find it in gta display settings)

example:

```
function ResourceStarted(resource)
if (resource ~= getThisResource()) then
return
end
local x,y = ConvertXYToRelative(800, 600, 400, 300)
outputChatBox("Relative sizes:  "..x..", "..y)
end

```

800x600 is the resolution i run gta on (more fps )

You'll have to add this Script server-side:

```function CallClientFunction(client, funcname, ...)
triggerClientEvent(client, "OnServerCallsClientFunction", getRootElement(), funcname, unpack(arg))
end

function CallServerFunction(funcname, ...)
_G[funcname](unpack(arg))
end

```

And this Script must be added client-side:

```function CallClientFunction(funcname, ...)
_G[funcname](unpack(arg))
end

function CallServerFunction(funcname, ...)
triggerServerEvent("OnClientCallsServerFunction", getRootElement(), funcname, unpack(arg))
end

```

These functions aren't working for me. I get an error:

And that line is:

_G[funcname](unpack(arg))

Alexander de Jong

Did you pass the Function Name as a String?

Syntax

boolean containsText ( string lookingFor, string text )

Required Arguments

* lookingFor: the text you want to look for

* text: the text in which you want to scan if it contains the first argument

Returns true if the second string contains the first string

or

false if you haven't passed an argument or the text doesn't contains the first string.

```function containsText ( lookingFor, text )

if lookingFor and text then
if #lookingFor >= #text then
if lookingFor == text then
return true
else
return false
end
else
for i = 0, #text - #lookingFor + 1 do
local switch = false
for k = 1, #lookingFor do
if string.sub ( text, i+k, i+k ) == string.sub ( lookingFor, k, k ) then
switch = true
else
switch = false
break
end
end
if switch then
return true
end
end
end
else
return false
end
end
```

For e.g. it could be used for a script against insults:

```function insultCheck ( msg )

if containsText ( "asshole", msg ) then
kickPlayer ( source, "Don't insult other people!" )
cancelEvent()
end
end
```

http://lua-users.org/wiki/StringLibraryTutorial

Scroll down a little. Seems like it's pretty much identical.

Syntax

boolean containsText ( string lookingFor, string text )

Uuh.. sorry to piss on your campfire, but..

function containsText(haystack, needle) return string.find(haystack,needle, 1, true) ~= nil; end

Looks like you just wasted some time writing that huge function.

Damn!

But hey, still good for the practise...

Chatcommands - Ccmd

Needs to be tested

- For at most 2 arguments

(Yeah i think there is no need for more than 2 Arguments, most of the Commands only requires 1-2)

Ccmd Table

Syntax Chatcommandname, CommandHandler

```c_cmds = {
"kick", "k_player",
"ban", "b_player"
}
```

Chatchecker

```function c_CommandHandler( message, messageType )
local arg2
if(message == 0)then
nBeginn["c_Start"], nEnd["c_End"] = string.find(message, "!")
if(nBeginn["c_Start"] ~= false and nBeginn["c_Start"] == 1)then
message = string.lower(message) -- for accepting chatcommands like /KIcK or /kICK
if(string.len(string.sub(message, 2)) > 0)then
l_pos = 1
for key, c_cmd in pairs(c_cmds), 2 do
nBeginn["c_Arg"] = string.sub(message, 2, #c_cmds[l_pos]+2)
-- Word Symbols
arg2 = #c_cmd[l_pos]+3 -- +1 next arg tab
l_pos=l_pos+2
if(nBeginn["c_Arg"] == c_cmd)then
--c_cmd[l_pos+1]
l_pos=l_pos-1
local c_Playa = getElementsByType( "player" )
for theKey, c_Target in ipairs(c_Playa) do
nBeginn["c_Target"], nEnd["c_Target"] = string.find(message, c_Target)
if(nBeginn["c_Target"] == arg2 and nEnd["c_Target"] == #getPlayerName(c_Target)+arg2)then
if(c_Target ~= source)then
executeCommandHandler ( c_cmds[l_pos], source, c_Target )
else
return outputChatBox("* You are targeting yourself, Retard!", source)
end
else
end
break -- playerloop
end
break -- arg1 loop
else
return outputChatBox("* Command !"..nBeginn["c_Arg"].." not found in tha Resource \"{SMILIES_PATH}/icon_surprised.gif\" alt=\"\" title=\"Surprised\" />", source)
end
end
end
end
end
end
```

Called Handler

```function kickPlayerHandler ( sourcePlayer, commandname, kickedname )
local kicked = getPlayerFromNick ( kickedname )
if ( hasObjectPermissionTo ( sourcePlayer, "function.kickPlayer" ) ) then
kickPlayer ( kicked, sourcePlayer )
end
end

function banPlayerCommand ( sourcePlayer, commandName, bannedName )
if ( hasObjectPermissionTo ( sourcePlayer, "function.banPlayer" ) ) then
local bannedPlayer = getPlayerFromNick ( bannedName )
banPlayer ( bannedPlayer, sourcePlayer )
outputChatBox ( "ban: " .. bannedName .. " successfully banned", sourcePlayer )
else
outputChatBox ( "ban: You don't have enough permissions", sourcePlayer )
end

end
```

what is outputChatBox("* Command !"..nBeginn["c_Arg"].." not found in tha Resource :o", source)

what is outputChatBox("* Command !"..nBeginn["c_Arg"].." not found in tha Resource :o", source)

```<!-- s:o --><img src=\"{SMILIES_PATH}/icon_surprised.gif\" alt=\":o\" title=\"Surprised\" /><!-- s:o -->
```

This is phpBB that things he is smart by parsing smillies in the code tags .

*facepalm fucking smileys

These are useful, they may be better placed on the wiki somewhere, though I'm not sure where. You could create a page or category for them. They're probably a bit too 'off topic' to be examples... Good job