Page 1 of 1

game.raise_event() is not protected from invalid entities.

Posted: Thu May 19, 2016 12:11 am
by Adil
I remember Rsending(?) saying in the modding section that the game is capable of catching the situation, when one mod destroys entity passed to event handler.
I've kinda broke that... :oops:
If the event is raised not by the game but through script at the worst case you can get the following mysterious thing:
Screenshot
I've uploaded archive with three mods that do that together and the save set up for test.
If you place stone furnace in that save, handlers from all three mods will print stuff to the screen.
If you place steel furnace, it will be destroyed by second handler and third one won't be called.
If you place turret - it will be destroyed by TurretRangeOnBuild mod, which will then create another dummy-turret and raise event with that one through game.raise_event() function, that dummy-turret will be destroyed by the ElectrifiedTurrets mod and here's where it breaks apart: on_entity_built event continues to handled with now invalid entity.

The mods are not reduced to relevant code but in TurretRangeOnBuild relevant lines are 27 - 50, in ElectrifiedTurrets - 31 - 53 and in WrenchFu - 11 - 16 (all in control.lua).
Weird thing is that if you comment out line 30 in TurretRangeOnBuild, that handles the error in that mod, then you'll get a proper backtrace.

Re: game.raise_event() is not protected from invalid entities.

Posted: Sat May 21, 2016 4:18 am
by Rseding91
That is protected from invalid entities - if it wasn't you'd get a crash instead of the error :)

There's not much that can be done with this - the system firing the requested event doesn't know what it should/shouldn't check against to be valid. It's just copying lua between mods and firing the event handlers.

Re: game.raise_event() is not protected from invalid entities.

Posted: Sat May 21, 2016 3:39 pm
by Adil
Well, it still takes the event identifier. It might at least check standard events.

It is possible to detect whether the variable points to userdata. The mods can't have their own userdata, can they? It seems reasonable assumption that no one expects a reference to invalid game object.

At the very least, modder himself could provide a function to verify whether the event should be given to the next handler in line, if the api would take that.
For current case, like:

Code: Select all

local event={entity=entity}
local verify = function(e) 
    return e.entity and e.entity.valid 
end
game.raise_event(event_name,event, verify)
Also, that's not an ordinary error still. pcall() is usually capable of nomming on standard errors but not on this one.

Unrelatedly, if the handler modifies the event given to it, will this change propagate to a next handler?

Re: game.raise_event() is not protected from invalid entities.

Posted: Wed Sep 21, 2016 6:27 pm
by aubergine18
Is this now fixed from 0.14.4? see: viewtopic.php?t=32039