diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index bb46a654c..50e1a1757 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,7 +14,7 @@ mapmanager = "1.8.0-SNAPSHOT" griefprevention = "17.0.0" griefdefender = "2.1.0-SNAPSHOT" residence = "4.5._13.1" -towny = "0.100.2.14" +towny = "0.100.3.0" plotsquared = "7.3.8" # Third party diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java index 473daaca6..5939cdd33 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_19_R3/PaperweightAdapter.java @@ -283,11 +283,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -554,11 +561,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES, null ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); @@ -626,15 +629,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, @@ -815,13 +817,16 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (bitMask == 0 && biomes == null && !lightUpdate) { callback = null; } else { + final int finalBitMask = bitMask; callback = () -> { // Set Modified nmsChunk.setLightCorrect(true); // Set Modified nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (!set + .getSideEffectSet() + .shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalBitMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -844,7 +849,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1102,38 +1107,25 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } BiomeType[] sectionBiomes; if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; + return null; } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java index 7e908c74c..dd1787868 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightGetBlocks_Copy.java @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java index 0a7453578..334289b08 100644 --- a/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_19_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_19_R3/PaperweightPlatformAdapter.java @@ -98,7 +98,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; + private static final Field fieldBiomes; private static final MethodHandle methodGetVisibleChunk; @@ -139,8 +139,15 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f")); - fieldNonEmptyBlockCount.setAccessible(true); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "j" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("j"); + } + fieldBiomes = tmpFieldBiomes; + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -502,6 +509,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(layer, dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java index 4abb61928..4df206ffc 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R1/PaperweightAdapter.java @@ -284,11 +284,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -553,11 +560,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -624,15 +627,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, @@ -813,13 +815,16 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (bitMask == 0 && biomes == null && !lightUpdate) { callback = null; } else { + final int finalBitMask = bitMask; callback = () -> { // Set Modified nmsChunk.setLightCorrect(true); // Set Modified nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (!set + .getSideEffectSet() + .shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalBitMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -842,7 +847,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1099,38 +1104,25 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } BiomeType[] sectionBiomes; if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; + return null; } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java index a3ca91376..d2412b98f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightGetBlocks_Copy.java @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java index 74eec9195..05c0b58f9 100644 --- a/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R1/PaperweightPlatformAdapter.java @@ -62,7 +62,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_20_R1.CraftChunk; -import sun.misc.Unsafe; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -102,7 +101,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; private static final MethodHandle methodGetVisibleChunk; @@ -111,6 +109,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final MethodHandle methodRemoveGameEventListener; private static final MethodHandle methodremoveTickingBlockEntity; + private static final Field fieldBiomes; private static final Field fieldOffers; private static final MerchantOffers OFFERS = new MerchantOffers(); @@ -149,8 +148,15 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); - fieldNonEmptyBlockCount.setAccessible(true); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "i" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); + } + fieldBiomes = tmpFieldBiomes; + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -417,7 +423,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); + return newChunkSection(biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); @@ -507,7 +513,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @SuppressWarnings("deprecation") // Only deprecated in paper private static LevelChunkSection newChunkSection( - int layer, Registry biomeRegistry, @Nullable PalettedContainer> biomes ) { @@ -522,6 +527,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index 6424cf82f..c7eab235d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -281,11 +281,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -561,11 +568,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -632,15 +635,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, @@ -821,13 +823,16 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (bitMask == 0 && biomes == null && !lightUpdate) { callback = null; } else { + final int finalBitMask = bitMask; callback = () -> { // Set Modified nmsChunk.setLightCorrect(true); // Set Modified nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (!set + .getSideEffectSet() + .shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalBitMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -850,7 +855,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1107,38 +1112,25 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } BiomeType[] sectionBiomes; if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; + return null; } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java index 1c1130764..b6f4c7d94 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java index 29d7278a5..91dcfe24e 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java @@ -59,7 +59,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager; import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; import org.bukkit.craftbukkit.v1_20_R2.CraftChunk; -import sun.misc.Unsafe; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -99,7 +98,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; private static final MethodHandle methodGetVisibleChunk; @@ -108,6 +106,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final MethodHandle methodRemoveGameEventListener; private static final MethodHandle methodremoveTickingBlockEntity; + private static final Field fieldBiomes; /* * This is a workaround for the changes from https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/1fddefce1cdce44010927b888432bf70c0e88cde#src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -143,8 +142,15 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); - fieldNonEmptyBlockCount.setAccessible(true); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "i" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); + } + fieldBiomes = tmpFieldBiomes; + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -408,7 +414,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); + return newChunkSection(biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); @@ -498,7 +504,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @SuppressWarnings("deprecation") // Only deprecated in paper private static LevelChunkSection newChunkSection( - int layer, Registry biomeRegistry, @Nullable PalettedContainer> biomes ) { @@ -513,6 +518,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java index f8dbbdf60..904ac5276 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R3/PaperweightAdapter.java @@ -281,11 +281,11 @@ public final class PaperweightAdapter implements BukkitImplAdapter> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -560,11 +567,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -631,15 +634,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); if (!PaperweightPlatformAdapter.setSectionAtomic( levelChunkSections, existingSection, @@ -820,13 +822,16 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (bitMask == 0 && biomes == null && !lightUpdate) { callback = null; } else { + final int finalBitMask = bitMask; callback = () -> { // Set Modified nmsChunk.setLightCorrect(true); // Set Modified nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (!set + .getSideEffectSet() + .shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalBitMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -849,7 +854,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1104,38 +1109,25 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } BiomeType[] sectionBiomes; if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; + return null; } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java index 92d9ec801..23c882284 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -144,7 +144,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -173,10 +173,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index 2f25bc6f1..f2f78eb7d 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -98,7 +98,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; + private static final Field fieldBiomes; private static final MethodHandle methodGetVisibleChunk; @@ -142,8 +142,15 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); - fieldNonEmptyBlockCount.setAccessible(true); + Field tmpFieldBiomes; + try { + // It seems to actually be biomes, but is apparently obfuscated to "i" + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("biomes"); + } catch (NoSuchFieldException ignored) { + tmpFieldBiomes = LevelChunkSection.class.getDeclaredField("i"); + } + fieldBiomes = tmpFieldBiomes; + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -407,7 +414,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); + return newChunkSection(biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); @@ -497,7 +504,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @SuppressWarnings("deprecation") // Only deprecated in paper private static LevelChunkSection newChunkSection( - int layer, Registry biomeRegistry, @Nullable PalettedContainer> biomes ) { @@ -512,6 +518,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts index a2b5aa66d..4fca485af 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts +++ b/worldedit-bukkit/adapters/adapter-1_20_5/build.gradle.kts @@ -12,6 +12,6 @@ repositories { dependencies { // url=https://repo.papermc.io/service/rest/repository/browse/maven-public/io/papermc/paper/dev-bundle/1.20.6-R0.1-SNAPSHOT/ - the().paperDevBundle("1.20.6-R0.1-20240604.210637-112") + the().paperDevBundle("1.20.6-R0.1-20240615.211816-120") compileOnly(libs.paperlib) } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java index aef908042..29fb9295f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java @@ -291,12 +291,12 @@ public final class PaperweightAdapter implements BukkitImplAdapter> paletteBiomes = setBiomesToPalettedContainer( + biomes, + setSectionIndex, + existingSection.getBiomes() + ); + if (paletteBiomes != null) { + PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes); + } } } } @@ -563,11 +570,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( biomeHolderIdMap, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId( - BiomeTypes.PLAINS)), + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)), PalettedContainer.Strategy.SECTION_BIOMES ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); newSection = PaperweightPlatformAdapter.newChunkSection( @@ -634,18 +637,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc existingSection.getBiomes() ); - newSection = - PaperweightPlatformAdapter.newChunkSection( - layerNo, - this::loadPrivately, - setArr, - adapter, - biomeRegistry, - biomeData - ); - if (!PaperweightPlatformAdapter.setSectionAtomic( - levelChunkSections, - existingSection, + newSection = PaperweightPlatformAdapter.newChunkSection( + layerNo, + this::loadPrivately, + setArr, + adapter, + biomeRegistry, + biomeData != null ? biomeData : (PalettedContainer>) existingSection.getBiomes() + ); + if (!PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, existingSection, newSection, getSectionIndex )) { @@ -823,13 +823,16 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc if (bitMask == 0 && biomes == null && !lightUpdate) { callback = null; } else { + final int finalBitMask = bitMask; callback = () -> { // Set Modified nmsChunk.setLightCorrect(true); // Set Modified nmsChunk.mustNotSave = false; nmsChunk.setUnsaved(true); // send to player - if (!set.getSideEffectSet().shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING) { + if (!set + .getSideEffectSet() + .shouldApply(SideEffect.LIGHTING) || !Settings.settings().LIGHTING.DELAY_PACKET_SENDING || finalBitMask == 0 && biomes != null) { this.send(); } if (finalizer != null) { @@ -852,7 +855,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc } if (callback == null) { if (finalizer != null) { - finalizer.run(); + queueHandler.async(finalizer, null); } return null; } else { @@ -1109,38 +1112,25 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc final int sectionIndex, final PalettedContainerRO> data ) { - PalettedContainer> biomeData; - if (data instanceof PalettedContainer> palettedContainer) { - biomeData = palettedContainer; - } else { - LOGGER.warn( - "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + - "type {} but got {}", - PalettedContainer.class.getSimpleName(), - data.getClass().getSimpleName() - ); - biomeData = data.recreate(); - } BiomeType[] sectionBiomes; if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) { - return biomeData; + return null; } + PalettedContainer> biomeData = data.recreate(); for (int y = 0, index = 0; y < 4; y++) { for (int z = 0; z < 4; z++) { for (int x = 0; x < 4; x++, index++) { BiomeType biomeType = sectionBiomes[index]; if (biomeType == null) { - continue; + biomeData.set(x, y, z, data.get(x, y, z)); + } else { + biomeData.set( + x, + y, + z, + biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType)) + ); } - biomeData.set( - x, - y, - z, - biomeHolderIdMap.byIdOrThrow(WorldEditPlugin - .getInstance() - .getBukkitImplAdapter() - .getInternalBiomeId(biomeType)) - ); } } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java index c0a7bda52..146760020 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java @@ -46,7 +46,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final int maxHeight; final ServerLevel serverLevel; final LevelChunk levelChunk; - private PalettedContainer>[] biomes = null; + private Holder[][] biomes = null; protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.levelChunk = levelChunk; @@ -145,7 +145,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { @Override public BiomeType getBiomeType(int x, int y, int z) { - Holder biome = biomes[(y >> 4) - getMinSectionPosition()].get(x >> 2, (y & 15) >> 2, z >> 2); + Holder biome = biomes[(y >> 4) - getMinSectionPosition()][(y & 12) << 2 | (z & 12) | (x & 12) >> 2]; return PaperweightPlatformAdapter.adapt(biome, serverLevel); } @@ -174,10 +174,15 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { protected void storeBiomes(int layer, PalettedContainerRO> biomeData) { if (biomes == null) { - biomes = new PalettedContainer[getSectionCount()]; + biomes = new Holder[getSectionCount()][]; + } + if (biomes[layer] == null) { + biomes[layer] = new Holder[64]; } if (biomeData instanceof PalettedContainer> palettedContainer) { - biomes[layer] = palettedContainer.copy(); + for (int i = 0; i < 64; i++) { + biomes[layer][i] = palettedContainer.get(i); + } } else { LOGGER.error( "Cannot correctly save biomes to history. Expected class type {} but got {}", diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index 76a7a9025..6c0f72590 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -10,7 +10,6 @@ import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.ReflectionUtils; import com.fastasyncworldedit.core.util.TaskManager; -import com.mojang.datafixers.util.Either; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.Refraction; @@ -77,7 +76,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Semaphore; import java.util.concurrent.TimeUnit; @@ -98,7 +96,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { private static final Field fieldTickingFluidCount; private static final Field fieldTickingBlockCount; - private static final Field fieldNonEmptyBlockCount; + private static final Field fieldBiomes; private static final MethodHandle methodGetVisibleChunk; @@ -142,8 +140,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { fieldTickingFluidCount.setAccessible(true); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount.setAccessible(true); - fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); - fieldNonEmptyBlockCount.setAccessible(true); + fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i")); + fieldBiomes.setAccessible(true); Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( "getVisibleChunkIfPresent", @@ -405,7 +403,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @Nullable PalettedContainer> biomes ) { if (set == null) { - return newChunkSection(layer, biomeRegistry, biomes); + return newChunkSection(biomeRegistry, biomes); } final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); @@ -495,7 +493,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { @SuppressWarnings("deprecation") // Only deprecated in paper private static LevelChunkSection newChunkSection( - int layer, Registry biomeRegistry, @Nullable PalettedContainer> biomes ) { @@ -510,6 +507,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter { return new LevelChunkSection(dataPaletteBlocks, biomes); } + public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer> biomes) { + try { + fieldBiomes.set(section, biomes); + } catch (IllegalAccessException e) { + LOGGER.error("Could not set biomes to chunk section", e); + } + } + /** * Create a new {@link PalettedContainer}. Should only be used if no biome container existed beforehand. */ diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java index 6ea8cad89..16e959d27 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/IBukkitAdapter.java @@ -166,10 +166,10 @@ public interface IBukkitAdapter { */ default Material adapt(ItemType itemType) { checkNotNull(itemType); - if (!itemType.getId().startsWith("minecraft:")) { + if (!itemType.id().startsWith("minecraft:")) { throw new IllegalArgumentException("Bukkit only supports Minecraft items"); } - return Material.getMaterial(itemType.getId().substring(10).toUpperCase(Locale.ROOT)); + return Material.getMaterial(itemType.id().substring(10).toUpperCase(Locale.ROOT)); } /** @@ -180,10 +180,10 @@ public interface IBukkitAdapter { */ default Material adapt(BlockType blockType) { checkNotNull(blockType); - if (!blockType.getId().startsWith("minecraft:")) { + if (!blockType.id().startsWith("minecraft:")) { throw new IllegalArgumentException("Bukkit only supports Minecraft blocks"); } - String id = blockType.getId().substring(10).toUpperCase(Locale.ROOT); + String id = blockType.id().substring(10).toUpperCase(Locale.ROOT); return Material.getMaterial(id); } @@ -293,11 +293,11 @@ public interface IBukkitAdapter { } default Biome adapt(BiomeType biomeType) { - if (!biomeType.getId().startsWith("minecraft:")) { + if (!biomeType.id().startsWith("minecraft:")) { throw new IllegalArgumentException("Bukkit only supports vanilla biomes"); } try { - return Biome.valueOf(biomeType.getId().substring(10).toUpperCase(Locale.ROOT)); + return Biome.valueOf(biomeType.id().substring(10).toUpperCase(Locale.ROOT)); } catch (IllegalArgumentException e) { return null; } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java index c847a8688..6a055de05 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/regions/WorldGuardFeature.java @@ -1,5 +1,6 @@ package com.fastasyncworldedit.bukkit.regions; +import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.regions.FaweMask; import com.fastasyncworldedit.core.regions.RegionWrapper; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -158,6 +159,9 @@ public class WorldGuardFeature extends BukkitMaskManager implements Listener { @Override public FaweMask getMask(com.sk89q.worldedit.entity.Player wePlayer, MaskType type, boolean isWhitelist) { + if (isWhitelist && Settings.settings().REGION_RESTRICTIONS_OPTIONS.WORLDGUARD_REGION_BLACKLIST) { + return new FaweMask(RegionWrapper.GLOBAL()); + } final Player player = BukkitAdapter.adapt(wePlayer); final LocalPlayer localplayer = this.worldguard.wrapPlayer(player); final Location location = player.getLocation(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java index f78e1ae6a..087834f9b 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitBiomeRegistry.java @@ -40,7 +40,7 @@ class BukkitBiomeRegistry implements BiomeRegistry { @Override public Component getRichName(BiomeType biomeType) { return TranslatableComponent.of( - TranslationManager.makeTranslationKey("biome", biomeType.getId()) + TranslationManager.makeTranslationKey("biome", biomeType.id()) ); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 8a0081484..44918557e 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -162,7 +162,7 @@ public class BukkitPlayer extends AbstractPlayerActor { final PlayerInventory inv = player.getInventory(); ItemStack newItem = BukkitAdapter.adapt(itemStack); TaskManager.taskManager().sync(() -> { - if (itemStack.getType().getId().equalsIgnoreCase(WorldEdit.getInstance().getConfiguration().wandItem)) { + if (itemStack.getType().id().equalsIgnoreCase(WorldEdit.getInstance().getConfiguration().wandItem)) { inv.remove(newItem); } final ItemStack item = player.getInventory().getItemInMainHand(); @@ -267,7 +267,7 @@ public class BukkitPlayer extends AbstractPlayerActor { @Override public void setGameMode(GameMode gameMode) { - player.setGameMode(org.bukkit.GameMode.valueOf(gameMode.getId().toUpperCase(Locale.ROOT))); + player.setGameMode(org.bukkit.GameMode.valueOf(gameMode.id().toUpperCase(Locale.ROOT))); } @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java index b060d78f8..2ad20fb6f 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitPlayerBlockBag.java @@ -192,6 +192,9 @@ public class BukkitPlayerBlockBag extends BlockBag implements SlottableBlockBag @Override public BaseItem getItem(int slot) { loadInventory(); + if (items[slot] == null) { + return null; + } return BukkitAdapter.adapt(items[slot]); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java index d0d3ee96c..73a7421c3 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitServerInterface.java @@ -234,7 +234,7 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser //FAWE start @Override - public String getId() { + public String id() { return "intellectualsites:bukkit"; } //FAWE end diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index b2fdeead9..66507c151 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -224,7 +224,7 @@ public class BukkitWorld extends AbstractWorld { //FAWE end @Override - public String getId() { + public String id() { return getWorld().getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java index b4556409c..faac1c955 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java @@ -137,6 +137,10 @@ public class WorldEditPlugin extends JavaPlugin { //noinspection ResultOfMethodCallIgnored getDataFolder().mkdirs(); + //FAWE start - Migrate from config-legacy to worldedit-config + migrateLegacyConfig(); + //FAWE end + //FAWE start - Modify WorldEdit config name config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "worldedit-config.yml"), true), this); // Load config before we say we've loaded platforms as it is used in listeners of the event @@ -151,10 +155,6 @@ public class WorldEditPlugin extends JavaPlugin { platform = new BukkitServerInterface(this, getServer()); worldEdit.getPlatformManager().register(platform); - //FAWE start - Migrate from config-legacy to worldedit-config - migrateLegacyConfig(); - //FAWE end - //FAWE start - Setup permission attachments permissionAttachmentManager = new BukkitPermissionAttachmentManager(this); //FAWE end diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java index 1fdb97ae6..01ad15c1e 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIBlockRegistry.java @@ -68,7 +68,7 @@ public class CLIBlockRegistry extends BundledBlockRegistry { @Override public Map> getProperties(BlockType blockType) { Map properties = - CLIWorldEdit.inst.getFileRegistries().getDataFile().blocks.get(blockType.getId()).properties; + CLIWorldEdit.inst.getFileRegistries().getDataFile().blocks.get(blockType.id()).properties; Maps.EntryTransformer> entryTransform = (key, value) -> createProperty(value.type, key, value.values); return ImmutableMap.copyOf(Maps.transformEntries(properties, entryTransform)); diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java index e9a397b73..4895a2922 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/CLIPlatform.java @@ -115,7 +115,7 @@ class CLIPlatform extends AbstractPlatform { @Override public World matchWorld(World world) { return this.worlds.stream() - .filter(w -> w.getId().equals(world.getId())) + .filter(w -> w.id().equals(world.id())) .findAny() .orElse(null); } diff --git a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java index a8190234c..e0b4c64f2 100644 --- a/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java +++ b/worldedit-cli/src/main/java/com/sk89q/worldedit/cli/schematic/ClipboardWorld.java @@ -85,7 +85,7 @@ public class ClipboardWorld extends AbstractWorld implements Clipboard, CLIWorld //FAWE end @Override - public String getId() { + public String id() { return getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java index ff2f69486..829f29da6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/Fawe.java @@ -2,6 +2,7 @@ package com.fastasyncworldedit.core; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.internal.exception.FaweException; +import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.queue.implementation.QueueHandler; import com.fastasyncworldedit.core.util.CachedTextureUtil; import com.fastasyncworldedit.core.util.CleanTextureUtil; @@ -105,6 +106,8 @@ public class Fawe { * Implementation dependent stuff */ this.setupConfigs(); + FaweLimit.MAX.CONFIRM_LARGE = + Settings.settings().LIMITS.get("default").CONFIRM_LARGE || Settings.settings().GENERAL.LIMIT_UNLIMITED_CONFIRMS; TaskManager.IMP = this.implementation.getTaskManager(); TaskManager.taskManager().async(() -> { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java index e5185e6d8..d230ab05b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Config.java @@ -100,6 +100,9 @@ public class Config { } public boolean load(File file) { + if (!file.exists()) { + return false; + } existingMigrateNodes = new ArrayList<>(); YamlConfiguration yml = YamlConfiguration.loadConfiguration(file); for (String key : yml.getKeys(true)) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java index cf0ba6f35..d069e62a1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/Settings.java @@ -791,6 +791,11 @@ public class Settings extends Config { }) public boolean UNSTUCK_ON_GENERATE = true; + @Comment({ + "If unlimited limits should still require /confirm on large. Defaults to limits.default.confirm-large otherwise." + }) + public boolean LIMIT_UNLIMITED_CONFIRMS = true; + } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/file/YamlConfiguration.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/file/YamlConfiguration.java index 1e2d5b0c4..f900451b5 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/file/YamlConfiguration.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/configuration/file/YamlConfiguration.java @@ -68,6 +68,7 @@ public class YamlConfiguration extends FileConfiguration { LOGGER.error("Could not read {}\n" + "Renamed to {}", file, dest.getAbsolutePath(), ex); } catch (final IOException e) { e.printStackTrace(); + ex.printStackTrace(); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/TransformFactory.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/TransformFactory.java index 06122c705..5cd2743ca 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/TransformFactory.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/TransformFactory.java @@ -21,22 +21,17 @@ import com.sk89q.worldedit.internal.registry.AbstractFactory; import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.util.formatting.text.TextComponent; -import java.util.ArrayList; import java.util.List; public class TransformFactory extends AbstractFactory { - private final RichTransformParser richTransformParser; - /** * Create a new factory. * * @param worldEdit the WorldEdit instance */ public TransformFactory(WorldEdit worldEdit) { - super(worldEdit, new NullTransformParser(worldEdit)); - - richTransformParser = new RichTransformParser(worldEdit); + super(worldEdit, new NullTransformParser(worldEdit), new RichTransformParser(worldEdit)); // split and parse each sub-transform register(new RandomTransformParser(worldEdit)); @@ -51,68 +46,7 @@ public class TransformFactory extends AbstractFactory { } @Override - public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException { - List transforms = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - ResettableExtent match = richTransformParser.parseFromInput(component, context); - if (match != null) { - transforms.add(match); - continue; - } - parseFromParsers(context, transforms, component); - } - - return getResettableExtent(input, transforms); - } - - private void parseFromParsers( - final ParserContext context, - final List transforms, - final String component - ) { - ResettableExtent match = null; - for (InputParser parser : getParsers()) { - match = parser.parseFromInput(component, context); - - if (match != null) { - break; - } - } - if (match == null) { - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); - } - transforms.add(match); - } - - /** - * Parses a transform without considering parsing through the {@link RichTransformParser}, therefore not accepting - * "richer" parsing where & and , are used. Exists to prevent stack overflows. - * - * @param input input string - * @param context input context - * @return parsed result - * @throws InputParseException if no result found - */ - public ResettableExtent parseWithoutRich(String input, ParserContext context) throws InputParseException { - List transforms = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - parseFromParsers(context, transforms, component); - } - - return getResettableExtent(input, transforms); - } - - private ResettableExtent getResettableExtent(final String input, final List transforms) { + protected ResettableExtent getParsed(final String input, final List transforms) { switch (transforms.size()) { case 0: throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/FaweParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/FaweParser.java index 11d33ef67..08dd05ad1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/FaweParser.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/FaweParser.java @@ -37,14 +37,14 @@ public abstract class FaweParser extends InputParser implements AliasedPar for (int i = 0; i < toParse.length(); i++) { char c = toParse.charAt(i); switch (c) { - case ',', '&' -> { + case ',', '&', ' ' -> { if (expression) { continue; } String result = toParse.substring(last, i); if (!result.isEmpty()) { inputs.add(result); - and.add(c == '&'); + and.add(c == '&' || c == ' '); } else { throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", c)); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/common/HotbarParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/common/HotbarParser.java new file mode 100644 index 000000000..0fe104990 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/common/HotbarParser.java @@ -0,0 +1,72 @@ +package com.fastasyncworldedit.core.extension.factory.parser.common; + +import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.extent.inventory.SlottableBlockBag; +import com.fastasyncworldedit.core.limit.FaweLimit; +import com.google.common.collect.ImmutableList; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.blocks.BaseItem; +import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.extension.input.DisallowedUsageException; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.registry.SimpleInputParser; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.world.block.BlockType; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public abstract class HotbarParser extends SimpleInputParser { + + private final List aliases = ImmutableList.of("#hotbar"); + + protected HotbarParser(final WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public List getMatchedAliases() { + return aliases; + } + + protected List getBlockTypes(ParserContext context) { + Player player = context.requirePlayer(); + BlockBag bag = player.getInventoryBlockBag(); + if (!(bag instanceof final SlottableBlockBag slottable)) { + // Matches DefaultBlockParser + throw new InputParseException(Caption.of("fawe.error.unsupported")); + } + List types = new ArrayList<>(); + FaweLimit limit = player.getLimit(); + boolean anyBlock = player.hasPermission("worldedit.anyblock"); + for (int slot = 0; slot < 9; slot++) { + BaseItem item = slottable.getItem(slot); + if (item != null && item.getType().hasBlockType()) { + BlockType type = item.getType().getBlockType(); + if (!anyBlock && worldEdit.getConfiguration().disallowedBlocks.contains(type.id().toLowerCase(Locale.ROOT))) { + throw new DisallowedUsageException(Caption.of( + "worldedit.error.disallowed-block", + TextComponent.of(type.getId()) + )); + } + if (!limit.isUnlimited()) { + if (limit.DISALLOWED_BLOCKS.contains(type.id().toLowerCase(Locale.ROOT))) { + throw new DisallowedUsageException(Caption.of( + "fawe.error.limit.disallowed-block", + TextComponent.of(type.getId()) + )); + } + } + types.add(type); + } + } + if (types.isEmpty()) { + throw new InputParseException(Caption.of("fawe.error.no-valid-on-hotbar")); + } + return types; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/HotbarMaskParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/HotbarMaskParser.java new file mode 100644 index 000000000..4f56ae109 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/mask/HotbarMaskParser.java @@ -0,0 +1,20 @@ +package com.fastasyncworldedit.core.extension.factory.parser.mask; + +import com.fastasyncworldedit.core.extension.factory.parser.common.HotbarParser; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.function.mask.BlockTypeMask; +import com.sk89q.worldedit.function.mask.Mask; + +public class HotbarMaskParser extends HotbarParser { + + public HotbarMaskParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public Mask parseFromSimpleInput(String input, ParserContext context) { + return new BlockTypeMask(context.getExtent(), getBlockTypes(context)); + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/HotbarPatternParser.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/HotbarPatternParser.java new file mode 100644 index 000000000..2f1db622e --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extension/factory/parser/pattern/HotbarPatternParser.java @@ -0,0 +1,26 @@ +package com.fastasyncworldedit.core.extension.factory.parser.pattern; + +import com.fastasyncworldedit.core.extension.factory.parser.common.HotbarParser; +import com.fastasyncworldedit.core.math.random.TrueRandom; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.extension.input.ParserContext; +import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.pattern.RandomPattern; +import com.sk89q.worldedit.world.block.BlockType; + +public class HotbarPatternParser extends HotbarParser { + + public HotbarPatternParser(WorldEdit worldEdit) { + super(worldEdit); + } + + @Override + public Pattern parseFromSimpleInput(String input, ParserContext context) { + RandomPattern random = new RandomPattern(new TrueRandom()); + for (BlockType type : getBlockTypes(context)) { + random.add(type, 1); + } + return random; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java index f1c523ce3..11f15131f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java @@ -101,7 +101,7 @@ public class DisallowedBlocksExtent extends AbstractDelegateExtent implements IB @SuppressWarnings("unchecked") private > B checkBlock(B block) { if (blockedBlocks != null) { - if (blockedBlocks.contains(block.getBlockType().getId())) { + if (blockedBlocks.contains(block.getBlockType().id())) { return (B) (block instanceof BlockState ? RESERVED : RESERVED.toBaseBlock()); // set to reserved/empty } } @@ -140,7 +140,7 @@ public class DisallowedBlocksExtent extends AbstractDelegateExtent implements IB } BlockState state = BlockTypesCache.states[block]; if (blockedBlocks != null) { - if (blockedBlocks.contains(state.getBlockType().getId())) { + if (blockedBlocks.contains(state.getBlockType().id())) { blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__; continue; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java index d85594215..daad170da 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/HistoryExtent.java @@ -110,7 +110,7 @@ public class HistoryExtent extends AbstractDelegateExtent { @Override public boolean setBiome(BlockVector3 position, BiomeType newBiome) { BiomeType oldBiome = this.getBiome(position); - if (!oldBiome.getId().equals(newBiome.getId())) { + if (!oldBiome.id().equals(newBiome.id())) { this.changeSet.addBiomeChange(position.x(), position.y(), position.z(), oldBiome, newBiome); return getExtent().setBiome(position, newBiome); } else { @@ -121,7 +121,7 @@ public class HistoryExtent extends AbstractDelegateExtent { @Override public boolean setBiome(int x, int y, int z, BiomeType newBiome) { BiomeType oldBiome = this.getBiome(mutable.setComponents(x, y, z)); - if (!oldBiome.getId().equals(newBiome.getId())) { + if (!oldBiome.id().equals(newBiome.id())) { this.changeSet.addBiomeChange(x, y, z, oldBiome, newBiome); return getExtent().setBiome(x, y, z, newBiome); } else { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java index 5218b1c1e..65a4a0e86 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicWriter.java @@ -237,7 +237,7 @@ public class FastSchematicWriter implements ClipboardWriter { if (!brokenEntities) { loc = loc.setPosition(loc.add(min.toVector3())); } - values.put("Id", new StringTag(state.getType().getId())); + values.put("Id", new StringTag(state.getType().id())); values.put("Pos", writeVector(loc)); values.put("Rotation", writeRotation(entity.getLocation())); @@ -297,7 +297,7 @@ public class FastSchematicWriter implements ClipboardWriter { for (int i = 0; i < paletteList.size(); i++) { int ordinal = paletteList.get(i); BiomeType state = BiomeTypes.get(ordinal); - out12.writeNamedTag(state.getId(), i); + out12.writeNamedTag(state.id(), i); } }); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java index d52d74b5a..91fb75495 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/schematic/MinecraftStructure.java @@ -19,7 +19,6 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.registry.state.AbstractProperty; import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.block.BaseBlock; @@ -174,27 +173,23 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { ArrayList> palette = new ArrayList<>(); for (BlockVector3 point : region) { BlockState block = clipboard.getBlock(point); - int combined = block.getInternalId(); + char ordinal = block.getOrdinalChar(); BlockType type = block.getBlockType(); - if (type == BlockTypes.STRUCTURE_VOID || indexes.containsKey(combined)) { + if (type == BlockTypes.STRUCTURE_VOID || indexes.containsKey(ordinal)) { continue; } - indexes.put(combined, (Integer) palette.size()); + indexes.put(ordinal, palette.size()); HashMap paletteEntry = new HashMap<>(); - paletteEntry.put("Name", type.getId()); + paletteEntry.put("Name", type.id()); if (block.getInternalId() != type.getInternalId()) { Map properties = null; - for (AbstractProperty property : (List>) type.getProperties()) { - int propIndex = property.getIndex(block.getInternalId()); - if (propIndex != 0) { - if (properties == null) { - properties = new HashMap<>(); - } - Object value = property.getValues().get(propIndex); - properties.put(property.getName(), value.toString()); + for (Map.Entry, Object> entry : block.getStates().entrySet()) { + if (properties == null) { + properties = new HashMap<>(); } + properties.put(entry.getKey().getName(), entry.getValue().toString()); } if (properties != null) { paletteEntry.put("Properties", properties); @@ -211,16 +206,23 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { for (BlockVector3 point : region) { BaseBlock block = clipboard.getFullBlock(point); if (block.getBlockType() != BlockTypes.STRUCTURE_VOID) { - int combined = block.getInternalId(); - int index = indexes.get(combined); - List pos = Arrays.asList(point.x() - min.x(), - point.y() - min.y(), point.z() - min.z() + char ordinal = block.getOrdinalChar(); + int index = indexes.get(ordinal); + List pos = Arrays.asList( + point.x() - min.x(), + point.y() - min.y(), + point.z() - min.z() ); if (!block.hasNbtData()) { blocks.add(FaweCache.INSTANCE.asMap("state", index, "pos", pos)); } else { + Map tag = new HashMap<>(block.getNbtData().getValue()); + tag.remove("x"); + tag.remove("y"); + tag.remove("z"); + CompoundTag cTag = new CompoundTag(tag); blocks.add( - FaweCache.INSTANCE.asMap("state", index, "pos", pos, "nbt", block.getNbtData())); + FaweCache.INSTANCE.asMap("state", index, "pos", pos, "nbt", cTag)); } } } @@ -231,16 +233,24 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter { ArrayList> entities = new ArrayList<>(); for (Entity entity : clipboard.getEntities()) { Location loc = entity.getLocation(); - List pos = Arrays.asList(loc.x(), loc.y(), loc.z()); - List blockPos = Arrays.asList(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + List pos = Arrays.asList( + loc.x() - min.x(), + loc.y() - min.y(), + loc.z() - min.z() + ); + List blockPos = Arrays.asList( + loc.getBlockX() - min.x(), + loc.getBlockY() - min.y(), + loc.getBlockZ() - min.z() + ); BaseEntity state = entity.getState(); if (state != null) { CompoundTag nbt = state.getNbtData(); - Map nbtMap = nbt.getValue(); + Map nbtMap = new HashMap<>(nbt.getValue()); // Replace rotation data nbtMap.put("Rotation", writeRotation(entity.getLocation())); - nbtMap.put("id", new StringTag(state.getType().getId())); - Map entityMap = FaweCache.INSTANCE.asMap("pos", pos, "blockPos", blockPos, "nbt", nbt); + nbtMap.put("id", new StringTag(state.getType().id())); + Map entityMap = FaweCache.INSTANCE.asMap("pos", pos, "blockPos", blockPos, "nbt", new CompoundTag(nbtMap)); entities.add(entityMap); } } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java index dbe717e49..2ad473130 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/lighting/NMSRelighter.java @@ -346,7 +346,7 @@ public class NMSRelighter implements Relighter { } int lightLevel = iChunk.getEmittedLight(node.x() & 15, node.y(), node.z() & 15); BlockState state = this.queue.getBlock(node.x(), node.y(), node.z()); - String id = state.getBlockType().getId().toLowerCase(Locale.ROOT); + String id = state.getBlockType().id().toLowerCase(Locale.ROOT); if (lightLevel <= 1) { continue; } @@ -396,7 +396,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairEast(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break east; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x + 1, y, z, currentLight, queue, visited); break east; } @@ -449,7 +449,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairWest(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break west; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x - 1, y, z, currentLight, queue, visited); break west; } @@ -502,7 +502,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairSouth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break south; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x, y, z + 1, currentLight, queue, visited); break south; } @@ -555,7 +555,7 @@ public class NMSRelighter implements Relighter { if (!(checkStairNorth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) { break north; } - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { this.computeSpreadBlockLight(x, y, z - 1, currentLight, queue, visited); break north; } @@ -707,7 +707,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairNorth(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -725,7 +725,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairSouth(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -743,7 +743,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairEast(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -761,7 +761,7 @@ public class NMSRelighter implements Relighter { } private boolean checkStairWest(BlockState state) { - if (!state.getBlockType().getId().toLowerCase(Locale.ROOT).contains("stair")) { + if (!state.getBlockType().id().toLowerCase(Locale.ROOT).contains("stair")) { return true; } Direction direction = getStairDir(state); @@ -787,11 +787,11 @@ public class NMSRelighter implements Relighter { } private boolean isStairOrTrueTop(BlockState state, boolean top) { - return !state.getBlockType().getId().contains("stair") || state.getState(stairHalf).equals("top") == top; + return !state.getBlockType().id().contains("stair") || state.getState(stairHalf).equals("top") == top; } private boolean isSlabOrTrueValue(BlockState state, String value) { - return !state.getBlockType().getId().contains("slab") || state.getState(slabHalf).equals(value); + return !state.getBlockType().id().contains("slab") || state.getState(slabHalf).equals(value); } private void computeRemoveBlockLight( diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java index b9a403f27..7e4b61514 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/generator/CavesGen.java @@ -236,7 +236,7 @@ public class CavesGen extends GenBase { BlockState material = chunk.getBlock(bx + local_x, local_y, bz + local_z); BlockState materialAbove = chunk.getBlock(bx + local_x, local_y + 1, bz + local_z); BlockType blockType = material.getBlockType(); - switch (blockType.getId()) { + switch (blockType.id()) { case "minecraft:mycelium", "minecraft:grass_block" -> grassFound = true; } if (this.isSuitableBlock(material, materialAbove)) { @@ -277,7 +277,7 @@ public class CavesGen extends GenBase { } protected boolean isSuitableBlock(BlockStateHolder material, BlockStateHolder materialAbove) { - return switch (material.getBlockType().getId()) { + return switch (material.getBlockType().id()) { case "minecraft:air", "minecraft:cave_air", "minecraft:void_air", "minecraft:water", "minecraft:lava", "minecraft:bedrock" -> false; default -> true; }; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java index 1f0b88bfa..7fdebdded 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/ABlockMask.java @@ -40,7 +40,7 @@ public abstract class ABlockMask extends AbstractExtentMask { List all = type.getAllStates(); hasAll = all.stream().map(this::test).reduce(true, (a, b) -> a && b); if (hasAll) { - strings.add(type.getId()); + strings.add(type.id()); } else { for (BlockState state : all) { if (test(state)) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java index 2471ff262..baef7f767 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/mask/BlockMaskBuilder.java @@ -183,7 +183,7 @@ public class BlockMaskBuilder { builders = new ArrayList<>(); Pattern pattern = Pattern.compile("(minecraft:)?" + regex); for (BlockType type : BlockTypesCache.values) { - if (pattern.matcher(type.getId()).find()) { + if (pattern.matcher(type.id()).find()) { blockTypeList.add(type); builders.add(new FuzzyStateAllowingBuilder(type)); add(type); @@ -284,7 +284,7 @@ public class BlockMaskBuilder { } else { boolean success = false; for (BlockType myType : BlockTypesCache.values) { - if (myType.getId().matches("(minecraft:)?" + input)) { + if (myType.id().matches("(minecraft:)?" + input)) { add(myType); success = true; } @@ -571,7 +571,7 @@ public class BlockMaskBuilder { throw new IllegalArgumentException(String.format( "Property %s cannot be applied to block type %s", property.getName(), - type.getId() + type.id() )); } masked.computeIfAbsent(property, k -> new ArrayList<>()).add(index); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java index efc122b5d..d222833a7 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/TypeSwapPattern.java @@ -79,7 +79,7 @@ public class TypeSwapPattern extends AbstractExtentPattern { } private BlockState getNewBlock(BlockState existing) { - String oldId = existing.getBlockType().getId(); + String oldId = existing.getBlockType().id(); String newId = oldId; if (inputPattern != null) { newId = inputPattern.matcher(oldId).replaceAll(outputString); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java index e5820fd44..08165577f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java @@ -297,7 +297,7 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { public void add(BlockChange change) { try { BlockVector3 loc = change.getPosition(); - BaseBlock from = change.getPrevious(); + BaseBlock from = change.previous(); BaseBlock to = change.getCurrent(); add(loc, from, to); } catch (Exception e) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java index 5ecc89d44..e30ee4db6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/limit/FaweLimit.java @@ -1,6 +1,7 @@ package com.fastasyncworldedit.core.limit; import com.fastasyncworldedit.core.FaweCache; +import com.fastasyncworldedit.core.configuration.Settings; import java.util.Collections; import java.util.Set; @@ -121,7 +122,8 @@ public class FaweLimit { MAX.SCHEM_FILE_SIZE_LIMIT = Integer.MAX_VALUE; MAX.MAX_EXPRESSION_MS = 50; MAX.FAST_PLACEMENT = true; - MAX.CONFIRM_LARGE = true; + MAX.CONFIRM_LARGE = + Settings.settings().LIMITS.get("default").CONFIRM_LARGE || Settings.settings().GENERAL.LIMIT_UNLIMITED_CONFIRMS; MAX.RESTRICT_HISTORY_TO_REGIONS = false; MAX.STRIP_NBT = Collections.emptySet(); MAX.UNIVERSAL_DISALLOWED_BLOCKS = false; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java index c2ca764e9..7f3da036f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IQueueExtent.java @@ -130,7 +130,7 @@ public interface IQueueExtent extends Flushable, Trimable, ICh * A filter block is used to iterate over blocks / positions. Essentially combines BlockVector3, * Extent and BlockState functions in a way that avoids lookups. */ - ChunkFilterBlock initFilterBlock(); + ChunkFilterBlock createFilterBlock(); /** * Returns the number of chunks in this queue. @@ -144,7 +144,14 @@ public interface IQueueExtent extends Flushable, Trimable, ICh */ boolean isEmpty(); - default ChunkFilterBlock apply(ChunkFilterBlock block, Filter filter, Region region, int chunkX, int chunkZ, boolean full) { + default ChunkFilterBlock apply( + @Nullable ChunkFilterBlock block, + Filter filter, + Region region, + int chunkX, + int chunkZ, + boolean full + ) { if (!filter.appliesChunk(chunkX, chunkZ)) { return block; } @@ -154,8 +161,9 @@ public interface IQueueExtent extends Flushable, Trimable, ICh if (newChunk != null) { chunk = newChunk; if (block == null) { - block = this.initFilterBlock(); + block = this.createFilterBlock(); } + block.initChunk(chunkX, chunkZ); chunk.filterBlocks(filter, block, region, full); } this.submit(chunk); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java index 8aadd1ffb..a79da2bbf 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/ParallelQueueExtent.java @@ -31,6 +31,7 @@ import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Countable; import com.sk89q.worldedit.util.SideEffectSet; @@ -145,9 +146,10 @@ public class ParallelQueueExtent extends PassthroughExtent { final int size = Math.min(chunks.size(), Settings.settings().QUEUE.PARALLEL_THREADS); if (size <= 1) { // if PQE is ever used with PARALLEL_THREADS = 1, or only one chunk is edited, just run sequentially + ChunkFilterBlock block = null; while (chunksIter.hasNext()) { BlockVector2 pos = chunksIter.next(); - getExtent().apply(null, filter, region, pos.x(), pos.z(), full); + block = getExtent().apply(block, filter, region, pos.x(), pos.z(), full); } getExtent().flush(); filter.finish(); @@ -155,6 +157,7 @@ public class ParallelQueueExtent extends PassthroughExtent { final ForkJoinTask[] tasks = IntStream.range(0, size).mapToObj(i -> handler.submit(() -> { try { final Filter newFilter = filter.fork(); + final Region newRegion = region.clone(); // Create a chunk that we will reuse/reset for each operation final SingleThreadQueueExtent queue = (SingleThreadQueueExtent) getNewQueue(); synchronized (queue) { @@ -172,7 +175,7 @@ public class ParallelQueueExtent extends PassthroughExtent { chunkX = pos.x(); chunkZ = pos.z(); } - block = queue.apply(block, newFilter, region, chunkX, chunkZ, full); + block = queue.apply(block, newFilter, newRegion, chunkX, chunkZ, full); } queue.flush(); filter.finish(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java index 47cf86933..389f0d66e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java @@ -495,7 +495,7 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen } @Override - public ChunkFilterBlock initFilterBlock() { + public ChunkFilterBlock createFilterBlock() { return new CharFilterBlock(this); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java index 6eae2db5b..047394322 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java @@ -17,13 +17,23 @@ public abstract class CharBlocks implements IBlocks { protected static final Section FULL = new Section() { @Override public char[] get(CharBlocks blocks, int layer) { - return blocks.blocks[layer]; + char[] arr = blocks.blocks[layer]; + if (arr == null) { + // Chunk probably trimmed mid-operations, but do nothing about it to avoid other issues + return EMPTY.get(blocks, layer, false); + } + return arr; } // Ignore aggressive switch here. @Override public char[] get(CharBlocks blocks, int layer, boolean aggressive) { - return blocks.blocks[layer]; + char[] arr = blocks.blocks[layer]; + if (arr == null) { + // Chunk probably trimmed mid-operations, but do nothing about it to avoid other issues + return EMPTY.get(blocks, layer, false); + } + return arr; } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java index dbfe840c8..a1471c9d8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/PolyhedralRegion.java @@ -71,7 +71,7 @@ public class PolyhedralRegion extends AbstractRegion { public PolyhedralRegion(PolyhedralRegion region) { this(region.world); vertices.addAll(region.vertices); - triangles.addAll(region.triangles); + region.triangles.forEach(triangle -> triangles.add(triangle.clone())); vertexBacklog.addAll(region.vertexBacklog); minimumPoint = region.minimumPoint; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java index 2bb9fc5ac..1d96d5f95 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/regions/Triangle.java @@ -7,10 +7,14 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.regions.polyhedron.Edge; -public class Triangle { +public class Triangle implements Cloneable { public static double RADIUS = 0.5; + private final BlockVector3 pos1; + private final BlockVector3 pos2; + private final BlockVector3 pos3; + private final double[][] verts = new double[3][3]; private final double[] center = new double[3]; private final double[] radius = new double[3]; @@ -28,6 +32,9 @@ public class Triangle { private final double b; public Triangle(BlockVector3 pos1, BlockVector3 pos2, BlockVector3 pos3) { + this.pos1 = pos1; + this.pos2 = pos2; + this.pos3 = pos3; verts[0] = new double[]{pos1.x(), pos1.y(), pos1.z()}; verts[1] = new double[]{pos2.x(), pos2.y(), pos2.z()}; verts[2] = new double[]{pos3.x(), pos3.y(), pos3.z()}; @@ -290,4 +297,9 @@ public class Triangle { return dot(normal, vmax) >= 0.0f; } + @Override + public Triangle clone() { + return new Triangle(pos1, pos2, pos3); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java index 117ab8fab..7d7d5d642 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/MainUtil.java @@ -444,7 +444,7 @@ public class MainUtil { @Nonnull public static CompoundTag setEntityInfo(@Nonnull CompoundTag tag, @Nonnull Entity entity) { Map map = new HashMap<>(tag.getValue()); - map.put("Id", new StringTag(entity.getState().getType().getId())); + map.put("Id", new StringTag(entity.getState().getType().id())); ListTag pos = (ListTag) map.get("Pos"); if (pos != null) { Location loc = entity.getLocation(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java index f6f896f56..7c4e7137b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/util/TextureUtil.java @@ -929,10 +929,10 @@ public class TextureUtil implements TextureHolder { }.getType(); for (BlockType blockType : BlockTypesCache.values) { - if (!blockType.getMaterial().isFullCube() || blockType.getId().toLowerCase().contains("shulker")) { + if (!blockType.getMaterial().isFullCube() || blockType.id().toLowerCase().contains("shulker")) { continue; } - switch (blockType.getId().toLowerCase(Locale.ROOT)) { + switch (blockType.id().toLowerCase(Locale.ROOT)) { case "slime_block": case "honey_block": case "mob_spawner": @@ -940,7 +940,7 @@ public class TextureUtil implements TextureHolder { continue; } int combined = blockType.getInternalId(); - String id = blockType.getId(); + String id = blockType.id(); String[] split = id.split(":", 2); String name = split.length == 1 ? id : split[1]; String nameSpace = split.length == 1 ? "" : split[0]; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java index 7e2ba4549..1301c5bb3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java @@ -196,7 +196,7 @@ public abstract class LocalConfiguration { BlockTypes.BEDROCK FAWE end*/ ); - return blockTypes.stream().filter(Objects::nonNull).map(BlockType::getId).toArray(String[]::new); + return blockTypes.stream().filter(Objects::nonNull).map(BlockType::id).toArray(String[]::new); } /** @@ -277,7 +277,7 @@ public abstract class LocalConfiguration { id = Integer.parseInt(splitter[0]); data = Byte.parseByte(splitter[1]); } - item = LegacyMapper.getInstance().getItemFromLegacy(id, data).getId(); + item = LegacyMapper.getInstance().getItemFromLegacy(id, data).id(); } catch (Throwable ignored) { } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java index 99f949be4..ff72fc4ea 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -1906,7 +1906,7 @@ public class LocalSession implements TextureHolder { */ @Deprecated public String getWandItem() { - return wandItem.getType().getId(); + return wandItem.getType().id(); } /** @@ -1917,7 +1917,7 @@ public class LocalSession implements TextureHolder { */ @Deprecated public String getNavWandItem() { - return navWandItem.getType().getId(); + return navWandItem.getType().id(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java index ac8236297..fe2e1a635 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java @@ -129,7 +129,7 @@ public class BaseItem implements NbtValued { } } - return getType().getId() + nbtString; + return getType().id() + nbtString; } //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java index 0b2bd576d..a60968da1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/BiomeCommands.java @@ -98,7 +98,7 @@ public class BiomeCommands { PaginationBox paginationBox = PaginationBox.fromComponents("Available Biomes", "/biomelist -p %page%", BiomeType.REGISTRY.values().stream() .map(biomeType -> TextComponent.builder() - .append(biomeType.getId()) + .append(biomeType.id()) .append(" (") .append(biomeRegistry.getRichName(biomeType)) .append(")") @@ -166,7 +166,7 @@ public class BiomeCommands { List components = biomes.stream().map(biome -> biomeRegistry.getRichName(biome).hoverEvent( - HoverEvent.showText(TextComponent.of(biome.getId())) + HoverEvent.showText(TextComponent.of(biome.id())) ) ).collect(Collectors.toList()); actor.print(Caption.of(messageKey, TextUtils.join(components, TextComponent.of(", ")))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java index 0cf5b1a78..3b271a1ec 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/GeneralCommands.java @@ -349,7 +349,7 @@ public class GeneralCommands { if (world == null) { actor.print(Caption.of("worldedit.world.remove")); } else { - actor.print(Caption.of("worldedit.world.set", TextComponent.of(world.getId()))); + actor.print(Caption.of("worldedit.world.set", TextComponent.of(world.id()))); } } @@ -641,7 +641,7 @@ public class GeneralCommands { if (itemsOnly && searchType.hasBlockType()) { continue; } - final String id = searchType.getId(); + final String id = searchType.id(); if (id.contains(idMatch)) { Component name = searchType.getRichName(); results.put(id, TextComponent.builder() diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index d000fcef7..ddca046ff 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -79,8 +79,6 @@ import com.sk89q.worldedit.util.formatting.text.format.TextColor; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockType; -import com.sk89q.worldedit.world.item.ItemType; -import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.storage.ChunkStore; import org.enginehub.piston.annotation.Command; import org.enginehub.piston.annotation.CommandContainer; @@ -841,7 +839,7 @@ public class SelectionCommands { toolTip = TextComponent.of(state.getAsString()); blockName = blockName.append(TextComponent.of("*")); } else { - toolTip = TextComponent.of(blockType.getId()); + toolTip = TextComponent.of(blockType.id()); } blockName = blockName.hoverEvent(HoverEvent.of(HoverEvent.Action.SHOW_TEXT, toolTip)); line.append(blockName); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java index db611b75c..04274a79a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/WorldEditCommands.java @@ -22,6 +22,8 @@ package com.sk89q.worldedit.command; import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.FaweVersion; import com.fastasyncworldedit.core.configuration.Caption; +import com.fastasyncworldedit.core.configuration.Settings; +import com.fastasyncworldedit.core.limit.FaweLimit; import com.fastasyncworldedit.core.util.UpdateNotification; import com.intellectualsites.paster.IncendoPaster; import com.sk89q.worldedit.LocalSession; @@ -97,6 +99,8 @@ public class WorldEditCommands { .getConfiguration())); //FAWE start Fawe.instance().setupConfigs(); + FaweLimit.MAX.CONFIRM_LARGE = + Settings.settings().LIMITS.get("default").CONFIRM_LARGE || Settings.settings().GENERAL.LIMIT_UNLIMITED_CONFIRMS; //FAWE end actor.print(Caption.of("worldedit.reload.config")); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java index fd043d440..54492497a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/argument/WorldConverter.java @@ -65,7 +65,7 @@ public class WorldConverter implements ArgumentConverter { @Override public List getSuggestions(String input, InjectedValueAccess context) { return getWorlds() - .map(World::getId) + .map(World::id) .filter(world -> world.startsWith(input)) .collect(Collectors.toList()); } @@ -73,7 +73,7 @@ public class WorldConverter implements ArgumentConverter { @Override public ConversionResult convert(String s, InjectedValueAccess injectedValueAccess) { World result = getWorlds() - .filter(world -> world.getId().equals(s)) + .filter(world -> world.id().equals(s)) .findAny().orElse(null); return result == null ? FailedConversion.from(new IllegalArgumentException( diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java index b9a2ee888..2d35b2226 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/command/tool/BlockDataCyler.java @@ -66,7 +66,7 @@ public class BlockDataCyler implements DoubleActionBlockTool { if (!config.allowedDataCycleBlocks.isEmpty() && !player.hasPermission("worldedit.override.data-cycler") - && !config.allowedDataCycleBlocks.contains(block.getBlockType().getId())) { + && !config.allowedDataCycleBlocks.contains(block.getBlockType().id())) { player.print(Caption.of("worldedit.tool.data-cycler.block-not-permitted")); return true; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java index 14ecb48f1..f436ce576 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/BlockFactory.java @@ -23,11 +23,16 @@ import com.sk89q.util.StringUtil; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser; import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.internal.registry.AbstractFactory; +import com.sk89q.worldedit.internal.registry.InputParser; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; import com.sk89q.worldedit.world.block.BaseBlock; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -67,4 +72,21 @@ public class BlockFactory extends AbstractFactory { return blocks; } + //FAWE start + @Override + public BaseBlock parseFromInput(String input, ParserContext context) throws InputParseException { + BaseBlock match; + + for (InputParser parser : parsers) { + match = parser.parseFromInput(input, context); + + if (match != null) { + return match; + } + } + + throw new NoMatchException(TranslatableComponent.of("worldedit.error.no-match", TextComponent.of(input))); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java index b1858a12d..8c907f42a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/ItemFactory.java @@ -22,7 +22,13 @@ package com.sk89q.worldedit.extension.factory; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.extension.factory.parser.DefaultItemParser; +import com.sk89q.worldedit.extension.input.InputParseException; +import com.sk89q.worldedit.extension.input.NoMatchException; +import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.internal.registry.AbstractFactory; +import com.sk89q.worldedit.internal.registry.InputParser; +import com.sk89q.worldedit.util.formatting.text.TextComponent; +import com.sk89q.worldedit.util.formatting.text.TranslatableComponent; public class ItemFactory extends AbstractFactory { @@ -35,4 +41,21 @@ public class ItemFactory extends AbstractFactory { super(worldEdit, new DefaultItemParser(worldEdit)); } + //FAWE start + @Override + public BaseItem parseFromInput(String input, ParserContext context) throws InputParseException { + BaseItem match; + + for (InputParser parser : parsers) { + match = parser.parseFromInput(input, context); + + if (match != null) { + return match; + } + } + + throw new NoMatchException(TranslatableComponent.of("worldedit.error.no-match", TextComponent.of(input))); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java index 5c8ff7d6f..3440b009c 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/MaskFactory.java @@ -25,6 +25,7 @@ import com.fastasyncworldedit.core.extension.factory.parser.mask.AngleMaskParser import com.fastasyncworldedit.core.extension.factory.parser.mask.BesideMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.ExtremaMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.FalseMaskParser; +import com.fastasyncworldedit.core.extension.factory.parser.mask.HotbarMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.LiquidMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.ROCAngleMaskParser; import com.fastasyncworldedit.core.extension.factory.parser.mask.RadiusMaskParser; @@ -52,16 +53,13 @@ import com.sk89q.worldedit.extension.factory.parser.mask.NoiseMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.OffsetMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser; -import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.MaskIntersection; import com.sk89q.worldedit.internal.registry.AbstractFactory; -import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.util.formatting.text.TextComponent; -import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -74,21 +72,13 @@ import java.util.stream.Collectors; */ public final class MaskFactory extends AbstractFactory { - //FAWE start - rich mask parsing - private final RichMaskParser richMaskParser; - //FAWE end - /** * Create a new mask registry. * * @param worldEdit the WorldEdit instance */ public MaskFactory(WorldEdit worldEdit) { - super(worldEdit, new BlocksMaskParser(worldEdit)); - - //FAWE start - rich mask parsing - richMaskParser = new RichMaskParser(worldEdit); - //FAWE end + super(worldEdit, new BlocksMaskParser(worldEdit), new RichMaskParser(worldEdit)); register(new ExistingMaskParser(worldEdit)); register(new AirMaskParser(worldEdit)); @@ -110,6 +100,7 @@ public final class MaskFactory extends AbstractFactory { register(new BesideMaskParser(worldEdit)); register(new ExtremaMaskParser(worldEdit)); register(new FalseMaskParser(worldEdit)); + register(new HotbarMaskParser(worldEdit)); register(new LiquidMaskParser(worldEdit)); register(new RadiusMaskParser(worldEdit)); register(new RichOffsetMaskParser(worldEdit)); @@ -123,7 +114,6 @@ public final class MaskFactory extends AbstractFactory { register(new ZAxisMaskParser(worldEdit)); register(new SurfaceAngleMaskParser(worldEdit)); //FAWE end - } @Override @@ -131,85 +121,24 @@ public final class MaskFactory extends AbstractFactory { final String[] split = input.split(" "); if (split.length > 1) { String prev = input.substring(0, input.lastIndexOf(" ")) + " "; - return super.getSuggestions(split[split.length - 1], parserContext).stream().map(s -> prev + s).collect(Collectors.toList()); + return super + .getSuggestions(split[split.length - 1], parserContext) + .stream() + .map(s -> prev + s) + .collect(Collectors.toList()); } return super.getSuggestions(input, parserContext); } - @Override - public Mask parseFromInput(String input, ParserContext context) throws InputParseException { - List masks = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - //FAWE start - rich mask parsing - Mask match = richMaskParser.parseFromInput(component, context); - if (match != null) { - masks.add(match); - continue; - } - parseFromParsers(context, masks, component); - //FAWE end - } - - return getMask(input, masks); - } - //FAWE start - rich mask parsing - private void parseFromParsers( - final ParserContext context, - final List masks, - final String component - ) { - Mask match = null; - for (InputParser parser : getParsers()) { - match = parser.parseFromInput(component, context); - if (match != null) { - break; - } - } - if (match == null) { - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); - } - masks.add(match); - } - - /** - * Parses a mask without considering parsing through the {@link RichMaskParser}, therefore not accepting - * "richer" parsing where & and , are used. Exists to prevent stack overflows. - * - * @param input input string - * @param context input context - * @return parsed result - * @throws InputParseException if no result found - */ - public Mask parseWithoutRich(String input, ParserContext context) throws InputParseException { - List masks = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - parseFromParsers(context, masks, component); - } - - return getMask(input, masks); - } - - private Mask getMask(final String input, final List masks) { - switch (masks.size()) { - case 0: - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); - case 1: - return masks.get(0).optimize(); - default: - return new MaskIntersection(masks).optimize(); - } + @Override + protected Mask getParsed(final String input, final List masks) { + return switch (masks.size()) { + case 0 -> throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); + case 1 -> masks.get(0).optimize(); + default -> new MaskIntersection(masks).optimize(); + }; } //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java index a76759833..25955adee 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/PatternFactory.java @@ -30,6 +30,7 @@ import com.fastasyncworldedit.core.extension.factory.parser.pattern.DarkenPatter import com.fastasyncworldedit.core.extension.factory.parser.pattern.DesaturatePatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.ExistingPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.ExpressionPatternParser; +import com.fastasyncworldedit.core.extension.factory.parser.pattern.HotbarPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.LightenPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.Linear2DPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.Linear3DPatternParser; @@ -42,8 +43,6 @@ import com.fastasyncworldedit.core.extension.factory.parser.pattern.OffsetPatter import com.fastasyncworldedit.core.extension.factory.parser.pattern.PerlinPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomFullClipboardPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomOffsetPatternParser; -import com.fastasyncworldedit.core.extension.factory.parser.pattern.TypeSwapPatternParser; -import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RelativePatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RidgedMultiFractalPatternParser; @@ -51,24 +50,22 @@ import com.fastasyncworldedit.core.extension.factory.parser.pattern.SaturatePatt import com.fastasyncworldedit.core.extension.factory.parser.pattern.SimplexPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.SolidRandomOffsetPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.SurfaceRandomOffsetPatternParser; +import com.fastasyncworldedit.core.extension.factory.parser.pattern.TypeSwapPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.VoronoiPatternParser; import com.fastasyncworldedit.core.math.random.TrueRandom; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.ClipboardPatternParser; +import com.sk89q.worldedit.extension.factory.parser.pattern.RandomPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.RandomStatePatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser; -import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; -import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.internal.registry.AbstractFactory; -import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.util.formatting.text.TextComponent; -import java.util.ArrayList; import java.util.List; /** @@ -80,20 +77,14 @@ import java.util.List; */ public final class PatternFactory extends AbstractFactory { - //FAWE start - rich pattern parsing - private final RichPatternParser richPatternParser; - //FAWE end - /** * Create a new instance. * * @param worldEdit the WorldEdit instance */ public PatternFactory(WorldEdit worldEdit) { - super(worldEdit, new SingleBlockPatternParser(worldEdit)); - //FAWE start - rich pattern parsing - richPatternParser = new RichPatternParser(worldEdit); + super(worldEdit, new SingleBlockPatternParser(worldEdit), new RichPatternParser(worldEdit)); //FAWE end // split and parse each sub-pattern @@ -116,6 +107,7 @@ public final class PatternFactory extends AbstractFactory { register(new DesaturatePatternParser(worldEdit)); register(new ExistingPatternParser(worldEdit)); register(new ExpressionPatternParser(worldEdit)); + register(new HotbarPatternParser(worldEdit)); register(new LightenPatternParser(worldEdit)); register(new Linear2DPatternParser(worldEdit)); register(new Linear3DPatternParser(worldEdit)); @@ -136,75 +128,10 @@ public final class PatternFactory extends AbstractFactory { register(new SurfaceRandomOffsetPatternParser(worldEdit)); register(new TypeSwapPatternParser(worldEdit)); register(new VoronoiPatternParser(worldEdit)); - //FAWE end } @Override - public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { - List patterns = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - //FAWE start - rich pattern parsing - Pattern match = richPatternParser.parseFromInput(component, context); - if (match != null) { - patterns.add(match); - continue; - } - parseFromParsers(context, patterns, component); - //FAWE end - } - - return getPattern(input, patterns); - } - - //FAWE start - rich pattern parsing - private void parseFromParsers( - final ParserContext context, - final List patterns, - final String component - ) { - Pattern match = null; - for (InputParser parser : getParsers()) { - match = parser.parseFromInput(component, context); - - if (match != null) { - break; - } - } - if (match == null) { - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); - } - patterns.add(match); - } - - /** - * Parses a pattern without considering parsing through the {@link RichPatternParser}, therefore not accepting - * "richer" parsing where & and , are used. Exists to prevent stack overflows. - * - * @param input input string - * @param context input context - * @return parsed result - * @throws InputParseException if no result found - */ - public Pattern parseWithoutRich(String input, ParserContext context) throws InputParseException { - List patterns = new ArrayList<>(); - - for (String component : input.split(" ")) { - if (component.isEmpty()) { - continue; - } - - parseFromParsers(context, patterns, component); - } - - return getPattern(input, patterns); - } - - private Pattern getPattern(final String input, final List patterns) { + protected Pattern getParsed(final String input, final List patterns) { switch (patterns.size()) { case 0: throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java index 969216896..03cfb51e3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java @@ -135,42 +135,42 @@ public class DefaultBlockParser extends InputParser { private String woolMapper(String string) { switch (string.toLowerCase(Locale.ROOT)) { case "white": - return BlockTypes.WHITE_WOOL.getId(); + return BlockTypes.WHITE_WOOL.id(); case "black": - return BlockTypes.BLACK_WOOL.getId(); + return BlockTypes.BLACK_WOOL.id(); case "blue": - return BlockTypes.BLUE_WOOL.getId(); + return BlockTypes.BLUE_WOOL.id(); case "brown": - return BlockTypes.BROWN_WOOL.getId(); + return BlockTypes.BROWN_WOOL.id(); case "cyan": - return BlockTypes.CYAN_WOOL.getId(); + return BlockTypes.CYAN_WOOL.id(); case "gray": case "grey": - return BlockTypes.GRAY_WOOL.getId(); + return BlockTypes.GRAY_WOOL.id(); case "green": - return BlockTypes.GREEN_WOOL.getId(); + return BlockTypes.GREEN_WOOL.id(); case "light_blue": case "lightblue": - return BlockTypes.LIGHT_BLUE_WOOL.getId(); + return BlockTypes.LIGHT_BLUE_WOOL.id(); case "light_gray": case "light_grey": case "lightgray": case "lightgrey": - return BlockTypes.LIGHT_GRAY_WOOL.getId(); + return BlockTypes.LIGHT_GRAY_WOOL.id(); case "lime": - return BlockTypes.LIME_WOOL.getId(); + return BlockTypes.LIME_WOOL.id(); case "magenta": - return BlockTypes.MAGENTA_WOOL.getId(); + return BlockTypes.MAGENTA_WOOL.id(); case "orange": - return BlockTypes.ORANGE_WOOL.getId(); + return BlockTypes.ORANGE_WOOL.id(); case "pink": - return BlockTypes.PINK_WOOL.getId(); + return BlockTypes.PINK_WOOL.id(); case "purple": - return BlockTypes.PURPLE_WOOL.getId(); + return BlockTypes.PURPLE_WOOL.id(); case "yellow": - return BlockTypes.YELLOW_WOOL.getId(); + return BlockTypes.YELLOW_WOOL.id(); case "red": - return BlockTypes.RED_WOOL.getId(); + return BlockTypes.RED_WOOL.id(); default: return string; } @@ -194,7 +194,7 @@ public class DefaultBlockParser extends InputParser { if (input.indexOf('[') == -1 && input.indexOf(']') == -1) { continue; } - if (!type.getId().equalsIgnoreCase(input.substring(0, input.indexOf('[')))) { + if (!type.id().equalsIgnoreCase(input.substring(0, input.indexOf('[')))) { continue; } String[] properties = input.substring(input.indexOf('[') + 1, input.indexOf(']')).split(","); @@ -249,10 +249,10 @@ public class DefaultBlockParser extends InputParser { throw new NoMatchException(Caption.of( "worldedit.error.parser.unknown-property", TextComponent.of(parts[0]), - TextComponent.of(type.getId()) + TextComponent.of(type.id()) )); } else { - WorldEdit.logger.debug("Unknown property " + parts[0] + " for block " + type.getId()); + WorldEdit.logger.debug("Unknown property " + parts[0] + " for block " + type.id()); } return Maps.newHashMap(); } @@ -516,20 +516,20 @@ public class DefaultBlockParser extends InputParser { //FAWE start - per-limit disallowed blocks if (actor != null) { if (!actor.hasPermission("worldedit.anyblock") - && worldEdit.getConfiguration().disallowedBlocks.contains(blockType.getId().toLowerCase(Locale.ROOT))) { + && worldEdit.getConfiguration().disallowedBlocks.contains(blockType.id().toLowerCase(Locale.ROOT))) { throw new DisallowedUsageException(Caption.of( "worldedit.error.disallowed-block", - TextComponent.of(blockType.getId()) + TextComponent.of(blockType.id()) )); } FaweLimit limit = actor.getLimit(); if (!limit.isUnlimited()) { // No need to account for blocked states/properties as it will simply return false in the equality check // during contains. - if (limit.DISALLOWED_BLOCKS.contains(blockType.getId().toLowerCase(Locale.ROOT))) { + if (limit.DISALLOWED_BLOCKS.contains(blockType.id().toLowerCase(Locale.ROOT))) { throw new DisallowedUsageException(Caption.of( "fawe.error.limit.disallowed-block", - TextComponent.of(blockType.getId()) + TextComponent.of(blockType.id()) )); } } @@ -559,14 +559,14 @@ public class DefaultBlockParser extends InputParser { if (ent == null) { throw new NoMatchException(Caption.of("worldedit.error.unknown-entity", TextComponent.of(mobName))); } - mobName = ent.getId(); + mobName = ent.id(); if (!worldEdit.getPlatformManager().queryCapability(Capability.USER_COMMANDS).isValidMobType(mobName)) { throw new NoMatchException(Caption.of("worldedit.error.unknown-mob", TextComponent.of(mobName))); } return validate(context, new MobSpawnerBlock(state, mobName)); } else { //noinspection ConstantConditions - return validate(context, new MobSpawnerBlock(state, EntityTypes.PIG.getId())); + return validate(context, new MobSpawnerBlock(state, EntityTypes.PIG.id())); } } else if (blockType == BlockTypes.PLAYER_HEAD || blockType == BlockTypes.PLAYER_WALL_HEAD) { // allow setting type/player/rotation diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java index 36d83eb37..089f2d861 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/pattern/BlockCategoryPatternParser.java @@ -71,7 +71,7 @@ public class BlockCategoryPatternParser extends InputParser implements Set blocks = category.getAll(); if (blocks.isEmpty()) { - throw new InputParseException(Caption.of("worldedit.error.empty-tag", TextComponent.of(category.getId()))); + throw new InputParseException(Caption.of("worldedit.error.empty-tag", TextComponent.of(category.id()))); } if (anyState) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/input/ParserContext.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/input/ParserContext.java index 430280814..989931b0b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/input/ParserContext.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/input/ParserContext.java @@ -23,6 +23,7 @@ import com.fastasyncworldedit.core.configuration.Caption; import com.sk89q.worldedit.IncompleteRegionException; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.factory.MaskFactory; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Capability; @@ -217,6 +218,20 @@ public class ParserContext { return actor; } + /** + * Get the {@link Player} set on this context. + * + * @return a player + * @throws InputParseException thrown if no {@link Actor} is set + */ + public Player requirePlayer() throws InputParseException { + Actor actor = getActor(); + if (!(actor instanceof Player player)) { + throw new InputParseException(Caption.of("worldedit.error.missing-player")); + } + return player; + } + /** * Returns whether there should be restrictions (as a result of * limits or permissions) considered when parsing the input. diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java index 8e63c3a29..346098de5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/Platform.java @@ -236,7 +236,7 @@ public interface Platform extends Keyed { */ @NonAbstractForCompatibility(delegateName = "getPlatformName", delegateParams = {}) @Override - default String getId() { + default String id() { return "legacy:" + getPlatformName().toLowerCase(Locale.ROOT).replaceAll("[^a-z_.-]", "_"); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java index 64b6eecc3..0abc80153 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java @@ -106,7 +106,8 @@ public class MaskingExtent extends AbstractDelegateExtent implements IBatchProce @Override public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { final ChunkFilterBlock filter = getOrCreateFilterBlock.apply(Thread.currentThread().getId()); - return filter.filter(chunk, get, set, MaskingExtent.this); + filter.initChunk(chunk.getX(), chunk.getZ()); + return filter.filter(chunk, get, set, this); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java index 4cd2ead97..cac9f4a7b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java @@ -423,7 +423,7 @@ public interface Clipboard extends Extent, Iterable, Closeable, Fl if (pasteEntities) { for (Entity entity : this.getEntities()) { // skip players on pasting schematic - if (entity.getState() != null && entity.getState().getType().getId() + if (entity.getState() != null && entity.getState().getType().id() .equals("minecraft:player")) { continue; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java index 24860dd3c..dc313b259 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/SpongeSchematicWriter.java @@ -223,7 +223,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { BlockVector3 pt = BlockVector3.at(x0, min.y(), z0); BiomeType biome = clipboard.getBiome(pt); - String biomeKey = biome.getId(); + String biomeKey = biome.id(); int biomeId; if (palette.containsKey(biomeKey)) { biomeId = palette.get(biomeKey); @@ -262,7 +262,7 @@ public class SpongeSchematicWriter implements ClipboardWriter { values.putAll(rawData.getValue()); } values.remove("id"); - values.put("Id", new StringTag(state.getType().getId())); + values.put("Id", new StringTag(state.getType().id())); final Location location = e.getLocation(); values.put("Pos", writeVector(location.toVector())); values.put("Rotation", writeRotation(location)); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java index 974000762..95d2fb091 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/FlowerPotCompatibilityHandler.java @@ -84,7 +84,7 @@ public class FlowerPotCompatibilityHandler implements NBTCompatibilityHandler { } else { BlockState plantedWithData = LegacyMapper.getInstance().getBlockFromLegacy(newId, data); if (plantedWithData != null) { - plantedName = plantedWithData.getBlockType().getId().substring(10); // remove "minecraft:" + plantedName = plantedWithData.getBlockType().id().substring(10); // remove "minecraft:" } } if (plantedName != null) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java index 25457042c..346f5f29e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/io/legacycompat/Pre13HangingCompatibilityHandler.java @@ -29,7 +29,7 @@ public class Pre13HangingCompatibilityHandler implements EntityNBTCompatibilityH @Override public boolean isAffectedEntity(EntityType type, CompoundTag tag) { - if (!type.getId().startsWith("minecraft:")) { + if (!type.id().startsWith("minecraft:")) { return false; } boolean hasLegacyDirection = tag.containsKey("Dir") || tag.containsKey("Direction"); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java index d9effa512..5f434cf9b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/transform/BlockTransformExtent.java @@ -441,7 +441,7 @@ public class BlockTransformExtent extends ResettableExtent { if (Settings.settings().ENABLED_COMPONENTS.DEBUG) { LOGGER.warn(String.format( "Index outside direction array length found for block:{%s} property:{%s}", - state.getBlockType().getId(), + state.getBlockType().id(), property.getName() )); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java index 4027220b2..962fb3c7d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/block/SnowSimulator.java @@ -116,7 +116,7 @@ public class SnowSimulator implements LayerFunction { if (!above.getBlockType().getMaterial().isAir() && (!stack || above.getBlockType() != BlockTypes.SNOW)) { return false; //FAWE start - } else if (!block.getBlockType().getId().toLowerCase(Locale.ROOT).contains("ice") && this.extent.getEmittedLight( + } else if (!block.getBlockType().id().toLowerCase(Locale.ROOT).contains("ice") && this.extent.getEmittedLight( abovePosition) > 10) { return false; } else if (!block.getBlockType().getMaterial().isFullCube()) { @@ -132,7 +132,7 @@ public class SnowSimulator implements LayerFunction { return false; } //FAWE end - } else if (!block.getBlockType().getId().toLowerCase(Locale.ROOT).contains("ice") && block + } else if (!block.getBlockType().id().toLowerCase(Locale.ROOT).contains("ice") && block .getBlockType() .getMaterial() .isTranslucent()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java index 2019e3022..f358ebfae 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/history/changeset/BlockOptimizedHistory.java @@ -56,7 +56,7 @@ public class BlockOptimizedHistory extends ArrayListHistory { BlockChange blockChange = (BlockChange) change; BlockVector3 position = blockChange.getPosition(); if (!previous.containsLocation(position)) { - previous.add(position, blockChange.getPrevious()); + previous.add(position, blockChange.previous()); } current.add(position, blockChange.getCurrent()); } else { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java index 8cc91f969..c30f6fa4d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/cui/ServerCUIHandler.java @@ -165,7 +165,7 @@ public class ServerCUIHandler { structureTag.putString("mode", "SAVE"); structureTag.putByte("ignoreEntities", (byte) 1); structureTag.putByte("showboundingbox", (byte) 1); - structureTag.putString("id", BlockTypes.STRUCTURE_BLOCK.getId()); + structureTag.putString("id", BlockTypes.STRUCTURE_BLOCK.id()); return BlockTypes.STRUCTURE_BLOCK.getDefaultState().toBaseBlock(structureTag.build()); //FAWE end diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java index 237dd1c4c..0934627b9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/internal/registry/AbstractFactory.java @@ -21,6 +21,9 @@ package com.sk89q.worldedit.internal.registry; import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser; +import com.fastasyncworldedit.core.extension.factory.parser.FaweParser; +import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser; +import com.sk89q.util.StringUtil; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.NoMatchException; @@ -43,7 +46,10 @@ import static com.google.common.base.Preconditions.checkNotNull; public abstract class AbstractFactory { protected final WorldEdit worldEdit; - private final List> parsers = new ArrayList<>(); + //FAWE start + protected final List> parsers = new ArrayList<>(); + private final FaweParser richParser; + //FWAE end /** * Create a new factory. @@ -52,11 +58,26 @@ public abstract class AbstractFactory { * @param defaultParser the parser to fall back to */ protected AbstractFactory(WorldEdit worldEdit, InputParser defaultParser) { + //FAWE start + this(worldEdit, defaultParser, null); + } + + /** + * Create a new factory with a given rich parser for FAWE rich parsing + * + * @param worldEdit the WorldEdit instance + * @param defaultParser the parser to fall back to + * @param richParser the rich parser + * @since TODO + */ + protected AbstractFactory(WorldEdit worldEdit, InputParser defaultParser, FaweParser richParser) { checkNotNull(worldEdit); checkNotNull(defaultParser); this.worldEdit = worldEdit; this.parsers.add(defaultParser); + this.richParser = richParser; } + //FAWE end /** * Gets an immutable list of parsers. @@ -71,7 +92,7 @@ public abstract class AbstractFactory { return Collections.unmodifiableList(parsers); } - //FAWE start - javadoc + //FAWE start /** * Parse a string and context to each {@link InputParser} added to this factory. If no result found, throws {@link InputParseException} @@ -81,20 +102,26 @@ public abstract class AbstractFactory { * @return parsed result * @throws InputParseException if no result found */ - //FAWE end public E parseFromInput(String input, ParserContext context) throws InputParseException { - E match; - - for (InputParser parser : parsers) { - match = parser.parseFromInput(input, context); - - if (match != null) { - return match; + List parsed = new ArrayList<>(); + for (String component : StringUtil.split(input,' ', '[', ']')) { + if (component.isEmpty()) { + continue; } + + if (richParser != null) { + E match = richParser.parseFromInput(component, context); + if (match != null) { + parsed.add(match); + continue; + } + } + parseFromParsers(context, parsed, component); } - throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); + return getParsed(input, parsed); } + //FAWE end @Deprecated public List getSuggestions(String input) { @@ -133,4 +160,48 @@ public abstract class AbstractFactory { }); } + //FAWE start + protected void parseFromParsers(final ParserContext context, final List parsed, final String component) { + E match = null; + for (InputParser parser : getParsers()) { + match = parser.parseFromInput(component, context); + + if (match != null) { + break; + } + } + if (match == null) { + throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); + } + parsed.add(match); + } + + /** + * Parses a pattern without considering parsing through the {@link RichPatternParser}, therefore not accepting + * "richer" parsing where & and , are used. Exists to prevent stack overflows. + * + * @param input input string + * @param context input context + * @return parsed result + * @throws InputParseException if no result found + */ + public E parseWithoutRich(String input, ParserContext context) throws InputParseException { + List parsed = new ArrayList<>(); + + for (String component : StringUtil.split(input, ' ', '[', ']')) { + if (component.isEmpty()) { + continue; + } + + parseFromParsers(context, parsed, component); + } + + return getParsed(input, parsed); + } + + protected E getParsed(final String input, final List parsed) { + return parsed.isEmpty() ? null : parsed.get(0); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index 8e4da9214..4b0894d91 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -755,7 +755,6 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { ) { int chunkX = chunk.getX(); int chunkZ = chunk.getZ(); - block = block.initChunk(chunkX, chunkZ); //Chunk entry is an "interior chunk" in regards to the entire region, so filter the chunk whole instead of partially if ((minX + 15) >> 4 <= chunkX && (maxX - 15) >> 4 >= chunkX && (minZ + 15) >> 4 <= chunkZ && (maxZ - 15) >> 4 >= chunkZ) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java index 944e7a14c..1bc13ed43 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/EllipsoidRegion.java @@ -412,8 +412,6 @@ public class EllipsoidRegion extends AbstractRegion { return; } - block = block.initChunk(chunk.getX(), chunk.getZ()); - // Get the solid layers int cy = center.y(); int diffYFull = MathMan.usqrt(diffY2); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java index e8c6da179..085274772 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java @@ -268,7 +268,6 @@ public interface Region extends Iterable, Cloneable, IBatchProcess ) { int minSection = Math.max(get.getMinSectionPosition(), getMinimumY() >> 4); int maxSection = Math.min(get.getMaxSectionPosition(), getMaximumY() >> 4); - block = block.initChunk(chunk.getX(), chunk.getZ()); for (int layer = minSection; layer <= maxSection; layer++) { if ((!full && !get.hasSection(layer)) || !filter.appliesLayer(chunk, layer)) { return; @@ -483,7 +482,7 @@ public interface Region extends Iterable, Cloneable, IBatchProcess } return set; } else { - return null; + return set; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java index c1a81834c..4312e50fa 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/RegionIntersection.java @@ -205,7 +205,7 @@ public class RegionIntersection extends AbstractRegion { BlockVector3 regMin = region.getMinimumPoint(); BlockVector3 regMax = region.getMaximumPoint(); if (tx >= regMin.x() && bx <= regMax.x() && tz >= regMin.z() && bz <= regMax.z()) { - return region.processSet(chunk, get, set, true); + set = region.processSet(chunk, get, set, true); } } return set; // default return set as no "blacklist" regions contained the chunk diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java index fc8a5e895..92a859652 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/registry/Category.java @@ -25,7 +25,7 @@ import java.util.HashSet; import java.util.Set; //FAWE start - implements RegistryItem -public abstract class Category implements RegistryItem { +public abstract class Category implements RegistryItem, Keyed { //FAWE end private final Set set = new HashSet<>(); @@ -36,7 +36,8 @@ public abstract class Category implements RegistryItem { this.id = id; } - public final String getId() { + @Override + public final String id() { return this.id; } @@ -81,7 +82,7 @@ public abstract class Category implements RegistryItem { @Override public String toString() { - return getId(); + return id(); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java index 7bec7c2f5..7a52770e3 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java @@ -114,7 +114,7 @@ public class PropertiesConfiguration extends LocalConfiguration { registerHelp = getBool("register-help", registerHelp); wandItem = getString("wand-item", wandItem); try { - wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).getId(); + wandItem = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(wandItem)).id(); } catch (Throwable ignored) { } superPickaxeDrop = getBool("super-pickaxe-drop-items", superPickaxeDrop); @@ -124,7 +124,7 @@ public class PropertiesConfiguration extends LocalConfiguration { useInventoryCreativeOverride = getBool("use-inventory-creative-override", useInventoryCreativeOverride); navigationWand = getString("nav-wand-item", navigationWand); try { - navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).getId(); + navigationWand = LegacyMapper.getInstance().getItemFromLegacy(Integer.parseInt(navigationWand)).id(); } catch (Throwable ignored) { } navigationWandMaxDistance = getInt("nav-wand-distance", navigationWandMaxDistance); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java index ccf8d8535..0e962d746 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -78,7 +78,7 @@ public class NullWorld extends AbstractWorld { //FAWE end @Override - public String getId() { + public String id() { return "null"; } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java index 79822a934..553792599 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/World.java @@ -419,7 +419,7 @@ public interface World extends Extent, Keyed, IChunkCache { } @Override - default String getId() { + default String id() { return getName().replace(" ", "_").toLowerCase(Locale.ROOT); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java index 6fe08a295..e8a5e144a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/biome/BiomeTypes.java @@ -291,7 +291,7 @@ public final class BiomeTypes { } public static BiomeType register(final BiomeType biome) { - return BiomeType.REGISTRY.register(biome.getId(), biome); + return BiomeType.REGISTRY.register(biome.id(), biome); } public static BiomeType getLegacy(int legacyId) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java index 5059c737a..713204843 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java @@ -154,7 +154,7 @@ public class BlockState implements BlockStateHolder, Pattern { String input = key.toString(); throw new SuggestInputParseException(Caption.of("fawe.error.invalid-block-type", TextComponent.of(input)), () -> Stream.of( BlockTypesCache.values) - .map(BlockType::getId) + .map(BlockType::id) .filter(id -> StringMan.blockStateMatches(input, id)) .sorted(StringMan.blockStateComparator(input)) .collect(Collectors.toList()) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java index 5f6667a13..e40482302 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java @@ -204,14 +204,14 @@ public interface BlockStateHolder> extends TileEnt default String getAsString() { if (getStates().isEmpty()) { - return this.getBlockType().getId(); + return this.getBlockType().id(); } else { String properties = getStates().entrySet().stream() .map(entry -> entry.getKey().getName() + "=" + entry.getValue().toString().toLowerCase(Locale.ROOT)) .collect(Collectors.joining(",")); - return this.getBlockType().getId() + "[" + properties + "]"; + return this.getBlockType().id() + "[" + properties + "]"; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java index a2e58a97c..d8b0ae046 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockType.java @@ -124,7 +124,7 @@ public class BlockType implements Keyed, Pattern { * @return The id */ @Override - public String getId() { + public String id() { return this.id; } @@ -135,13 +135,13 @@ public class BlockType implements Keyed, Pattern { //FAWE start public String getNamespace() { - String id = getId(); + String id = id(); int i = id.indexOf(':'); return i == -1 ? "minecraft" : id.substring(0, i); } public String getResource() { - String id = getId(); + String id = id(); return id.substring(id.indexOf(':') + 1); } //FAWE end @@ -156,7 +156,7 @@ public class BlockType implements Keyed, Pattern { public String getName() { String name = this.name.getValue(); if (name == null || name.isEmpty()) { - return getId(); + return id(); } return name; } @@ -180,7 +180,7 @@ public class BlockType implements Keyed, Pattern { LOGGER.error( "Attempted to load blockstate with id {} of type {} outside of state ordinals length. Using default state.", propertyId, - getId() + id() ); return settings.defaultState; } @@ -189,7 +189,7 @@ public class BlockType implements Keyed, Pattern { LOGGER.error( "Attempted to load blockstate with ordinal {} of type {} outside of states length. Using default state. Using default state.", ordinal, - getId() + id() ); return settings.defaultState; } @@ -405,7 +405,7 @@ public class BlockType implements Keyed, Pattern { @Override public String toString() { - return getId(); + return id(); } //FAWE start diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java index 0206cdf92..2667d44f9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockTypes.java @@ -2235,8 +2235,8 @@ public final class BlockTypes { throw new SuggestInputParseException(Caption.of("fawe.error.invalid-block-type", TextComponent.of(input)), () -> Stream.of( BlockTypesCache.values) - .filter(b -> StringMan.blockStateMatches(inputLower, b.getId())) - .map(BlockType::getId) + .filter(b -> StringMan.blockStateMatches(inputLower, b.id())) + .map(BlockType::id) .sorted(StringMan.blockStateComparator(inputLower)) .collect(Collectors.toList()) ); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java index 31bb7606c..a8c2d63c2 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk13.java @@ -125,7 +125,7 @@ public class AnvilChunk13 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java index 6d366c295..3789f9a79 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk17.java @@ -133,7 +133,7 @@ public class AnvilChunk17 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java index 4fa50629e..1e36938c4 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/chunk/AnvilChunk18.java @@ -146,7 +146,7 @@ public class AnvilChunk18 implements Chunk { } catch (IllegalArgumentException e) { throw new InvalidFormatException("Invalid block state for " + blockState .getBlockType() - .getId() + ", " + property.getName() + ": " + value); + .id() + ", " + property.getName() + ": " + value); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java index 2788fdebe..79569156e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidCategories.java @@ -37,7 +37,7 @@ public final class FluidCategories { } public static FluidCategory register(final FluidCategory tag) { - return FluidCategory.REGISTRY.register(tag.getId(), tag); + return FluidCategory.REGISTRY.register(tag.id(), tag); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java index 18c43d8c8..dd5b0270e 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/fluid/FluidTypes.java @@ -40,7 +40,7 @@ public final class FluidTypes { } public static FluidType register(final FluidType fluid) { - return FluidType.REGISTRY.register(fluid.getId(), fluid); + return FluidType.REGISTRY.register(fluid.id(), fluid); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java index ce87f9ce7..b6d151ba8 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/gamemode/GameModes.java @@ -36,7 +36,7 @@ public final class GameModes { } public static GameMode register(final GameMode gameMode) { - return GameMode.REGISTRY.register(gameMode.getId(), gameMode); + return GameMode.REGISTRY.register(gameMode.id(), gameMode); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java index 5dc7f9277..e7a72b3c9 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemType.java @@ -49,7 +49,7 @@ public class ItemType implements RegistryItem, Keyed { .getRegistries().getItemRegistry().getName(this), "" ); - return name.isEmpty() ? getId() : name; + return name.isEmpty() ? id() : name; }); @SuppressWarnings("this-escape") private transient final LazyReference richName = LazyReference.from(() -> @@ -76,7 +76,7 @@ public class ItemType implements RegistryItem, Keyed { } @Override - public String getId() { + public String id() { return this.id; } @@ -153,7 +153,7 @@ public class ItemType implements RegistryItem, Keyed { @Override public String toString() { - return getId(); + return id(); } @Override diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java index 3f7181397..11663a4f1 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledBlockRegistry.java @@ -41,7 +41,7 @@ public class BundledBlockRegistry implements BlockRegistry { @Override public Component getRichName(BlockType blockType) { - BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.getId()); + BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.id()); if (blockEntry != null) { // This is more likely to be "right", but not translated // Some vanilla MC blocks have overrides so we need this name here @@ -50,7 +50,7 @@ public class BundledBlockRegistry implements BlockRegistry { return TextComponent.of(blockEntry.localizedName); } return Caption.of( - TranslationManager.makeTranslationKey("block", blockType.getId()) + TranslationManager.makeTranslationKey("block", blockType.id()) ); } @@ -60,14 +60,14 @@ public class BundledBlockRegistry implements BlockRegistry { // dumb_intellij.jpg - Ok?? @SuppressWarnings("deprecation") public String getName(BlockType blockType) { - BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.getId()); + BundledBlockData.BlockEntry blockEntry = BundledBlockData.getInstance().findById(blockType.id()); return blockEntry != null ? blockEntry.localizedName : null; } @Nullable @Override public BlockMaterial getMaterial(BlockType blockType) { - return new PassthroughBlockMaterial(BundledBlockData.getInstance().getMaterialById(blockType.getId())); + return new PassthroughBlockMaterial(BundledBlockData.getInstance().getMaterialById(blockType.id())); } @Nullable diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java index 2e1d42121..53a707821 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/BundledItemRegistry.java @@ -34,7 +34,7 @@ import javax.annotation.Nullable; public class BundledItemRegistry implements ItemRegistry { private BundledItemData.ItemEntry getEntryById(ItemType itemType) { - return BundledItemData.getInstance().findById(itemType.getId()); + return BundledItemData.getInstance().findById(itemType.id()); } @Override @@ -48,7 +48,7 @@ public class BundledItemRegistry implements ItemRegistry { return TextComponent.of(itemEntry.localizedName); } return Caption.of( - TranslationManager.makeTranslationKey("item", itemType.getId()) + TranslationManager.makeTranslationKey("item", itemType.id()) ); } @@ -62,7 +62,7 @@ public class BundledItemRegistry implements ItemRegistry { if (itemEntry != null) { String localized = itemEntry.localizedName; if (localized.equals("Air")) { - String id = itemType.getId(); + String id = itemType.id(); int c = id.indexOf(':'); return c < 0 ? id : id.substring(c + 1); } @@ -74,7 +74,7 @@ public class BundledItemRegistry implements ItemRegistry { @Nullable @Override public ItemMaterial getMaterial(ItemType itemType) { - return new PassthroughItemMaterial(BundledItemData.getInstance().getMaterialById(itemType.getId())); + return new PassthroughItemMaterial(BundledItemData.getInstance().getMaterialById(itemType.id())); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java index c52c507b9..dade2d193 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/CategoryRegistry.java @@ -38,7 +38,7 @@ public interface CategoryRegistry { Set getCategorisedByName(String category); default Set getAll(final Category category) { - return getCategorisedByName(category.getId()); + return getCategorisedByName(category.id()); } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java index 346c94477..19fdd3b88 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/NullBiomeRegistry.java @@ -41,7 +41,7 @@ public class NullBiomeRegistry implements BiomeRegistry { @Override public Component getRichName(BiomeType biomeType) { return Caption.of( - TranslationManager.makeTranslationKey("biome", biomeType.getId()) + TranslationManager.makeTranslationKey("biome", biomeType.id()) ); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java index 404e8d6da..458f17f25 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/weather/WeatherTypes.java @@ -35,7 +35,7 @@ public final class WeatherTypes { } public static WeatherType register(WeatherType weather) { - return WeatherType.REGISTRY.register(weather.getId(), weather); + return WeatherType.REGISTRY.register(weather.id(), weather); } @Nullable diff --git a/worldedit-core/src/main/resources/lang/strings.json b/worldedit-core/src/main/resources/lang/strings.json index 39bc334c1..7921bc291 100644 --- a/worldedit-core/src/main/resources/lang/strings.json +++ b/worldedit-core/src/main/resources/lang/strings.json @@ -139,6 +139,7 @@ "fawe.error.occurred-continuing": "Ignorable error occurred during edit: {0}", "fawe.error.limit.max-brush-radius": "Maximum brush radius in limit: {0}", "fawe.error.limit.max-radius": "Maximum radius in limit: {0}", + "fawe.error.no-valid-on-hotbar": "No valid block types on hotbar", "fawe.cancel.count": "Cancelled {0} edits.", "fawe.cancel.reason.confirm": "Use //confirm to execute {0}", "fawe.cancel.reason.confirm.region": "Your selection is large ({0} -> {1}, containing {3} blocks). Use //confirm to execute {2}", @@ -240,6 +241,7 @@ "worldedit.error.missing-session": "No LocalSession is known", "worldedit.error.missing-world": "You need to provide a world (Try //world)", "worldedit.error.missing-actor": "No actor is known", + "worldedit.error.missing-player": "No player is known", "worldedit.error.no-file-selected": "No file selected.", "worldedit.error.file-resolution.outside-root": "Path is outside allowable root", "worldedit.error.file-resolution.resolve-failed": "Failed to resolve path",