Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Addlibs

  1. You could use getRealTime to get the current timestamp, calculate the seconds remaining until the next scheduled time point (which you can calculate with getTimestamp), and setTimer for the many milliseconds.
  2. It's also important to note the server script usually starts before the client script is ready (especially when the client needs to download the scripts and files), meaning an client-bound event dispatched on onResourceStart can turn up ignored for not being added client-side (as the client script isn't running yet). Best way to correct that is have the client send an event to the server when it is ready (i.e. when the resource starts client-side, after all necessary downloads -- onClientResourceStart), and the server's event handler for that event to triggerClientEvent back.
  3. You cannot directly send an SMS using MTA. However, you can use fetchRemote to communicate with external web APIs such as SMS texting services. These services are typically not free, however. You can send emails with one-time passcodes for free if you already have an HTTP server, using PHP's mail() function for example, or a full SMTP server if you have one. These would be triggered by making a request to a particular webpage/server (that is, fetching/requesting the remote page), which can be done though the aforementioned fetchRemote function.
  4. 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)
  5. 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
  6. 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.
  7. 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)
  8. 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?
  9. 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.
  10. Have you tried attachElements?
  11. 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.
  12. No need to disable the HS system if you can modify it, simply add checks like the ones above within the system.
  13. 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.
  14. 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.
  15. 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?
  16. 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.
  17. 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.
  18. 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.
  19. local arg1Colors = { ["pink"] = pink_1, ["blue"] = blue_1, ["yellow"] = yellow_1, ["red"] = red_1 } local arg2Colors = { ["pink"] = pink, ["blue"] = blue, ["yellow"] = yellow, ["red"] = red } local arg3Colors = { ["pink"] = pink_2, ["blue"] = blue_2, ["yellow"] = yellow_2, ["red"] = red_2 } function getColorToImage(arg1, arg2, arg3) -- dont check anything if arg1 is nil if (not arg1) then return false end -- return with nil-coalescing 'or' functionality in order of arg2, then arg1 and lastly arg3 return arg2Colors[arg2] or arg1Colors[arg1] or arg3Colors[arg3] or nil end This is one way of simplifying the function, a tiny bit more readable and maintainable, but still unfortunately cryptic with these argument names.
  20. Addlibs


    You cannot hide players from the MTA server browser player list, but you could disguise all players with non-identifying nicknames but use more identifiable nicknames in chat messages, etc. If you want to hide yourself from the ingame scoreboard (the one you get when holding tab), you can modify the scoreboard resource, or whichever resource you use for scoreboards if you have a custom one, to hide the rows of “hidden” players
  21. Addlibs

    HTML script

    HTML is not a "script" language, but you can use HTML on the client-side for user interface / rendering through Lua and the CEF browser functions.
  22. Additionally, it seems Chassi is suposed to be unique, yet the database contains the following duplicates: ID,Conta,Vehiculo,Chassi 379,fynkffx,Mercedes AMG 63,6762 483,mercenario,Impala 1967,6762 665,Kryvios,GTR R35,31969 666,CireloPlay,GTR R35,31969 279,Nirvana,Civic Type R,61810 667,Gabriel665,Civic Type R,61810 244,Nirvana,Nissan GTR,77690 337,relmen,GTR R35,77690 513,NINJATV22,Audi R8,83450 646,michael,Shineray,83450 Some of these duplicates appear to be the same vehicle, others not. You should probably mark the column as UNIQUE in the database to prevent this from being allowed by the database. Also, this is the wrong way to do what you're setting out to do local sucess = dbExec(database, "DELETE FROM playersConce WHERE Model = ? AND Chassi = ?", tonumber(model), qChassi) local sucess1 = dbExec(database, "INSERT INTO playersConce (Conta,Model,Veiculo,Chassi) VALUES (?,?,?,?)", getAccountName(getPlayerAccount(pID)), tonumber(model), Config.VEICULOS.CARROS.nome, Chassi) What you probably want is local sucess = dbExec(database, "UPDATE playersConce SET Conta = ? WHERE Chassi = ?", getAccountName(getPlayerAccount(pID)), qChassi) which changes the vehicle's owner by modifying the row, instead of deleting the old one and inserting a new one.
  23. A screenshot of /debugscript 3 when attempting to sell a vehicle would be a good start.
  24. I don't need the whole file, I need the debug script logs, to see which debug statements (iprint) get printed.
  25. Could you put the code into code tags please? Also, I see a number of iprints, can you share the debugscript log as well? Does dxMsg(player, "Você vendeu seu veículo com sucesso.", "success") dxMsg(pID, "Você recebeu um veículo.", "success") ever get executed? What is this supposed to do, and why? local query = dbPoll(dbQuery(database, "SELECT * FROM playersConce WHERE Model = ?", tonumber(model)), -1) It appears to check if there are any vehicles in the database of that model ID, but it feels redundant to check, if you could later go on to check if query["Chassi"] == getElementData(vehicleConces[player], "Yammy.vehicleBank") then local Chassi = query["Chassi"] local query_02 = dbPoll(dbQuery(database, "SELECT * FROM playersConce WHERE Model = ? AND Chassi = ?", tonumber(model), query["Chassi"]), -1) This could be shortened to just one query, similar to the latter one, but in place of query["Chassi"] it would just be getElementdata(vehicleConces[player], "Yammy.vehicleBank") The way your current code is structured is to execute a SELECT statement checking Model and Chassi for every record in playersConce where Model is tonumber(model). This means if you have 3000 records with model = 429 (Banshee), your code executes 3000 searches, x, for matching Model = 429 and Chassi = x["Chassi"] = getElementData(vehicleConces[player], "Yammy.vehicleBank")), where just one would suffice: SELECT search for Model = 429 and Chassi = getElementData(vehicleConces[player], "Yammy.vehicleBank")
  • Create New...