Jump to content

Script optimization? (Avoid crash)


Recommended Posts

Well, I've been trying to solve this problem time ago but nothing seems to work. When I was testing my new "login-system" I started to reconnect while the script was running and it crashed in the "Character creation", it always happen at that part, it never crashes at the login, register, or selection part, just when the player creates a character. 

I still can't figure out what it's causing this crash, basically all that part it's on Client-Side with dxDraw as panels :/ I'm not even geting element data or something like this, take a look at the code:


addEvent("createCharacter", true)
addEventHandler("createCharacter", getRootElement(), function()
	setCameraMatrix(206.72476196289,-36.323947906494,1001.8046875, 209.75735473633,-33.699203491211,1001.9296875)
	addEventHandler("onClientRender", getRootElement(), createCharacterPanel)
	createCharacterButtons()
end
)

--The rest it's the panel, I removed it, and the problem it's still happening so...

 

Link to comment

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?

Edited by Addlibs
Link to comment

When my MTA crashes, a new window shows up and give me information about the crash (some codes like 0x0c005, i don't remember at all).

There is no other function inside "createCharacterPanel", just dxDraw.

And this doesn't happen randomly when the player enter into the "character creation", it only happens when the player reconnect

 

Link to comment

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)

Edited by Addlibs
  • Like 1
Link to comment
--Server Side--
function callCharacterCreation(player, slot)
	setElementPosition(player, 209.75735473633,-33.699203491211,1001.9296875)
	setElementRotation(player, -0, 0, 137.15386962891)
	triggerClientEvent(source, "createCharacter", source, slot)
end

This is what the server-side trigger looks like. ^

I changed all the "getRootElement" to "root" but the problem it's still happening.

This is what the error msg says:

Version = 1.5.9-release-21210.0.000
Time = --
Module = D:\Multi Theft Auto\mta\multiplayer_sa.dll
Code = 0xC0000005
Offset = 0x000026CB

 

Link to comment

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:

12 hours ago, Cronoss said:
function callCharacterCreation(player, slot)
	setElementPosition(player, 209.75735473633,-33.699203491211,1001.9296875)
	setElementRotation(player, -0, 0, 137.15386962891)
	triggerClientEvent(source, "createCharacter", source, slot)
end

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:

16 hours ago, Addlibs said:

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.

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.

Link to comment
Quote

Is the createCharacter event triggered anywhere else

The event is triggered once, inside the function "callCharacterCreation".

Quote

and how is the event responsible for callCharacterCreation triggered?

This is where it is called:

addEvent("selectionSlot", true)
addEventHandler("selectionSlot", getRootElement(), function(player, selected, characterName, characterName2, characterName3)
	if selected == 1 then
    	if characterName ~= "" then --If the character's name it's not empty then...
        	--Removes the unnecesary element data
			local slot = 1 --Unnecesary 
			callCharacterCreation(player, slot) --Triggers the function
		else
        	--Removes the unnecesary element data
        end
	end
  
--This function continues like that till the third slot
--I noticed that I might use "selected" instead of creating a new variable called slot but I don't think that's the problem
--And yes, I'm removing element data in every conditional part in the function because of; it's information that it's only necesary for the selection panel, after that, I don't need it

 

Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...