3
0
Mirror von https://github.com/IntellectualSites/FastAsyncWorldEdit.git synchronisiert 2024-11-19 17:30:08 +01:00

Merge branch 'main' into feat/improved-entity-operations

# Conflicts:
#	worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java
Dieser Commit ist enthalten in:
dordsor21 2024-06-15 15:11:02 +01:00
Commit 220a0a66c9
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 1E53E88969FFCF0B
18 geänderte Dateien mit 428 neuen und 430 gelöschten Zeilen

Datei anzeigen

@ -494,7 +494,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
} }
} else { } else {
setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); PalettedContainer<Holder<Biome>> paletteBiomes = setBiomesToPalettedContainer(
biomes,
setSectionIndex,
existingSection.getBiomes()
);
if (paletteBiomes != null) {
PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes);
}
} }
} }
} }
@ -536,11 +543,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (existingSection == null) { if (existingSection == null) {
PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>( PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>(
biomeHolderIdMap, biomeHolderIdMap,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(
BiomeTypes.PLAINS)),
PalettedContainer.Strategy.SECTION_BIOMES, PalettedContainer.Strategy.SECTION_BIOMES,
null null
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
@ -608,15 +611,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
existingSection.getBiomes() existingSection.getBiomes()
); );
newSection = newSection = PaperweightPlatformAdapter.newChunkSection(
PaperweightPlatformAdapter.newChunkSection( layerNo,
layerNo, this::loadPrivately,
this::loadPrivately, setArr,
setArr, adapter,
adapter, biomeRegistry,
biomeRegistry, biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
biomeData );
);
if (!PaperweightPlatformAdapter.setSectionAtomic( if (!PaperweightPlatformAdapter.setSectionAtomic(
levelChunkSections, levelChunkSections,
existingSection, existingSection,
@ -828,7 +830,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
if (callback == null) { if (callback == null) {
if (finalizer != null) { if (finalizer != null) {
finalizer.run(); queueHandler.async(finalizer, null);
} }
return null; return null;
} else { } else {
@ -1086,9 +1088,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
final int sectionIndex, final int sectionIndex,
final PalettedContainerRO<Holder<Biome>> data final PalettedContainerRO<Holder<Biome>> data
) { ) {
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null;
}
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData;
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer; biomeData = palettedContainer.copy();
} else { } else {
LOGGER.warn( LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
@ -1098,10 +1104,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
); );
biomeData = data.recreate(); biomeData = data.recreate();
} }
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return biomeData;
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
@ -1113,10 +1115,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
x, x,
y, y,
z, z,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(biomeType))
); );
} }
} }

Datei anzeigen

@ -98,7 +98,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldTickingFluidCount; private static final Field fieldTickingFluidCount;
private static final Field fieldTickingBlockCount; private static final Field fieldTickingBlockCount;
private static final Field fieldNonEmptyBlockCount; private static final Field fieldBiomes;
private static final MethodHandle methodGetVisibleChunk; private static final MethodHandle methodGetVisibleChunk;
@ -139,8 +139,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldTickingFluidCount.setAccessible(true); fieldTickingFluidCount.setAccessible(true);
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g")); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "g"));
fieldTickingBlockCount.setAccessible(true); fieldTickingBlockCount.setAccessible(true);
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "f")); fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "j"));
fieldNonEmptyBlockCount.setAccessible(true); fieldBiomes.setAccessible(true);
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
"getVisibleChunkIfPresent", "getVisibleChunkIfPresent",
@ -502,6 +502,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return new LevelChunkSection(layer, dataPaletteBlocks, biomes); return new LevelChunkSection(layer, dataPaletteBlocks, biomes);
} }
public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer<Holder<Biome>> biomes) {
try {
fieldBiomes.set(section, biomes);
} catch (IllegalAccessException e) {
LOGGER.error("Could not set biomes to chunk section", e);
}
}
/** /**
* Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand. * Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand.
*/ */

Datei anzeigen

@ -493,7 +493,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
} }
} else { } else {
setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); PalettedContainer<Holder<Biome>> paletteBiomes = setBiomesToPalettedContainer(
biomes,
setSectionIndex,
existingSection.getBiomes()
);
if (paletteBiomes != null) {
PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes);
}
} }
} }
} }
@ -535,11 +542,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (existingSection == null) { if (existingSection == null) {
PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>( PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>(
biomeHolderIdMap, biomeHolderIdMap,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(
BiomeTypes.PLAINS)),
PalettedContainer.Strategy.SECTION_BIOMES PalettedContainer.Strategy.SECTION_BIOMES
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
newSection = PaperweightPlatformAdapter.newChunkSection( newSection = PaperweightPlatformAdapter.newChunkSection(
@ -606,15 +609,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
existingSection.getBiomes() existingSection.getBiomes()
); );
newSection = newSection = PaperweightPlatformAdapter.newChunkSection(
PaperweightPlatformAdapter.newChunkSection( layerNo,
layerNo, this::loadPrivately,
this::loadPrivately, setArr,
setArr, adapter,
adapter, biomeRegistry,
biomeRegistry, biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
biomeData );
);
if (!PaperweightPlatformAdapter.setSectionAtomic( if (!PaperweightPlatformAdapter.setSectionAtomic(
levelChunkSections, levelChunkSections,
existingSection, existingSection,
@ -826,7 +828,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
if (callback == null) { if (callback == null) {
if (finalizer != null) { if (finalizer != null) {
finalizer.run(); queueHandler.async(finalizer, null);
} }
return null; return null;
} else { } else {
@ -1083,9 +1085,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
final int sectionIndex, final int sectionIndex,
final PalettedContainerRO<Holder<Biome>> data final PalettedContainerRO<Holder<Biome>> data
) { ) {
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null;
}
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData;
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer; biomeData = palettedContainer.copy();
} else { } else {
LOGGER.warn( LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
@ -1095,10 +1101,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
); );
biomeData = data.recreate(); biomeData = data.recreate();
} }
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return biomeData;
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
@ -1110,10 +1112,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
x, x,
y, y,
z, z,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(biomeType))
); );
} }
} }

