Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chain reactions do not work, even with prevention turned off #49

Open
ApparitionX opened this issue Jul 23, 2017 · 13 comments
Open

Chain reactions do not work, even with prevention turned off #49

ApparitionX opened this issue Jul 23, 2017 · 13 comments

Comments

@ApparitionX
Copy link

ApparitionX commented Jul 23, 2017

We have "prevent-chain-reaction: false" in advanced.yml. However, if I were to place two TnT next to each other and light one TnT, the nearby TnT does not explode and, instead, is destroyed as if it were any other block. If I set "prevent-chain-reaction" to true, the adjacent TnT is not destroyed at all. (I tested this plugin by itself on an empty server. We are using CreeperHeal-7.0.5, and there are no errors in the logs.)

This is an issue for us because it prevents players from creating effective TnT cannons. One reason we enjoy CreeperHeal is because it allows PvPers to break into protected areas while preventing permanent damage to buildings.

Thank you for your work; we've enjoyed the plugin for years.

@nitnelave
Copy link
Owner

Hi!
Are you sure it isn't related to another plugin? I test each release of CreeperHeal with a big stack of TNT.

However, I realize that I haven't released anything recently, and the implementation of Minecraft has somewhat changed. Please make sure that if you disable completely CreeperHeal (remove the plugin) and blow up TNT, you can still make a chain reaction.

@ApparitionX
Copy link
Author

I'm sure, but to make sure it's not the server itself, I just tested it on a blank server (PaperSpigot 1155) without any plugins, and the chain reactions work fine. However, when I stop the same server and enable just CreeperHeal, the nearby TnT just breaks like a regular block, and when I do /ch heal, the nearby TnT reappears.

@nitnelave
Copy link
Owner

Okay, I'll have a look when I have time (but I don't know when that's going to be, sadly... I don't really maintain this plugin anymore)

@ApparitionX
Copy link
Author

Thanks, I understand.

However, I found a workaround. I added '46' (the item ID for TNT) to the blacklist of each world, and chain reactions work now. And the latter explosions seem to heal too.

This solution works fine for our server, though I don't know if that's intended. Might not be intuitive for other server admins. I went into the source code and the "prevent-chain-reaction" option just seems to decide whether to treat nearby TNT in explosions like protected blocks or not.

In CreeperExplosion.java, I tried changing:

     /**
     * Record one block and remove it. If it is protected, add to the
     * replace-immediately list. Check for dependent blocks around.
     * 
     * @param block
     *            The block to record.
     */
    public void record(Block block)
    {
    	if (block.getType() == Material.PORTAL)
    		return;
    	
        CreeperBlock cBlock = CreeperBlock.newBlock(block.getState());

        if (cBlock == null || checked.contains(new ShortLocation(block)))
            return;

        checked.add(new ShortLocation(block));

        if ((CreeperConfig.getBool(CfgVal.PREVENT_CHAIN_REACTION) && block.getType().equals(Material.TNT))
            || world.isProtected(block))
        {
            ToReplaceList.addToReplace(cBlock);
            cBlock.remove();
            return;
        }

        BlockId id = new BlockId(block);
        if (!world.isBlackListed(id))
        {
            // The block should be replaced.

            for (NeighborBlock b : cBlock.getDependentNeighbors())
                if (b.isNeighbor())
                    record(b.getBlock());

            blockList.add(cBlock);
            cBlock.remove();
        }
        else if (CreeperConfig.getBool(CfgVal.DROP_DESTROYED_BLOCKS))
        {
            cBlock.drop(false);
            cBlock.remove();

        }

    }

