-
Posts
6,058 -
Joined
-
Last visited
-
Days Won
208
Everything posted by IIYAMA
-
And what does this output? console.log("Parsed leaderboard data:", leaderboardStats, typeof(leaderboardStats));
-
And if you do not modify the JSON? (and use backticks) local testJSON = toJSON(leaderboardData) if isElement(initBrowser) then local script = string.format("populateLeaderboard(`%s`);", testJSON) outputChatBox("SCRIPT : " ..script) executeBrowserJavascript(theBrowser, script) end const leaderboardStats = JSON.parse(leaderboardDataJSON); console.log("Parsed leaderboard data:", leaderboardStats);
-
Additional context: Serverside is code executed on the server. The application all players are connected to. Clientside is code executed on each client/player his game. There are as many clientsides as there are players in the server. They all run a copy of all clientside scripts. Each player downloads the clientside code from the server. When a player joins the server, in most cases the copy of the code will only run until the download is finished. (with an exception if priority is given to a specific resource) Shared is code executed On the server And a copy of the code is executed on each client / player his game Nothing is shared between them, except for running the same copy of the code.
-
It looks like you got some unparsed JSON in your JSON result. console.log(typeof(leaderboardStats)) // If type is object: const result = JSON.parse(leaderboardStats[0]) // or if the type is a string: const result = JSON.parse(leaderboardStats) To make things a bit easier, use back-ticks so you do not have to escape your own JSON: local script = string.format("populateLeaderboard(`%s`);", escapedTestJSON)
-
Which debug lines are being called in the browser? (if any) Use the following function to open the dev tools and check which ones are visible: https://wiki.multitheftauto.com/wiki/ToggleBrowserDevTools
-
Are you sure those newlines are correct? As far as I can remember the following is considered a newline in Lua: \n Or auto newlines: local test = [[ newline newline newline newline ]] But I can be mistaken, maybe MySQL also accepts your way. Also make sure multi_statements is enabled, see: https://wiki.multitheftauto.com/wiki/DbConnect
-
@Perseus It looks like a latency issue or bullet sync is not enabled. Also, what is your server FPS? The bullets here are behind the player, see screenshots. You could also try to freeze the player with this function: https://wiki.multitheftauto.com/wiki/SetElementFrozen And shoot from the side while running, that way you can verify if it is 1 issue or 2 issues.
-
What if you switch roles and film the one that gets hit? That way you can verify if it is a bug. Also: Double check if bullet sync is active. It is indeed possible to override the bullet/damage system, but lag compensation is very complex and often result in unexpected results.
-
What is the ping of the other player? It is normal to compensate your aim for latency, when the damage is registered clientside. You should aim at the location where the player is moving to. The higher the ping. the more you need to compensate. If you shoot a player in the back/front, latency matters less, it just delays the inevitable. Having 0 recoil makes the latency issue even worse, because the spread normally makes sure that at least some bullets hit. I recommend to put the recoil not to 0. It is fine to put it very low, but if you put it to 0, some calculations might be miscalculated. Increasing the interval does reduce some of the extra latency. To be specific from 100 > 50 could potential update the player position 50ms faster. But that is only the case with a stable internet connection. In case of an unstable internet connection, it might even increase latency when the network is being blocked by too many unreceived position updates.
-
This function is able to mimic that behaviour you just mentioned. Just be aware. It might be worthed to look in to it and test if it has any impact if any of those are restarted. Also double check if the remote access is disabled for all of them. (2e argument of addEvent)
-
Are you using addDebugHook function somewhere in your resources? Also the addEvent function should also be called at the resource where addEventHandler is being used.
-
If: clientside only without local files It might be possible with: fetchRemote + requestBrowserDomains But only very small images because of JSON limitations. fetchRemote only accepts JSON format. I do not recommend this method unless it is only for small avatars. You also need an webserver/host where you save the images in JSON format and send it to the client.
-
There is not really a non expensive way except for the debughook, which is CPU expensive to use. From my perspective, the more complex you make this threshold mechanism, the faster your server will be downed. For sensitive events attached to for example a database, you want to have some kind of firewall, for example: checkPassiveTimer (utility with clean-up)
-
if x and y and z and world and dimension and rotation then local player = client -- < HERE setElementData(player, "player.activeMarker", false) Make `player` a local variable. Else all players will share the variable `player` for the (delayed) timer functions. You can also pass the predefined `client` variable like this: setTimer(function (player) end, 1500, 1, client)
- 1 reply
-
- 1
-
When saving the userdata of an element inside of a variable and delete the element afterwards, it's userdata type becomes generic/something else. This might also be the case for accounts. https://wiki.multitheftauto.com/wiki/GetUserdataType
-
Purrrrfect!
-
It depends on the amount of players and the server. 10 players should be fine. More players? It is fine to save the the current km's inside of the memory. But writing it immediately to the database will definitely be a waste of performance, that can be spend else were.
-
For example trigger every 10 seconds a latent event. Those last <10 seconds do not really matter. You want to balance performance and accuracy. To reduce server load and less db crash exploit able: Save it inside of the memory and write every 10/X minutes updates to the database. + onResourceStop
-
Multiple reasons onClientPlayerQuit is for remote players only. (Other players than yourself) Currently when another player leaves, the stats of all other players are being saved, except yours. When you quit the game, the client code on your system will stop. Not sure if there is enough time to send data on onClientResourceStop + resourceRoot. But I wouldn't rely on it. Using a timer to delay sending data, makes things really impossible. Other issues: onClientPlayerWasted should be attached to the localPlayer, not the root element. Else it also triggers for remote players. addEventHandler("onClientPlayerWasted", localPlayer, onPlayerWasted) The source from remote events can't be trusted, use the predefined variable client instead: if not exports.login:isPlayerLoggedIn(client) then return end exports.login:updatePlayerStat(client, "stat", "stat", data)
-
No, not through config files. Only resources might be able to do this.
-
How about screenSource? Here a few lines of code I copied out of my smartphone remote control app. I can vaguely remember that there were some limits I ran in to, which is why the resolution is so low. But not sure which component was affected by it -> probably the JSON format by callRemote. I probably should have used fetchRemote instead, but didn't know better at that time. Client myScreenSource = dxCreateScreenSource( 640 / 2, 480 / 2 ) --- ... dxUpdateScreenSource( myScreenSource ) local pixels = dxGetTexturePixels( myScreenSource ) local jpegPixels = dxConvertPixels( pixels, 'jpeg', 20 ) triggerServerEvent( "screen-stream", localPlayer, jpegPixels ) --- ... Server addEvent( "screen-stream", true ) addEventHandler( "screen-stream", root, function( jpegPixels ) callRemote( "http://127.0.0.1:3134/stream", result, base64Encode( jpegPixels ) ) -- end ) App http.createServer(function (req, res) { if (req.url == "/stream") { const chunks = []; req.on('data', chunk => chunks.push(chunk)); req.on('end', () => { const data = JSON.parse(Buffer.concat(chunks).toString('utf8')); if (data != undefined && data[0] != undefined) { // I used socket IO to send the screenshots to my Phone // io.emit('broadcast', data[0].toString('base64')); // base64 image: "data:image/jpeg;base64," + data[0].toString('base64') } }) } res.end(); }).listen(3134, "127.0.0.1"); Web browser: const image = new Image(2560, 1440); // Socket IO socket.on("broadcast", data => { image.src = "data:image/jpeg;base64," + data // Replace an image with my screen });
-
Did you know that the definition file counts up to a whopping 1364 unique functions? While the actual value might be higher or lower (missing, unknown, class/OOP or deprecated functions). Having this amount of functions in MTA is an incredible accomplish by this community. Some other statistics: 125 client unique events 88 server unique events
- 15 replies
-
- 1
-
- lua
- lua language server
- (and 13 more)
-
Downloads are not always done in a straight line. They are bound to resources. Even if the client finished downloading, a new resource can be started by the server admin. Clientside: Downloads are often busy when the transferbox is visible. https://wiki.multitheftauto.com/wiki/IsTransferBoxVisible According to the wiki, it is possible to forcefully show the transferbox at all times. But I doubt anybody would be willing to create a worse experience for themselves. https://wiki.multitheftauto.com/wiki/IsTransferBoxAlwaysVisible Serverside: Downloads often start at https://wiki.multitheftauto.com/wiki/OnPlayerJoin And end for each resource at: https://wiki.multitheftauto.com/wiki/OnPlayerResourceStart
-
The code is ran single threaded so it doesn't really matter, it is not as if the CPU is doing nothing during that delay. Trigger events will move the execution to the next (server) frame, it is just delayed. Why that extra overhead? (for events and exports) Another environment has to be accessed. The data arguments/parameters have to be cloned. If tables are passed I can imagine that will be even slower. Here are some performance browser details + examples. Results will probably be different on your system. I expected the events to be much worse, but that doesn't really seems to be the case. Might be because exports do also return values back to the original caller. (for better or worse) function exportMe(a, b, c) end local thisResource = getThisResource() setTimer(function() for i = 1, 10000, 1 do call(thisResource, "exportMe", "a", "b", "c") end end, 50, 0) Export: 58% > 60% CPU function exportMe(a, b, c) end addEvent("blabla", true) addEventHandler("blabla", resourceRoot, exportMe) setTimer(function() for i = 1, 10000, 1 do triggerEvent("blabla", resourceRoot, "a", "b", "c") end end, 50, 0) Event: 62% > 64% CPU Context: This resourceRoot has no extra elements. function exportMe(a, b, c) end addEvent("blabla", true) addEventHandler("blabla", resourceRoot, exportMe) -- 400 extra children for i = 1, 400, 1 do createElement("test") end setTimer(function() for i = 1, 10000, 1 do triggerEvent("blabla", resourceRoot, "a", "b", "c") end end, 50, 0) Event: 67 > 68% CPU Context: Source element with 400 extra children
-
I would also go for the suggestion @FernandoMTA made, but with the syntax that works for you. If possible move some of the events that are triggered on the same side (client/server) to export functions. Serverside function customOutputChatBox () -- export function -- Add rate limit here for each player -- Show message end How to create/call export functions? Clientside (if available) If you use remote access. function customOutputChatBox () -- export function -- Add rate limit here, protecting the server from spam triggerServerEvent(...) end