Datei anzeigen

@ -62,7 +62,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R1.CraftChunk; import org.bukkit.craftbukkit.v1_20_R1.CraftChunk;
import sun.misc.Unsafe;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -102,7 +101,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldTickingFluidCount; private static final Field fieldTickingFluidCount;
private static final Field fieldTickingBlockCount; private static final Field fieldTickingBlockCount;
private static final Field fieldNonEmptyBlockCount;
private static final MethodHandle methodGetVisibleChunk; private static final MethodHandle methodGetVisibleChunk;
@ -111,6 +109,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final MethodHandle methodRemoveGameEventListener; private static final MethodHandle methodRemoveGameEventListener;
private static final MethodHandle methodremoveTickingBlockEntity; private static final MethodHandle methodremoveTickingBlockEntity;
private static final Field fieldBiomes;
private static final Field fieldOffers; private static final Field fieldOffers;
private static final MerchantOffers OFFERS = new MerchantOffers(); private static final MerchantOffers OFFERS = new MerchantOffers();
@ -149,8 +148,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldTickingFluidCount.setAccessible(true); fieldTickingFluidCount.setAccessible(true);
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f"));
fieldTickingBlockCount.setAccessible(true); fieldTickingBlockCount.setAccessible(true);
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i"));
fieldNonEmptyBlockCount.setAccessible(true); fieldBiomes.setAccessible(true);
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
"getVisibleChunkIfPresent", "getVisibleChunkIfPresent",
@ -417,7 +416,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
if (set == null) { if (set == null) {
return newChunkSection(layer, biomeRegistry, biomes); return newChunkSection(biomeRegistry, biomes);
} }
final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get();
final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get();
@ -507,7 +506,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
@SuppressWarnings("deprecation") // Only deprecated in paper @SuppressWarnings("deprecation") // Only deprecated in paper
private static LevelChunkSection newChunkSection( private static LevelChunkSection newChunkSection(
int layer,
Registry<Biome> biomeRegistry, Registry<Biome> biomeRegistry,
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
@ -522,6 +520,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return new LevelChunkSection(dataPaletteBlocks, biomes); return new LevelChunkSection(dataPaletteBlocks, biomes);
} }
public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer<Holder<Biome>> biomes) {
try {
fieldBiomes.set(section, biomes);
} catch (IllegalAccessException e) {
LOGGER.error("Could not set biomes to chunk section", e);
}
}
/** /**
* Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand. * Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand.
*/ */

Datei anzeigen

@ -31,7 +31,11 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import io.papermc.paper.event.block.BeaconDeactivatedEvent; import io.papermc.paper.event.block.BeaconDeactivatedEvent;
import net.minecraft.core.*; import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.IdMap;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.IntTag; import net.minecraft.nbt.IntTag;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
@ -44,7 +48,14 @@ import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BeaconBlockEntity; import net.minecraft.world.level.block.entity.BeaconBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.*; import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.HashMapPalette;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.LinearPalette;
import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.PalettedContainerRO;
import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.lighting.LevelLightEngine;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -54,7 +65,17 @@ import org.bukkit.craftbukkit.v1_20_R2.block.CraftBlock;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.*; import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -479,7 +500,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
} }
} else { } else {
setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); PalettedContainer<Holder<Biome>> paletteBiomes = setBiomesToPalettedContainer(
biomes,
setSectionIndex,
existingSection.getBiomes()
);
if (paletteBiomes != null) {
PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes);
}
} }
} }
} }
@ -521,11 +549,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (existingSection == null) { if (existingSection == null) {
PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>( PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>(
biomeHolderIdMap, biomeHolderIdMap,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(
BiomeTypes.PLAINS)),
PalettedContainer.Strategy.SECTION_BIOMES PalettedContainer.Strategy.SECTION_BIOMES
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
newSection = PaperweightPlatformAdapter.newChunkSection( newSection = PaperweightPlatformAdapter.newChunkSection(
@ -592,15 +616,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
existingSection.getBiomes() existingSection.getBiomes()
); );
newSection = newSection = PaperweightPlatformAdapter.newChunkSection(
PaperweightPlatformAdapter.newChunkSection( layerNo,
layerNo, this::loadPrivately,
this::loadPrivately, setArr,
setArr, adapter,
adapter, biomeRegistry,
biomeRegistry, biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
biomeData );
);
if (!PaperweightPlatformAdapter.setSectionAtomic( if (!PaperweightPlatformAdapter.setSectionAtomic(
levelChunkSections, levelChunkSections,
existingSection, existingSection,
@ -812,7 +835,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
if (callback == null) { if (callback == null) {
if (finalizer != null) { if (finalizer != null) {
finalizer.run(); queueHandler.async(finalizer, null);
} }
return null; return null;
} else { } else {
@ -1069,9 +1092,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
final int sectionIndex, final int sectionIndex,
final PalettedContainerRO<Holder<Biome>> data final PalettedContainerRO<Holder<Biome>> data
) { ) {
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null;
}
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData;
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer; biomeData = palettedContainer.copy();
} else { } else {
LOGGER.warn( LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
@ -1081,10 +1108,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
); );
biomeData = data.recreate(); biomeData = data.recreate();
} }
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return biomeData;
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
@ -1096,10 +1119,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
x, x,
y, y,
z, z,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(biomeType))
); );
} }
} }

