Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Addlibs last won the day on April 14

Addlibs had the most liked content!



  • Location
    United Kingdom
  • Occupation
    Scripting Guru

Recent Profile Visitors

4,216 profile views

Addlibs's Achievements



  1. Every onClientGUIClick event handler's attachment needs propagate set to false: addEventHandler("onClientGUIClick", theButton, function() -- ... end, false -- add a false after the function's end (4th argument of addEventHandler) ) Otherwise the event is attached to the given element's/button's element tree, meaning the event being triggered on any child element or parent element will trigger the handler, which is not what you want with GUIs. The other workaround is, in each function, adding an if-block with condition checking the event's source (this isn't the most efficient though, since the function will still be called unnecessarily, just that it won't do anything. addEventHandler("onClientGUIClick", theButton, function() if source == theButton then -- verify the event's source is the button you attached this function to -- do whatever the function does end end)
  2. if vehType == "Automobile" or "Monster Truck" or "Quad" or "Bike" then evaluates as true because "Monster Truck" evaluates true because meaning it isn't false or nil, "Quad" and "Bike" are likewise evaluated as such. What you probably intended was if vehType == "Automobile" or vehType == "Monster Truck" or vehType == "Quad" or vehType == "Bike" then
  3. Can you also check your mta/logs/clientscript.log file for warnings or errors in your script at the time of crash? Changing getRootElement() to root is mostly a stylistic change, doesn't really impact the functionality of the code at all, except saving you a couple calls. Regarding this code, this code contains a potential vulnerability: Seems like source and player are referring to the same thing? Perhaps it'd be best to assert (i.e. assert(source == player, "Source and player mismatch") -- this will print out the second argument in the debug box if the first argument's evaluation is false) that they are equal, or only use one of these variables. It seems like whoever triggers this event can cause a player's to be teleported but not receive the createCharacter event, perhaps by mistake in your code or by a hacked client sending off maliciously crafted events with a source mismatching the player argument. Regarding your initial issue: Is the createCharacter event triggered anywhere else, and how is the event responsible for callCharacterCreation triggered? A minor correction to my previous statement: I actually tested this and it turns out I was slightly wrong - addEventHandler does not let you register the same function with the same event multiple times, but if its attempted, it prints an error in the debug box (and log), so your render function probably not being called multiple times per frame as I've suggested previously.
  4. How is createCharacter triggered? I think I might see the problem. Do you have a lot of elements spawned (vehicles, peds, objects, etc. even if they're out of the streaming range)? It seems your handler function for createCharacter is attached to the root element and all its children. If you trigger it on the root element, rather than, for example, the target's player element, then what actually happens is the same event is dispatched on each element with the given element as its source, and your handler is attached to be called on any child of root, in other words, your handler gets executed as many times as there are elements. In other words, if you have n elements in the element tree, your handler attaches an new event handler for onClientRender n times! Your createCharacterPanel function gets called n times per frame, or 60n times for a client running 60 fps. A quick fix would be to one of the following: change the triggerClientEvent calls everywhere to use the target player as source (since players rarely have any child elements, the event gets dispatched only once per trigger) (likely the best option here), OR add the fourth argument to addEventHandler for createCharacter set to false, to make the handler only get called for the root element and not its children (less preferable; however you should add that to the onClientRender handler attachment regardless), and/or add an if check in the handler to verify that source == getRootElement() (least preferable option as it means your function still gets called tens or hundreds of times only to exit early when you could avoid calling it at all in those circumstances) Doing options 1 and option 2 and/or 3 at the same time will break functionality, as you'll call with a player as source but the function will expect root and only root, disallowing its children (and the player is a child element of root)
  5. By crash do you mean the MTA client crashes, or are you saying your script "crashes" (i.e. stops working?) If it's an MTA client crash, perhaps you're doing something you're not supposed to be doing in the onClientRender handler function. Apart of dx calls, what other functions do you call within createCharacterPanel? Any create* functions in there? All create* functions outlast a frame and its possible you're spawning so many of them you cause a crash due to loading/streaming, or run out of memory. Perhaps its the setCameraMatrix? Does your client ever crash when suddenly streaming in a different part of the map? Does it happen on different computers or only for you?
  6. The error is telling you that mysql_ping function is not defined. Either this script wasn't written for MTA, or it was written to be used with a server module (modules allow server-side Lua to call functions implemented in C or C++). This code in particular appears to want to handle a MySQL connection; this is very deprecated way of doing things as MTA has built-in support for SQLite and MySQL connections though the dbConnect and other db* functions. To fix your issue, you either need to find the module for which this code was written (not recommended, MySQL modules are old and outdated nowadays), or redesign the code to use MTA's built-in db* functions.
  7. Have you tried attachElements?
  8. Actually, code_descriptions is neither a string nor a number, it is an array type. Meaning if you want to print its string, you need to add [1] to the variable that holds the array, to get the first (and only) value in that array, or use a for each loop to iterate over all strings in that array if there can conceivably be more than one in the actual data. tonumber on a string that does not contain a correctly formed number returns nil, which is the case in your original code; also I'm pretty sure fromJSON takes care of returning numbers correctly from a JSON where they're written as number literals rather than strings, so you shouldn't need to use tonumber unless your input data sometimes returns the number within a string.
  9. No need to disable the HS system if you can modify it, simply add checks like the ones above within the system.
  10. You can either use getTickCount() which counts milliseconds since the client/server started, or you can use setTimer to manually increment a variable until it reaches your desired value. getTickCount requires a tiny bit of basic math, but ultimately more efficient than a creating timer.
  11. You can augment the original weapon system if you replace original weapons with empty meshes and attach custom objects to player hands, however, this won't give you new IDs on its own and you'll need to code in a system to refer to and switch between these weapons yourself.
  12. Have you checked using toggleBrowserDevTools DOM inspector whether the JS executes correctly and updates the DOM, that is, whether the element #orghomelogo's src parameter is indeed what you expect it to be?
  13. You need to base64Encode the output of dxGetTexturePixels(texture) not just texture itself, and you need to prepend "data:image/png;base64," to the encoded base64 if you want it to be interpreted as raw data rather than a URL.
  14. You're missing libssl.so in your shared libraries path (typically /usr/local/lib, /usr/local/lib64, /usr/lib and/or /usr/lib64), which is required by dbconmy.so (the shared library responsible for database functionality in MTA). You might be missing the packages openssl-1.1 and openssl-solibs-1.1. If you are your system administrator, you should be able to easily add these packages using apt-get or yum depending on your distro; if you don't know how to do that you can find tons of information about installing packages on Linux on Google. If you don't have access to the root user and/or sudo, you might need to get in contact with your system administrator or service provider and ask them for assistance.
  15. You don't seem to be using the result of local check = exports.mysql:mysql_query_single("SELECT * FROM `players` WHERE `login` = ?", login) anywhere in the snippet, you might want to move it closer to where you use it for more readability, and either way, its not relevant to this snippet so it could have been omitted. Now if you want to do a case insensitive comparison between people's logins, your best bet is to lowercase or uppercase both sides of the comparison, or ensure one of the sides is always lowercase/uppercase and case fold the other side: -- turn both sides to lowercase if(string.lower(getElementData(p, "login")) == string.lower(login)) then -- ... end -- or -- lowercase the user input local lowercaseLogin = string.lower(login) for _, p in --[[...]] do if(getElementData(p, "login") == lowercaseLogin) then -- compare stored -- ... end end --- ... -- ensure the login value in element data is always stored in lowercase setElementData(p, "login", lowercaseLogin) The second option is slightly more efficient since you only need to lowercase it once per player when logging in, rather than for every player when one player logs in, essentially a O(1) vs O(n) difference.
  • Create New...