CyclopsMC / CapabilityProxy

Access block capabilities from multiple sides
MIT License
5 stars 5 forks source link

Infinite loop in onBlockActivate #4

Closed OneEyeMaker closed 7 years ago

OneEyeMaker commented 7 years ago

Hello. Firstly, thank you for your mods (and for this mod especially). I've simple suggestion. Capability proxy blocks (accidentally or intentionally) can be placed to form loops. And it can lead to infinite cycles and StackOverflowException (read: server crashes). I suggest to add protection against such behavior. It can be accomplished in 3 steps: 1) Add similar method to code of TileCapabilityProxy:

public boolean isInLoop()
{
    BlockPos pos = getPos();
    TileEntity tileEntity = this;
    do
    {
        TileCapabilityProxy proxy = (TileCapabilityProxy) tileEntity;
        pos = proxy.getPos().offset(proxy.getOffset());
        tileEntity = proxy.getWorld().getTileEntity(pos);
    }
    while (tileEntity instanceof TileCapabilityProxy && !pos.equals(getPos()));
    return pos.equals(getPos());
}

2) Call this method in BlockCapabilityProxy.onBlockActivated, TileCapabilityProxy.hasCapability, TileCapabilityProxy.getCapability. If this method return true, return false, false, null (respectively). 3) Deactivate proxy block, if this method returns true.

rubensworks commented 7 years ago

When exactly does the stackoverflow error occur? Can you send me the crashlog? Because a stackoverflow protection actually already is in place.

OneEyeMaker commented 7 years ago

@rubensworks Place 4 proxy blocks in loop and right-click one of them. BlockCapabilityProxy.onBlockActivate just calls onBlockActivate of next proxy block (in loop) and this causes StackOverflowException.

Crash Report: https://pastebin.com/621eH87g

rubensworks commented 7 years ago

Thanks, it looks like onBlockActivate is the only method that is not protected from stackoverflow, I missed that.