Skip to content

Commit

Permalink
Fix for ConcurrentModificationException due to ICopyableCap.copyTo()
Browse files Browse the repository at this point in the history
  • Loading branch information
Stormwind99 committed Aug 12, 2018
1 parent 00db846 commit f9a58aa
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
6 changes: 5 additions & 1 deletion src/main/java/com/wumple/util/ModConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ public static class MatchingConfig
public static class Debugging
{
@Name("Debug mode")
@Config.Comment("Enable debug features on this menu, display extra debug info.")
@Config.Comment("Enable general debug features, display extra debug info.")
public boolean debug = false;

@Name("Placeholder TileEntity")
@Config.Comment("Use placeholder TileEntity to hold caps if block has none. May crash. May not persist.")
public boolean usePlaceholderTileEntity = false;
}

@Mod.EventBusSubscriber(modid = Reference.MOD_ID)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ default void onPlaceBlock(BlockEvent.PlaceEvent event)
ItemStack stack = event.getPlayer().getHeldItem(event.getHand());
BlockPos pos = event.getPos();

// this can fail if pos (aka Block at pos) has no TileEntity!
copyToFrom(pos, stack, world);
}

Expand Down
38 changes: 24 additions & 14 deletions src/main/java/com/wumple/util/capability/copier/ICopyableCap.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;

import com.wumple.util.ModConfig;
import com.wumple.util.placeholder.TileEntityPlaceholder;

import net.minecraft.item.ItemStack;
Expand Down Expand Up @@ -93,25 +94,34 @@ default void copyTo(BlockPos pos, World world)
{
TileEntity tileentity = world.getTileEntity(pos);

if (tileentity == null)
if (ModConfig.zdebugging.usePlaceholderTileEntity)
{
tileentity = getNewTE();
if (tileentity != null)
if (tileentity == null)
{
Chunk chunk = world.getChunk(pos);
// Obvious method doesn't work: world.setTileEntity(pos, tileentity);
// Block.hasTileEntity() false would cause Chunk.addTileEntity() to reject
tileentity.setWorld(world);
tileentity.setPos(pos);
tileentity.validate();
chunk.getTileEntityMap().put(pos, tileentity);
chunk.markDirty();
world.addTileEntity(tileentity);
// TODO: tileentity will not persist - loading/saving will strip it out since Block.hasTileEntity() false
tileentity = getNewTE();
if (tileentity != null)
{
Chunk chunk = world.getChunk(pos);
// Obvious method doesn't work: world.setTileEntity(pos, tileentity);
// Block.hasTileEntity() false would cause Chunk.addTileEntity() to reject
tileentity.setWorld(world);
tileentity.setPos(pos);
tileentity.validate();
// THIS CAUSES ConcurrentModificationException !!!
// However World.processingLoadedTiles that World.setTileEntity uses is private
chunk.getTileEntityMap().put(pos, tileentity);
chunk.markDirty();
world.addTileEntity(tileentity);
// TODO: tileentity will not persist - loading/saving will strip it out since Block.hasTileEntity() false
}
}
}

copyTo(tileentity);
if (tileentity != null)
{
copyTo(tileentity);
}
// else failure: no TileEntity to copy cap to
}

default void copyTo(TileEntity tileentity)
Expand Down

0 comments on commit f9a58aa

Please sign in to comment.