CreeperHeal

CreeperHeal

281k Downloads

Chain reactions do not work, even with prevention turned off

ApparitionX opened this issue ยท 13 comments

commented

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.

commented

@Programie Have you tried adding TNT to the blacklist?

commented

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.

commented

@Programie Working as intended. What were you expecting?

commented

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.

commented

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

commented

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
commented

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.

commented

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.

commented

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.

commented

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)

commented

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.

commented

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.

commented

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?