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
This commit is contained in:
IronApollo 2020-03-26 16:08:36 -04:00
parent 3e98bb1acf
commit fa738504a8
3 changed files with 90 additions and 57 deletions

View File

@ -79,6 +79,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> { public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
private final Spigot_v1_14_R4 parent; private final Spigot_v1_14_R4 parent;
private char[] ibdToStateOrdinal;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Code that may break between versions of Minecraft // 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; return parent;
} }
public char[] idbToStateOrdinal;
private synchronized boolean init() { private synchronized boolean init() {
if (idbToStateOrdinal != null) return false; if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) return false;
idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
for (int i = 0; i < idbToStateOrdinal.length; i++) { for (int i = 0; i < ibdToStateOrdinal.length; i++) {
BlockState state = BlockTypesCache.states[i]; BlockState state = BlockTypesCache.states[i];
BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial(); BlockMaterial_1_14 material = (BlockMaterial_1_14) state.getMaterial();
int id = Block.REGISTRY_ID.getId(material.getState()); int id = Block.REGISTRY_ID.getId(material.getState());
idbToStateOrdinal[id] = state.getOrdinalChar(); ibdToStateOrdinal[id] = state.getOrdinalChar();
} }
return true; return true;
} }
@ -251,26 +250,38 @@ public final class FAWE_Spigot_v1_14_R4 extends CachedBukkitAdapter implements I
} }
public BlockState adapt(IBlockData ibd) { 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) { public int adaptToInt(IBlockData ibd) {
try { synchronized (this) {
int id = Block.REGISTRY_ID.getId(ibd); try {
return idbToStateOrdinal[id]; int id = Block.REGISTRY_ID.getId(ibd);
} catch (NullPointerException e) { return ibdToStateOrdinal[id];
init(); } catch (NullPointerException e) {
return adaptToInt(ibd); init();
return adaptToInt(ibd);
}
} }
} }
public char adaptToChar(IBlockData ibd) { public char adaptToChar(IBlockData ibd) {
try { synchronized (this) {
int id = Block.REGISTRY_ID.getId(ibd); try {
return idbToStateOrdinal[id]; int id = Block.REGISTRY_ID.getId(ibd);
} catch (NullPointerException e) { return ibdToStateOrdinal[id];
init(); } catch (NullPointerException e) {
return adaptToChar(ibd); 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;
}
} }
} }

View File

@ -82,6 +82,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> { public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
private final Spigot_v1_15_R1 parent; private final Spigot_v1_15_R1 parent;
private char[] ibdToStateOrdinal;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Code that may break between versions of Minecraft // 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; return parent;
} }
public char[] idbToStateOrdinal;
private synchronized boolean init() { private synchronized boolean init() {
if (idbToStateOrdinal != null) return false; if (ibdToStateOrdinal != null) return false;
idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
for (int i = 0; i < idbToStateOrdinal.length; i++) { for (int i = 0; i < ibdToStateOrdinal.length; i++) {
BlockState state = BlockTypesCache.states[i]; BlockState state = BlockTypesCache.states[i];
BlockMaterial_1_15 material = (BlockMaterial_1_15) state.getMaterial(); BlockMaterial_1_15 material = (BlockMaterial_1_15) state.getMaterial();
int id = Block.REGISTRY_ID.getId(material.getState()); int id = Block.REGISTRY_ID.getId(material.getState());
idbToStateOrdinal[id] = state.getOrdinalChar(); ibdToStateOrdinal[id] = state.getOrdinalChar();
} }
return true; return true;
} }
@ -258,26 +257,38 @@ public final class FAWE_Spigot_v1_15_R1 extends CachedBukkitAdapter implements I
} }
public BlockState adapt(IBlockData ibd) { 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) { public int adaptToInt(IBlockData ibd) {
try { synchronized (this) {
int id = Block.REGISTRY_ID.getId(ibd); try {
return idbToStateOrdinal[id]; int id = Block.REGISTRY_ID.getId(ibd);
} catch (NullPointerException e) { return ibdToStateOrdinal[id];
init(); } catch (NullPointerException e) {
return adaptToInt(ibd); init();
return adaptToInt(ibd);
}
} }
} }
public char adaptToChar(IBlockData ibd) { public char adaptToChar(IBlockData ibd) {
try { synchronized (this) {
int id = Block.REGISTRY_ID.getId(ibd); try {
return idbToStateOrdinal[id]; int id = Block.REGISTRY_ID.getId(ibd);
} catch (NullPointerException e) { return ibdToStateOrdinal[id];
init(); } catch (NullPointerException e) {
return adaptToChar(ibd); 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;
}
} }
} }

View File

@ -82,6 +82,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> { public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements IDelegateBukkitImplAdapter<NBTBase> {
private final Spigot_v1_15_R2 parent; private final Spigot_v1_15_R2 parent;
private char[] ibdToStateOrdinal;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Code that may break between versions of Minecraft // 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; return parent;
} }
public char[] idbToStateOrdinal;
private synchronized boolean init() { private synchronized boolean init() {
if (idbToStateOrdinal != null) return false; if (ibdToStateOrdinal != null && ibdToStateOrdinal[1] != 0) return false;
idbToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size ibdToStateOrdinal = new char[Block.REGISTRY_ID.a()]; // size
for (int i = 0; i < idbToStateOrdinal.length; i++) { for (int i = 0; i < ibdToStateOrdinal.length; i++) {
BlockState state = BlockTypesCache.states[i]; BlockState state = BlockTypesCache.states[i];
BlockMaterial_1_15_2 material = (BlockMaterial_1_15_2) state.getMaterial(); BlockMaterial_1_15_2 material = (BlockMaterial_1_15_2) state.getMaterial();
int id = Block.REGISTRY_ID.getId(material.getState()); int id = Block.REGISTRY_ID.getId(material.getState());
idbToStateOrdinal[id] = state.getOrdinalChar(); ibdToStateOrdinal[id] = state.getOrdinalChar();
} }
return true; return true;
} }
@ -260,26 +259,38 @@ public final class FAWE_Spigot_v1_15_R2 extends CachedBukkitAdapter implements I
} }
public BlockState adapt(IBlockData ibd) { 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) { public int adaptToInt(IBlockData ibd) {
try { synchronized (this) {
int id = Block.REGISTRY_ID.getId(ibd); try {
return idbToStateOrdinal[id]; int id = Block.REGISTRY_ID.getId(ibd);
} catch (NullPointerException e) { return ibdToStateOrdinal[id];
init(); } catch (NullPointerException e) {
return adaptToInt(ibd); init();
return adaptToInt(ibd);
}
} }
} }
public char adaptToChar(IBlockData ibd) { public char adaptToChar(IBlockData ibd) {
try { synchronized (this) {
int id = Block.REGISTRY_ID.getId(ibd); try {
return idbToStateOrdinal[id]; int id = Block.REGISTRY_ID.getId(ibd);
} catch (NullPointerException e) { return ibdToStateOrdinal[id];
init(); } catch (NullPointerException e) {
return adaptToChar(ibd); 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;
}
} }
} }