Datei anzeigen

@ -59,7 +59,6 @@ import net.minecraft.world.level.entity.PersistentEntitySectionManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_20_R2.CraftChunk; import org.bukkit.craftbukkit.v1_20_R2.CraftChunk;
import sun.misc.Unsafe;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -99,7 +98,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldTickingFluidCount; private static final Field fieldTickingFluidCount;
private static final Field fieldTickingBlockCount; private static final Field fieldTickingBlockCount;
private static final Field fieldNonEmptyBlockCount;
private static final MethodHandle methodGetVisibleChunk; private static final MethodHandle methodGetVisibleChunk;
@ -108,6 +106,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final MethodHandle methodRemoveGameEventListener; private static final MethodHandle methodRemoveGameEventListener;
private static final MethodHandle methodremoveTickingBlockEntity; 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 * 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,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldTickingFluidCount.setAccessible(true); fieldTickingFluidCount.setAccessible(true);
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f"));
fieldTickingBlockCount.setAccessible(true); fieldTickingBlockCount.setAccessible(true);
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i"));
fieldNonEmptyBlockCount.setAccessible(true); fieldBiomes.setAccessible(true);
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
"getVisibleChunkIfPresent", "getVisibleChunkIfPresent",
@ -408,7 +407,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
if (set == null) { if (set == null) {
return newChunkSection(layer, biomeRegistry, biomes); return newChunkSection(biomeRegistry, biomes);
} }
final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get();
final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get();
@ -498,7 +497,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
@SuppressWarnings("deprecation") // Only deprecated in paper @SuppressWarnings("deprecation") // Only deprecated in paper
private static LevelChunkSection newChunkSection( private static LevelChunkSection newChunkSection(
int layer,
Registry<Biome> biomeRegistry, Registry<Biome> biomeRegistry,
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
@ -513,6 +511,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return new LevelChunkSection(dataPaletteBlocks, biomes); return new LevelChunkSection(dataPaletteBlocks, biomes);
} }
public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer<Holder<Biome>> biomes) {
try {
fieldBiomes.set(section, biomes);
} catch (IllegalAccessException e) {
LOGGER.error("Could not set biomes to chunk section", e);
}
}
/** /**
* Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand. * Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand.
*/ */

Datei anzeigen

@ -31,7 +31,11 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import io.papermc.paper.event.block.BeaconDeactivatedEvent; import io.papermc.paper.event.block.BeaconDeactivatedEvent;
import net.minecraft.core.*; import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.IdMap;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.IntTag; import net.minecraft.nbt.IntTag;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundEvents;
@ -44,7 +48,14 @@ import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BeaconBlockEntity; import net.minecraft.world.level.block.entity.BeaconBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.*; import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.HashMapPalette;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.LinearPalette;
import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.PalettedContainerRO;
import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.lighting.LevelLightEngine;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -54,7 +65,17 @@ import org.bukkit.craftbukkit.v1_20_R3.block.CraftBlock;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.*; import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -478,7 +499,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
} }
} else { } else {
setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); PalettedContainer<Holder<Biome>> paletteBiomes = setBiomesToPalettedContainer(
biomes,
setSectionIndex,
existingSection.getBiomes()
);
if (paletteBiomes != null) {
PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes);
}
} }
} }
} }
@ -520,11 +548,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (existingSection == null) { if (existingSection == null) {
PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>( PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>(
biomeHolderIdMap, biomeHolderIdMap,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(
BiomeTypes.PLAINS)),
PalettedContainer.Strategy.SECTION_BIOMES PalettedContainer.Strategy.SECTION_BIOMES
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
newSection = PaperweightPlatformAdapter.newChunkSection( newSection = PaperweightPlatformAdapter.newChunkSection(
@ -591,15 +615,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
existingSection.getBiomes() existingSection.getBiomes()
); );
newSection = newSection = PaperweightPlatformAdapter.newChunkSection(
PaperweightPlatformAdapter.newChunkSection( layerNo,
layerNo, this::loadPrivately,
this::loadPrivately, setArr,
setArr, adapter,
adapter, biomeRegistry,
biomeRegistry, biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
biomeData );
);
if (!PaperweightPlatformAdapter.setSectionAtomic( if (!PaperweightPlatformAdapter.setSectionAtomic(
levelChunkSections, levelChunkSections,
existingSection, existingSection,
@ -811,7 +834,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
if (callback == null) { if (callback == null) {
if (finalizer != null) { if (finalizer != null) {
finalizer.run(); queueHandler.async(finalizer, null);
} }
return null; return null;
} else { } else {
@ -1066,9 +1089,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
final int sectionIndex, final int sectionIndex,
final PalettedContainerRO<Holder<Biome>> data final PalettedContainerRO<Holder<Biome>> data
) { ) {
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null;
}
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData;
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer; biomeData = palettedContainer.copy();
} else { } else {
LOGGER.warn( LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
@ -1078,10 +1105,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
); );
biomeData = data.recreate(); biomeData = data.recreate();
} }
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return biomeData;
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
@ -1093,10 +1116,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
x, x,
y, y,
z, z,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(biomeType))
); );
} }
} }

Datei anzeigen