To:

    /**
     * Record one block and remove it. If it is protected, add to the
     * replace-immediately list. Check for dependent blocks around.
     * 
     * @param block
     *            The block to record.
     */
    public void record(Block block)
    {
    	if (block.getType() == Material.PORTAL)
    		return;
    	
        CreeperBlock cBlock = CreeperBlock.newBlock(block.getState());

        if (cBlock == null || checked.contains(new ShortLocation(block)))
            return;

        checked.add(new ShortLocation(block));

        if (world.isProtected(block))
        {
            ToReplaceList.addToReplace(cBlock);
            cBlock.remove();
            return;
        }
        
        //If chain reactions are *not* prevented and the block is TNT, return
        if (!CreeperConfig.getBool(CfgVal.PREVENT_CHAIN_REACTION) && block.getType().equals(Material.TNT))
        		return;
        
        BlockId id = new BlockId(block);
        if (!world.isBlackListed(id))
        {
            // The block should be replaced.

            for (NeighborBlock b : cBlock.getDependentNeighbors())
                if (b.isNeighbor())
                    record(b.getBlock());

            blockList.add(cBlock);
            cBlock.remove();
        }
        else if (CreeperConfig.getBool(CfgVal.DROP_DESTROYED_BLOCKS))
        {
            cBlock.drop(false);
            cBlock.remove();

        }

    }

Since chain reactions are disabled by default, this change checks if "prevent-chain-reaction" is false and if the block is TNT. If so, it just returns, treating TNT like vanilla would and igniting it. Otherwise it would remove it like a non-TNT block. Though, I don't know, maybe other server admins would prefer the TNT be treated like protected blocks as the setting does now.

Anyway, just my two cents. The workaround works fine for us.

@nitnelave
Copy link
Owner

Thanks for the workaround, but normally it should be part of the plugin, I agree. I seem to remember that we're explicitly handling TNT differently.

As for the prevent-chain-reaction setting, it's just if admins want to completely prevent any chain reaction (as part of a griefing control system), so you would have to detonate each TNT block on its own.

@ryantheleach
Copy link
Contributor

ryantheleach commented Aug 3, 2017

I think the current behavior is correct if I understand correctly.

Adding TNT to the blacklist, essentially means, 'let this block act like it exploded naturally' in tnt's case, that's spawning/causing an explosion.

Changing prevent-chain-reaction to true means Do not chain react tnt, do not explode it, let it stay in the world. so that it can be triggered again by a player or outside cause.

leaving tnt as is, means that the tnt will be caught by creeperheal, and healed back as 'normal'?

Maybe the default should be having tnt added to the blacklist?

@Programie
Copy link

Is there already any progress on this issue?

I'm having the same issue with this plugin. prevent-chain-reaction is set to false, but the TNT blocks not directly triggered by Redstone do not explode, they just react like a normal block.

This is how an explosion looks like just after one TNT block exploded:
image

I'm using the latest version (7.0.5) of the plugin.

@ryantheleach
Copy link
Contributor

@Programie Working as intended. What were you expecting?

@nitnelave
Copy link
Owner

@Programie Have you tried adding TNT to the blacklist?

@Programie
Copy link

I just tried it again by adding TNT (ID '46') to the blacklist but the issue still exists for me.

If I understand it correctly I have to update the advanced.yml of my world (e.g. plugins/CreeperHeal/world/advanced.yml) and add the item ID of TNT to restrict -> blacklist, right?

That's my current advanced.yml file:

restrict:
  use-whitelist: false
  blacklist:
  - '46'
  whitelist: '0'
replace-grass-with-dirt: false
repair-time-of-day: -1
protected-list: '0'
factions:
  ignore-wilderness: false
  ignore-territory: false
drop-chest-contents: false

I'm not sure whether blacklist should be a list of items (just like the file above) or a simple string containing the IDs (e.g. blacklist: '46'). I tried both and even restarted my Minecraft server for each try.

@nitnelave
Copy link
Owner

The blacklist contains a string with comma-separated IDs (see https://github.com/nitnelave/CreeperHeal/blob/master/src/main/resources/world-advanced.yml)

@Programie
Copy link

If I get you correctly, this should work but it doesn't for me:

restrict:
  use-whitelist: false
  blacklist: '46'
  whitelist: '0'
replace-grass-with-dirt: false
repair-time-of-day: -1
protected-list: '0'
factions:
  ignore-wilderness: false
  ignore-territory: false
drop-chest-contents: false

@nitnelave
Copy link
Owner

Sorry, I really haven't fired Minecraft for 2 years, I don't really know what's going on. I never had any problem with chain reactions, though, even with the default settings. Something must have changed in the Spout/Bukkit code, but I don't know what.

Sorry I can't help more. If you do find the issue, please post it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants