Plugins that Cause Events Should Register Them (Proposed Standard)

Discussion in 'Plugin Development' started by tkelly, Jan 25, 2011.

Thread Status:
Not open for further replies.
  1. Offline


    So I'm proposing, for your consideration, a new standard for plugins, to send events for applicable actions to the plugin manager. I'll give example code, a few practical examples, reasons why it's necessary, and a reason why it'd suck. I hope I can win the hearts of all plugin developers, but please comment on your opinion (whether for or against). :)

    Example Code:
     * Blocks that players stand on are deleted when they move.
    Block block world.getBlockAt(player.getLocation().getBlockX(), player.getLocation().getBlockY()-1player.getLocation().getBlockZ());
    BlockDamageEvent event = new BlockDamageEvent(Type.BLOCK_DAMAGEDblockBlockDamageLevel.BROKENplayer);
    if (!
    event.isCancelled()) {

    Example 1:
    A user is using iStick or WorldEdit's superpick. Every time a block is removed or placed, the plugin calls the BLOCK_DAMAGED or BLOCK_PLACED, check if it got cancelled, and respond appropriately.

    Example 2:
    Some plugin that has a poison affect on users, changes their health over time. Every time it does, it calls the ENTITY_DAMAGED event, and again, responds appropriately.

    Support 1: Implicit "Protection Plugin" support
    Rather than building plugins around protection plugins, they can directly interact using this system. If someone without permissions is iStick'ing into a protected area, the block placed/damaged event that gets called by iStick will be cancelled and iStick will not work in that area. Rather than having the developer of a block manipulation plugin build in support for the many protection plugins there are/will be, this will pull it all together.

    Support 2: Implicit "Logging Plugin" support
    If there is a logging plugin watching for player actions, block manipulations, etc, actions by plugins that directly modify the world can't be recorded. This results in a hole in the information that is logged, resulting in (begin slight exaggeration) security risks, angry users, and, at the very least, a lack of data integrity (end slight exaggeration). But if these actions are sent as events, the logging plugins can pick those up, and all is good.

    Un-Support 1: More work...
    It'll take a couple extra lines of code to add this in.
  2. Offline


    I emphatically support this initiative, and will henceforth ensure that anything I write calls events that it would cause, and checks their cancellation prior to action.

    In an instance of "practice what you preach" (well, not really, but I wanted to say that) though, I can't run MyHome with any sort of command management plugin (other than Permissions, for which support is directly integrated) because it registers and acts on its own command without checking in to see if that command would be otherwise allowed.
  3. Offline


    Another option would be that the API calls themselves generate the event calls.

    If you modify a player's health, then the function could return true if the change succeeds.

    Remember, more work is not a minor issue :). You are making it take 4-5 times as many lines of code.

    Maybe the API could have


    The second one would generate the event and return false if it failed.

    Also, this could be implemented as a helper plugin.
  4. Offline


    @SquallSeeD31 : Well the current command system in Bukkit is separate and different from the event system; commands are sent directly to plugins that register the commands. Because of this, command management plugins simply won't work with plugins that use these standards (eg MyHome).

    @Raphfrk : Yea, I thought of that as a possible solution as well and that sounds like it'd be better. (Although, I think 4-5 times the lines of code is slight exaggeration ;))

    A possible solution would have to be block.setTypeId(0) and block.noEventSetTypeId(0), so that the default is creating the event and only if the developer finds it necessary to skip the event process, they can choose to skip it; also, so new developers who don't really know the API will pick the setTypeId before they'd pick eventSetTypeId.
  5. Offline


    There's really no benefit to having plugin develops implement it for each and every event-generating-change themselves; Raphfrk's suggestion hence makes a lot more sense.
  6. Offline


    i support this
  7. Offline


    This sounds like a better alternative. It'd be insane for some plugins to register every event. Having the API do it makes much more sense.
  8. Offline


    It would be great if every single developer released a javadoc for every single plugin, and made every single thing with inter plugin communication. But it just isn't going to happen.

    That being said, I am making this effort myself, I am currently working on a TeamManager plugin that can be used by anyone wanting to make team based game modes.
  9. Offline


    Exactly, which is why Bukkit should handle it in the API, firing events when it changing block types, etc. Then you don't need to rely on the kindness of other programmers.
  10. Offline


    I am 100% for this. It would also solve some of the concerns I had about event priorities.

    Would the server take much of a performance hit to do this? (I'm doubting it)
  11. Offline


    A small hit. It would depend on the plugins installed. Plugins that modify a ton of blocks at one (MoveCraft, etc) would be the ones to cause the largest performance hit, but still not that big. Probably comparable to 5 players mining at once on your server.
  12. Offline


    Oh yeah, and WordEdit modifying 350,000 blocks at once... well perhaps that type of thing is justification for the noEventSetBlockId() API calls. If you're writing large scale block-changing functions, it stands to reason you won't want to trip events. That type of thing should be reserved for mods/admins anyway.

    How would the plugin specify if it was a player or some other action that caused the change? As in, I make an API call block.setBlockId(0); - how does the API know if this is my response to a player's action or something else (Redstone timer with ControllerBlock for example). I would expect that a player might not be able to directly alter blocks in a protected area, but if they have access to a lever or pressure plate that causes changes in that area then I'd expect that would still work. Thoughts?
Thread Status:
Not open for further replies.

Share This Page