@ -98,7 +98,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldTickingFluidCount; private static final Field fieldTickingFluidCount;
private static final Field fieldTickingBlockCount; private static final Field fieldTickingBlockCount;
private static final Field fieldNonEmptyBlockCount; private static final Field fieldBiomes;
private static final MethodHandle methodGetVisibleChunk; private static final MethodHandle methodGetVisibleChunk;
@ -142,8 +142,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldTickingFluidCount.setAccessible(true); fieldTickingFluidCount.setAccessible(true);
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f"));
fieldTickingBlockCount.setAccessible(true); fieldTickingBlockCount.setAccessible(true);
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i"));
fieldNonEmptyBlockCount.setAccessible(true); fieldBiomes.setAccessible(true);
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
"getVisibleChunkIfPresent", "getVisibleChunkIfPresent",
@ -407,7 +407,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
if (set == null) { if (set == null) {
return newChunkSection(layer, biomeRegistry, biomes); return newChunkSection(biomeRegistry, biomes);
} }
final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get();
final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get();
@ -497,7 +497,6 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
@SuppressWarnings("deprecation") // Only deprecated in paper @SuppressWarnings("deprecation") // Only deprecated in paper
private static LevelChunkSection newChunkSection( private static LevelChunkSection newChunkSection(
int layer,
Registry<Biome> biomeRegistry, Registry<Biome> biomeRegistry,
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
@ -512,6 +511,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return new LevelChunkSection(dataPaletteBlocks, biomes); return new LevelChunkSection(dataPaletteBlocks, biomes);
} }
public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer<Holder<Biome>> biomes) {
try {
fieldBiomes.set(section, biomes);
} catch (IllegalAccessException e) {
LOGGER.error("Could not set biomes to chunk section", e);
}
}
/** /**
* Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand. * Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand.
*/ */

Datei anzeigen

@ -31,7 +31,11 @@ import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockTypesCache; import com.sk89q.worldedit.world.block.BlockTypesCache;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import io.papermc.paper.event.block.BeaconDeactivatedEvent; import io.papermc.paper.event.block.BeaconDeactivatedEvent;
import net.minecraft.core.*; import net.minecraft.core.BlockPos;
import net.minecraft.core.Holder;
import net.minecraft.core.IdMap;
import net.minecraft.core.Registry;
import net.minecraft.core.SectionPos;
import net.minecraft.nbt.IntTag; import net.minecraft.nbt.IntTag;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
@ -45,7 +49,14 @@ import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.entity.BeaconBlockEntity; import net.minecraft.world.level.block.entity.BeaconBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.*; import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.HashMapPalette;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.LinearPalette;
import net.minecraft.world.level.chunk.Palette;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.PalettedContainerRO;
import net.minecraft.world.level.levelgen.Heightmap; import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.lighting.LevelLightEngine; import net.minecraft.world.level.lighting.LevelLightEngine;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -54,7 +65,16 @@ import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.CreatureSpawnEvent;
import java.util.*; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable; import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future; import java.util.concurrent.Future;
@ -479,7 +499,14 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
} }
} else { } else {
setBiomesToPalettedContainer(biomes, setSectionIndex, existingSection.getBiomes()); PalettedContainer<Holder<Biome>> paletteBiomes = setBiomesToPalettedContainer(
biomes,
setSectionIndex,
existingSection.getBiomes()
);
if (paletteBiomes != null) {
PaperweightPlatformAdapter.setBiomesToChunkSection(existingSection, paletteBiomes);
}
} }
} }
} }
@ -521,11 +548,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
if (existingSection == null) { if (existingSection == null) {
PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>( PalettedContainer<Holder<Biome>> biomeData = biomes == null ? new PalettedContainer<>(
biomeHolderIdMap, biomeHolderIdMap,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(BiomeTypes.PLAINS)),
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(
BiomeTypes.PLAINS)),
PalettedContainer.Strategy.SECTION_BIOMES PalettedContainer.Strategy.SECTION_BIOMES
) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap); ) : PaperweightPlatformAdapter.getBiomePalettedContainer(biomes[setSectionIndex], biomeHolderIdMap);
newSection = PaperweightPlatformAdapter.newChunkSection( newSection = PaperweightPlatformAdapter.newChunkSection(
@ -592,18 +615,15 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
existingSection.getBiomes() existingSection.getBiomes()
); );
newSection = newSection = PaperweightPlatformAdapter.newChunkSection(
PaperweightPlatformAdapter.newChunkSection( layerNo,
layerNo, this::loadPrivately,
this::loadPrivately, setArr,
setArr, adapter,
adapter, biomeRegistry,
biomeRegistry, biomeData != null ? biomeData : (PalettedContainer<Holder<Biome>>) existingSection.getBiomes()
biomeData );
); if (!PaperweightPlatformAdapter.setSectionAtomic(levelChunkSections, existingSection,
if (!PaperweightPlatformAdapter.setSectionAtomic(
levelChunkSections,
existingSection,
newSection, newSection,
getSectionIndex getSectionIndex
)) { )) {
@ -812,7 +832,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
} }
if (callback == null) { if (callback == null) {
if (finalizer != null) { if (finalizer != null) {
finalizer.run(); queueHandler.async(finalizer, null);
} }
return null; return null;
} else { } else {
@ -1069,9 +1089,13 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
final int sectionIndex, final int sectionIndex,
final PalettedContainerRO<Holder<Biome>> data final PalettedContainerRO<Holder<Biome>> data
) { ) {
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return null;
}
PalettedContainer<Holder<Biome>> biomeData; PalettedContainer<Holder<Biome>> biomeData;
if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) { if (data instanceof PalettedContainer<Holder<Biome>> palettedContainer) {
biomeData = palettedContainer; biomeData = palettedContainer.copy();
} else { } else {
LOGGER.warn( LOGGER.warn(
"Cannot correctly set biomes to world, existing biomes may be lost. Expected class " + "Cannot correctly set biomes to world, existing biomes may be lost. Expected class " +
@ -1081,10 +1105,6 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
); );
biomeData = data.recreate(); biomeData = data.recreate();
} }
BiomeType[] sectionBiomes;
if (biomes == null || (sectionBiomes = biomes[sectionIndex]) == null) {
return biomeData;
}
for (int y = 0, index = 0; y < 4; y++) { for (int y = 0, index = 0; y < 4; y++) {
for (int z = 0; z < 4; z++) { for (int z = 0; z < 4; z++) {
for (int x = 0; x < 4; x++, index++) { for (int x = 0; x < 4; x++, index++) {
@ -1096,10 +1116,7 @@ public class PaperweightGetBlocks extends CharGetBlocks implements BukkitGetBloc
x, x,
y, y,
z, z,
biomeHolderIdMap.byIdOrThrow(WorldEditPlugin biomeHolderIdMap.byIdOrThrow(adapter.getInternalBiomeId(biomeType))
.getInstance()
.getBukkitImplAdapter()
.getInternalBiomeId(biomeType))
); );
} }
} }

