From fa738504a8c23220e3e88c3519487d862162c7af Mon Sep 17 00:00:00 2001 From: IronApollo Date: Thu, 26 Mar 2020 16:08:36 -0400 Subject: [PATCH] Fix some important chunk issues This commit should properly synchronize the initialization of the adapter's ibdToStateOrdinal (the char array FAWE uses to convert NMS IBlockData objects to an internal ordinal for chunk operations) so references to this array do not push incorrect characters down the line. Potentially fixes #373 Fixes #363 Fixes #332 --- .../adapter/impl/FAWE_Spigot_v1_14_R4.java | 49 ++++++++++++------- .../adapter/impl/FAWE_Spigot_v1_15_R1.java | 49 ++++++++++++------- .../adapter/impl/FAWE_Spigot_v1_15_R2.java | 49 ++++++++++++------- 3 files changed, 90 insertions(+), 57 deletions(-) diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java index dd7d81691..a3dc483f3 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_14_R4.java @@ -79,6 +79,7 @@ import static com.google.common.base.Preconditions.checkNotNull; public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { private final Spigot_v1_14_R4 parent; + private char[] ibdToStateOrdinal; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft @@ -93,16 +94,14 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I return parent; } - public char[] idbToStateOrdinal; - private synchronized boolean init() { - if (idbToStateOrdinal != null) return false; - idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size - for (int i = 0; i < idbToStateOrdinal.length; i++) { + if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) return false; + ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size + for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); - idbToStateOrdinal[id] = state.getOrdinalChar(); + ibdToStateOrdinal[id] = state.getOrdinalChar(); } return true; } @@ -251,26 +250,38 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I } public BlockState adapt(IBlockData ibd) { - return BlockTypesCache.states[adaptToInt(ibd)]; + return BlockTypesCache.states[adaptToChar(ibd)]; } + /** + * @deprecated + * Method unused. Use #adaptToChar(IBlockData). + */ + @Deprecated public int adaptToInt(IBlockData ibd) { - try { - int id = Block.REGISTRY_ID.getId(ibd); - return idbToStateOrdinal[id]; - } catch (NullPointerException e) { - init(); - return adaptToInt(ibd); + synchronized (this) { + try { + int id = Block.REGISTRY_ID.getId(ibd); + return ibdToStateOrdinal[id]; + } catch (NullPointerException e) { + init(); + return adaptToInt(ibd); + } } } public char adaptToChar(IBlockData ibd) { - try { - int id = Block.REGISTRY_ID.getId(ibd); - return idbToStateOrdinal[id]; - } catch (NullPointerException e) { - init(); - return adaptToChar(ibd); + synchronized (this) { + try { + int id = Block.REGISTRY_ID.getId(ibd); + return ibdToStateOrdinal[id]; + } catch (NullPointerException e) { + init(); + return adaptToChar(ibd); + } catch(ArrayIndexOutOfBoundsException e1){ + Fawe.debug("Attempted to convert " + ibd.getBlock() + " with ID " + Block.REGISTRY_ID.getId(ibd) + " to char. ibdToStateOrdinal length: " + ibdToStateOrdinal.length + ". Defaulting to air!"); + return 0; + } } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java index d3cc0d29a..ce6091bb9 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R1.java @@ -82,6 +82,7 @@ import static com.google.common.base.Preconditions.checkNotNull; public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { private final Spigot_v1_15_R1 parent; + private char[] ibdToStateOrdinal; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft @@ -96,16 +97,14 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I return parent; } - public char[] idbToStateOrdinal; - private synchronized boolean init() { - if (idbToStateOrdinal != null) return false; - idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size - for (int i = 0; i < idbToStateOrdinal.length; i++) { + if (ibdToStateOrdinal != null) return false; + ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size + for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_15 material = (BlockMaterial_1_15) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); - idbToStateOrdinal[id] = state.getOrdinalChar(); + ibdToStateOrdinal[id] = state.getOrdinalChar(); } return true; } @@ -258,26 +257,38 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I } public BlockState adapt(IBlockData ibd) { - return BlockTypesCache.states[adaptToInt(ibd)]; + return BlockTypesCache.states[adaptToChar(ibd)]; } + /** + * @deprecated + * Method unused. Use #adaptToChar(IBlockData). + */ + @Deprecated public int adaptToInt(IBlockData ibd) { - try { - int id = Block.REGISTRY_ID.getId(ibd); - return idbToStateOrdinal[id]; - } catch (NullPointerException e) { - init(); - return adaptToInt(ibd); + synchronized (this) { + try { + int id = Block.REGISTRY_ID.getId(ibd); + return ibdToStateOrdinal[id]; + } catch (NullPointerException e) { + init(); + return adaptToInt(ibd); + } } } public char adaptToChar(IBlockData ibd) { - try { - int id = Block.REGISTRY_ID.getId(ibd); - return idbToStateOrdinal[id]; - } catch (NullPointerException e) { - init(); - return adaptToChar(ibd); + synchronized (this) { + try { + int id = Block.REGISTRY_ID.getId(ibd); + return ibdToStateOrdinal[id]; + } catch (NullPointerException e) { + init(); + return adaptToChar(ibd); + } catch (ArrayIndexOutOfBoundsException e1) { + Fawe.debug("Attempted to convert " + ibd.getBlock() + " with ID " + Block.REGISTRY_ID.getId(ibd) + " to char. ibdToStateOrdinal length: " + ibdToStateOrdinal.length + ". Defaulting to air!"); + return 0; + } } } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java index c79ff01de..e384bd4e4 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/FAWE_Spigot_v1_15_R2.java @@ -82,6 +82,7 @@ import static com.google.common.base.Preconditions.checkNotNull; public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter { private final Spigot_v1_15_R2 parent; + private char[] ibdToStateOrdinal; // ------------------------------------------------------------------------ // Code that may break between versions of Minecraft @@ -96,16 +97,14 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I return parent; } - public char[] idbToStateOrdinal; - private synchronized boolean init() { - if (idbToStateOrdinal != null) return false; - idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size - for (int i = 0; i < idbToStateOrdinal.length; i++) { + if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) return false; + ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size + for (int i = 0; i < ibdToStateOrdinal.length; i++) { BlockState state = BlockTypesCache.states[i]; BlockMaterial_1_15_2 material = (BlockMaterial_1_15_2) state.getMaterial(); int id = Block.REGISTRY_ID.getId(material.getState()); - idbToStateOrdinal[id] = state.getOrdinalChar(); + ibdToStateOrdinal[id] = state.getOrdinalChar(); } return true; } @@ -260,26 +259,38 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I } public BlockState adapt(IBlockData ibd) { - return BlockTypesCache.states[adaptToInt(ibd)]; + return BlockTypesCache.states[adaptToChar(ibd)]; } + /** + * @deprecated + * Method unused. Use #adaptToChar(IBlockData). + */ + @Deprecated public int adaptToInt(IBlockData ibd) { - try { - int id = Block.REGISTRY_ID.getId(ibd); - return idbToStateOrdinal[id]; - } catch (NullPointerException e) { - init(); - return adaptToInt(ibd); + synchronized (this) { + try { + int id = Block.REGISTRY_ID.getId(ibd); + return ibdToStateOrdinal[id]; + } catch (NullPointerException e) { + init(); + return adaptToInt(ibd); + } } } public char adaptToChar(IBlockData ibd) { - try { - int id = Block.REGISTRY_ID.getId(ibd); - return idbToStateOrdinal[id]; - } catch (NullPointerException e) { - init(); - return adaptToChar(ibd); + synchronized (this) { + try { + int id = Block.REGISTRY_ID.getId(ibd); + return ibdToStateOrdinal[id]; + } catch (NullPointerException e) { + init(); + return adaptToChar(ibd); + } catch(ArrayIndexOutOfBoundsException e1){ + Fawe.debug("Attempted to convert " + ibd.getBlock() + " with ID " + Block.REGISTRY_ID.getId(ibd) + " to char. ibdToStateOrdinal length: " + ibdToStateOrdinal.length + ". Defaulting to air!"); + return 0; + } } }