NeonBlack Posted May 24, 2008 Share Posted May 24, 2008 (edited) 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. I'll start with three useful functions concerning Date and Time. 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 May 30, 2008 by Guest Link to comment
NeonBlack Posted May 24, 2008 Author Share Posted May 24, 2008 (edited) 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. I'll start with three useful functions concerning Date and Time. 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 May 30, 2008 by Guest Link to comment
eAi Posted May 24, 2008 Share Posted May 24, 2008 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 Link to comment
eAi Posted May 24, 2008 Share Posted May 24, 2008 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 Link to comment
NeonBlack Posted May 30, 2008 Author Share Posted May 30, 2008 (edited) 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 June 27, 2008 by Guest Link to comment
50p Posted June 14, 2008 Share Posted June 14, 2008 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 Link to comment
capitanazop Posted June 14, 2008 Share Posted June 14, 2008 (edited) Respawn a Destroyed Vehicle Whit timer function respawnDetroyedVehicle() setTimer(respawnVehicle, 4000, 1, source) end addEventHandler("onVehicleExplode", getRootElement(), respawnDetroyedVehicle) 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 addEventHandler("onPickupHit", expedicion, house) Edited June 14, 2008 by Guest Link to comment
50p Posted June 14, 2008 Share Posted June 14, 2008 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 addEventHandler("onPickupHit", expedicion1, house) I can see an error on line 9. NOTE: Test your code before you post it here! Link to comment
Gothem Posted June 14, 2008 Share Posted June 14, 2008 change addEventHandler("onPickupHit", expedicion1, house) to addEventHandler("onPickupHit", getRootElement(), house) Link to comment
50p Posted June 14, 2008 Share Posted June 14, 2008 change addEventHandler("onPickupHit", expedicion1, house) to addEventHandler("onPickupHit", getRootElement(), house) Your code it wrong too. Read wiki. Link to comment
capitanazop Posted June 14, 2008 Share Posted June 14, 2008 sorry i change the title of house for translade spanish to english. i fix the code sorry Link to comment
NeonBlack Posted June 27, 2008 Author Share Posted June 27, 2008 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 addEvent("OnClientCallsServerFunction", true) addEventHandler("OnClientCallsServerFunction", getRootElement(), CallServerFunction) 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 addEvent("OnServerCallsClientFunction", true) addEventHandler("OnServerCallsClientFunction", getRootElement(), CallClientFunction) 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 return tonumber(formattedNumber) end Link to comment
DutchCaffeine Posted June 28, 2008 Share Posted June 28, 2008 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 if k == "password" then v = string.format("SHA1('%s')", v) elseif k == "username_clean" then 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 if k == "password" then v = string.format("SHA1('%s')", v) elseif k == "username_clean" then 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 = { username = "Alexander", username_clean = "Alexander", password = "alexATmta" } 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. Link to comment
Cazomino05 Posted June 29, 2008 Share Posted June 29, 2008 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 addEventHandler("onResourceStart", getRootElement(), ResourceStarted) 800x600 is the resolution i run gta on (more fps ) Link to comment
DutchCaffeine Posted June 30, 2008 Share Posted June 30, 2008 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 addEvent("OnClientCallsServerFunction", true) addEventHandler("OnClientCallsServerFunction", getRootElement(), CallServerFunction) 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 addEvent("OnServerCallsClientFunction", true) addEventHandler("OnServerCallsClientFunction", getRootElement(), CallClientFunction) These functions aren't working for me. I get an error: INFO: Loading script failed: D:/mtaservers/lf/mods/deathmatch/resources/lexlife/server/core/utils.lua:6: '' expected near 'in' And that line is: _G[funcname](unpack(arg)) Alexander de Jong Link to comment
NeonBlack Posted July 6, 2008 Author Share Posted July 6, 2008 Did you pass the Function Name as a String? Link to comment
JackZipper Posted March 20, 2010 Share Posted March 20, 2010 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 addEventHandler( "onPlayerChat", getRootElement(), insultCheck ) Link to comment
Gamesnert Posted March 20, 2010 Share Posted March 20, 2010 What about string.find? http://lua-users.org/wiki/StringLibraryTutorial Scroll down a little. Seems like it's pretty much identical. Link to comment
robhol Posted March 20, 2010 Share Posted March 20, 2010 Syntaxboolean 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. Link to comment
JackZipper Posted March 20, 2010 Share Posted March 20, 2010 Damn! But hey, still good for the practise... Link to comment
Jason_Gregory Posted March 22, 2010 Share Posted March 22, 2010 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 return outputChatBox("* Player "..string.sub(message,arg2).." not found!", source) 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 addEventHandler( "onPlayerChat", getRootElement(), c_CommandHandler) Called Handler function kickPlayerHandler ( sourcePlayer, commandname, kickedname ) local kicked = getPlayerFromNick ( kickedname ) if ( hasObjectPermissionTo ( sourcePlayer, "function.kickPlayer" ) ) then kickPlayer ( kicked, sourcePlayer ) end end addCommandHandler ( "k_player", kickPlayerHandler ) 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 addCommandHandler ( "b_player", banPlayerCommand ) Link to comment
karlis Posted March 22, 2010 Share Posted March 22, 2010 what is outputChatBox("* Command !"..nBeginn["c_Arg"].." not found in tha Resource :o", source) Link to comment
DutchCaffeine Posted March 22, 2010 Share Posted March 22, 2010 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 . Link to comment
Jason_Gregory Posted March 23, 2010 Share Posted March 23, 2010 *facepalm fucking smileys Link to comment
Chusmadones Posted July 14, 2010 Share Posted July 14, 2010 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 https://wiki.multitheftauto.com/wiki/Cod ... ts_General Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now