Rework Event Handling
Pheotis opened this issue ยท 8 comments
Currently, there are a bunch of problems with events.
These will need to be ironed out to account for add-on requirements.
Background
All Stargate events can be cancelled, which means that after calling an event, we must always check if the event has been cancelled, and abort if it has.
The deny methods allow add-ons to allow actions the player does not have the necessary permissions for, and deny actions the player has the necessary permissions for.
Legacy Stargate events:
StargateAccessEvent
: Triggered when a player is entering or activating a stargate. Can overwrite whether the access should be denied.StargateActivateEvent
: Triggered when a player is activating (right-clicking the sign of) a stargate. Can overwrite the destinations displayed to the player, and overwrite the currently active destination.StargateCloseEvent
: Triggered when a stargate is closed for whatever reason. Can change whether a portal should be forced to close or not.StargateCreateEvent
: Triggered when a Stargate is created. Can be used to change whether the creation should be denied, and can be used to change the cost for creating the Stargate.StargateDeactivateEvent
: Triggered whenever a Stargate is deactivated. Only used to keep track of Stargate de-activation, or cancelling the event for some reason reason.StargateDestroyEvent
: Triggered whenever a Stargate is destroyed by a player. Can change whether the destruction should be denied, and can be used to change the cost of the creation.StargateOpenEvent
: Triggered whenever a Stargate is opened by a player. Can change whether a portal should be forced open or not.StargatePortalEvent
: Triggered whenever a player is teleporting through a portal. Can change the exit location of the teleported player.
Bugs:
StargateAccessEvent
is never called or used
StargateActivateEvent
does not allow add-ons to change the displayed destinations
StargateCloseEvent
is never called or used
StargateCreateEvent
does not use the deny value, which means the event's deny value cannot be overridden
StargateDestroyEvent
does not use the deny value, which means the event's deny value cannot be overridden. The deny reason is also not used, making defining a custom deny reason impossible.
StargateOpenEvent
's getIsForced
value is never checked, making it impossible for an add-on to force a Stargate to open.
StargatePortalEvent
has a bug which makes it impossible to change the exit location. The exit location is never retrieved from the event, making it impossible for add-ons to change the exit location.
Context
This will need to be solved while considering addon requirements.
Although this functionality is not fully recorded, some of the requirements are tracked below:
I propose moving all permission code away from the events, as the permission system is just a more complicated and less powerful version of deny. The deny toggle together with the deny message allows checking for custom permissions and custom conditions such as this example: For factions, you might want to only allow players in the faction to use a Stargate inside claimed land. You obviously also want to tell the player why they cannot use the portal. This is possible using the deny methods, but it's not possible using the related perms stuff. The initial deny value assumes all permission have been checked, so it makes no sense to check permissions after, or in, the events.
All permissions should be checked before calling any stargate event. Then, the deny toggle should be properly used to allow add-ons to deny, override a deny, and setting a deny reason. Any objections?
As the events have never been properly implemented, and implementing them requires a lot of code changes, here's an overview of how events need to be called:
- Access event: On entering/activating a Stargate (All permission/access checks for opening/activation/teleporting should use this event) [Deny reason is not in legacy, but should be availble to allow add-on deny descriptions]
- Activate event: When activating a Stargate (for a player). Called after Access event
- Open event: When (a player is) opening a Stargate. Called after Access event and Activate event
- Portal event: When an entity is about to be teleported. Called after Access event (Possibly: Access->Activate->Open->Access->Portal)
- Close event: When closing a Stargate (regardless of cause)
- Create event: When (a player is) creating a new Stargate
- Deactivate event: When deactivating a Stargate (regardless of cause)
- Destroy event: When a player destroys a Stargate (Should an additional event be created to account for non-player destuction such as TNT or creepers?)
Deniable: Access, Create, Destroy
Cancellable: All
The deniable events are the ones that actually deal with player permissions/access while the rest are more for changing information/cancelling.
As all events are cancellable, they must always be called before any values or data is changed.
Since this issue will involve reworking permissions, going to post all existing permission issues on this thread:
Builder Preset
Users with the builder preset can create gates on the central network, but can not destroy them.
sg.destroy.network.default
Default Permissions - Destroying Portals
Under the current default permission setup, non-op'd users are unable to destroy their own portals.
This is odd as the gatemaker permission preset appears to allow this as intended.
Default Permissions - Creating Portals
Under the current default permission setup, non-op'd users are unable to create their own portals.
This likely has something to do with the sg.create.design.<>
nodes.
This is odd as the gatemaker permission preset appears to allow this as intended.
Going to mention issue #122 on this issue as they both involve events.
Going to hopefully rework events this week.
While the permissions have been disconnected, the events aren't called when they should and how they should. fix-events has commented versions of the events which have been altered with the necessary changes. Though the events have been fixed, the event calls have not. See above for details.
Note: For any deniable event, permissions should be checked first, and the result of the permission check should be given to the event. The deny value when the event is finished decides if the event should proceed or be cancelled.
- StargateAccessEvent
- getDeny
- setDeny
- getDenyReason
- setDenyReason
- getHandlerList
- getHandlers
- StargateActivateEvent
- getDestinations
- setDestinations
- getDestination
- setDestination
- getHandlerList
- getHandlers
- StargateCloseEvent
- getForce
- setForce
- getHandlerList
- getHandlers
- StargateCreateEvent
- getLine
- getDeny
- setDeny
- getDenyReason
- setDenyReason
- getCost
- setCost
- getHandlerList
- getHandlers
- StargateDeactivateEvent
- getHandlerList
- getHandlers
- getHandlerList
- StargateDestroyEvent
- getDeny
- setDeny
- getDenyReason
- setDenyReason
- getCost
- setCost
- getHandlerList
- getHandlers
- StarGateEntityEvent
- getEntity
- StargateEvent
- getPortal
- setCancelled
- StargateOpenEvent
- getForce
- setForce
- getHandlerList
- getHandlers
- StargatePortalEvent
- getEntity
- getDestination
- getExit
- setExit
- getHandlerList
- getHandlers
- Implement accessEvent in AbstractPortal
Closed with pull request #151