Datei anzeigen

@ -10,7 +10,6 @@ import com.fastasyncworldedit.core.math.BitArrayUnstretched;
import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.MathMan;
import com.fastasyncworldedit.core.util.ReflectionUtils; import com.fastasyncworldedit.core.util.ReflectionUtils;
import com.fastasyncworldedit.core.util.TaskManager; import com.fastasyncworldedit.core.util.TaskManager;
import com.mojang.datafixers.util.Either;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.Refraction; import com.sk89q.worldedit.bukkit.adapter.Refraction;
@ -77,7 +76,6 @@ import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -98,7 +96,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
private static final Field fieldTickingFluidCount; private static final Field fieldTickingFluidCount;
private static final Field fieldTickingBlockCount; private static final Field fieldTickingBlockCount;
private static final Field fieldNonEmptyBlockCount; private static final Field fieldBiomes;
private static final MethodHandle methodGetVisibleChunk; private static final MethodHandle methodGetVisibleChunk;
@ -142,8 +140,8 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
fieldTickingFluidCount.setAccessible(true); fieldTickingFluidCount.setAccessible(true);
fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f")); fieldTickingBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("tickingBlockCount", "f"));
fieldTickingBlockCount.setAccessible(true); fieldTickingBlockCount.setAccessible(true);
fieldNonEmptyBlockCount = LevelChunkSection.class.getDeclaredField(Refraction.pickName("nonEmptyBlockCount", "e")); fieldBiomes = LevelChunkSection.class.getDeclaredField(Refraction.pickName("biomes", "i"));
fieldNonEmptyBlockCount.setAccessible(true); fieldBiomes.setAccessible(true);
Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName( Method getVisibleChunkIfPresent = ChunkMap.class.getDeclaredMethod(Refraction.pickName(
"getVisibleChunkIfPresent", "getVisibleChunkIfPresent",
@ -405,7 +403,7 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
if (set == null) { if (set == null) {
return newChunkSection(layer, biomeRegistry, biomes); return newChunkSection(biomeRegistry, biomes);
} }
final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get(); final int[] blockToPalette = FaweCache.INSTANCE.BLOCK_TO_PALETTE.get();
final int[] paletteToBlock = FaweCache.INSTANCE.PALETTE_TO_BLOCK.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 @SuppressWarnings("deprecation") // Only deprecated in paper
private static LevelChunkSection newChunkSection( private static LevelChunkSection newChunkSection(
int layer,
Registry<Biome> biomeRegistry, Registry<Biome> biomeRegistry,
@Nullable PalettedContainer<Holder<Biome>> biomes @Nullable PalettedContainer<Holder<Biome>> biomes
) { ) {
@ -510,6 +507,14 @@ public final class PaperweightPlatformAdapter extends NMSAdapter {
return new LevelChunkSection(dataPaletteBlocks, biomes); return new LevelChunkSection(dataPaletteBlocks, biomes);
} }
public static void setBiomesToChunkSection(LevelChunkSection section, PalettedContainer<Holder<Biome>> biomes) {
try {
fieldBiomes.set(section, biomes);
} catch (IllegalAccessException e) {
LOGGER.error("Could not set biomes to chunk section", e);
}
}
/** /**
* Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand. * Create a new {@link PalettedContainer<Biome>}. Should only be used if no biome container existed beforehand.
*/ */

Datei anzeigen

@ -21,22 +21,17 @@ import com.sk89q.worldedit.internal.registry.AbstractFactory;
import com.sk89q.worldedit.internal.registry.InputParser; import com.sk89q.worldedit.internal.registry.InputParser;
import com.sk89q.worldedit.util.formatting.text.TextComponent; import com.sk89q.worldedit.util.formatting.text.TextComponent;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class TransformFactory extends AbstractFactory<ResettableExtent> { public class TransformFactory extends AbstractFactory<ResettableExtent> {
private final RichTransformParser richTransformParser;
/** /**
* Create a new factory. * Create a new factory.
* *
* @param worldEdit the WorldEdit instance * @param worldEdit the WorldEdit instance
*/ */
public TransformFactory(WorldEdit worldEdit) { public TransformFactory(WorldEdit worldEdit) {
super(worldEdit, new NullTransformParser(worldEdit)); super(worldEdit, new NullTransformParser(worldEdit), new RichTransformParser(worldEdit));
richTransformParser = new RichTransformParser(worldEdit);
// split and parse each sub-transform // split and parse each sub-transform
register(new RandomTransformParser(worldEdit)); register(new RandomTransformParser(worldEdit));
@ -51,68 +46,7 @@ public class TransformFactory extends AbstractFactory<ResettableExtent> {
} }
@Override @Override
public ResettableExtent parseFromInput(String input, ParserContext context) throws InputParseException { protected ResettableExtent getParsed(final String input, final List<ResettableExtent> transforms) {
List<ResettableExtent> 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<ResettableExtent> transforms,
final String component
) {
ResettableExtent match = null;
for (InputParser<ResettableExtent> 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 &amp; 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<ResettableExtent> 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<ResettableExtent> transforms) {
switch (transforms.size()) { switch (transforms.size()) {
case 0: case 0:
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));

Datei anzeigen

@ -37,14 +37,14 @@ public abstract class FaweParser<T> extends InputParser<T> implements AliasedPar
for (int i = 0; i < toParse.length(); i++) { for (int i = 0; i < toParse.length(); i++) {
char c = toParse.charAt(i); char c = toParse.charAt(i);
switch (c) { switch (c) {
case ',', '&' -> { case ',', '&', ' ' -> {
if (expression) { if (expression) {
continue; continue;
} }
String result = toParse.substring(last, i); String result = toParse.substring(last, i);
if (!result.isEmpty()) { if (!result.isEmpty()) {
inputs.add(result); inputs.add(result);
and.add(c == '&'); and.add(c == '&' || c == ' ');
} else { } else {
throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", c)); throw new InputParseException(Caption.of("fawe.error.parse.invalid-dangling-character", c));
} }

Datei anzeigen

@ -19,7 +19,6 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.AbstractProperty;
import com.sk89q.worldedit.registry.state.Property; import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
@ -174,27 +173,23 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter {
ArrayList<HashMap<String, Object>> palette = new ArrayList<>(); ArrayList<HashMap<String, Object>> palette = new ArrayList<>();
for (BlockVector3 point : region) { for (BlockVector3 point : region) {
BlockState block = clipboard.getBlock(point); BlockState block = clipboard.getBlock(point);
int combined = block.getInternalId(); char ordinal = block.getOrdinalChar();
BlockType type = block.getBlockType(); BlockType type = block.getBlockType();
if (type == BlockTypes.STRUCTURE_VOID || indexes.containsKey(combined)) { if (type == BlockTypes.STRUCTURE_VOID || indexes.containsKey(ordinal)) {
continue; continue;
} }
indexes.put(combined, (Integer) palette.size()); indexes.put(ordinal, palette.size());
HashMap<String, Object> paletteEntry = new HashMap<>(); HashMap<String, Object> paletteEntry = new HashMap<>();
paletteEntry.put("Name", type.id()); paletteEntry.put("Name", type.id());
if (block.getInternalId() != type.getInternalId()) { if (block.getInternalId() != type.getInternalId()) {
Map<String, Object> properties = null; Map<String, Object> properties = null;
for (AbstractProperty property : (List<AbstractProperty<?>>) type.getProperties()) { for (Map.Entry<Property<?>, Object> entry : block.getStates().entrySet()) {
int propIndex = property.getIndex(block.getInternalId()); if (properties == null) {
if (propIndex != 0) { properties = new HashMap<>();
if (properties == null) {
properties = new HashMap<>();
}
Object value = property.getValues().get(propIndex);
properties.put(property.getName(), value.toString());
} }
properties.put(entry.getKey().getName(), entry.getValue().toString());
} }
if (properties != null) { if (properties != null) {
paletteEntry.put("Properties", properties); paletteEntry.put("Properties", properties);
@ -211,16 +206,23 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter {
for (BlockVector3 point : region) { for (BlockVector3 point : region) {
BaseBlock block = clipboard.getFullBlock(point); BaseBlock block = clipboard.getFullBlock(point);
if (block.getBlockType() != BlockTypes.STRUCTURE_VOID) { if (block.getBlockType() != BlockTypes.STRUCTURE_VOID) {
int combined = block.getInternalId(); char ordinal = block.getOrdinalChar();
int index = indexes.get(combined); int index = indexes.get(ordinal);
List<Integer> pos = Arrays.asList(point.x() - min.x(), List<Integer> pos = Arrays.asList(
point.y() - min.y(), point.z() - min.z() point.x() - min.x(),
point.y() - min.y(),
point.z() - min.z()
); );
if (!block.hasNbtData()) { if (!block.hasNbtData()) {
blocks.add(FaweCache.INSTANCE.asMap("state", index, "pos", pos)); blocks.add(FaweCache.INSTANCE.asMap("state", index, "pos", pos));
} else { } else {
Map<String, Tag> tag = new HashMap<>(block.getNbtData().getValue());
tag.remove("x");
tag.remove("y");
tag.remove("z");
CompoundTag cTag = new CompoundTag(tag);
blocks.add( blocks.add(
FaweCache.INSTANCE.asMap("state", index, "pos", pos, "nbt", block.getNbtData())); FaweCache.INSTANCE.asMap("state", index, "pos", pos, "nbt", cTag));
} }
} }
} }
@ -231,8 +233,16 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter {
ArrayList<Map<String, Object>> entities = new ArrayList<>(); ArrayList<Map<String, Object>> entities = new ArrayList<>();
for (Entity entity : clipboard.getEntities()) { for (Entity entity : clipboard.getEntities()) {
Location loc = entity.getLocation(); Location loc = entity.getLocation();
List<Double> pos = Arrays.asList(loc.x(), loc.y(), loc.z()); List<Double> pos = Arrays.asList(
List<Integer> blockPos = Arrays.asList(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); loc.x() - min.x(),
loc.y() - min.y(),
loc.z() - min.z()
);
List<Integer> blockPos = Arrays.asList(
loc.getBlockX() - min.x(),
loc.getBlockY() - min.y(),
loc.getBlockZ() - min.z()
);
BaseEntity state = entity.getState(); BaseEntity state = entity.getState();
if (state != null) { if (state != null) {
CompoundTag nbt = state.getNbtData(); CompoundTag nbt = state.getNbtData();

Datei anzeigen

@ -23,11 +23,16 @@ import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser; import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser;
import com.sk89q.worldedit.extension.input.InputParseException; 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.extension.input.ParserContext;
import com.sk89q.worldedit.internal.registry.AbstractFactory; 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 com.sk89q.worldedit.world.block.BaseBlock;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
@ -67,4 +72,21 @@ public class BlockFactory extends AbstractFactory<BaseBlock> {
return blocks; return blocks;
} }
//FAWE start
@Override
public BaseBlock parseFromInput(String input, ParserContext context) throws InputParseException {
BaseBlock match;
for (InputParser<BaseBlock> 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
} }

Datei anzeigen

@ -22,7 +22,13 @@ package com.sk89q.worldedit.extension.factory;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.extension.factory.parser.DefaultItemParser; 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.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<BaseItem> { public class ItemFactory extends AbstractFactory<BaseItem> {
@ -35,4 +41,21 @@ public class ItemFactory extends AbstractFactory<BaseItem> {
super(worldEdit, new DefaultItemParser(worldEdit)); super(worldEdit, new DefaultItemParser(worldEdit));
} }
//FAWE start
@Override
public BaseItem parseFromInput(String input, ParserContext context) throws InputParseException {
BaseItem match;
for (InputParser<BaseItem> 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
} }

Datei anzeigen

@ -53,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.OffsetMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser; import com.sk89q.worldedit.extension.factory.parser.mask.RegionMaskParser;
import com.sk89q.worldedit.extension.factory.parser.mask.SolidMaskParser; 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.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext; import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.mask.MaskIntersection; import com.sk89q.worldedit.function.mask.MaskIntersection;
import com.sk89q.worldedit.internal.registry.AbstractFactory; 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.TextComponent;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -75,21 +72,13 @@ import java.util.stream.Collectors;
*/ */
public final class MaskFactory extends AbstractFactory<Mask> { public final class MaskFactory extends AbstractFactory<Mask> {
//FAWE start - rich mask parsing
private final RichMaskParser richMaskParser;
//FAWE end
/** /**
* Create a new mask registry. * Create a new mask registry.
* *
* @param worldEdit the WorldEdit instance * @param worldEdit the WorldEdit instance
*/ */
public MaskFactory(WorldEdit worldEdit) { public MaskFactory(WorldEdit worldEdit) {
super(worldEdit, new BlocksMaskParser(worldEdit)); super(worldEdit, new BlocksMaskParser(worldEdit), new RichMaskParser(worldEdit));
//FAWE start - rich mask parsing
richMaskParser = new RichMaskParser(worldEdit);
//FAWE end
register(new ExistingMaskParser(worldEdit)); register(new ExistingMaskParser(worldEdit));
register(new AirMaskParser(worldEdit)); register(new AirMaskParser(worldEdit));
@ -125,7 +114,6 @@ public final class MaskFactory extends AbstractFactory<Mask> {
register(new ZAxisMaskParser(worldEdit)); register(new ZAxisMaskParser(worldEdit));
register(new SurfaceAngleMaskParser(worldEdit)); register(new SurfaceAngleMaskParser(worldEdit));
//FAWE end //FAWE end
} }
@Override @Override
@ -133,85 +121,24 @@ public final class MaskFactory extends AbstractFactory<Mask> {
final String[] split = input.split(" "); final String[] split = input.split(" ");
if (split.length > 1) { if (split.length > 1) {
String prev = input.substring(0, input.lastIndexOf(" ")) + " "; 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); return super.getSuggestions(input, parserContext);
} }
@Override
public Mask parseFromInput(String input, ParserContext context) throws InputParseException {
List<Mask> 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 //FAWE start - rich mask parsing
private void parseFromParsers(
final ParserContext context,
final List<Mask> masks,
final String component
) {
Mask match = null;
for (InputParser<Mask> parser : getParsers()) {
match = parser.parseFromInput(component, context);
if (match != null) { @Override
break; protected Mask getParsed(final String input, final List<Mask> masks) {
} return switch (masks.size()) {
} case 0 -> throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));
if (match == null) { case 1 -> masks.get(0).optimize();
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(component))); default -> new MaskIntersection(masks).optimize();
} };
masks.add(match);
}
/**
* Parses a mask without considering parsing through the {@link RichMaskParser}, therefore not accepting
* "richer" parsing where &amp; 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<Mask> 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<Mask> 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();
}
} }
//FAWE end //FAWE end

Datei anzeigen

@ -20,7 +20,6 @@
package com.sk89q.worldedit.extension.factory; package com.sk89q.worldedit.extension.factory;
import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.mask.HotbarMaskParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.AngleColorPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.AngleColorPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.AverageColorPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.AverageColorPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.BiomePatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.BiomePatternParser;
@ -44,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.PerlinPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RandomFullClipboardPatternParser; 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.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.RelativePatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RichPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.RidgedMultiFractalPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.RidgedMultiFractalPatternParser;
@ -53,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.SimplexPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.SolidRandomOffsetPatternParser; 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.SurfaceRandomOffsetPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.TypeSwapPatternParser;
import com.fastasyncworldedit.core.extension.factory.parser.pattern.VoronoiPatternParser; import com.fastasyncworldedit.core.extension.factory.parser.pattern.VoronoiPatternParser;
import com.fastasyncworldedit.core.math.random.TrueRandom; import com.fastasyncworldedit.core.math.random.TrueRandom;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.factory.parser.pattern.BlockCategoryPatternParser; 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.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.RandomStatePatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser; import com.sk89q.worldedit.extension.factory.parser.pattern.SingleBlockPatternParser;
import com.sk89q.worldedit.extension.factory.parser.pattern.TypeOrStateApplyingPatternParser; 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.NoMatchException;
import com.sk89q.worldedit.extension.input.ParserContext;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.function.pattern.RandomPattern; import com.sk89q.worldedit.function.pattern.RandomPattern;
import com.sk89q.worldedit.internal.registry.AbstractFactory; 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.TextComponent;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -82,20 +77,14 @@ import java.util.List;
*/ */
public final class PatternFactory extends AbstractFactory<Pattern> { public final class PatternFactory extends AbstractFactory<Pattern> {
//FAWE start - rich pattern parsing
private final RichPatternParser richPatternParser;
//FAWE end
/** /**
* Create a new instance. * Create a new instance.
* *
* @param worldEdit the WorldEdit instance * @param worldEdit the WorldEdit instance
*/ */
public PatternFactory(WorldEdit worldEdit) { public PatternFactory(WorldEdit worldEdit) {
super(worldEdit, new SingleBlockPatternParser(worldEdit));
//FAWE start - rich pattern parsing //FAWE start - rich pattern parsing
richPatternParser = new RichPatternParser(worldEdit); super(worldEdit, new SingleBlockPatternParser(worldEdit), new RichPatternParser(worldEdit));
//FAWE end //FAWE end
// split and parse each sub-pattern // split and parse each sub-pattern
@ -139,75 +128,10 @@ public final class PatternFactory extends AbstractFactory<Pattern> {
register(new SurfaceRandomOffsetPatternParser(worldEdit)); register(new SurfaceRandomOffsetPatternParser(worldEdit));
register(new TypeSwapPatternParser(worldEdit)); register(new TypeSwapPatternParser(worldEdit));
register(new VoronoiPatternParser(worldEdit)); register(new VoronoiPatternParser(worldEdit));
//FAWE end
} }
@Override @Override
public Pattern parseFromInput(String input, ParserContext context) throws InputParseException { protected Pattern getParsed(final String input, final List<Pattern> patterns) {
List<Pattern> 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<Pattern> patterns,
final String component
) {
Pattern match = null;
for (InputParser<Pattern> 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 &amp; 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<Pattern> 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<Pattern> patterns) {
switch (patterns.size()) { switch (patterns.size()) {
case 0: case 0:
throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input))); throw new NoMatchException(Caption.of("worldedit.error.no-match", TextComponent.of(input)));

Datei anzeigen

@ -21,6 +21,9 @@ package com.sk89q.worldedit.internal.registry;
import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Caption;
import com.fastasyncworldedit.core.extension.factory.parser.AliasedParser; 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.WorldEdit;
import com.sk89q.worldedit.extension.input.InputParseException; import com.sk89q.worldedit.extension.input.InputParseException;
import com.sk89q.worldedit.extension.input.NoMatchException; import com.sk89q.worldedit.extension.input.NoMatchException;
@ -43,7 +46,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
public abstract class AbstractFactory<E> { public abstract class AbstractFactory<E> {
protected final WorldEdit worldEdit; protected final WorldEdit worldEdit;
private final List<InputParser<E>> parsers = new ArrayList<>(); //FAWE start
protected final List<InputParser<E>> parsers = new ArrayList<>();
private final FaweParser<E> richParser;
//FWAE end
/** /**
* Create a new factory. * Create a new factory.
@ -52,11 +58,26 @@ public abstract class AbstractFactory<E> {
* @param defaultParser the parser to fall back to * @param defaultParser the parser to fall back to
*/ */
protected AbstractFactory(WorldEdit worldEdit, InputParser<E> defaultParser) { protected AbstractFactory(WorldEdit worldEdit, InputParser<E> 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<E> defaultParser, FaweParser<E> richParser) {
checkNotNull(worldEdit); checkNotNull(worldEdit);
checkNotNull(defaultParser); checkNotNull(defaultParser);
this.worldEdit = worldEdit; this.worldEdit = worldEdit;
this.parsers.add(defaultParser); this.parsers.add(defaultParser);
this.richParser = richParser;
} }
//FAWE end
/** /**
* Gets an immutable list of parsers. * Gets an immutable list of parsers.
@ -71,7 +92,7 @@ public abstract class AbstractFactory<E> {
return Collections.unmodifiableList(parsers); 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} * 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<E> {
* @return parsed result * @return parsed result
* @throws InputParseException if no result found * @throws InputParseException if no result found
*/ */
//FAWE end
public E parseFromInput(String input, ParserContext context) throws InputParseException { public E parseFromInput(String input, ParserContext context) throws InputParseException {
E match; List<E> parsed = new ArrayList<>();
for (String component : StringUtil.split(input,' ', '[', ']')) {
for (InputParser<E> parser : parsers) { if (component.isEmpty()) {
match = parser.parseFromInput(input, context); continue;
if (match != null) {
return match;
} }
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 @Deprecated
public List<String> getSuggestions(String input) { public List<String> getSuggestions(String input) {
@ -133,4 +160,48 @@ public abstract class AbstractFactory<E> {
}); });
} }
//FAWE start
protected void parseFromParsers(final ParserContext context, final List<E> parsed, final String component) {
E match = null;
for (InputParser<E> 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 &amp; 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<E> 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<E> parsed) {
return parsed.isEmpty() ? null : parsed.get(0);
}
//FAWE end
} }