server) {
this.mod = mod;
- this.dataFixer = new NeoForgeDataFixer(getDataVersion());
+ this.dataFixer = new CoreMcDataFixer(this, getDataVersion());
+ this.registries = new CoreMcRegistries(this);
+ this.transmogrifier = new CoreMcTransmogrifier(this);
+ this.server = server;
+ this.watchdog = server.flatMap(s -> {
+ if (s instanceof DedicatedServer dedicatedServer) {
+ return new ConstantLifecycled<>(new CoreMcWatchdog(dedicatedServer));
+ } else {
+ return SimpleLifecycled.invalid();
+ }
+ });
}
- boolean isHookingEvents() {
- return hookingEvents;
+ // region Methods to be implemented by subclasses that are not public API
+
+ protected abstract void sendCUIPacket(ServerPlayer player, CUIPacket packet);
+
+ protected void extraOnBlockStateChange(ServerLevel level, BlockPos pos, BlockState oldState, BlockState newState) {
}
- @Override
- public ResourceLoader getResourceLoader() {
- return resourceLoader;
+ // endregion
+
+ /**
+ * {@return the platform-specific {@link CoreMcAdapter}}
+ */
+ public abstract CoreMcAdapter getAdapter();
+
+ /**
+ * {@return the registry access of this platform's server}
+ */
+ public RegistryAccess serverRegistryAccess() {
+ return server.valueOrThrow().registryAccess();
+ }
+
+ public CoreMcMod getMod() {
+ return mod;
+ }
+
+ /**
+ * {@return the permissions provider for this platform}
+ *
+ * Queried via {@link Capability#PERMISSIONS}.
+ */
+ public CoreMcPermissionsProvider getPermissionsProvider() {
+ return permissionsProvider;
+ }
+
+ /**
+ * Set the permissions provider for this platform.
+ *
+ * @param provider the permissions provider
+ */
+ public void setPermissionsProvider(CoreMcPermissionsProvider provider) {
+ this.permissionsProvider = Objects.requireNonNull(provider);
+ }
+
+ public boolean isHookingEvents() {
+ return hookingEvents;
}
@Override
public Registries getRegistries() {
- return NeoForgeRegistries.getInstance();
+ return registries;
+ }
+
+ public CoreMcTransmogrifier getTransmogrifier() {
+ return transmogrifier;
}
@Override
@@ -104,29 +171,18 @@ public void reload() {
super.reload();
}
- @Override
- public int schedule(long delay, long period, Runnable task) {
- return -1;
- }
-
@Override
@Nullable
- public NeoForgeWatchdog getWatchdog() {
- if (watchdog == null) {
- MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
- if (server instanceof DedicatedServer dedicatedServer) {
- watchdog = new NeoForgeWatchdog(dedicatedServer);
- }
- }
- return watchdog;
+ public Watchdog getWatchdog() {
+ return watchdog.value().orElse(null);
}
@Override
public List extends World> getWorlds() {
- Iterable worlds = ServerLifecycleHooks.getCurrentServer().getAllLevels();
+ Iterable worlds = server.valueOrThrow().getAllLevels();
List ret = new ArrayList<>();
for (ServerLevel world : worlds) {
- ret.add(new NeoForgeWorld(world));
+ ret.add(new CoreMcWorld(this, world));
}
return ret;
}
@@ -134,23 +190,23 @@ public List extends World> getWorlds() {
@Nullable
@Override
public Player matchPlayer(Player player) {
- if (player instanceof NeoForgePlayer) {
+ if (player instanceof CoreMcPlayer) {
return player;
} else {
- ServerPlayer entity = ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayerByName(player.getName());
- return entity != null ? new NeoForgePlayer(entity) : null;
+ ServerPlayer entity = server.valueOrThrow().getPlayerList().getPlayerByName(player.getName());
+ return entity != null ? getAdapter().fromNativePlayer(entity) : null;
}
}
@Nullable
@Override
public World matchWorld(World world) {
- if (world instanceof NeoForgeWorld) {
+ if (world instanceof CoreMcWorld) {
return world;
} else {
- for (ServerLevel ws : ServerLifecycleHooks.getCurrentServer().getAllLevels()) {
+ for (ServerLevel ws : server.valueOrThrow().getAllLevels()) {
if (((ServerLevelData) ws.getLevelData()).getLevelName().equals(world.getName())) {
- return new NeoForgeWorld(ws);
+ return new CoreMcWorld(this, ws);
}
}
@@ -160,21 +216,7 @@ public World matchWorld(World world) {
@Override
public void registerCommands(CommandManager manager) {
- MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
- if (server == null) {
- return;
- }
- Commands mcMan = server.getCommands();
-
- for (Command command : manager.getAllCommands().toList()) {
- CommandWrapper.register(mcMan.getDispatcher(), command);
- Set perms = command.getCondition().as(PermissionCondition.class)
- .map(PermissionCondition::getPermissions)
- .orElseGet(Collections::emptySet);
- if (!perms.isEmpty()) {
- perms.forEach(NeoForgeWorldEdit.inst.getPermissionsProvider()::registerPermission);
- }
- }
+ // No-op, we register using the platform's event system.
}
@Override
@@ -183,7 +225,7 @@ public void setGameHooksEnabled(boolean enabled) {
}
@Override
- public NeoForgeConfiguration getConfiguration() {
+ public CoreMcConfiguration getConfiguration() {
return mod.getConfig();
}
@@ -192,19 +234,9 @@ public String getVersion() {
return mod.getInternalVersion();
}
- @Override
- public String getPlatformName() {
- return "NeoForge-Official";
- }
-
@Override
public String getPlatformVersion() {
- return mod.getInternalVersion();
- }
-
- @Override
- public String id() {
- return "enginehub:neoforge";
+ return getVersion();
}
@Override
@@ -219,14 +251,6 @@ public Map getCapabilities() {
return capabilities;
}
- private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
- SideEffect.VALIDATION,
- SideEffect.ENTITY_AI,
- SideEffect.LIGHTING,
- SideEffect.NEIGHBORS,
- SideEffect.UPDATE
- );
-
@Override
public Set getSupportedSideEffects() {
return SUPPORTED_SIDE_EFFECTS;
@@ -234,17 +258,15 @@ public Set getSupportedSideEffects() {
@Override
public long getTickCount() {
- return ServerLifecycleHooks.getCurrentServer().getTickCount();
+ return server.valueOrThrow().getTickCount();
}
@Override
public Collection getConnectedUsers() {
List users = new ArrayList<>();
- PlayerList scm = ServerLifecycleHooks.getCurrentServer().getPlayerList();
+ PlayerList scm = server.valueOrThrow().getPlayerList();
for (ServerPlayer entity : scm.getPlayers()) {
- if (entity != null) {
- users.add(new NeoForgePlayer(entity));
- }
+ users.add(getAdapter().fromNativePlayer(entity));
}
return users;
}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcPlayer.java
similarity index 76%
rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcPlayer.java
index 5e0a9de72e..96b9b58cfb 100644
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlayer.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcPlayer.java
@@ -17,14 +17,13 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.fabric;
+package com.sk89q.worldedit.coremc.internal;
import com.sk89q.worldedit.blocks.BaseItemStack;
+import com.sk89q.worldedit.coremc.mixin.AccessorClientboundBlockEntityDataPacket;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
import com.sk89q.worldedit.extent.inventory.BlockBag;
-import com.sk89q.worldedit.fabric.internal.ComponentConverter;
-import com.sk89q.worldedit.fabric.internal.NBTConverter;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@@ -39,11 +38,8 @@
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockTypes;
-import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
-import net.minecraft.network.chat.MutableComponent;
-import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
@@ -58,12 +54,22 @@
import java.util.UUID;
import javax.annotation.Nullable;
-public class FabricPlayer extends AbstractPlayerActor {
+/**
+ * Common player implementation for platforms sharing native Minecraft code.
+ */
+public class CoreMcPlayer extends AbstractPlayerActor {
+ private final CoreMcPlatform platform;
private final ServerPlayer player;
- protected FabricPlayer(ServerPlayer player) {
+ public CoreMcPlayer(CoreMcPlatform platform, ServerPlayer player) {
+ this.platform = platform;
this.player = player;
+
+ if (getUniqueId() == null) {
+ throw new AssertionError("Player UUID cannot be null");
+ }
+
ThreadSafeCache.getInstance().getOnlineIds().add(getUniqueId());
}
@@ -74,8 +80,12 @@ public UUID getUniqueId() {
@Override
public BaseItemStack getItemInHand(HandSide handSide) {
- ItemStack is = this.player.getItemInHand(handSide == HandSide.MAIN_HAND ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND);
- return FabricAdapter.adapt(is);
+ ItemStack is = this.player.getItemInHand(
+ handSide == HandSide.MAIN_HAND
+ ? InteractionHand.MAIN_HAND
+ : InteractionHand.OFF_HAND
+ );
+ return platform.getAdapter().fromNativeItemStack(is);
}
@Override
@@ -92,15 +102,16 @@ public BaseEntity getState() {
public Location getLocation() {
Vector3 position = Vector3.at(this.player.getX(), this.player.getY(), this.player.getZ());
return new Location(
- FabricWorldEdit.inst.getWorld(this.player.level()),
+ platform.getAdapter().fromNativeWorld(this.player.level()),
position,
this.player.getYRot(),
- this.player.getXRot());
+ this.player.getXRot()
+ );
}
@Override
public boolean setLocation(Location location) {
- ServerLevel level = (ServerLevel) FabricAdapter.adapt((World) location.getExtent());
+ ServerLevel level = platform.getAdapter().toNativeWorld((World) location.getExtent());
this.player.teleportTo(
level,
location.getX(), location.getY(), location.getZ(),
@@ -108,28 +119,27 @@ public boolean setLocation(Location location) {
location.getYaw(), location.getPitch(),
true
);
- // This check doesn't really ever get to be false in Fabric
- // Since Fabric API doesn't allow cancelling the teleport.
- // However, other mods could theoretically mix this in, so allow the detection.
+ // This may be false if the teleport was cancelled by a mod
return this.player.level() == level;
}
@Override
public World getWorld() {
- return FabricWorldEdit.inst.getWorld(this.player.level());
+ return platform.getAdapter().fromNativeWorld(this.player.level());
}
@Override
public void giveItem(BaseItemStack itemStack) {
- this.player.getInventory().add(FabricAdapter.adapt(itemStack));
+ this.player.getInventory().add(platform.getAdapter().toNativeItemStack(itemStack));
}
@Override
public void dispatchCUIEvent(CUIEvent event) {
- ServerPlayNetworking.send(
- this.player,
- new CUIPacket(event.getTypeId(), event.getParameters())
- );
+ platform.sendCUIPacket(this.player, new CUIPacket(event.getTypeId(), event.getParameters()));
+ }
+
+ public ServerPlayer getPlayer() {
+ return this.player;
}
@Override
@@ -169,15 +179,16 @@ public void printError(String msg) {
public void print(Component component) {
this.player.sendSystemMessage(ComponentConverter.Serializer.fromJson(
GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale())),
- player.level().registryAccess()
+ player.registryAccess()
));
}
private void sendColorized(String msg, ChatFormatting formatting) {
for (String part : msg.split("\n", 0)) {
- MutableComponent component = net.minecraft.network.chat.Component.literal(part)
- .withStyle(style -> style.withColor(formatting));
- this.player.sendSystemMessage(component);
+ this.player.sendSystemMessage(
+ net.minecraft.network.chat.Component.literal(part)
+ .withStyle(style -> style.withColor(formatting))
+ );
}
}
@@ -189,7 +200,7 @@ public boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
@Override
public String[] getGroups() {
- return new String[]{}; // WorldEditMod.inst.getPermissionsResolver().getGroups(this.player.username);
+ return new String[]{};
}
@Override
@@ -199,7 +210,7 @@ public BlockBag getInventoryBlockBag() {
@Override
public boolean hasPermission(String perm) {
- return FabricWorldEdit.inst.getPermissionsProvider().hasPermission(player, perm);
+ return platform.getPermissionsProvider().hasPermission(player, perm);
}
@Nullable
@@ -224,23 +235,25 @@ public void setFlying(boolean flying) {
@Override
public > void sendFakeBlock(BlockVector3 pos, B block) {
World world = getWorld();
- if (!(world instanceof FabricWorld fabricWorld)) {
+ if (!(world instanceof CoreMcWorld coreMcWorld)) {
return;
}
- BlockPos loc = FabricAdapter.toBlockPos(pos);
+ BlockPos loc = platform.getAdapter().toBlockPos(pos);
if (block == null) {
- final ClientboundBlockUpdatePacket packetOut = new ClientboundBlockUpdatePacket(fabricWorld.getWorld(), loc);
+ final ClientboundBlockUpdatePacket packetOut = new ClientboundBlockUpdatePacket(
+ coreMcWorld.getWorld(), loc
+ );
player.connection.send(packetOut);
} else {
final ClientboundBlockUpdatePacket packetOut = new ClientboundBlockUpdatePacket(
loc,
- FabricAdapter.adapt(block.toImmutableState())
+ platform.getAdapter().toNativeBlockState(block.toImmutableState())
);
player.connection.send(packetOut);
if (block instanceof BaseBlock baseBlock && block.getBlockType().equals(BlockTypes.STRUCTURE_BLOCK)) {
final LinCompoundTag nbtData = baseBlock.getNbt();
if (nbtData != null) {
- player.connection.send(new ClientboundBlockEntityDataPacket(
+ player.connection.send(AccessorClientboundBlockEntityDataPacket.create(
new BlockPos(pos.x(), pos.y(), pos.z()),
BlockEntityType.STRUCTURE_BLOCK,
NBTConverter.toNative(nbtData)
@@ -255,13 +268,13 @@ public SessionKey getSessionKey() {
return new SessionKeyImpl(player);
}
- static class SessionKeyImpl implements SessionKey {
- // If not static, this will leak a reference
+ // If not static, this will leak a reference
+ public static final class SessionKeyImpl implements SessionKey {
private final UUID uuid;
private final String name;
- SessionKeyImpl(ServerPlayer player) {
+ public SessionKeyImpl(ServerPlayer player) {
this.uuid = player.getUUID();
this.name = player.getName().getString();
}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricPropertyAdapter.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcPropertyAdapter.java
similarity index 89%
rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricPropertyAdapter.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcPropertyAdapter.java
index bbfbc28720..14d1c09cce 100644
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricPropertyAdapter.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcPropertyAdapter.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.fabric.internal;
+package com.sk89q.worldedit.coremc.internal;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.registry.state.Property;
@@ -27,12 +27,12 @@
import static com.google.common.base.Preconditions.checkArgument;
-class FabricPropertyAdapter> implements Property {
+public final class CoreMcPropertyAdapter> implements Property {
private final net.minecraft.world.level.block.state.properties.Property property;
private final List values;
- FabricPropertyAdapter(net.minecraft.world.level.block.state.properties.Property property) {
+ public CoreMcPropertyAdapter(net.minecraft.world.level.block.state.properties.Property property) {
this.property = property;
this.values = ImmutableList.copyOf(property.getPossibleValues());
}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricRegistries.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcRegistries.java
similarity index 68%
rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricRegistries.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcRegistries.java
index 143bd0bd33..e18feec9fb 100644
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricRegistries.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcRegistries.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.fabric;
+package com.sk89q.worldedit.coremc.internal;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
@@ -27,16 +27,22 @@
import com.sk89q.worldedit.world.registry.ItemRegistry;
/**
- * World data for the Fabric platform.
+ * Registry aggregation for Minecraft platforms sharing native code.
*/
-class FabricRegistries extends BundledRegistries {
+public final class CoreMcRegistries extends BundledRegistries {
- private static final FabricRegistries INSTANCE = new FabricRegistries();
- private final BlockRegistry blockRegistry = new FabricBlockRegistry();
- private final BiomeRegistry biomeRegistry = new FabricBiomeRegistry();
- private final ItemRegistry itemRegistry = new FabricItemRegistry();
- private final BlockCategoryRegistry blockCategoryRegistry = new FabricBlockCategoryRegistry();
- private final ItemCategoryRegistry itemCategoryRegistry = new FabricItemCategoryRegistry();
+ private final BlockRegistry blockRegistry;
+ private final BiomeRegistry biomeRegistry = new CoreMcBiomeRegistry();
+ private final ItemRegistry itemRegistry;
+ private final BlockCategoryRegistry blockCategoryRegistry;
+ private final ItemCategoryRegistry itemCategoryRegistry;
+
+ public CoreMcRegistries(CoreMcPlatform platform) {
+ this.blockRegistry = new CoreMcBlockRegistry(platform);
+ this.itemRegistry = new CoreMcItemRegistry(platform);
+ this.blockCategoryRegistry = new CoreMcBlockCategoryRegistry(platform);
+ this.itemCategoryRegistry = new CoreMcItemCategoryRegistry(platform);
+ }
@Override
public BlockRegistry getBlockRegistry() {
@@ -62,14 +68,4 @@ public BlockCategoryRegistry getBlockCategoryRegistry() {
public ItemCategoryRegistry getItemCategoryRegistry() {
return itemCategoryRegistry;
}
-
- /**
- * Get a static instance.
- *
- * @return an instance
- */
- public static FabricRegistries getInstance() {
- return INSTANCE;
- }
-
}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeServerLevelDelegateProxy.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcServerLevelDelegateProxy.java
similarity index 78%
rename from worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeServerLevelDelegateProxy.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcServerLevelDelegateProxy.java
index 746ba6d121..9d36009e8b 100644
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeServerLevelDelegateProxy.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcServerLevelDelegateProxy.java
@@ -17,14 +17,13 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.neoforge.internal;
+package com.sk89q.worldedit.coremc.internal;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
-import com.sk89q.worldedit.neoforge.NeoForgeAdapter;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.concurrency.LazyReference;
import net.minecraft.core.BlockPos;
@@ -45,26 +44,28 @@
import java.util.Map;
import java.util.function.Predicate;
-public class NeoForgeServerLevelDelegateProxy implements InvocationHandler, AutoCloseable {
+public final class CoreMcServerLevelDelegateProxy implements InvocationHandler, AutoCloseable {
+ private final CoreMcPlatform platform;
private final EditSession editSession;
private final ServerLevel serverLevel;
private final Map createdBlockEntities = new HashMap<>();
- private NeoForgeServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel) {
+ private CoreMcServerLevelDelegateProxy(CoreMcPlatform platform, EditSession editSession, ServerLevel serverLevel) {
+ this.platform = platform;
this.editSession = editSession;
this.serverLevel = serverLevel;
}
- public record LevelAndProxy(WorldGenLevel level, NeoForgeServerLevelDelegateProxy proxy) implements AutoCloseable {
+ public record LevelAndProxy(WorldGenLevel level, CoreMcServerLevelDelegateProxy proxy) implements AutoCloseable {
@Override
public void close() throws MaxChangedBlocksException {
proxy.close();
}
}
- public static LevelAndProxy newInstance(EditSession editSession, ServerLevel serverLevel) {
- NeoForgeServerLevelDelegateProxy proxy = new NeoForgeServerLevelDelegateProxy(editSession, serverLevel);
+ public static LevelAndProxy newInstance(CoreMcPlatform platform, EditSession editSession, ServerLevel serverLevel) {
+ CoreMcServerLevelDelegateProxy proxy = new CoreMcServerLevelDelegateProxy(platform, editSession, serverLevel);
return new LevelAndProxy(
(WorldGenLevel) Proxy.newProxyInstance(
serverLevel.getClass().getClassLoader(),
@@ -79,18 +80,18 @@ public static LevelAndProxy newInstance(EditSession editSession, ServerLevel ser
private BlockEntity getBlockEntity(BlockPos blockPos) {
// This doesn't synthesize or load from world. I think editing existing block entities without setting the block
// (in the context of features) should not be supported in the first place.
- BlockVector3 pos = NeoForgeAdapter.adapt(blockPos);
+ BlockVector3 pos = platform.getAdapter().adapt(blockPos);
return createdBlockEntities.get(pos);
}
private BlockState getBlockState(BlockPos blockPos) {
- return NeoForgeAdapter.adapt(this.editSession.getBlockWithBuffer(NeoForgeAdapter.adapt(blockPos)));
+ return platform.getAdapter().toNativeBlockState(this.editSession.getBlockWithBuffer(platform.getAdapter().adapt(blockPos)));
}
private boolean setBlock(BlockPos blockPos, BlockState blockState) {
try {
handleBlockEntity(blockPos, blockState);
- return editSession.setBlock(NeoForgeAdapter.adapt(blockPos), NeoForgeAdapter.adapt(blockState));
+ return editSession.setBlock(platform.getAdapter().adapt(blockPos), platform.getAdapter().fromNativeBlockState(blockState));
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
}
@@ -99,7 +100,7 @@ private boolean setBlock(BlockPos blockPos, BlockState blockState) {
// For BlockEntity#setBlockState, not sure why it's deprecated
@SuppressWarnings("deprecation")
private void handleBlockEntity(BlockPos blockPos, BlockState blockState) {
- BlockVector3 pos = NeoForgeAdapter.adapt(blockPos);
+ BlockVector3 pos = platform.getAdapter().adapt(blockPos);
if (blockState.hasBlockEntity()) {
if (!(blockState.getBlock() instanceof EntityBlock entityBlock)) {
// This will probably never happen, as Mojang's own code assumes that
@@ -124,9 +125,9 @@ private boolean removeBlock(BlockPos blockPos) {
}
private boolean addEntity(Entity entity) {
- Vector3 pos = NeoForgeAdapter.adapt(entity.getPosition(0.0f));
- Location location = new Location(NeoForgeAdapter.adapt(serverLevel), pos.x(), pos.y(), pos.z());
- BaseEntity baseEntity = new NeoForgeEntity(entity).getState();
+ Vector3 pos = platform.getAdapter().adapt(entity.getPosition(0.0f));
+ Location location = new Location(platform.getAdapter().fromNativeWorld(serverLevel), pos.x(), pos.y(), pos.z());
+ BaseEntity baseEntity = new CoreMcEntity(platform, entity).getState();
return editSession.createEntity(location, baseEntity) != null;
}
@@ -136,7 +137,7 @@ public void close() throws MaxChangedBlocksException {
BlockVector3 blockPos = entry.getKey();
BlockEntity blockEntity = entry.getValue();
- net.minecraft.nbt.CompoundTag tag = NeoForgeLoggingProblemReporter.with(
+ net.minecraft.nbt.CompoundTag tag = CoreMcLoggingProblemReporter.with(
() -> "saving block entity at " + blockPos,
reporter -> {
var tagValueOutput = TagValueOutput.createWithContext(reporter, serverLevel.registryAccess());
@@ -146,7 +147,7 @@ public void close() throws MaxChangedBlocksException {
);
editSession.setBlock(
blockPos,
- NeoForgeAdapter.adapt(blockEntity.getBlockState())
+ platform.getAdapter().fromNativeBlockState(blockEntity.getBlockState())
.toBaseBlock(LazyReference.from(() -> NBTConverter.fromNative(tag)))
);
}
@@ -155,39 +156,40 @@ public void close() throws MaxChangedBlocksException {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
switch (method.getName()) {
- case "getBlockState", "m_8055_" -> {
+ case "getBlockState" -> {
if (args.length == 1 && args[0] instanceof BlockPos blockPos) {
return getBlockState(blockPos);
}
}
- case "isStateAtPosition", "m_7433_" -> {
+ case "isStateAtPosition" -> {
if (args.length == 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Predicate) {
@SuppressWarnings("unchecked")
Predicate predicate = (Predicate) args[1];
return predicate.test(getBlockState(blockPos));
}
}
- case "getBlockEntity", "m_7702_" -> {
+ case "getBlockEntity" -> {
if (args.length == 1 && args[0] instanceof BlockPos blockPos) {
return getBlockEntity(blockPos);
}
}
- case "setBlock", "m_7731_" -> {
+ case "setBlock" -> {
if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) {
return setBlock(blockPos, blockState);
}
}
- case "removeBlock", "destroyBlock", "m_7471_", "m_7740_" -> {
+ case "removeBlock", "destroyBlock" -> {
if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean) {
return removeBlock(blockPos);
}
}
- case "addEntity", "m_8872_", "addFreshEntityWithPassengers", "m_47205_" -> {
+ case "addFreshEntityWithPassengers" -> {
if (args.length >= 1 && args[0] instanceof Entity entity) {
return addEntity(entity);
}
}
- default -> { }
+ default -> {
+ }
}
return method.invoke(this.serverLevel, args);
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeTransmogrifier.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcTransmogrifier.java
similarity index 74%
rename from worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeTransmogrifier.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcTransmogrifier.java
index 0f95732868..e1945d8b4a 100644
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeTransmogrifier.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcTransmogrifier.java
@@ -17,13 +17,12 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.neoforge.internal;
+package com.sk89q.worldedit.coremc.internal;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
-import com.sk89q.worldedit.neoforge.NeoForgeAdapter;
import com.sk89q.worldedit.registry.state.BooleanProperty;
import com.sk89q.worldedit.registry.state.DirectionalProperty;
import com.sk89q.worldedit.registry.state.EnumProperty;
@@ -43,11 +42,11 @@
/**
* Raw, un-cached transformations.
*/
-public class NeoForgeTransmogrifier {
-
- private static final LoadingCache, Property>> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader<>() {
+public final class CoreMcTransmogrifier {
+ private final CoreMcPlatform platform;
+ private final LoadingCache, Property>> propertyCache = CacheBuilder.newBuilder().build(new CacheLoader<>() {
@Override
- public Property> load(net.minecraft.world.level.block.state.properties.Property> property) throws Exception {
+ public Property> load(net.minecraft.world.level.block.state.properties.Property> property) {
return switch (property) {
case net.minecraft.world.level.block.state.properties.BooleanProperty booleanProperty ->
new BooleanProperty(property.getName(), ImmutableList.copyOf(booleanProperty.getPossibleValues()));
@@ -56,32 +55,33 @@ public Property> load(net.minecraft.world.level.block.state.properties.Propert
case net.minecraft.world.level.block.state.properties.EnumProperty> enumProperty -> {
if (property.getValueClass() == net.minecraft.core.Direction.class) {
yield new DirectionalProperty(property.getName(), property.getPossibleValues().stream()
- .map(v -> NeoForgeAdapter.adaptEnumFacing((net.minecraft.core.Direction) v))
+ .map(v -> CoreMcTransmogrifier.this.platform.getAdapter().adaptEnumFacing((net.minecraft.core.Direction) v))
.collect(ImmutableList.toImmutableList()));
}
- // Note: do not make x.asString a method reference.
- // It will cause runtime bootstrap exceptions.
- //noinspection Convert2MethodRef
yield new EnumProperty(property.getName(), enumProperty.getPossibleValues().stream()
- .map(x -> x.getSerializedName())
+ .map(StringRepresentable::getSerializedName)
.collect(ImmutableList.toImmutableList()));
}
- default -> new NeoForgePropertyAdapter<>(property);
+ default -> new CoreMcPropertyAdapter<>(property);
};
}
});
- public static Property> transmogToWorldEditProperty(net.minecraft.world.level.block.state.properties.Property> property) {
- return PROPERTY_CACHE.getUnchecked(property);
+ public CoreMcTransmogrifier(CoreMcPlatform platform) {
+ this.platform = platform;
+ }
+
+ public Property> transmogToWorldEditProperty(net.minecraft.world.level.block.state.properties.Property> property) {
+ return propertyCache.getUnchecked(property);
}
- public static Map, Object> transmogToWorldEditProperties(BlockType block, net.minecraft.world.level.block.state.BlockState blockState) {
+ public Map, Object> transmogToWorldEditProperties(BlockType block, net.minecraft.world.level.block.state.BlockState blockState) {
Map, Object> props = new TreeMap<>(Comparator.comparing(Property::name));
for (net.minecraft.world.level.block.state.properties.Property> property : blockState.getProperties()) {
Object value = blockState.getValue(property);
if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
if (property.getValueClass() == net.minecraft.core.Direction.class) {
- value = NeoForgeAdapter.adaptEnumFacing((net.minecraft.core.Direction) value);
+ value = platform.getAdapter().adaptEnumFacing((net.minecraft.core.Direction) value);
} else {
value = ((StringRepresentable) value).getSerializedName();
}
@@ -92,7 +92,7 @@ public static Map, Object> transmogToWorldEditProperties(BlockType b
}
@SuppressWarnings({"rawtypes", "unchecked"})
- private static net.minecraft.world.level.block.state.BlockState transmogToMinecraftProperties(
+ private net.minecraft.world.level.block.state.BlockState transmogToMinecraftProperties(
StateDefinition stateContainer,
net.minecraft.world.level.block.state.BlockState newState,
Map, Object> states
@@ -104,7 +104,7 @@ private static net.minecraft.world.level.block.state.BlockState transmogToMinecr
if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
if (property.getValueClass() == net.minecraft.core.Direction.class) {
Direction dir = (Direction) value;
- value = NeoForgeAdapter.adapt(dir);
+ value = platform.getAdapter().adapt(dir);
} else {
String enumName = (String) value;
value = ((net.minecraft.world.level.block.state.properties.EnumProperty>) property).getValue((String) value).orElseThrow(() ->
@@ -118,18 +118,15 @@ private static net.minecraft.world.level.block.state.BlockState transmogToMinecr
return newState;
}
- public static net.minecraft.world.level.block.state.BlockState transmogToMinecraft(BlockState blockState) {
- Block mcBlock = NeoForgeAdapter.adapt(blockState.getBlockType());
+ public net.minecraft.world.level.block.state.BlockState transmogToMinecraft(BlockState blockState) {
+ Block mcBlock = platform.getAdapter().toNativeBlock(blockState.getBlockType());
net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState();
Map, Object> states = blockState.getStates();
return transmogToMinecraftProperties(mcBlock.getStateDefinition(), newState, states);
}
- public static BlockState transmogToWorldEdit(net.minecraft.world.level.block.state.BlockState blockState) {
- BlockType blockType = NeoForgeAdapter.adapt(blockState.getBlock());
+ public BlockState transmogToWorldEdit(net.minecraft.world.level.block.state.BlockState blockState) {
+ BlockType blockType = platform.getAdapter().fromNativeBlock(blockState.getBlock());
return blockType.getState(transmogToWorldEditProperties(blockType, blockState));
}
-
- private NeoForgeTransmogrifier() {
- }
}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWatchdogImpl.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWatchdog.java
similarity index 78%
rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWatchdogImpl.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWatchdog.java
index cf4107b4ac..6dfa0eb9da 100644
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWatchdogImpl.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWatchdog.java
@@ -17,21 +17,22 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.fabric.internal;
+package com.sk89q.worldedit.coremc.internal;
+import com.sk89q.worldedit.coremc.mixin.AccessorMinecraftServer;
import com.sk89q.worldedit.extension.platform.Watchdog;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.Util;
-public final class FabricWatchdogImpl implements Watchdog {
+public final class CoreMcWatchdog implements Watchdog {
private final MinecraftServer server;
- public FabricWatchdogImpl(MinecraftServer server) {
+ public CoreMcWatchdog(MinecraftServer server) {
this.server = server;
}
@Override
public void tick() {
- server.nextTickTimeNanos = Util.getNanos();
+ ((AccessorMinecraftServer) server).setNextTickTimeNanos(Util.getNanos());
}
}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWorld.java
similarity index 80%
rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWorld.java
index bb81378a7c..d8c9f7b4b1 100644
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorld.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWorld.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.fabric;
+package com.sk89q.worldedit.coremc.internal;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
@@ -33,14 +33,11 @@
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
+import com.sk89q.worldedit.coremc.mixin.AccessorChunkMap;
+import com.sk89q.worldedit.coremc.mixin.AccessorMinecraftServer;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
-import com.sk89q.worldedit.fabric.internal.FabricEntity;
-import com.sk89q.worldedit.fabric.internal.FabricLoggingProblemReporter;
-import com.sk89q.worldedit.fabric.internal.FabricServerLevelDelegateProxy;
-import com.sk89q.worldedit.fabric.internal.FabricWorldNativeAccess;
-import com.sk89q.worldedit.fabric.internal.NBTConverter;
import com.sk89q.worldedit.function.mask.AbstractExtentMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.internal.Constants;
@@ -52,6 +49,7 @@
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
+import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.util.concurrency.LazyReference;
import com.sk89q.worldedit.util.io.file.SafeFiles;
import com.sk89q.worldedit.world.AbstractWorld;
@@ -78,7 +76,6 @@
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey;
-import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerChunkCache;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.RandomSource;
@@ -97,7 +94,6 @@
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.chunk.ChunkAccess;
-import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.level.chunk.LevelChunk;
import net.minecraft.world.level.chunk.PalettedContainer;
import net.minecraft.world.level.chunk.status.ChunkStatus;
@@ -108,7 +104,6 @@
import net.minecraft.world.level.levelgen.structure.Structure;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.saveddata.WeatherData;
-import net.minecraft.world.level.storage.LevelData;
import net.minecraft.world.level.storage.LevelStorageSource;
import net.minecraft.world.level.storage.ServerLevelData;
import net.minecraft.world.level.storage.TagValueOutput;
@@ -121,7 +116,6 @@
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -137,31 +131,34 @@
import static com.google.common.base.Preconditions.checkState;
/**
- * An adapter to Minecraft worlds for WorldEdit.
+ * Shared implementation of a Minecraft world for platforms sharing native code.
*/
-public class FabricWorld extends AbstractWorld {
+public final class CoreMcWorld extends AbstractWorld {
private static final RandomSource random = RandomSource.create();
- private static Identifier getDimensionRegistryKey(Level world) {
+ private static Identifier getDimensionRegistryKey(ServerLevel world) {
return Objects.requireNonNull(world.getServer(), "server cannot be null")
.registryAccess()
.lookupOrThrow(Registries.DIMENSION_TYPE)
.getKey(world.dimensionType());
}
- private final WeakReference worldRef;
- private final FabricWorldNativeAccess worldNativeAccess;
+ private final CoreMcPlatform platform;
+ private final WeakReference worldRef;
+ private final CoreMcWorldNativeAccess worldNativeAccess;
/**
* Construct a new world.
*
+ * @param platform the owning platform
* @param world the world
*/
- FabricWorld(Level world) {
+ public CoreMcWorld(CoreMcPlatform platform, ServerLevel world) {
checkNotNull(world);
+ this.platform = platform;
this.worldRef = new WeakReference<>(world);
- this.worldNativeAccess = new FabricWorldNativeAccess(worldRef);
+ this.worldNativeAccess = new CoreMcWorldNativeAccess(platform, worldRef);
}
/**
@@ -170,8 +167,8 @@ private static Identifier getDimensionRegistryKey(Level world) {
* @return the world
* @throws RuntimeException thrown if a reference to the world was lost (i.e. world was unloaded)
*/
- public Level getWorld() {
- Level world = worldRef.get();
+ public ServerLevel getWorld() {
+ ServerLevel world = worldRef.get();
if (world != null) {
return world;
} else {
@@ -181,8 +178,7 @@ public Level getWorld() {
@Override
public String getName() {
- LevelData levelProperties = getWorld().getLevelData();
- return ((ServerLevelData) levelProperties).getLevelName();
+ return ((ServerLevelData) getWorld().getLevelData()).getLevelName();
}
@Override
@@ -192,10 +188,8 @@ public String id() {
@Override
public Path getStoragePath() {
- final Level world = getWorld();
- MinecraftServer server = world.getServer();
- checkState(server != null, "Need a server world");
- return server.storageSource.getDimensionPath(world.dimension());
+ ServerLevel world = getWorld();
+ return ((AccessorMinecraftServer) world.getServer()).getStorageSource().getDimensionPath(world.dimension());
}
@Override
@@ -207,20 +201,19 @@ public > boolean setBlock(BlockVector3 position, B
@Override
public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) {
worldNativeAccess.applySideEffects(position, previousType, sideEffectSet);
- return Sets.intersection(FabricWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply());
+ return Sets.intersection(platform.getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply());
}
@Override
public int getBlockLightLevel(BlockVector3 position) {
checkNotNull(position);
- return getWorld().getMaxLocalRawBrightness(FabricAdapter.toBlockPos(position));
+ return getWorld().getMaxLocalRawBrightness(platform.getAdapter().toBlockPos(position));
}
@Override
public boolean clearContainerBlockContents(BlockVector3 position) {
checkNotNull(position);
-
- BlockEntity tile = getWorld().getBlockEntity(FabricAdapter.toBlockPos(position));
+ BlockEntity tile = getWorld().getBlockEntity(platform.getAdapter().toBlockPos(position));
if (tile instanceof Clearable clearable) {
clearable.clearContent();
return true;
@@ -236,7 +229,7 @@ public BiomeType getBiome(BlockVector3 position) {
}
private BiomeType getBiomeInChunk(BlockVector3 position, ChunkAccess chunk) {
- return FabricAdapter.adapt(
+ return platform.getAdapter().fromNativeBiome(
chunk.getNoiseBiome(position.x() >> 2, position.y() >> 2, position.z() >> 2).value()
);
}
@@ -251,22 +244,21 @@ public boolean setBiome(BlockVector3 position, BiomeType biome) {
var biomeArray = (PalettedContainer>) chunk.getSection(chunk.getSectionIndex(position.y())).getBiomes();
biomeArray.getAndSetUnchecked(
(position.x() >> 2) & 3, (position.y() >> 2) & 3, (position.z() >> 2) & 3,
- getWorld().registryAccess().lookup(Registries.BIOME)
- .orElseThrow()
+ getWorld().registryAccess().lookupOrThrow(Registries.BIOME)
.getOrThrow(ResourceKey.create(Registries.BIOME, Identifier.parse(biome.id())))
);
chunk.markUnsaved();
return true;
}
- private static final LoadingCache fakePlayers
- = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(FabricFakePlayer::new));
+ private static final LoadingCache fakePlayers
+ = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(CoreMcFakePlayer::new));
@Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
- ItemStack stack = FabricAdapter.adapt(new BaseItemStack(item.getType(), item.getNbtReference(), 1));
- ServerLevel world = (ServerLevel) getWorld();
- final FabricFakePlayer fakePlayer;
+ ItemStack stack = platform.getAdapter().toNativeItemStack(new BaseItemStack(item.getType(), item.getNbtReference(), 1));
+ ServerLevel world = getWorld();
+ final CoreMcFakePlayer fakePlayer;
try {
fakePlayer = fakePlayers.get(world);
} catch (ExecutionException ignored) {
@@ -274,20 +266,19 @@ public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
}
fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
fakePlayer.absSnapTo(position.x(), position.y(), position.z(),
- (float) face.toVector().toYaw(), (float) face.toVector().toPitch());
- final BlockPos blockPos = FabricAdapter.toBlockPos(position);
- final BlockHitResult rayTraceResult = new BlockHitResult(FabricAdapter.toVec3(position),
- FabricAdapter.adapt(face), blockPos, false);
+ (float) face.toVector().toYaw(), (float) face.toVector().toPitch());
+ final BlockPos blockPos = platform.getAdapter().toBlockPos(position);
+ final BlockHitResult rayTraceResult = new BlockHitResult(platform.getAdapter().toVec3(position),
+ platform.getAdapter().adapt(face), blockPos, false);
UseOnContext itemUseContext = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTraceResult);
InteractionResult used = stack.useOn(itemUseContext);
- if (used != InteractionResult.SUCCESS) {
- // try activating the block
- used = getWorld().getBlockState(blockPos).useItemOn(stack, world, fakePlayer, InteractionHand.MAIN_HAND, rayTraceResult);
- }
- if (used != InteractionResult.SUCCESS) {
- used = stack.use(world, fakePlayer, InteractionHand.MAIN_HAND);
+ if (!used.consumesAction()) {
+ used = world.getBlockState(blockPos).useItemOn(stack, world, fakePlayer, InteractionHand.MAIN_HAND, rayTraceResult);
+ if (!used.consumesAction()) {
+ used = stack.getItem().use(world, fakePlayer, InteractionHand.MAIN_HAND);
+ }
}
- return used == InteractionResult.SUCCESS;
+ return used.consumesAction();
}
@Override
@@ -299,30 +290,24 @@ public void dropItem(Vector3 position, BaseItemStack item) {
return;
}
- ItemEntity entity = new ItemEntity(getWorld(), position.x(), position.y(), position.z(), FabricAdapter.adapt(item));
+ ItemEntity entity = new ItemEntity(getWorld(), position.x(), position.y(), position.z(), platform.getAdapter().toNativeItemStack(item));
entity.setPickUpDelay(10);
getWorld().addFreshEntity(entity);
}
@Override
public void simulateBlockMine(BlockVector3 position) {
- BlockPos pos = FabricAdapter.toBlockPos(position);
+ BlockPos pos = platform.getAdapter().toBlockPos(position);
getWorld().destroyBlock(pos, true);
}
@Override
public boolean canPlaceAt(BlockVector3 position, BlockState blockState) {
- return FabricAdapter.adapt(blockState).canSurvive(getWorld(), FabricAdapter.toBlockPos(position));
+ return platform.getAdapter().toNativeBlockState(blockState).canSurvive(getWorld(), platform.getAdapter().toBlockPos(position));
}
@Override
public boolean regenerate(Region region, Extent extent, RegenOptions options) {
- // Don't even try to regen if it's going to fail.
- ChunkSource provider = getWorld().getChunkSource();
- if (!(provider instanceof ServerChunkCache)) {
- return false;
- }
-
if (options.getSeed().isPresent()) {
throw new UnsupportedOperationException("26.1+ worldgen does not support overriding the seed for regen");
}
@@ -340,7 +325,7 @@ private void doRegen(Region region, Extent extent, RegenOptions options) throws
Path tempDir = Files.createTempDirectory("WorldEditWorldGen");
LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir);
try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("WorldEditTempGen")) {
- ServerLevel originalWorld = (ServerLevel) getWorld();
+ ServerLevel originalWorld = getWorld();
ResourceKey worldRegKey = originalWorld.dimension();
try (ServerLevel serverWorld = new ServerLevel(
@@ -373,7 +358,7 @@ private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld
List> chunkLoadings = submitChunkLoadTasks(region, serverWorld);
// drive executor until loading finishes
- serverWorld.getChunkSource().mainThreadProcessor
+ ((AccessorChunkMap) serverWorld.getChunkSource().chunkMap).getMainThreadExecutor()
.managedBlock(() -> {
// bail out early if a future fails
if (chunkLoadings.stream().anyMatch(ftr ->
@@ -393,12 +378,12 @@ private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld
}
for (BlockVector3 vec : region) {
- BlockPos pos = FabricAdapter.toBlockPos(vec);
+ BlockPos pos = platform.getAdapter().toBlockPos(vec);
ChunkAccess chunk = chunks.get(ChunkPos.containing(pos));
- BlockStateHolder> state = FabricAdapter.adapt(chunk.getBlockState(pos));
+ BlockStateHolder> state = platform.getAdapter().fromNativeBlockState(chunk.getBlockState(pos));
BlockEntity blockEntity = chunk.getBlockEntity(pos);
if (blockEntity != null) {
- CompoundTag tag = FabricLoggingProblemReporter.with(
+ CompoundTag tag = CoreMcLoggingProblemReporter.with(
() -> "serializing block entity at " + pos,
reporter -> {
var tagValueOutput = TagValueOutput.createWithContext(reporter, getWorld().registryAccess());
@@ -431,7 +416,7 @@ private List> submitChunkLoadTasks(Region region,
@SuppressWarnings("deprecation")
@Nullable
- private static ResourceKey createTreeFeatureGenerator(com.sk89q.worldedit.util.TreeGenerator.TreeType type) {
+ private static ResourceKey createTreeFeatureGenerator(TreeGenerator.TreeType type) {
return switch (type) {
// Based off of the SaplingGenerator class, as well as uses of DefaultBiomeFeatures fields
case TREE -> TreePlacements.OAK_CHECKED;
@@ -459,7 +444,7 @@ private static ResourceKey createTreeFeatureGenerator(com.sk89q.w
case RANDOM -> {
// We're intentionally using index here to get a random tree type
@SuppressWarnings("EnumOrdinal")
- com.sk89q.worldedit.util.TreeGenerator.TreeType randomTreeType = com.sk89q.worldedit.util.TreeGenerator.TreeType.values()[ThreadLocalRandom.current().nextInt(com.sk89q.worldedit.util.TreeGenerator.TreeType.values().length)];
+ TreeGenerator.TreeType randomTreeType = TreeGenerator.TreeType.values()[ThreadLocalRandom.current().nextInt(TreeGenerator.TreeType.values().length)];
yield createTreeFeatureGenerator(randomTreeType);
}
default -> null;
@@ -468,19 +453,19 @@ private static ResourceKey createTreeFeatureGenerator(com.sk89q.w
@SuppressWarnings("deprecation")
@Override
- public boolean generateTree(com.sk89q.worldedit.util.TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
- ServerLevel world = (ServerLevel) getWorld();
+ public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
+ ServerLevel world = getWorld();
PlacedFeature generator = Optional.ofNullable(createTreeFeatureGenerator(type))
.map(k -> world.registryAccess().lookupOrThrow(Registries.PLACED_FEATURE).getValue(k))
.orElse(null);
ServerChunkCache chunkManager = world.getChunkSource();
- if (type == com.sk89q.worldedit.util.TreeGenerator.TreeType.CHORUS_PLANT) {
+ if (type == TreeGenerator.TreeType.CHORUS_PLANT) {
position = position.add(0, 1, 0);
}
- try (FabricServerLevelDelegateProxy.LevelAndProxy proxyLevel = FabricServerLevelDelegateProxy.newInstance(editSession, world)) {
+ try (CoreMcServerLevelDelegateProxy.LevelAndProxy proxyLevel = CoreMcServerLevelDelegateProxy.newInstance(platform, editSession, world)) {
return generator != null && generator.place(
proxyLevel.level(), chunkManager.getGenerator(), random,
- FabricAdapter.toBlockPos(position)
+ platform.getAdapter().toBlockPos(position)
);
}
}
@@ -491,26 +476,26 @@ public boolean generateTree(TreeType type, EditSession editSession, BlockVector3
if (customResult != null) {
return customResult;
}
- ServerLevel world = (ServerLevel) getWorld();
+ ServerLevel world = getWorld();
PlacedFeature generator = world.registryAccess().lookupOrThrow(Registries.PLACED_FEATURE).getValue(Identifier.tryParse(type.id()));
ServerChunkCache chunkManager = world.getChunkSource();
- try (FabricServerLevelDelegateProxy.LevelAndProxy proxyLevel = FabricServerLevelDelegateProxy.newInstance(editSession, world)) {
+ try (CoreMcServerLevelDelegateProxy.LevelAndProxy proxyLevel = CoreMcServerLevelDelegateProxy.newInstance(platform, editSession, world)) {
return generator != null && generator.place(
- proxyLevel.level(), chunkManager.getGenerator(), random,
- FabricAdapter.toBlockPos(position)
+ proxyLevel.level(), chunkManager.getGenerator(), random,
+ platform.getAdapter().toBlockPos(position)
);
}
}
@Override
public boolean generateFeature(ConfiguredFeatureType type, EditSession editSession, BlockVector3 position) {
- ServerLevel world = (ServerLevel) getWorld();
+ ServerLevel world = getWorld();
ConfiguredFeature, ?> feature = world.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).getValue(Identifier.tryParse(type.id()));
ServerChunkCache chunkManager = world.getChunkSource();
- try (FabricServerLevelDelegateProxy.LevelAndProxy proxyLevel = FabricServerLevelDelegateProxy.newInstance(editSession, world)) {
+ try (CoreMcServerLevelDelegateProxy.LevelAndProxy proxyLevel = CoreMcServerLevelDelegateProxy.newInstance(platform, editSession, world)) {
return feature != null && feature.place(
proxyLevel.level(), chunkManager.getGenerator(), random,
- FabricAdapter.toBlockPos(position)
+ platform.getAdapter().toBlockPos(position)
);
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
@@ -519,7 +504,7 @@ public boolean generateFeature(ConfiguredFeatureType type, EditSession editSessi
@Override
public boolean generateStructure(StructureType type, EditSession editSession, BlockVector3 position) {
- ServerLevel world = (ServerLevel) getWorld();
+ ServerLevel world = getWorld();
Registry structureRegistry = world.registryAccess().lookupOrThrow(Registries.STRUCTURE);
Structure structure = structureRegistry.getValue(Identifier.tryParse(type.id()));
if (structure == null) {
@@ -527,7 +512,7 @@ public boolean generateStructure(StructureType type, EditSession editSession, Bl
}
ServerChunkCache chunkManager = world.getChunkSource();
- try (FabricServerLevelDelegateProxy.LevelAndProxy proxyLevel = FabricServerLevelDelegateProxy.newInstance(editSession, world)) {
+ try (CoreMcServerLevelDelegateProxy.LevelAndProxy proxyLevel = CoreMcServerLevelDelegateProxy.newInstance(platform, editSession, world)) {
ChunkPos chunkPos = ChunkPos.containing(new BlockPos(position.x(), position.y(), position.z()));
StructureStart structureStart = structure.generate(
structureRegistry.wrapAsHolder(structure), world.dimension(), world.registryAccess(),
@@ -559,7 +544,7 @@ public boolean generateStructure(StructureType type, EditSession editSession, Bl
@Override
public void checkLoadedChunk(BlockVector3 pt) {
- getWorld().getChunk(FabricAdapter.toBlockPos(pt));
+ getWorld().getChunk(platform.getAdapter().toBlockPos(pt));
}
@Override
@@ -573,16 +558,16 @@ public void sendBiomeUpdates(Iterable chunks) {
for (BlockVector2 chunk : chunks) {
nativeChunks.add(getWorld().getChunk(chunk.x(), chunk.z(), ChunkStatus.BIOMES, false));
}
- ((ServerLevel) getWorld()).getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
+ getWorld().getChunkSource().chunkMap.resendBiomesForChunks(nativeChunks);
}
@Override
public void fixLighting(Iterable chunks) {
- Level world = getWorld();
+ ServerLevel world = getWorld();
for (BlockVector2 chunk : chunks) {
// Fetch the chunk after light initialization at least
// We'll be doing a full relight anyways, so we don't need to be LIGHT yet
- ((ServerLevel) world).getChunkSource().getLightEngine().lightChunk(world.getChunk(
+ world.getChunkSource().getLightEngine().lightChunk(world.getChunk(
chunk.x(), chunk.z(), ChunkStatus.INITIALIZE_LIGHT
), false).exceptionally(t -> {
WorldEdit.logger.warn("Failed to relight chunk at " + chunk, t);
@@ -650,16 +635,15 @@ public int getMaxY() {
@Override
public BlockVector3 getSpawnPosition() {
- return FabricAdapter.adapt(getWorld().getLevelData().getRespawnData().pos());
+ return platform.getAdapter().adapt(getWorld().getLevelData().getRespawnData().pos());
}
@Override
public BlockState getBlock(BlockVector3 position) {
net.minecraft.world.level.block.state.BlockState mcState = getWorld()
- .getChunk(position.x() >> 4, position.z() >> 4)
- .getBlockState(FabricAdapter.toBlockPos(position));
-
- return FabricAdapter.adapt(mcState);
+ .getChunk(position.x() >> 4, position.z() >> 4)
+ .getBlockState(platform.getAdapter().toBlockPos(position));
+ return platform.getAdapter().fromNativeBlockState(mcState);
}
@Override
@@ -669,7 +653,7 @@ public BaseBlock getFullBlock(BlockVector3 position) {
BlockEntity tile = ((LevelChunk) getWorld().getChunk(pos)).getBlockEntity(pos, LevelChunk.EntityCreationType.CHECK);
if (tile != null) {
- CompoundTag tag = FabricLoggingProblemReporter.with(
+ CompoundTag tag = CoreMcLoggingProblemReporter.with(
() -> "serializing block entity at " + pos,
reporter -> {
var tagValueOutput = TagValueOutput.createWithContext(reporter, getWorld().registryAccess());
@@ -691,9 +675,9 @@ public int hashCode() {
@Override
public boolean equals(Object o) {
return switch (o) {
- case FabricWorld other -> {
- Level otherWorld = other.worldRef.get();
- Level thisWorld = worldRef.get();
+ case CoreMcWorld other -> {
+ ServerLevel otherWorld = other.worldRef.get();
+ ServerLevel thisWorld = worldRef.get();
yield otherWorld != null && otherWorld.equals(thisWorld);
}
case World world -> world.getName().equals(getName());
@@ -703,36 +687,33 @@ public boolean equals(Object o) {
@Override
public List extends Entity> getEntities(Region region) {
- final Level world = getWorld();
+ final ServerLevel world = getWorld();
AABB box = new AABB(
- FabricAdapter.toVec3(region.getMinimumPoint()),
- FabricAdapter.toVec3(region.getMaximumPoint().add(BlockVector3.ONE))
+ platform.getAdapter().toVec3(region.getMinimumPoint()),
+ platform.getAdapter().toVec3(region.getMaximumPoint().add(BlockVector3.ONE))
);
List nmsEntities = world.getEntities(
(net.minecraft.world.entity.Entity) null,
box,
- e -> region.contains(FabricAdapter.adapt(e.blockPosition()))
+ e -> region.contains(platform.getAdapter().adapt(e.blockPosition()))
);
return nmsEntities.stream()
- .map(FabricEntity::new)
+ .map(e -> new CoreMcEntity(platform, e))
.collect(ImmutableList.toImmutableList());
}
@Override
public List extends Entity> getEntities() {
- final Level world = getWorld();
- if (!(world instanceof ServerLevel serverLevel)) {
- return Collections.emptyList();
- }
- return Streams.stream(serverLevel.getAllEntities())
- .map(FabricEntity::new)
+ final ServerLevel world = getWorld();
+ return Streams.stream(world.getAllEntities())
+ .map(entity -> new CoreMcEntity(platform, entity))
.collect(ImmutableList.toImmutableList());
}
@Nullable
@Override
public Entity createEntity(Location location, BaseEntity entity) {
- ServerLevel world = (ServerLevel) getWorld();
+ ServerLevel world = getWorld();
String entityId = entity.getType().id();
final Optional> entityType = EntityType.byString(entityId);
if (entityType.isEmpty()) {
@@ -754,7 +735,7 @@ public Entity createEntity(Location location, BaseEntity entity) {
});
if (createdEntity != null) {
world.addFreshEntityWithPassengers(createdEntity);
- return new FabricEntity(createdEntity);
+ return new CoreMcEntity(platform, createdEntity);
}
return null;
}
@@ -777,7 +758,7 @@ public Mask createLiquidMask() {
return new AbstractExtentMask(this) {
@Override
public boolean test(BlockVector3 vector) {
- return FabricAdapter.adapt(getExtent().getBlock(vector)).getBlock() instanceof LiquidBlock;
+ return platform.getAdapter().toNativeBlockState(getExtent().getBlock(vector)).getBlock() instanceof LiquidBlock;
}
};
}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeWorldNativeAccess.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWorldNativeAccess.java
similarity index 92%
rename from worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeWorldNativeAccess.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWorldNativeAccess.java
index de54fef426..63466108b1 100644
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NeoForgeWorldNativeAccess.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/CoreMcWorldNativeAccess.java
@@ -17,17 +17,15 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.neoforge.internal;
+package com.sk89q.worldedit.coremc.internal;
import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
-import com.sk89q.worldedit.neoforge.NeoForgeAdapter;
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.SideEffectSet;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.FullChunkStatus;
import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
@@ -40,11 +38,13 @@
import java.util.Objects;
import javax.annotation.Nullable;
-public class NeoForgeWorldNativeAccess implements WorldNativeAccess {
+public final class CoreMcWorldNativeAccess implements WorldNativeAccess {
+ private final CoreMcPlatform platform;
private final WeakReference world;
private SideEffectSet sideEffectSet;
- public NeoForgeWorldNativeAccess(WeakReference world) {
+ public CoreMcWorldNativeAccess(CoreMcPlatform platform, WeakReference world) {
+ this.platform = platform;
this.world = world;
}
@@ -67,7 +67,7 @@ public BlockState toNative(com.sk89q.worldedit.world.block.BlockState state) {
int stateId = BlockStateIdAccess.getBlockStateId(state);
return BlockStateIdAccess.isValidInternalId(stateId)
? Block.stateById(stateId)
- : NeoForgeAdapter.adapt(state);
+ : platform.getAdapter().toNativeBlockState(state);
}
@Override
@@ -106,12 +106,12 @@ public void updateLightingForBlock(BlockPos position) {
@Override
public boolean updateTileEntity(BlockPos position, LinCompoundTag tag) {
net.minecraft.nbt.CompoundTag nativeTag = NBTConverter.toNative(tag);
- Level level = getWorld();
+ ServerLevel level = getWorld();
BlockEntity tileEntity = level.getChunkAt(position).getBlockEntity(position);
if (tileEntity == null) {
return false;
}
- return NeoForgeLoggingProblemReporter.with(
+ return CoreMcLoggingProblemReporter.with(
() -> "loading tile entity at " + position,
reporter -> {
var tagValueInput = TagValueInput.create(reporter, level.registryAccess(), nativeTag);
@@ -175,6 +175,6 @@ public void updateNeighbors(BlockPos pos, BlockState oldState, BlockState newSta
@Override
public void onBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) {
getWorld().updatePOIOnBlockStateChange(pos, oldState, newState);
- newState.onBlockStateChange(getWorld(), pos, oldState);
+ platform.extraOnBlockStateChange(getWorld(), pos, oldState, newState);
}
}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NBTConverter.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/NBTConverter.java
similarity index 99%
rename from worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NBTConverter.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/NBTConverter.java
index b2813e7fbc..d0230a9b30 100644
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/internal/NBTConverter.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/NBTConverter.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.neoforge.internal;
+package com.sk89q.worldedit.coremc.internal;
import net.minecraft.nbt.ByteArrayTag;
import net.minecraft.nbt.ByteTag;
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/ThreadSafeCache.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/ThreadSafeCache.java
similarity index 92%
rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/ThreadSafeCache.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/ThreadSafeCache.java
index d769334316..92131860de 100644
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/ThreadSafeCache.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/ThreadSafeCache.java
@@ -17,9 +17,8 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.fabric;
+package com.sk89q.worldedit.coremc.internal;
-import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
@@ -31,7 +30,7 @@
/**
* Caches data that cannot be accessed from another thread safely.
*/
-public class ThreadSafeCache implements ServerTickEvents.EndTick {
+public class ThreadSafeCache {
private static final long REFRESH_DELAY = 1000 * 30;
private static final ThreadSafeCache INSTANCE = new ThreadSafeCache();
@@ -47,7 +46,6 @@ public Set getOnlineIds() {
return onlineIds;
}
- @Override
public void onEndTick(MinecraftServer server) {
long now = System.currentTimeMillis();
diff --git a/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/VanillaPermissionsProvider.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/VanillaPermissionsProvider.java
new file mode 100644
index 0000000000..d26b84c55c
--- /dev/null
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/internal/VanillaPermissionsProvider.java
@@ -0,0 +1,44 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.coremc.internal;
+
+import com.sk89q.worldedit.coremc.CoreMcPermissionsProvider;
+import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.world.level.GameType;
+
+final class VanillaPermissionsProvider implements CoreMcPermissionsProvider {
+ private final CoreMcPlatform platform;
+
+ VanillaPermissionsProvider(CoreMcPlatform platform) {
+ this.platform = platform;
+ }
+
+ @Override
+ public boolean hasPermission(ServerPlayer player, String permission) {
+ CoreMcConfiguration configuration = platform.getConfiguration();
+ return configuration.cheatMode
+ || player.level().getServer().getPlayerList().isOp(player.nameAndId())
+ || (configuration.creativeEnable && player.gameMode.getGameModeForPlayer() == GameType.CREATIVE);
+ }
+
+ @Override
+ public void registerPermission(String permission) {
+ }
+}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeWatchdog.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorChunkMap.java
similarity index 64%
rename from worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeWatchdog.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorChunkMap.java
index c6a9b475ae..0b24ac85a0 100644
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeWatchdog.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorChunkMap.java
@@ -17,22 +17,15 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.neoforge;
+package com.sk89q.worldedit.coremc.mixin;
-import com.sk89q.worldedit.extension.platform.Watchdog;
-import net.minecraft.server.dedicated.DedicatedServer;
-import net.minecraft.util.Util;
+import net.minecraft.server.level.ChunkMap;
+import net.minecraft.util.thread.BlockableEventLoop;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
-class NeoForgeWatchdog implements Watchdog {
-
- private final DedicatedServer server;
-
- NeoForgeWatchdog(DedicatedServer server) {
- this.server = server;
- }
-
- @Override
- public void tick() {
- server.nextTickTimeNanos = Util.getNanos();
- }
+@Mixin(ChunkMap.class)
+public interface AccessorChunkMap {
+ @Accessor
+ BlockableEventLoop getMainThreadExecutor();
}
diff --git a/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorClientboundBlockEntityDataPacket.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorClientboundBlockEntityDataPacket.java
new file mode 100644
index 0000000000..75bac830d3
--- /dev/null
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorClientboundBlockEntityDataPacket.java
@@ -0,0 +1,41 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.coremc.mixin;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
+import net.minecraft.world.level.block.entity.BlockEntityType;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+@Mixin(ClientboundBlockEntityDataPacket.class)
+public interface AccessorClientboundBlockEntityDataPacket {
+ // We want to call this as it will be replaced at runtime
+ @SuppressWarnings("DoNotCallSuggester")
+ @Invoker("")
+ static ClientboundBlockEntityDataPacket create(
+ final BlockPos pos,
+ final BlockEntityType> type,
+ final CompoundTag tag
+ ) {
+ throw new AssertionError("Should be replaced by Mixin");
+ }
+}
diff --git a/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorCommandSourceStack.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorCommandSourceStack.java
new file mode 100644
index 0000000000..c8973c75ac
--- /dev/null
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorCommandSourceStack.java
@@ -0,0 +1,31 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.coremc.mixin;
+
+import net.minecraft.commands.CommandSource;
+import net.minecraft.commands.CommandSourceStack;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+@Mixin(CommandSourceStack.class)
+public interface AccessorCommandSourceStack {
+ @Accessor
+ CommandSource getSource();
+}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricConfiguration.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorMinecraftServer.java
similarity index 54%
rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricConfiguration.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorMinecraftServer.java
index 76f2a9b4cf..2f6388aaee 100644
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricConfiguration.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorMinecraftServer.java
@@ -17,29 +17,18 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.fabric;
+package com.sk89q.worldedit.coremc.mixin;
-import com.sk89q.worldedit.util.PropertiesConfiguration;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.level.storage.LevelStorageSource;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
-import java.nio.file.Path;
+@Mixin(MinecraftServer.class)
+public interface AccessorMinecraftServer {
+ @Accessor
+ void setNextTickTimeNanos(long nextTickTimeNanos);
-public class FabricConfiguration extends PropertiesConfiguration {
-
- public boolean creativeEnable = false;
- public boolean cheatMode = false;
-
- public FabricConfiguration(FabricWorldEdit mod) {
- super(mod.getWorkingDir().resolve("worldedit.properties"));
- }
-
- @Override
- protected void loadExtra() {
- creativeEnable = getBool("use-in-creative", false);
- cheatMode = getBool("cheat-mode", false);
- }
-
- @Override
- public Path getWorkingDirectoryPath() {
- return FabricWorldEdit.inst.getWorkingDir();
- }
+ @Accessor
+ LevelStorageSource.LevelStorageAccess getStorageSource();
}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/mixin/AccessorServerPlayerGameMode.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorServerPlayerGameMode.java
similarity index 96%
rename from worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/mixin/AccessorServerPlayerGameMode.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorServerPlayerGameMode.java
index 234799dc28..af29455420 100644
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/mixin/AccessorServerPlayerGameMode.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/AccessorServerPlayerGameMode.java
@@ -17,7 +17,7 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.neoforge.mixin;
+package com.sk89q.worldedit.coremc.mixin;
import net.minecraft.server.level.ServerPlayerGameMode;
import org.spongepowered.asm.mixin.Mixin;
@@ -25,7 +25,6 @@
@Mixin(ServerPlayerGameMode.class)
public interface AccessorServerPlayerGameMode {
-
@Accessor("isDestroyingBlock")
boolean isDestroyingBlock();
}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/mixin/MixinServerGamePacketListenerImpl.java b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/MixinServerGamePacketListenerImpl.java
similarity index 57%
rename from worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/mixin/MixinServerGamePacketListenerImpl.java
rename to worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/MixinServerGamePacketListenerImpl.java
index 5c94f5b140..3cfb931060 100644
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/mixin/MixinServerGamePacketListenerImpl.java
+++ b/worldedit-core-mc/src/main/java/com/sk89q/worldedit/coremc/mixin/MixinServerGamePacketListenerImpl.java
@@ -17,10 +17,15 @@
* along with this program. If not, see .
*/
-package com.sk89q.worldedit.neoforge.mixin;
+package com.sk89q.worldedit.coremc.mixin;
import com.google.errorprone.annotations.Keep;
-import com.sk89q.worldedit.neoforge.NeoForgeWorldEdit;
+import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.coremc.internal.CoreMcPlatform;
+import com.sk89q.worldedit.extension.platform.Capability;
+import com.sk89q.worldedit.util.lifecycle.ConstantLifecycled;
+import com.sk89q.worldedit.util.lifecycle.Lifecycled;
+import com.sk89q.worldedit.util.lifecycle.SimpleLifecycled;
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
import net.minecraft.network.protocol.game.ServerboundSwingPacket;
import net.minecraft.server.level.ServerPlayer;
@@ -34,6 +39,18 @@
@Mixin(ServerGamePacketListenerImpl.class)
public class MixinServerGamePacketListenerImpl {
+
+ @Unique
+ private static final Lifecycled WORLD_EDITING_PLATFORM = WorldEdit.getInstance().getPlatformManager()
+ .getPreferred(Capability.WORLD_EDITING)
+ .flatMap(platform -> {
+ if (platform instanceof CoreMcPlatform coreMcPlatform) {
+ return new ConstantLifecycled<>(coreMcPlatform);
+ } else {
+ return SimpleLifecycled.invalid();
+ }
+ });
+
@Shadow
public ServerPlayer player;
@@ -41,22 +58,28 @@ public class MixinServerGamePacketListenerImpl {
private int ignoreSwingPackets;
@Keep
- @SuppressWarnings("UnusedVariable")
- @Inject(method = "handleAnimate", at = @At("HEAD"))
- private void onAnimate(ServerboundSwingPacket packet, CallbackInfo ci) {
+ @Inject(
+ method = "handleAnimate",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;swing(Lnet/minecraft/world/InteractionHand;)V")
+ )
+ private void onAnimate(ServerboundSwingPacket packet, @SuppressWarnings("UnusedVariable") CallbackInfo ci) {
if (!((AccessorServerPlayerGameMode) this.player.gameMode).isDestroyingBlock()) {
if (this.ignoreSwingPackets > 0) {
this.ignoreSwingPackets--;
- } else if (NeoForgeWorldEdit.inst != null) {
- NeoForgeWorldEdit.inst.onLeftClickAir(this.player, packet.getHand());
+ } else {
+ WORLD_EDITING_PLATFORM.value().ifPresent(platform ->
+ platform.getMod().onLeftClickAir(this.player, packet.getHand())
+ );
}
}
}
@Keep
- @SuppressWarnings("UnusedVariable")
- @Inject(method = "handlePlayerAction", at = @At("HEAD"))
- private void onAction(ServerboundPlayerActionPacket packet, CallbackInfo ci) {
+ @Inject(
+ method = "handlePlayerAction",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerPlayer;resetLastActionTime()V")
+ )
+ private void onAction(ServerboundPlayerActionPacket packet, @SuppressWarnings("UnusedVariable") CallbackInfo ci) {
switch (packet.getAction()) {
case DROP_ITEM, DROP_ALL_ITEMS, START_DESTROY_BLOCK -> this.ignoreSwingPackets++;
default -> {
diff --git a/worldedit-fabric/src/main/resources/assets/worldedit/icon.png b/worldedit-core-mc/src/main/resources/assets/worldedit/icon.png
similarity index 100%
rename from worldedit-fabric/src/main/resources/assets/worldedit/icon.png
rename to worldedit-core-mc/src/main/resources/assets/worldedit/icon.png
diff --git a/worldedit-fabric/src/main/resources/defaults/worldedit.properties b/worldedit-core-mc/src/main/resources/defaults/worldedit.properties
similarity index 100%
rename from worldedit-fabric/src/main/resources/defaults/worldedit.properties
rename to worldedit-core-mc/src/main/resources/defaults/worldedit.properties
diff --git a/worldedit-fabric/src/main/resources/pack.mcmeta b/worldedit-core-mc/src/main/resources/pack.mcmeta
similarity index 100%
rename from worldedit-fabric/src/main/resources/pack.mcmeta
rename to worldedit-core-mc/src/main/resources/pack.mcmeta
diff --git a/worldedit-core-mc/src/main/resources/worldedit-coremc.mixins.json b/worldedit-core-mc/src/main/resources/worldedit-coremc.mixins.json
new file mode 100644
index 0000000000..3e2a614b29
--- /dev/null
+++ b/worldedit-core-mc/src/main/resources/worldedit-coremc.mixins.json
@@ -0,0 +1,18 @@
+{
+ "required": true,
+ "package": "com.sk89q.worldedit.coremc.mixin",
+ "compatibilityLevel": "JAVA_8",
+ "mixins": [
+ "AccessorChunkMap",
+ "AccessorClientboundBlockEntityDataPacket",
+ "AccessorCommandSourceStack",
+ "AccessorMinecraftServer",
+ "AccessorServerPlayerGameMode",
+ "MixinServerGamePacketListenerImpl"
+ ],
+ "server": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/worldedit-core-mc/textconv-core-mc.py b/worldedit-core-mc/textconv-core-mc.py
new file mode 100755
index 0000000000..d62b4e7c61
--- /dev/null
+++ b/worldedit-core-mc/textconv-core-mc.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+"""
+Git textconv filter that normalizes platform-specific terms to platform$.
+
+Replaces Fabric/NeoForge/CoreMc identifiers with neutral placeholders so that
+git diff only shows code changes.
+
+Setup:
+ git config diff.core-mc.textconv ./worldedit-core-mc/textconv-core-mc.py
+"""
+import re
+import sys
+
+
+def normalize(content: str) -> str:
+ """Replace all platform-specific terms with placeholders."""
+ # Package names -- longest (with .internal) first to avoid partial matches
+ content = content.replace("com.sk89q.worldedit.fabric.internal", "com.sk89q.worldedit._platform_.internal")
+ content = content.replace("com.sk89q.worldedit.neoforge.internal", "com.sk89q.worldedit._platform_.internal")
+ content = content.replace("com.sk89q.worldedit.coremc.internal", "com.sk89q.worldedit._platform_.internal")
+ content = content.replace("com.sk89q.worldedit.fabric", "com.sk89q.worldedit._platform_")
+ content = content.replace("com.sk89q.worldedit.neoforge", "com.sk89q.worldedit._platform_")
+ content = content.replace("com.sk89q.worldedit.coremc", "com.sk89q.worldedit._platform_")
+
+ # PascalCase class/type prefixes: FabricPlayer -> platform$Player
+ content = re.sub(r"\bFabric(?=[A-Z])", "platform$", content)
+ content = re.sub(r"\bNeoForge(?=[A-Z])", "platform$", content)
+ content = re.sub(r"\bCoreMc(?=[A-Z])", "platform$", content)
+
+ # camelCase variable prefixes: fabricWorld -> platform$World
+ content = re.sub(r"\bfabric(?=[A-Z])", "platform$", content)
+ content = re.sub(r"\bneoForge(?=[A-Z])", "platform$", content)
+ content = re.sub(r"\bcoreMc(?=[A-Z])", "platform$", content)
+
+ return content
+
+
+def main() -> int:
+ if len(sys.argv) != 2:
+ print(f"Usage: {sys.argv[0]} ", file=sys.stderr)
+ return 2
+
+ with open(sys.argv[1]) as f:
+ content = f.read()
+
+ sys.stdout.write(normalize(content))
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/worldedit-core/build.gradle.kts b/worldedit-core/build.gradle.kts
index 51a6506fdb..1d69bf7a09 100644
--- a/worldedit-core/build.gradle.kts
+++ b/worldedit-core/build.gradle.kts
@@ -4,6 +4,7 @@ plugins {
`java-library`
antlr
id("buildlogic.core-and-platform")
+ id("buildlogic.expose-resources")
}
configurations {
@@ -122,17 +123,6 @@ tasks.named("processResources") {
}
}
-// "Publish" a resources variant for other projects to consume
-configurations.consumable("resourcesVariant") {
- // Similar to mainSourceElements
- attributes {
- attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category::class, Category.VERIFICATION))
- attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling::class, Bundling.EXTERNAL))
- attribute(VerificationType.VERIFICATION_TYPE_ATTRIBUTE, objects.named(VerificationType::class, "resources"))
- }
- outgoing.artifact(tasks.named("processResources"))
-}
-
configure {
publications.named("maven") {
artifactId = the().archivesName.get()
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
index 2a01d6925d..a61eb098d3 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/PlatformManager.java
@@ -19,6 +19,7 @@
package com.sk89q.worldedit.extension.platform;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
@@ -46,18 +47,19 @@
import com.sk89q.worldedit.util.SideEffect;
import com.sk89q.worldedit.util.concurrency.EvenMoreExecutors;
import com.sk89q.worldedit.util.eventbus.Subscribe;
+import com.sk89q.worldedit.util.lifecycle.Lifecycled;
import com.sk89q.worldedit.util.lifecycle.SimpleLifecycled;
import com.sk89q.worldedit.world.World;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.EnumMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Stream;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
@@ -78,7 +80,11 @@ public class PlatformManager {
private final PlatformCommandManager platformCommandManager;
private final SimpleLifecycled executorService;
private final Map platforms = Maps.newHashMap();
- private final Map preferences = new EnumMap<>(Capability.class);
+ private final ImmutableMap> preferences = Stream.of(Capability.values())
+ .collect(Maps.toImmutableEnumMap(
+ c -> c,
+ _ -> SimpleLifecycled.invalid()
+ ));
private @Nullable String firstSeenVersion;
private final AtomicBoolean initialized = new AtomicBoolean();
private final AtomicBoolean configured = new AtomicBoolean();
@@ -144,12 +150,14 @@ public synchronized boolean unregister(Platform platform) {
// Check whether this platform was chosen to be the preferred one
// for any capability and be sure to remove it
- Iterator> it = preferences.entrySet().iterator();
- while (it.hasNext()) {
- Entry entry = it.next();
- if (entry.getValue().equals(platform)) {
- entry.getKey().uninitialize(this, entry.getValue());
- it.remove();
+ for (Entry> entry : preferences.entrySet()) {
+ Capability cap = entry.getKey();
+ SimpleLifecycled lifecycled = entry.getValue();
+
+ Platform value = lifecycled.value().orElse(null);
+ if (platform.equals(value)) {
+ cap.uninitialize(this, platform);
+ lifecycled.invalidate();
choosePreferred = true; // Have to choose new favorites
}
}
@@ -162,6 +170,28 @@ public synchronized boolean unregister(Platform platform) {
return removed;
}
+ private SimpleLifecycled getPreferredUnsynchronized(Capability capability) {
+ SimpleLifecycled prefLifecycled = preferences.get(capability);
+ assert prefLifecycled != null : "All capabilities should have a lifecycled in the map";
+ return prefLifecycled;
+ }
+
+ /**
+ * Get the preferred platform for handling a certain capability.
+ *
+ *
+ * The lifecycled will be valid if a platform is currently preferred for the capability, and invalid otherwise.
+ * If preferences are updated, then the lifecycled will be invalidated and a new value will be set if a new
+ * preferred platform is found.
+ *
+ *
+ * @param capability the capability
+ * @return the lifecycled preferred platform
+ */
+ public synchronized Lifecycled getPreferred(Capability capability) {
+ return getPreferredUnsynchronized(capability);
+ }
+
/**
* Get the preferred platform for handling a certain capability. Throws if none are available.
*
@@ -170,9 +200,9 @@ public synchronized boolean unregister(Platform platform) {
* @throws NoCapablePlatformException thrown if no platform is capable
*/
public synchronized Platform queryCapability(Capability capability) throws NoCapablePlatformException {
- Platform platform = preferences.get(checkNotNull(capability));
- if (platform != null) {
- return platform;
+ Optional platform = getPreferredUnsynchronized(checkNotNull(capability)).value();
+ if (platform.isPresent()) {
+ return platform.get();
} else {
if (preferences.isEmpty()) {
// Not all platforms registered, this is being called too early!
@@ -192,7 +222,10 @@ private synchronized void choosePreferred() {
for (Capability capability : Capability.values()) {
Platform preferred = findMostPreferred(capability);
if (preferred != null) {
- Platform oldPreferred = preferences.put(capability, preferred);
+ SimpleLifecycled prefLifecycled = getPreferredUnsynchronized(capability);
+
+ Platform oldPreferred = prefLifecycled.value().orElse(null);
+ prefLifecycled.newValue(preferred);
// only (re)initialize if it changed
if (preferred != oldPreferred) {
// uninitialize if needed
@@ -205,7 +238,7 @@ private synchronized void choosePreferred() {
}
// Fire configuration event
- if (preferences.containsKey(Capability.CONFIGURATION) && configured.compareAndSet(false, true)) {
+ if (getPreferredUnsynchronized(Capability.CONFIGURATION).isValid() && configured.compareAndSet(false, true)) {
worldEdit.getEventBus().post(new ConfigurationLoadEvent(queryCapability(Capability.CONFIGURATION).getConfiguration()));
}
}
@@ -365,7 +398,9 @@ public void handlePlatformsRegistered(PlatformsRegisteredEvent event) {
*/
@Subscribe
public void handleNewPlatformReady(PlatformReadyEvent event) {
- preferences.forEach((cap, platform) -> cap.ready(this, platform));
+ preferences.forEach((cap, platform) ->
+ platform.value().ifPresent(p -> cap.ready(this, p))
+ );
platforms.put(event.getPlatform(), true);
if (!executorService.isValid()) {
executorService.newValue(createExecutor());
@@ -377,7 +412,9 @@ public void handleNewPlatformReady(PlatformReadyEvent event) {
*/
@Subscribe
public void handleNewPlatformUnready(PlatformUnreadyEvent event) {
- preferences.forEach((cap, platform) -> cap.unready(this, platform));
+ preferences.forEach((cap, platform) ->
+ platform.value().ifPresent(p -> cap.unready(this, p))
+ );
platforms.put(event.getPlatform(), false);
if (!platforms.containsValue(true)) {
executorService.value().ifPresent(ListeningExecutorService::shutdownNow);
diff --git a/worldedit-fabric/build.gradle.kts b/worldedit-fabric/build.gradle.kts
index dc831d093c..49df120495 100644
--- a/worldedit-fabric/build.gradle.kts
+++ b/worldedit-fabric/build.gradle.kts
@@ -1,3 +1,4 @@
+import buildlogic.addEngineHubRepository
import buildlogic.internalVersion
import buildlogic.withCuiProtocolDependsOnCommonRule
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
@@ -18,35 +19,24 @@ platform {
val fabricApiConfiguration: Configuration = configurations.create("fabricApi")
-loom {
- accessWidenerPath.set(project.file("src/main/resources/worldedit.accesswidener"))
-}
-
tasks.withType().configureEach {
javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
}
repositories {
- maven {
- name = "EngineHub (Non-Mirrored)"
- url = URI.create("https://repo.enginehub.org/libs-release/")
- metadataSources {
- gradleMetadata()
- mavenPom()
- artifact()
- }
- }
+ addEngineHubRepository()
}
withCuiProtocolDependsOnCommonRule(libs.cuiProtocol.fabric.get().module)
dependencies {
- "api"(project(":worldedit-core"))
+ api(project(":worldedit-core"))
+ api(project(":worldedit-core-mc"))
- "minecraft"(libs.fabric.minecraft)
- "implementation"(libs.fabric.loader)
- "implementation"(libs.cuiProtocol.fabric)
- "include"(libs.cuiProtocol.fabric) {
+ minecraft(libs.fabric.minecraft)
+ implementation(libs.fabric.loader)
+ implementation(libs.cuiProtocol.fabric)
+ include(libs.cuiProtocol.fabric) {
attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling::class, Bundling.SHADOWED))
}
@@ -63,15 +53,15 @@ dependencies {
// [2] Request the matching dependency from fabric-loom
for (wantedDependency in wantedDependencies) {
val dep = fabricApi.module(wantedDependency, libs.versions.fabric.api.get())
- "include"(dep)
- "implementation"(dep)
+ include(dep)
+ implementation(dep)
}
// No need for this at runtime
- "compileOnly"(libs.fabric.permissions.api)
+ compileOnly(libs.fabric.permissions.api)
// Silence some warnings, since apparently this isn't on the compile classpath like it should be.
- "compileOnly"(libs.errorprone.annotations)
+ compileOnly(libs.errorprone.annotations)
}
configure {
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/CommandWrapper.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/CommandWrapper.java
deleted file mode 100644
index e782a870de..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/CommandWrapper.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.google.common.collect.ImmutableList;
-import com.mojang.brigadier.Command;
-import com.mojang.brigadier.CommandDispatcher;
-import com.mojang.brigadier.arguments.StringArgumentType;
-import com.mojang.brigadier.builder.LiteralArgumentBuilder;
-import com.mojang.brigadier.context.CommandContext;
-import com.mojang.brigadier.context.StringRange;
-import com.mojang.brigadier.exceptions.CommandSyntaxException;
-import com.mojang.brigadier.suggestion.Suggestion;
-import com.mojang.brigadier.suggestion.Suggestions;
-import com.mojang.brigadier.suggestion.SuggestionsBuilder;
-import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
-import com.sk89q.worldedit.extension.platform.Actor;
-import com.sk89q.worldedit.internal.util.Substring;
-import net.minecraft.commands.CommandSourceStack;
-import org.enginehub.piston.inject.InjectedValueStore;
-import org.enginehub.piston.inject.Key;
-import org.enginehub.piston.inject.MapBackedValueStore;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-import java.util.function.Predicate;
-
-import static com.sk89q.worldedit.fabric.FabricAdapter.adaptCommandSource;
-import static net.minecraft.commands.Commands.argument;
-import static net.minecraft.commands.Commands.literal;
-
-
-public final class CommandWrapper {
-
- private CommandWrapper() {
- }
-
- public static void register(CommandDispatcher dispatcher, org.enginehub.piston.Command command) {
- ImmutableList.Builder aliases = ImmutableList.builder();
- aliases.add(command.getName()).addAll(command.getAliases());
-
- Command commandRunner = ctx -> {
- WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
- adaptCommandSource(ctx.getSource()),
- "/" + ctx.getInput()
- ));
- return 0;
- };
-
- for (String alias : aliases.build()) {
- LiteralArgumentBuilder base = literal(alias).executes(commandRunner)
- .then(argument("args", StringArgumentType.greedyString())
- .suggests(CommandWrapper::suggest)
- .executes(commandRunner));
- if (command.getCondition() != org.enginehub.piston.Command.Condition.TRUE) {
- base.requires(requirementsFor(command));
- }
- dispatcher.register(base);
- }
- }
-
- private static Predicate requirementsFor(org.enginehub.piston.Command mapping) {
- return ctx -> {
- InjectedValueStore store = MapBackedValueStore.create();
- final Actor actor = FabricAdapter.adaptCommandSource(ctx);
- store.injectValue(Key.of(Actor.class), context -> Optional.of(actor));
- return mapping.getCondition().satisfied(store);
- };
- }
-
- private static CompletableFuture suggest(CommandContext context,
- SuggestionsBuilder builder) throws CommandSyntaxException {
- CommandSuggestionEvent event = new CommandSuggestionEvent(
- FabricAdapter.adaptCommandSource(context.getSource()),
- builder.getInput()
- );
- WorldEdit.getInstance().getEventBus().post(event);
- List suggestions = event.getSuggestions();
-
- ImmutableList.Builder result = ImmutableList.builder();
-
- for (Substring suggestion : suggestions) {
- String suggestionText = suggestion.getSubstring();
- // If at end, we are actually suggesting the next argument
- // Ensure there is a space!
- if (suggestion.getStart() == suggestion.getEnd()
- && suggestion.getEnd() == builder.getInput().length()
- && !builder.getInput().endsWith(" ")
- && !builder.getInput().endsWith("\"")) {
- suggestionText = " " + suggestionText;
- }
- result.add(new Suggestion(
- StringRange.between(suggestion.getStart(), suggestion.getEnd()),
- suggestionText
- ));
- }
-
- return CompletableFuture.completedFuture(
- Suggestions.create(builder.getInput(), result.build())
- );
- }
-
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricAdapter.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricAdapter.java
index 34c3337634..5d6481d8ea 100644
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricAdapter.java
+++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricAdapter.java
@@ -19,281 +19,29 @@
package com.sk89q.worldedit.fabric;
-import com.mojang.serialization.Codec;
-import com.sk89q.worldedit.blocks.BaseItemStack;
-import com.sk89q.worldedit.extension.platform.Actor;
-import com.sk89q.worldedit.fabric.internal.FabricTransmogrifier;
-import com.sk89q.worldedit.fabric.internal.NBTConverter;
-import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
-import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.math.Vector3;
-import com.sk89q.worldedit.registry.state.Property;
-import com.sk89q.worldedit.util.Direction;
-import com.sk89q.worldedit.util.concurrency.LazyReference;
-import com.sk89q.worldedit.world.World;
-import com.sk89q.worldedit.world.biome.BiomeType;
-import com.sk89q.worldedit.world.biome.BiomeTypes;
-import com.sk89q.worldedit.world.block.BaseBlock;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BlockType;
-import com.sk89q.worldedit.world.block.BlockTypes;
-import com.sk89q.worldedit.world.item.ItemType;
-import com.sk89q.worldedit.world.item.ItemTypes;
-import net.minecraft.commands.CommandSourceStack;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.RegistryAccess;
-import net.minecraft.core.component.DataComponentPatch;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.nbt.NbtOps;
-import net.minecraft.resources.Identifier;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.util.StringRepresentable;
-import net.minecraft.world.item.Item;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.level.BaseCommandBlock;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.block.entity.BlockEntity;
-import net.minecraft.world.level.storage.TagValueOutput;
-import net.minecraft.world.phys.Vec3;
-import org.enginehub.linbus.tree.LinCompoundTag;
+import com.sk89q.worldedit.coremc.CoreMcAdapter;
+import com.sk89q.worldedit.coremc.internal.CoreMcPlatform;
+import com.sk89q.worldedit.fabric.internal.FabricWorldEdit;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Objects;
-import java.util.TreeMap;
-import javax.annotation.Nullable;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public final class FabricAdapter {
-
- private FabricAdapter() {
- }
-
- public static World adapt(net.minecraft.world.level.Level world) {
- return new FabricWorld(world);
- }
-
- /**
- * Create a Fabric world from a WorldEdit world.
- *
- * @param world the WorldEdit world
- * @return a Fabric world
- */
- public static net.minecraft.world.level.Level adapt(World world) {
- checkNotNull(world);
- if (world instanceof FabricWorld fabricWorld) {
- return fabricWorld.getWorld();
- } else {
- // TODO introduce a better cross-platform world API to match more easily
- throw new UnsupportedOperationException("Cannot adapt from a " + world.getClass());
- }
- }
-
- public static Biome adapt(BiomeType biomeType) {
- return FabricWorldEdit.getRegistry(Registries.BIOME)
- .getValue(Identifier.parse(biomeType.id()));
- }
-
- public static BiomeType adapt(Biome biome) {
- Identifier id = FabricWorldEdit.getRegistry(Registries.BIOME).getKey(biome);
- Objects.requireNonNull(id, "biome is not registered");
- return BiomeTypes.get(id.toString());
- }
-
- public static Vector3 adapt(Vec3 vector) {
- return Vector3.at(vector.x, vector.y, vector.z);
- }
-
- public static BlockVector3 adapt(BlockPos pos) {
- return BlockVector3.at(pos.getX(), pos.getY(), pos.getZ());
- }
-
- public static Vec3 toVec3(BlockVector3 vector) {
- return new Vec3(vector.x(), vector.y(), vector.z());
- }
-
- public static net.minecraft.core.Direction adapt(Direction face) {
- return switch (face) {
- case NORTH -> net.minecraft.core.Direction.NORTH;
- case SOUTH -> net.minecraft.core.Direction.SOUTH;
- case WEST -> net.minecraft.core.Direction.WEST;
- case EAST -> net.minecraft.core.Direction.EAST;
- case DOWN -> net.minecraft.core.Direction.DOWN;
- default -> net.minecraft.core.Direction.UP;
- };
- }
-
- public static Direction adaptEnumFacing(@Nullable net.minecraft.core.Direction face) {
- if (face == null) {
- return null;
- }
- return switch (face) {
- case NORTH -> Direction.NORTH;
- case SOUTH -> Direction.SOUTH;
- case WEST -> Direction.WEST;
- case EAST -> Direction.EAST;
- case DOWN -> Direction.DOWN;
- default -> Direction.UP;
- };
- }
-
- public static BlockPos toBlockPos(BlockVector3 vector) {
- return new BlockPos(vector.x(), vector.y(), vector.z());
- }
-
- /**
- * Adapts property.
- *
- * @deprecated without replacement, use the block adapter methods
- */
- // Suppress InlineMeSuggester: There is no replacement, so this shouldn't be inlined
- @SuppressWarnings("InlineMeSuggester")
- @Deprecated
- public static Property> adaptProperty(net.minecraft.world.level.block.state.properties.Property> property) {
- return FabricTransmogrifier.transmogToWorldEditProperty(property);
- }
-
- /**
- * Adapts properties.
- *
- * @deprecated without replacement, use the block adapter methods
- */
- @Deprecated
- public static Map, Object> adaptProperties(BlockType block, Map, Comparable>> mcProps) {
- Map, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
- for (Map.Entry, Comparable>> prop : mcProps.entrySet()) {
- Object value = prop.getValue();
- if (prop.getKey() instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
- if (prop.getKey().getValueClass() == net.minecraft.core.Direction.class) {
- value = adaptEnumFacing((net.minecraft.core.Direction) value);
- } else {
- value = ((StringRepresentable) value).getSerializedName();
- }
- }
- props.put(block.getProperty(prop.getKey().getName()), value);
- }
- return props;
- }
-
- public static net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
- int blockStateId = BlockStateIdAccess.getBlockStateId(blockState);
- if (!BlockStateIdAccess.isValidInternalId(blockStateId)) {
- return FabricTransmogrifier.transmogToMinecraft(blockState);
- }
- return Block.stateById(blockStateId);
- }
-
- public static BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) {
- int blockStateId = Block.getId(blockState);
- BlockState worldEdit = BlockStateIdAccess.getBlockStateById(blockStateId);
- if (worldEdit == null) {
- return FabricTransmogrifier.transmogToWorldEdit(blockState);
- }
- return worldEdit;
- }
-
- public static BaseBlock adapt(BlockEntity blockEntity) {
- if (!blockEntity.hasLevel()) {
- throw new IllegalArgumentException("BlockEntity must have a level");
- }
- RegistryAccess registries = blockEntity.getLevel().registryAccess();
- return adapt(blockEntity, registries);
- }
-
- public static BaseBlock adapt(BlockEntity blockEntity, RegistryAccess registries) {
- int blockStateId = Block.getId(blockEntity.getBlockState());
- BlockState worldEdit = BlockStateIdAccess.getBlockStateById(blockStateId);
- if (worldEdit == null) {
- worldEdit = FabricTransmogrifier.transmogToWorldEdit(blockEntity.getBlockState());
- }
- // Save this outside the reference to ensure it doesn't mutate
- net.minecraft.nbt.CompoundTag savedNative = com.sk89q.worldedit.fabric.internal.FabricLoggingProblemReporter.with(
- () -> "serializing block entity " + blockEntity.getClass().getSimpleName(),
- reporter -> {
- var tagValueOutput = TagValueOutput.createWithContext(reporter, registries);
- blockEntity.saveWithId(tagValueOutput);
- return tagValueOutput.buildResult();
- }
- );
-
- return worldEdit.toBaseBlock(LazyReference.from(() -> NBTConverter.fromNative(savedNative)));
- }
-
- public static Block adapt(BlockType blockType) {
- return FabricWorldEdit.getRegistry(Registries.BLOCK).getValue(Identifier.parse(blockType.id()));
- }
-
- public static BlockType adapt(Block block) {
- return BlockTypes.get(FabricWorldEdit.getRegistry(Registries.BLOCK).getKey(block).toString());
- }
-
- public static Item adapt(ItemType itemType) {
- return FabricWorldEdit.getRegistry(Registries.ITEM).getValue(Identifier.parse(itemType.id()));
- }
+/**
+ * Public API to adapt between WorldEdit and Fabric.
+ */
+public final class FabricAdapter extends CoreMcAdapter {
- public static ItemType adapt(Item item) {
- return ItemTypes.get(FabricWorldEdit.getRegistry(Registries.ITEM).getKey(item).toString());
- }
+ private static final FabricAdapter INSTANCE = new FabricAdapter();
/**
- * For serializing and deserializing components.
+ * {@return the Fabric adapter}
*/
- private static final Codec COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf(
- "components", DataComponentPatch.EMPTY
- ).codec();
-
- public static ItemStack adapt(BaseItemStack baseItemStack) {
- final ItemStack itemStack = new ItemStack(adapt(baseItemStack.getType()), baseItemStack.getAmount());
- LinCompoundTag nbt = baseItemStack.getNbt();
- if (nbt != null) {
- DataComponentPatch componentPatch = COMPONENTS_CODEC.parse(
- FabricWorldEdit.registryAccess().createSerializationContext(NbtOps.INSTANCE),
- NBTConverter.toNative(nbt)
- ).getOrThrow();
- itemStack.applyComponents(componentPatch);
- }
- return itemStack;
+ public static FabricAdapter get() {
+ return INSTANCE;
}
- public static BaseItemStack adapt(ItemStack itemStack) {
- CompoundTag tag = (CompoundTag) COMPONENTS_CODEC.encodeStart(
- FabricWorldEdit.registryAccess().createSerializationContext(NbtOps.INSTANCE),
- itemStack.getComponentsPatch()
- ).getOrThrow();
- return new BaseItemStack(
- adapt(itemStack.getItem()), LazyReference.from(() -> NBTConverter.fromNative(tag)), itemStack.getCount()
- );
- }
-
- /**
- * Get the WorldEdit proxy for the given player.
- *
- * @param player the player
- * @return the WorldEdit player
- */
- public static FabricPlayer adaptPlayer(ServerPlayer player) {
- checkNotNull(player);
- return new FabricPlayer(player);
+ private FabricAdapter() {
}
- /**
- * Get the WorldEdit proxy for the given command source.
- *
- * @param commandSourceStack the command source
- * @return the WorldEdit actor
- */
- public static Actor adaptCommandSource(CommandSourceStack commandSourceStack) {
- checkNotNull(commandSourceStack);
- if (commandSourceStack.isPlayer()) {
- return adaptPlayer(commandSourceStack.getPlayer());
- }
- if (FabricWorldEdit.inst.getConfig().commandBlockSupport && commandSourceStack.source instanceof BaseCommandBlock commandBlock) {
- return new FabricBlockCommandSender(commandBlock, commandSourceStack.getLevel(), commandSourceStack.getPosition());
- }
-
- return new FabricCommandSender(commandSourceStack);
+ @Override
+ protected CoreMcPlatform getPlatform() {
+ return FabricWorldEdit.getPlatform();
}
}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBiomeRegistry.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBiomeRegistry.java
deleted file mode 100644
index ffe1a2b380..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBiomeRegistry.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.sk89q.worldedit.util.formatting.text.Component;
-import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
-import com.sk89q.worldedit.world.biome.BiomeData;
-import com.sk89q.worldedit.world.biome.BiomeType;
-import com.sk89q.worldedit.world.registry.BiomeRegistry;
-import net.minecraft.resources.Identifier;
-import net.minecraft.util.Util;
-
-/**
- * Provides access to biome data in Fabric.
- */
-class FabricBiomeRegistry implements BiomeRegistry {
-
- @Override
- public Component getRichName(BiomeType biomeType) {
- return TranslatableComponent.of(Util.makeDescriptionId("biome", Identifier.parse(biomeType.id())));
- }
-
- @Deprecated
- @Override
- public BiomeData getData(BiomeType biome) {
- return new FabricBiomeData(biome);
- }
-
- @Deprecated
- private static class FabricBiomeData implements BiomeData {
- private final BiomeType biome;
-
- /**
- * Create a new instance.
- *
- * @param biome the base biome
- */
- private FabricBiomeData(BiomeType biome) {
- this.biome = biome;
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public String getName() {
- return biome.id();
- }
- }
-
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBlockCommandSender.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBlockCommandSender.java
deleted file mode 100644
index a0a9c91509..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBlockCommandSender.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.extension.platform.AbstractCommandBlockActor;
-import com.sk89q.worldedit.fabric.internal.ComponentConverter;
-import com.sk89q.worldedit.session.SessionKey;
-import com.sk89q.worldedit.util.Location;
-import com.sk89q.worldedit.util.auth.AuthorizationException;
-import com.sk89q.worldedit.util.formatting.WorldEditText;
-import com.sk89q.worldedit.util.formatting.text.Component;
-import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
-import net.minecraft.ChatFormatting;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.SectionPos;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.level.BaseCommandBlock;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.block.Blocks;
-import net.minecraft.world.phys.Vec3;
-
-import java.nio.charset.StandardCharsets;
-import java.util.Locale;
-import java.util.UUID;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class FabricBlockCommandSender extends AbstractCommandBlockActor {
- private final BaseCommandBlock sender;
- private final UUID uuid;
- private final ServerLevel level;
- private final Vec3 pos;
-
- public FabricBlockCommandSender(BaseCommandBlock sender, ServerLevel level, Vec3 pos) {
- super(new Location(FabricAdapter.adapt(checkNotNull(level)), FabricAdapter.adapt(checkNotNull(pos))));
-
- this.sender = sender;
- this.level = level;
- this.pos = pos;
- this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.getName()).getBytes(StandardCharsets.UTF_8));
- }
-
- @Override
- public String getName() {
- return sender.getName().getString();
- }
-
- @Override
- @Deprecated
- public void printRaw(String msg) {
- for (String part : msg.split("\n", 0)) {
- sendMessage(net.minecraft.network.chat.Component.literal(part));
- }
- }
-
- @Override
- @Deprecated
- public void printDebug(String msg) {
- sendColorized(msg, ChatFormatting.GRAY);
- }
-
- @Override
- @Deprecated
- public void print(String msg) {
- sendColorized(msg, ChatFormatting.LIGHT_PURPLE);
- }
-
- @Override
- @Deprecated
- public void printError(String msg) {
- sendColorized(msg, ChatFormatting.RED);
- }
-
- @Override
- public void print(Component component) {
- sendMessage(ComponentConverter.Serializer.fromJson(
- GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale())),
- this.level.registryAccess()
- ));
- }
-
- private void sendColorized(String msg, ChatFormatting formatting) {
- for (String part : msg.split("\n", 0)) {
- var component = net.minecraft.network.chat.Component.literal(part);
- component.withStyle(formatting);
- sendMessage(component);
- }
- }
-
- private void sendMessage(net.minecraft.network.chat.Component textComponent) {
- this.sender.setLastOutput(textComponent);
- }
-
- @Override
- public Locale getLocale() {
- return WorldEdit.getInstance().getConfiguration().defaultLocale;
- }
-
- @Override
- public UUID getUniqueId() {
- return uuid;
- }
-
- @Override
- public String[] getGroups() {
- return new String[0];
- }
-
- @Override
- public void checkPermission(String permission) throws AuthorizationException {
- if (!hasPermission(permission)) {
- throw new AuthorizationException();
- }
- }
-
- @Override
- public boolean hasPermission(String permission) {
- return true;
- }
-
- public BaseCommandBlock getSender() {
- return this.sender;
- }
-
- @Override
- public SessionKey getSessionKey() {
- return new SessionKey() {
-
- private volatile boolean active = true;
-
- private void updateActive() {
- BlockPos blockPos = new BlockPos((int) pos.x, (int) pos.y, (int) pos.z);
- int chunkX = SectionPos.blockToSectionCoord(blockPos.getX());
- int chunkZ = SectionPos.blockToSectionCoord(blockPos.getZ());
- if (!level.getChunkSource().hasChunk(chunkX, chunkZ)) {
- active = false;
- return;
- }
- Block type = level.getBlockState(blockPos).getBlock();
- active = type == Blocks.COMMAND_BLOCK
- || type == Blocks.CHAIN_COMMAND_BLOCK
- || type == Blocks.REPEATING_COMMAND_BLOCK;
- }
-
- @Override
- public String getName() {
- return sender.getName().getString();
- }
-
- @Override
- public boolean isActive() {
- level.getServer().execute(this::updateActive);
- return active;
- }
-
- @Override
- public boolean isPersistent() {
- return true;
- }
-
- @Override
- public UUID getUniqueId() {
- return uuid;
- }
- };
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBlockRegistry.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBlockRegistry.java
deleted file mode 100644
index 48ef164a80..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricBlockRegistry.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.sk89q.worldedit.fabric.internal.FabricTransmogrifier;
-import com.sk89q.worldedit.registry.state.Property;
-import com.sk89q.worldedit.util.formatting.text.Component;
-import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BlockType;
-import com.sk89q.worldedit.world.registry.BlockMaterial;
-import com.sk89q.worldedit.world.registry.BlockRegistry;
-import net.minecraft.world.level.block.Block;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.OptionalInt;
-import java.util.TreeMap;
-
-public class FabricBlockRegistry implements BlockRegistry {
-
- private final Map materialMap = new HashMap<>();
-
- @Override
- public Component getRichName(BlockType blockType) {
- return TranslatableComponent.of(FabricAdapter.adapt(blockType).getDescriptionId());
- }
-
- @Override
- public BlockMaterial getMaterial(BlockType blockType) {
- Block block = FabricAdapter.adapt(blockType);
- return materialMap.computeIfAbsent(
- block.defaultBlockState(),
- FabricBlockMaterial::new
- );
- }
-
- @Override
- public Map> getProperties(BlockType blockType) {
- Block block = FabricAdapter.adapt(blockType);
- Map> map = new TreeMap<>();
- Collection> propertyKeys = block
- .defaultBlockState()
- .getProperties();
- for (net.minecraft.world.level.block.state.properties.Property> key : propertyKeys) {
- map.put(key.getName(), FabricTransmogrifier.transmogToWorldEditProperty(key));
- }
- return map;
- }
-
- @Override
- public OptionalInt getInternalBlockStateId(BlockState state) {
- net.minecraft.world.level.block.state.BlockState equivalent = FabricAdapter.adapt(state);
- return OptionalInt.of(Block.getId(equivalent));
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricEntityProperties.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricEntityProperties.java
deleted file mode 100644
index 97badd1292..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricEntityProperties.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.sk89q.worldedit.entity.metadata.EntityProperties;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.world.entity.Entity;
-import net.minecraft.world.entity.ExperienceOrb;
-import net.minecraft.world.entity.Mob;
-import net.minecraft.world.entity.TamableAnimal;
-import net.minecraft.world.entity.ambient.AmbientCreature;
-import net.minecraft.world.entity.animal.Animal;
-import net.minecraft.world.entity.animal.fish.WaterAnimal;
-import net.minecraft.world.entity.animal.golem.AbstractGolem;
-import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
-import net.minecraft.world.entity.decoration.ArmorStand;
-import net.minecraft.world.entity.decoration.ItemFrame;
-import net.minecraft.world.entity.decoration.painting.Painting;
-import net.minecraft.world.entity.item.FallingBlockEntity;
-import net.minecraft.world.entity.item.ItemEntity;
-import net.minecraft.world.entity.item.PrimedTnt;
-import net.minecraft.world.entity.npc.Npc;
-import net.minecraft.world.entity.player.Player;
-import net.minecraft.world.entity.projectile.Projectile;
-import net.minecraft.world.entity.vehicle.boat.Boat;
-import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart;
-import net.minecraft.world.item.trading.Merchant;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class FabricEntityProperties implements EntityProperties {
-
- private final Entity entity;
-
- public FabricEntityProperties(Entity entity) {
- checkNotNull(entity);
- this.entity = entity;
- }
-
- @Override
- public boolean isPlayerDerived() {
- return entity instanceof Player;
- }
-
- @Override
- public boolean isProjectile() {
- return entity instanceof Projectile;
- }
-
- @Override
- public boolean isItem() {
- return entity instanceof ItemEntity;
- }
-
- @Override
- public boolean isFallingBlock() {
- return entity instanceof FallingBlockEntity;
- }
-
- @Override
- public boolean isPainting() {
- return entity instanceof Painting;
- }
-
- @Override
- public boolean isItemFrame() {
- return entity instanceof ItemFrame;
- }
-
- @Override
- public boolean isBoat() {
- return entity instanceof Boat;
- }
-
- @Override
- public boolean isMinecart() {
- return entity instanceof AbstractMinecart;
- }
-
- @Override
- public boolean isTNT() {
- return entity instanceof PrimedTnt;
- }
-
- @Override
- public boolean isExperienceOrb() {
- return entity instanceof ExperienceOrb;
- }
-
- @Override
- public boolean isLiving() {
- return entity instanceof Mob;
- }
-
- @Override
- public boolean isAnimal() {
- return entity instanceof Animal;
- }
-
- @Override
- public boolean isAmbient() {
- return entity instanceof AmbientCreature;
- }
-
- @Override
- public boolean isNPC() {
- return entity instanceof Npc || entity instanceof Merchant;
- }
-
- @Override
- public boolean isGolem() {
- return entity instanceof AbstractGolem;
- }
-
- @Override
- public boolean isTamed() {
- return entity instanceof TamableAnimal tamableAnimal && tamableAnimal.isTame();
- }
-
- @Override
- public boolean isTagged() {
- return entity.hasCustomName();
- }
-
- @Override
- public boolean isArmorStand() {
- return entity instanceof ArmorStand;
- }
-
- @Override
- public boolean isPasteable() {
- return !(entity instanceof ServerPlayer || entity instanceof EnderDragon);
- }
-
- @Override
- public boolean isWaterCreature() {
- return entity instanceof WaterAnimal;
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricFakePlayer.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricFakePlayer.java
deleted file mode 100644
index 4b2daa1e76..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricFakePlayer.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.mojang.authlib.GameProfile;
-import net.minecraft.server.level.ClientInformation;
-import net.minecraft.server.level.ParticleStatus;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.stats.Stat;
-import net.minecraft.world.entity.HumanoidArm;
-import net.minecraft.world.entity.player.ChatVisiblity;
-
-import java.nio.charset.StandardCharsets;
-import java.util.UUID;
-
-public class FabricFakePlayer extends ServerPlayer {
- private static final GameProfile FAKE_WORLDEDIT_PROFILE = new GameProfile(
- UUID.nameUUIDFromBytes("worldedit".getBytes(StandardCharsets.UTF_8)),
- "[WorldEdit]"
- );
- private static final ClientInformation FAKE_CLIENT_INFO = new ClientInformation(
- "en_US", 16, ChatVisiblity.FULL, true, 0, HumanoidArm.LEFT, false, false, ParticleStatus.MINIMAL
- );
-
- public FabricFakePlayer(ServerLevel world) {
- super(world.getServer(), world, FAKE_WORLDEDIT_PROFILE, FAKE_CLIENT_INFO);
- }
-
- @Override
- public void tick() {
- }
-
- @Override
- public void awardStat(Stat> stat, int incrementer) {
- }
-
- @Override
- public void awardStat(Stat> stat) {
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricItemRegistry.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricItemRegistry.java
deleted file mode 100644
index 384ac042f9..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricItemRegistry.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.sk89q.worldedit.blocks.BaseItemStack;
-import com.sk89q.worldedit.fabric.internal.ComponentConverter;
-import com.sk89q.worldedit.util.formatting.text.Component;
-import com.sk89q.worldedit.util.formatting.text.TranslatableComponent;
-import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
-import com.sk89q.worldedit.world.item.ItemType;
-import com.sk89q.worldedit.world.registry.BundledItemRegistry;
-
-@SuppressWarnings("removal")
-public class FabricItemRegistry extends BundledItemRegistry {
-
- @Override
- public Component getRichName(ItemType itemType) {
- return TranslatableComponent.of(
- FabricAdapter.adapt(itemType).getDescriptionId()
- );
- }
-
- @Override
- public Component getRichName(BaseItemStack itemStack) {
- return GsonComponentSerializer.INSTANCE.deserialize(
- ComponentConverter.Serializer.toJson(
- FabricAdapter.adapt(itemStack).getItemName(),
- FabricWorldEdit.LIFECYCLED_SERVER.valueOrThrow().registryAccess()
- )
- );
- }
-
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPermissionsProvider.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPermissionsProvider.java
deleted file mode 100644
index 2e0df21f4f..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPermissionsProvider.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import me.lucko.fabric.api.permissions.v0.Permissions;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.world.level.GameType;
-
-public interface FabricPermissionsProvider {
-
- boolean hasPermission(ServerPlayer player, String permission);
-
- void registerPermission(String permission);
-
- class VanillaPermissionsProvider implements FabricPermissionsProvider {
-
- private final FabricPlatform platform;
-
- public VanillaPermissionsProvider(FabricPlatform platform) {
- this.platform = platform;
- }
-
- @Override
- public boolean hasPermission(ServerPlayer player, String permission) {
- FabricConfiguration configuration = platform.getConfiguration();
- return configuration.cheatMode
- || player.level().getServer().getPlayerList().isOp(player.nameAndId())
- || (configuration.creativeEnable && player.gameMode.getGameModeForPlayer() == GameType.CREATIVE);
- }
-
- @Override
- public void registerPermission(String permission) {
- }
- }
-
- class LuckoFabricPermissionsProvider extends VanillaPermissionsProvider {
-
- public LuckoFabricPermissionsProvider(FabricPlatform platform) {
- super(platform);
- }
-
- @Override
- public boolean hasPermission(ServerPlayer player, String permission) {
- return Permissions.getPermissionValue(player, permission)
- .orElseGet(() -> super.hasPermission(player, permission));
- }
-
- @Override
- public void registerPermission(String permission) {
- }
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java
deleted file mode 100644
index 7f2c4dd3fa..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.google.common.collect.Sets;
-import com.sk89q.worldedit.entity.Player;
-import com.sk89q.worldedit.extension.platform.AbstractPlatform;
-import com.sk89q.worldedit.extension.platform.Actor;
-import com.sk89q.worldedit.extension.platform.Capability;
-import com.sk89q.worldedit.extension.platform.MultiUserPlatform;
-import com.sk89q.worldedit.extension.platform.Preference;
-import com.sk89q.worldedit.extension.platform.Watchdog;
-import com.sk89q.worldedit.fabric.internal.FabricWatchdogImpl;
-import com.sk89q.worldedit.util.SideEffect;
-import com.sk89q.worldedit.util.lifecycle.Lifecycled;
-import com.sk89q.worldedit.world.DataFixer;
-import com.sk89q.worldedit.world.World;
-import com.sk89q.worldedit.world.registry.Registries;
-import net.minecraft.SharedConstants;
-import net.minecraft.resources.Identifier;
-import net.minecraft.server.dedicated.DedicatedServer;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.server.players.PlayerList;
-import net.minecraft.world.level.storage.ServerLevelData;
-import org.enginehub.piston.CommandManager;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.function.Function;
-import javax.annotation.Nullable;
-
-class FabricPlatform extends AbstractPlatform implements MultiUserPlatform {
-
- private final FabricWorldEdit mod;
- private final FabricDataFixer dataFixer;
- private final Lifecycled> watchdog;
- private boolean hookingEvents = false;
-
- FabricPlatform(FabricWorldEdit mod) {
- this.mod = mod;
- this.dataFixer = new FabricDataFixer(getDataVersion());
-
- this.watchdog = FabricWorldEdit.LIFECYCLED_SERVER.map(
- server -> server instanceof DedicatedServer
- ? Optional.of(new FabricWatchdogImpl(server))
- : Optional.empty()
- );
- }
-
- boolean isHookingEvents() {
- return hookingEvents;
- }
-
- @Override
- public Registries getRegistries() {
- return FabricRegistries.getInstance();
- }
-
- @Override
- public int getDataVersion() {
- return SharedConstants.getCurrentVersion().dataVersion().version();
- }
-
- @Override
- public DataFixer getDataFixer() {
- return dataFixer;
- }
-
- @Override
- public boolean isValidMobType(String type) {
- return FabricWorldEdit.getRegistry(net.minecraft.core.registries.Registries.ENTITY_TYPE)
- .containsKey(Identifier.parse(type));
- }
-
- @Override
- public void reload() {
- getConfiguration().load();
- super.reload();
- }
-
- @Override
- public int schedule(long delay, long period, Runnable task) {
- return -1;
- }
-
- @Override
- @Nullable
- public Watchdog getWatchdog() {
- return watchdog.value().flatMap(Function.identity()).orElse(null);
- }
-
- @Override
- public List extends World> getWorlds() {
- Iterable worlds = FabricWorldEdit.LIFECYCLED_SERVER.valueOrThrow().getAllLevels();
- List ret = new ArrayList<>();
- for (ServerLevel world : worlds) {
- ret.add(new FabricWorld(world));
- }
- return ret;
- }
-
- @Nullable
- @Override
- public Player matchPlayer(Player player) {
- if (player instanceof FabricPlayer) {
- return player;
- } else {
- ServerPlayer entity = FabricWorldEdit.LIFECYCLED_SERVER.valueOrThrow()
- .getPlayerList().getPlayerByName(player.getName());
- return entity != null ? new FabricPlayer(entity) : null;
- }
- }
-
- @Nullable
- @Override
- public World matchWorld(World world) {
- if (world instanceof FabricWorld) {
- return world;
- } else {
- for (ServerLevel ws : FabricWorldEdit.LIFECYCLED_SERVER.valueOrThrow().getAllLevels()) {
- if (((ServerLevelData) ws.getLevelData()).getLevelName().equals(world.getName())) {
- return new FabricWorld(ws);
- }
- }
-
- return null;
- }
- }
-
- @Override
- public void registerCommands(CommandManager manager) {
- // No-op, we register using Fabric's event
- }
-
- @Override
- public void setGameHooksEnabled(boolean enabled) {
- this.hookingEvents = enabled;
- }
-
- @Override
- public FabricConfiguration getConfiguration() {
- return mod.getConfig();
- }
-
- @Override
- public String getVersion() {
- return mod.getInternalVersion();
- }
-
- @Override
- public String getPlatformName() {
- return "Fabric-Official";
- }
-
- @Override
- public String getPlatformVersion() {
- return mod.getInternalVersion();
- }
-
- @Override
- public String id() {
- return "enginehub:fabric";
- }
-
- @Override
- public Map getCapabilities() {
- Map capabilities = new EnumMap<>(Capability.class);
- capabilities.put(Capability.CONFIGURATION, Preference.PREFER_OTHERS);
- capabilities.put(Capability.WORLDEDIT_CUI, Preference.NORMAL);
- capabilities.put(Capability.GAME_HOOKS, Preference.NORMAL);
- capabilities.put(Capability.PERMISSIONS, Preference.NORMAL);
- capabilities.put(Capability.USER_COMMANDS, Preference.NORMAL);
- capabilities.put(Capability.WORLD_EDITING, Preference.PREFERRED);
- return capabilities;
- }
-
- private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet(
- SideEffect.VALIDATION,
- SideEffect.ENTITY_AI,
- SideEffect.LIGHTING,
- SideEffect.NEIGHBORS,
- SideEffect.UPDATE
- );
-
- @Override
- public Set getSupportedSideEffects() {
- return SUPPORTED_SIDE_EFFECTS;
- }
-
- @Override
- public long getTickCount() {
- return FabricWorldEdit.LIFECYCLED_SERVER.valueOrThrow().getTickCount();
- }
-
- @Override
- public Collection getConnectedUsers() {
- List users = new ArrayList<>();
- PlayerList scm = FabricWorldEdit.LIFECYCLED_SERVER.valueOrThrow().getPlayerList();
- for (ServerPlayer entity : scm.getPlayers()) {
- if (entity != null) {
- users.add(new FabricPlayer(entity));
- }
- }
- return users;
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorldEdit.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorldEdit.java
deleted file mode 100644
index 663e3020c9..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricWorldEdit.java
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric;
-
-import com.mojang.brigadier.CommandDispatcher;
-import com.sk89q.worldedit.LocalSession;
-import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.command.util.PermissionCondition;
-import com.sk89q.worldedit.event.platform.ConfigurationLoadEvent;
-import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
-import com.sk89q.worldedit.event.platform.PlatformUnreadyEvent;
-import com.sk89q.worldedit.event.platform.PlatformsRegisteredEvent;
-import com.sk89q.worldedit.event.platform.SessionIdleEvent;
-import com.sk89q.worldedit.extension.platform.Capability;
-import com.sk89q.worldedit.extension.platform.Platform;
-import com.sk89q.worldedit.extension.platform.PlatformManager;
-import com.sk89q.worldedit.internal.anvil.ChunkDeleter;
-import com.sk89q.worldedit.internal.event.InteractionDebouncer;
-import com.sk89q.worldedit.internal.util.LogManagerCompat;
-import com.sk89q.worldedit.registry.CommonRegistries;
-import com.sk89q.worldedit.util.Location;
-import com.sk89q.worldedit.util.lifecycle.Lifecycled;
-import com.sk89q.worldedit.util.lifecycle.SimpleLifecycled;
-import com.sk89q.worldedit.world.biome.BiomeCategory;
-import com.sk89q.worldedit.world.biome.BiomeType;
-import com.sk89q.worldedit.world.block.BlockCategory;
-import com.sk89q.worldedit.world.block.BlockType;
-import com.sk89q.worldedit.world.entity.EntityType;
-import com.sk89q.worldedit.world.generation.ConfiguredFeatureType;
-import com.sk89q.worldedit.world.generation.StructureType;
-import com.sk89q.worldedit.world.generation.TreeType;
-import com.sk89q.worldedit.world.item.ItemCategory;
-import com.sk89q.worldedit.world.item.ItemType;
-import net.fabricmc.api.ModInitializer;
-import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
-import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
-import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
-import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
-import net.fabricmc.fabric.api.event.player.UseBlockCallback;
-import net.fabricmc.fabric.api.event.player.UseItemCallback;
-import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
-import net.fabricmc.loader.api.FabricLoader;
-import net.fabricmc.loader.api.ModContainer;
-import net.fabricmc.loader.api.Version;
-import net.fabricmc.loader.api.metadata.ModMetadata;
-import net.fabricmc.loader.api.metadata.version.VersionPredicate;
-import net.minecraft.commands.CommandBuildContext;
-import net.minecraft.commands.CommandSourceStack;
-import net.minecraft.commands.Commands;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderSet;
-import net.minecraft.core.Registry;
-import net.minecraft.core.RegistryAccess;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.resources.Identifier;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.server.network.ServerGamePacketListenerImpl;
-import net.minecraft.world.InteractionHand;
-import net.minecraft.world.InteractionResult;
-import net.minecraft.world.entity.player.Player;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.levelgen.feature.CoralTreeFeature;
-import net.minecraft.world.level.levelgen.feature.FallenTreeFeature;
-import net.minecraft.world.level.levelgen.feature.TreeFeature;
-import net.minecraft.world.level.levelgen.placement.PlacedFeature;
-import net.minecraft.world.phys.BlockHitResult;
-import org.apache.logging.log4j.Logger;
-import org.enginehub.piston.Command;
-import org.enginehub.worldeditcui.protocol.CUIPacket;
-import org.enginehub.worldeditcui.protocol.CUIPacketHandler;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.sk89q.worldedit.fabric.FabricAdapter.adaptPlayer;
-import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
-
-/**
- * The Fabric implementation of WorldEdit.
- */
-public class FabricWorldEdit implements ModInitializer {
-
- private static final Logger LOGGER = LogManagerCompat.getLogger();
- public static final String MOD_ID = "worldedit";
-
- public static final Lifecycled LIFECYCLED_SERVER;
-
- static {
- SimpleLifecycled lifecycledServer = SimpleLifecycled.invalid();
- ServerLifecycleEvents.SERVER_STARTED.register(lifecycledServer::newValue);
- ServerLifecycleEvents.SERVER_STOPPING.register(__ -> lifecycledServer.invalidate());
- LIFECYCLED_SERVER = lifecycledServer;
- }
-
- /**
- * {@return current server's registry access} Not for long-term storage.
- */
- public static RegistryAccess registryAccess() {
- return LIFECYCLED_SERVER.valueOrThrow().registryAccess();
- }
-
- /**
- * {@return current server's registry} Not for long-term storage.
- *
- * @param key the registry key
- */
- public static Registry getRegistry(ResourceKey> key) {
- return LIFECYCLED_SERVER.valueOrThrow().registryAccess().lookupOrThrow(key);
- }
-
- private FabricPermissionsProvider provider;
-
- public static FabricWorldEdit inst;
-
- private InteractionDebouncer debouncer;
- private FabricPlatform platform;
- private FabricConfiguration config;
- private Path workingDir;
-
- private ModContainer container;
-
- public FabricWorldEdit() {
- inst = this;
- }
-
- @Override
- public void onInitialize() {
- this.container = FabricLoader.getInstance().getModContainer("worldedit").orElseThrow(
- () -> new IllegalStateException("WorldEdit mod missing in Fabric")
- );
-
- // Setup working directory
- workingDir = FabricLoader.getInstance().getConfigDir().resolve("worldedit");
- if (!Files.exists(workingDir)) {
- try {
- Files.createDirectory(workingDir);
- } catch (IOException e) {
- throw new UncheckedIOException(e);
- }
- }
- this.platform = new FabricPlatform(this);
- debouncer = new InteractionDebouncer(platform);
-
- WorldEdit.getInstance().getPlatformManager().register(platform);
-
- config = new FabricConfiguration(this);
- this.provider = getInitialPermissionsProvider();
-
- CUIPacketHandler.instance().registerServerboundHandler(this::onCuiPacket);
-
- ServerTickEvents.END_SERVER_TICK.register(ThreadSafeCache.getInstance());
- CommandRegistrationCallback.EVENT.register(this::registerCommands);
- ServerLifecycleEvents.SERVER_STARTING.register(this::onStartingServer);
- ServerLifecycleEvents.SERVER_STARTED.register(this::onStartServer);
- ServerLifecycleEvents.SERVER_STOPPING.register(this::onStopServer);
- ServerPlayConnectionEvents.DISCONNECT.register(this::onPlayerDisconnect);
- AttackBlockCallback.EVENT.register(this::onLeftClickBlock);
- UseBlockCallback.EVENT.register(this::onRightClickBlock);
- UseItemCallback.EVENT.register(this::onRightClickItem);
- LOGGER.info("WorldEdit for Fabric (version " + getInternalVersion() + ") is loaded");
- }
-
- private void registerCommands(CommandDispatcher dispatcher, CommandBuildContext registryAccess, Commands.CommandSelection environment) {
- WorldEdit.getInstance().getEventBus().post(new PlatformsRegisteredEvent());
- PlatformManager manager = WorldEdit.getInstance().getPlatformManager();
- Platform commandsPlatform = manager.queryCapability(Capability.USER_COMMANDS);
- if (commandsPlatform != platform || !platform.isHookingEvents()) {
- // We're not in control of commands/events -- do not register.
- return;
- }
-
- List commands = manager.getPlatformCommandManager().getCommandManager()
- .getAllCommands().toList();
- for (Command command : commands) {
- CommandWrapper.register(dispatcher, command);
- Set perms = command.getCondition().as(PermissionCondition.class)
- .map(PermissionCondition::getPermissions)
- .orElseGet(Collections::emptySet);
- if (!perms.isEmpty()) {
- perms.forEach(getPermissionsProvider()::registerPermission);
- }
- }
- }
-
- private FabricPermissionsProvider getInitialPermissionsProvider() {
- try {
- Class.forName("me.lucko.fabric.api.permissions.v0.Permissions", false, getClass().getClassLoader());
- Optional version = FabricLoader.getInstance().getModContainer("fabric-permissions-api-v0")
- .map(ModContainer::getMetadata)
- .map(ModMetadata::getVersion);
-
- if (version.isPresent() && !VersionPredicate.parse(">=0.7.0").test(version.get())) {
- throw new RuntimeException("Fabric permissions version " + version.get() + " is not supported. Please update Fabric Permissions API");
- }
-
- return new FabricPermissionsProvider.LuckoFabricPermissionsProvider(platform);
- } catch (ClassNotFoundException ignored) {
- // fallback to vanilla
- } catch (Exception e) {
- // catch any exception to prevent crashing the server, but still print a warning
- LOGGER.warn("Failed to load Fabric permissions provider. Falling back to Minecraft", e);
- }
-
- return new FabricPermissionsProvider.VanillaPermissionsProvider(platform);
- }
-
- private void setupRegistries(MinecraftServer server) {
- // Blocks
- for (Identifier name : server.registryAccess().lookupOrThrow(Registries.BLOCK).keySet()) {
- String key = name.toString();
- if (BlockType.REGISTRY.get(key) == null) {
- BlockType.REGISTRY.register(key, new BlockType(key,
- input -> FabricAdapter.adapt(FabricAdapter.adapt(input.getBlockType()).defaultBlockState())));
- }
- }
- // Items
- for (Identifier name : server.registryAccess().lookupOrThrow(Registries.ITEM).keySet()) {
- String key = name.toString();
- if (ItemType.REGISTRY.get(key) == null) {
- ItemType.REGISTRY.register(key, new ItemType(key));
- }
- }
- // Entities
- for (Identifier name : server.registryAccess().lookupOrThrow(Registries.ENTITY_TYPE).keySet()) {
- String key = name.toString();
- if (EntityType.REGISTRY.get(key) == null) {
- EntityType.REGISTRY.register(key, new EntityType(key));
- }
- }
- // Biomes
- for (Identifier name : server.registryAccess().lookupOrThrow(Registries.BIOME).keySet()) {
- String key = name.toString();
- if (BiomeType.REGISTRY.get(key) == null) {
- BiomeType.REGISTRY.register(key, new BiomeType(key));
- }
- }
- // Tags
- server.registryAccess().lookupOrThrow(Registries.BLOCK).getTags().map(t -> t.key().location()).forEach(name -> {
- String key = name.toString();
- if (BlockCategory.REGISTRY.get(key) == null) {
- BlockCategory.REGISTRY.register(key, new BlockCategory(key));
- }
- });
- server.registryAccess().lookupOrThrow(Registries.ITEM).getTags().map(t -> t.key().location()).forEach(name -> {
- String key = name.toString();
- if (ItemCategory.REGISTRY.get(key) == null) {
- ItemCategory.REGISTRY.register(key, new ItemCategory(key));
- }
- });
- Registry biomeRegistry = server.registryAccess().lookupOrThrow(Registries.BIOME);
- biomeRegistry.getTags().forEach(tag -> {
- String key = tag.key().location().toString();
- if (BiomeCategory.REGISTRY.get(key) == null) {
- BiomeCategory.REGISTRY.register(key, new BiomeCategory(
- key,
- () -> biomeRegistry.get(tag.key())
- .stream()
- .flatMap(HolderSet.Named::stream)
- .map(Holder::value)
- .map(FabricAdapter::adapt)
- .collect(Collectors.toSet()))
- );
- }
- });
- // Features
- for (Identifier name : server.registryAccess().lookupOrThrow(Registries.CONFIGURED_FEATURE).keySet()) {
- String key = name.toString();
- if (ConfiguredFeatureType.REGISTRY.get(key) == null) {
- ConfiguredFeatureType.REGISTRY.register(key, new ConfiguredFeatureType(key));
- }
- }
- // Structures
- for (Identifier name : server.registryAccess().lookupOrThrow(Registries.STRUCTURE).keySet()) {
- String key = name.toString();
- if (StructureType.REGISTRY.get(key) == null) {
- StructureType.REGISTRY.register(key, new StructureType(key));
- }
- }
- // Trees
- Registry placedFeatureRegistry = server.registryAccess().lookupOrThrow(Registries.PLACED_FEATURE);
- for (Identifier name : placedFeatureRegistry.keySet()) {
- // Do some hackery to make sure this is a tree
- var underlyingFeature = placedFeatureRegistry.get(name).get().value().feature().value().feature();
- if (underlyingFeature instanceof TreeFeature || underlyingFeature instanceof FallenTreeFeature || underlyingFeature instanceof CoralTreeFeature) {
- String key = name.toString();
- if (TreeType.REGISTRY.get(key) == null) {
- TreeType.REGISTRY.register(key, new TreeType(key));
- }
- }
- }
-
- // Common registries
- CommonRegistries.init();
- }
-
- private void onStartingServer(MinecraftServer minecraftServer) {
- final Path delChunks = workingDir.resolve(DELCHUNKS_FILE_NAME);
- if (Files.exists(delChunks)) {
- ChunkDeleter.runFromFile(delChunks, true);
- }
- }
-
- private void onStartServer(MinecraftServer minecraftServer) {
- setupRegistries(minecraftServer);
-
- config.load();
- WorldEdit.getInstance().getEventBus().post(new ConfigurationLoadEvent(config));
- WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent(platform));
- }
-
- private void onStopServer(MinecraftServer minecraftServer) {
- WorldEdit worldEdit = WorldEdit.getInstance();
- worldEdit.getSessionManager().unload();
- WorldEdit.getInstance().getEventBus().post(new PlatformUnreadyEvent(platform));
- }
-
- private boolean skipEvents() {
- return platform == null || !platform.isHookingEvents();
- }
-
- private boolean skipInteractionEvent(Player player, InteractionHand hand) {
- return skipEvents() || hand != InteractionHand.MAIN_HAND || player.level().isClientSide() || !(player instanceof ServerPlayer);
- }
-
- private InteractionResult onLeftClickBlock(Player playerEntity, Level world, InteractionHand hand, BlockPos blockPos, Direction direction) {
- if (skipInteractionEvent(playerEntity, hand)) {
- return InteractionResult.PASS;
- }
-
- WorldEdit we = WorldEdit.getInstance();
- FabricPlayer player = adaptPlayer((ServerPlayer) playerEntity);
- FabricWorld localWorld = getWorld(world);
- Location pos = new Location(localWorld,
- blockPos.getX(),
- blockPos.getY(),
- blockPos.getZ()
- );
- com.sk89q.worldedit.util.Direction weDirection = FabricAdapter.adaptEnumFacing(direction);
-
- boolean result = we.handleBlockLeftClick(player, pos, weDirection) || we.handleArmSwing(player);
- debouncer.setLastInteraction(player, result);
-
- return result ? InteractionResult.SUCCESS : InteractionResult.PASS;
- }
-
- private InteractionResult onRightClickBlock(Player playerEntity, Level world, InteractionHand hand, BlockHitResult blockHitResult) {
- if (skipInteractionEvent(playerEntity, hand)) {
- return InteractionResult.PASS;
- }
-
- WorldEdit we = WorldEdit.getInstance();
- FabricPlayer player = adaptPlayer((ServerPlayer) playerEntity);
- FabricWorld localWorld = getWorld(world);
- Location pos = new Location(localWorld,
- blockHitResult.getBlockPos().getX(),
- blockHitResult.getBlockPos().getY(),
- blockHitResult.getBlockPos().getZ()
- );
- com.sk89q.worldedit.util.Direction direction = FabricAdapter.adaptEnumFacing(blockHitResult.getDirection());
-
- boolean result = we.handleBlockRightClick(player, pos, direction) || we.handleRightClick(player);
- debouncer.setLastInteraction(player, result);
-
- return result ? InteractionResult.SUCCESS : InteractionResult.PASS;
- }
-
- public void onLeftClickAir(ServerPlayer playerEntity, InteractionHand hand) {
- if (skipInteractionEvent(playerEntity, hand)) {
- return;
- }
-
- WorldEdit we = WorldEdit.getInstance();
- FabricPlayer player = adaptPlayer(playerEntity);
-
- Optional previousResult = debouncer.getDuplicateInteractionResult(player);
- if (previousResult.isPresent()) {
- return;
- }
-
- boolean result = we.handleArmSwing(player);
- debouncer.setLastInteraction(player, result);
- }
-
- private InteractionResult onRightClickItem(Player playerEntity, Level world, InteractionHand hand) {
- if (skipInteractionEvent(playerEntity, hand)) {
- return InteractionResult.PASS;
- }
-
- WorldEdit we = WorldEdit.getInstance();
- FabricPlayer player = adaptPlayer((ServerPlayer) playerEntity);
-
- Optional previousResult = debouncer.getDuplicateInteractionResult(player);
- if (previousResult.isPresent()) {
- return previousResult.get() ? InteractionResult.SUCCESS : InteractionResult.PASS;
- }
-
- boolean result = we.handleRightClick(player);
- debouncer.setLastInteraction(player, result);
-
- return result ? InteractionResult.SUCCESS : InteractionResult.PASS;
- }
-
- private void onPlayerDisconnect(ServerGamePacketListenerImpl handler, MinecraftServer server) {
- debouncer.clearInteraction(adaptPlayer(handler.player));
-
- WorldEdit.getInstance().getEventBus()
- .post(new SessionIdleEvent(new FabricPlayer.SessionKeyImpl(handler.player)));
- }
-
- private void onCuiPacket(CUIPacket payload, CUIPacketHandler.PacketContext context) {
- if (!(context.player() instanceof ServerPlayer player)) {
- // Ignore - this is not a server-bound packet
- return;
- }
-
- FabricPlayer actor = FabricAdapter.adaptPlayer(player);
- LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
- session.handleCUIInitializationMessage(payload.eventType(), payload.args(), actor);
- }
-
- /**
- * Get the configuration.
- *
- * @return the Fabric configuration
- */
- FabricConfiguration getConfig() {
- return this.config;
- }
-
- /**
- * Get the session for a player.
- *
- * @param player the player
- * @return the session
- */
- public LocalSession getSession(ServerPlayer player) {
- checkNotNull(player);
- return WorldEdit.getInstance().getSessionManager().get(adaptPlayer(player));
- }
-
- /**
- * Get the WorldEdit proxy for the given world.
- *
- * @param world the world
- * @return the WorldEdit world
- */
- public FabricWorld getWorld(Level world) {
- checkNotNull(world);
- return new FabricWorld(world);
- }
-
- /**
- * Get the WorldEdit proxy for the platform.
- *
- * @return the WorldEdit platform
- */
- public Platform getPlatform() {
- return this.platform;
- }
-
- /**
- * Get the working directory where WorldEdit's files are stored.
- *
- * @return the working directory
- */
- public Path getWorkingDir() {
- return this.workingDir;
- }
-
- /**
- * Get the version of the WorldEdit-Fabric implementation.
- *
- * @return a version string
- */
- String getInternalVersion() {
- return container.getMetadata().getVersion().getFriendlyString();
- }
-
- public void setPermissionsProvider(FabricPermissionsProvider provider) {
- this.provider = provider;
- }
-
- public FabricPermissionsProvider getPermissionsProvider() {
- return provider;
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricPlatform.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricPlatform.java
new file mode 100644
index 0000000000..a27de5a38e
--- /dev/null
+++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricPlatform.java
@@ -0,0 +1,64 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.fabric.internal;
+
+import com.sk89q.worldedit.coremc.internal.CoreMcPlatform;
+import com.sk89q.worldedit.fabric.FabricAdapter;
+import com.sk89q.worldedit.util.lifecycle.Lifecycled;
+import com.sk89q.worldedit.util.lifecycle.SimpleLifecycled;
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
+import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.level.ServerPlayer;
+import org.enginehub.worldeditcui.protocol.CUIPacket;
+
+class FabricPlatform extends CoreMcPlatform {
+
+ private static Lifecycled createMinecraftServerLifecycled() {
+ SimpleLifecycled lifecycledServer = SimpleLifecycled.invalid();
+ ServerLifecycleEvents.SERVER_STARTING.register(lifecycledServer::newValue);
+ ServerLifecycleEvents.SERVER_STOPPING.register(_ -> lifecycledServer.invalidate());
+ return lifecycledServer;
+ }
+
+ FabricPlatform(FabricWorldEdit mod) {
+ super(mod, createMinecraftServerLifecycled());
+ }
+
+ @Override
+ public FabricAdapter getAdapter() {
+ return FabricAdapter.get();
+ }
+
+ @Override
+ public void sendCUIPacket(ServerPlayer player, CUIPacket packet) {
+ ServerPlayNetworking.send(player, packet);
+ }
+
+ @Override
+ public String getPlatformName() {
+ return "Fabric-Official";
+ }
+
+ @Override
+ public String id() {
+ return "enginehub:fabric";
+ }
+}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java
deleted file mode 100644
index 34b0cac1f1..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricServerLevelDelegateProxy.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric.internal;
-
-import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.MaxChangedBlocksException;
-import com.sk89q.worldedit.entity.BaseEntity;
-import com.sk89q.worldedit.fabric.FabricAdapter;
-import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.math.Vector3;
-import com.sk89q.worldedit.util.Location;
-import net.minecraft.core.BlockPos;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.entity.Entity;
-import net.minecraft.world.level.WorldGenLevel;
-import net.minecraft.world.level.block.Blocks;
-import net.minecraft.world.level.block.EntityBlock;
-import net.minecraft.world.level.block.entity.BlockEntity;
-import net.minecraft.world.level.block.state.BlockState;
-import org.jetbrains.annotations.Nullable;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Predicate;
-
-public class FabricServerLevelDelegateProxy implements InvocationHandler, AutoCloseable {
-
- private final EditSession editSession;
- private final ServerLevel serverLevel;
- private final Map createdBlockEntities = new HashMap<>();
-
- private FabricServerLevelDelegateProxy(EditSession editSession, ServerLevel serverLevel) {
- this.editSession = editSession;
- this.serverLevel = serverLevel;
- }
-
- public record LevelAndProxy(WorldGenLevel level, FabricServerLevelDelegateProxy proxy) implements AutoCloseable {
- @Override
- public void close() throws MaxChangedBlocksException {
- proxy.close();
- }
- }
-
- public static LevelAndProxy newInstance(EditSession editSession, ServerLevel serverLevel) {
- FabricServerLevelDelegateProxy proxy = new FabricServerLevelDelegateProxy(editSession, serverLevel);
- return new LevelAndProxy(
- (WorldGenLevel) Proxy.newProxyInstance(
- serverLevel.getClass().getClassLoader(),
- serverLevel.getClass().getInterfaces(),
- proxy
- ),
- proxy
- );
- }
-
- @Nullable
- private BlockEntity getBlockEntity(BlockPos blockPos) {
- // This doesn't synthesize or load from world. I think editing existing block entities without setting the block
- // (in the context of features) should not be supported in the first place.
- BlockVector3 pos = FabricAdapter.adapt(blockPos);
- return createdBlockEntities.get(pos);
- }
-
- private BlockState getBlockState(BlockPos blockPos) {
- return FabricAdapter.adapt(this.editSession.getBlockWithBuffer(FabricAdapter.adapt(blockPos)));
- }
-
- private boolean setBlock(BlockPos blockPos, BlockState blockState) {
- try {
- handleBlockEntity(blockPos, blockState);
- return editSession.setBlock(FabricAdapter.adapt(blockPos), FabricAdapter.adapt(blockState));
- } catch (MaxChangedBlocksException e) {
- throw new RuntimeException(e);
- }
- }
-
- // For BlockEntity#setBlockState, not sure why it's deprecated
- @SuppressWarnings("deprecation")
- private void handleBlockEntity(BlockPos blockPos, BlockState blockState) {
- BlockVector3 pos = FabricAdapter.adapt(blockPos);
- if (blockState.hasBlockEntity()) {
- if (!(blockState.getBlock() instanceof EntityBlock entityBlock)) {
- // This will probably never happen, as Mojang's own code assumes that
- // hasBlockEntity implies instanceof EntityBlock, but just to be safe...
- throw new AssertionError("BlockState has block entity but block is not an EntityBlock: " + blockState);
- }
- BlockEntity newEntity = entityBlock.newBlockEntity(blockPos, blockState);
- if (newEntity != null) {
- newEntity.setBlockState(blockState);
- createdBlockEntities.put(pos, newEntity);
- // Should we load existing NBT here? This is for feature / structure gen so it seems unnecessary.
- // But it would align with the behavior of the real setBlock method.
- return;
- }
- }
- // Discard any block entity that was previously created if new block is set without block entity
- createdBlockEntities.remove(pos);
- }
-
- private boolean removeBlock(BlockPos blockPos) {
- return setBlock(blockPos, Blocks.AIR.defaultBlockState());
- }
-
- private boolean addEntity(Entity entity) {
- Vector3 pos = FabricAdapter.adapt(entity.getPosition(0.0f));
- Location location = new Location(FabricAdapter.adapt(serverLevel), pos.x(), pos.y(), pos.z());
- BaseEntity baseEntity = new FabricEntity(entity).getState();
- return editSession.createEntity(location, baseEntity) != null;
- }
-
- @Override
- public void close() throws MaxChangedBlocksException {
- for (Map.Entry entry : createdBlockEntities.entrySet()) {
- BlockVector3 blockPos = entry.getKey();
- BlockEntity blockEntity = entry.getValue();
- editSession.setBlock(
- blockPos,
- FabricAdapter.adapt(blockEntity, serverLevel.registryAccess())
- );
- }
- }
-
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- switch (method.getName()) {
- case "getBlockState", "method_8320" -> {
- if (args.length == 1 && args[0] instanceof BlockPos blockPos) {
- return getBlockState(blockPos);
- }
- }
- case "isStateAtPosition", "method_16358" -> {
- if (args.length == 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Predicate) {
- @SuppressWarnings("unchecked")
- Predicate predicate = (Predicate) args[1];
- return predicate.test(getBlockState(blockPos));
- }
- }
- case "getBlockEntity", "method_8321" -> {
- if (args.length == 1 && args[0] instanceof BlockPos blockPos) {
- return getBlockEntity(blockPos);
- }
- }
- case "setBlock", "method_8652" -> {
- if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof BlockState blockState) {
- return setBlock(blockPos, blockState);
- }
- }
- case "removeBlock", "destroyBlock", "method_8650", "method_8651" -> {
- if (args.length >= 2 && args[0] instanceof BlockPos blockPos && args[1] instanceof Boolean) {
- return removeBlock(blockPos);
- }
- }
- case "addEntity", "method_14175", "addFreshEntityWithPassengers", "method_30771" -> {
- if (args.length >= 1 && args[0] instanceof Entity entity) {
- return addEntity(entity);
- }
- }
- default -> {
- }
- }
-
- return method.invoke(this.serverLevel, args);
- }
-
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricTransmogrifier.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricTransmogrifier.java
deleted file mode 100644
index 4b26f77ab9..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricTransmogrifier.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric.internal;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableList;
-import com.sk89q.worldedit.fabric.FabricAdapter;
-import com.sk89q.worldedit.registry.state.BooleanProperty;
-import com.sk89q.worldedit.registry.state.DirectionalProperty;
-import com.sk89q.worldedit.registry.state.EnumProperty;
-import com.sk89q.worldedit.registry.state.IntegerProperty;
-import com.sk89q.worldedit.registry.state.Property;
-import com.sk89q.worldedit.util.Direction;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BlockType;
-import net.minecraft.util.StringRepresentable;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.block.state.StateDefinition;
-
-import java.util.Comparator;
-import java.util.Map;
-import java.util.TreeMap;
-
-/**
- * Raw, un-cached transformations.
- */
-public class FabricTransmogrifier {
-
- private static final LoadingCache, Property>> PROPERTY_CACHE = CacheBuilder.newBuilder().build(new CacheLoader<>() {
- @Override
- public Property> load(net.minecraft.world.level.block.state.properties.Property> property) throws Exception {
- return switch (property) {
- case net.minecraft.world.level.block.state.properties.BooleanProperty booleanProperty ->
- new BooleanProperty(property.getName(), ImmutableList.copyOf(booleanProperty.getPossibleValues()));
- case net.minecraft.world.level.block.state.properties.IntegerProperty integerProperty ->
- new IntegerProperty(property.getName(), ImmutableList.copyOf(integerProperty.getPossibleValues()));
- case net.minecraft.world.level.block.state.properties.EnumProperty> enumProperty -> {
- if (property.getValueClass() == net.minecraft.core.Direction.class) {
- yield new DirectionalProperty(property.getName(), property.getPossibleValues().stream()
- .map(v -> FabricAdapter.adaptEnumFacing((net.minecraft.core.Direction) v))
- .collect(ImmutableList.toImmutableList()));
- }
- // Note: do not make x.asString a method reference.
- // It will cause runtime bootstrap exceptions.
- //noinspection Convert2MethodRef
- yield new EnumProperty(property.getName(), enumProperty.getPossibleValues().stream()
- .map(x -> x.getSerializedName())
- .collect(ImmutableList.toImmutableList()));
- }
- default -> new FabricPropertyAdapter<>(property);
- };
- }
- });
-
- public static Property> transmogToWorldEditProperty(net.minecraft.world.level.block.state.properties.Property> property) {
- return PROPERTY_CACHE.getUnchecked(property);
- }
-
- private static Map, Object> transmogToWorldEditProperties(BlockType block, net.minecraft.world.level.block.state.BlockState blockState) {
- Map, Object> props = new TreeMap<>(Comparator.comparing(Property::name));
- for (net.minecraft.world.level.block.state.properties.Property> property : blockState.getProperties()) {
- Object value = blockState.getValue(property);
- if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
- if (property.getValueClass() == net.minecraft.core.Direction.class) {
- value = FabricAdapter.adaptEnumFacing((net.minecraft.core.Direction) value);
- } else {
- value = ((StringRepresentable) value).getSerializedName();
- }
- }
- props.put(block.getProperty(property.getName()), value);
- }
- return props;
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- private static net.minecraft.world.level.block.state.BlockState transmogToMinecraftProperties(
- StateDefinition stateContainer,
- net.minecraft.world.level.block.state.BlockState newState,
- Map, Object> states
- ) {
- for (Map.Entry, Object> state : states.entrySet()) {
- net.minecraft.world.level.block.state.properties.Property property = stateContainer.getProperty(state.getKey().name());
- Comparable value = (Comparable) state.getValue();
- // we may need to adapt this value, depending on the source prop
- if (property instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
- if (property.getValueClass() == net.minecraft.core.Direction.class) {
- Direction dir = (Direction) value;
- value = FabricAdapter.adapt(dir);
- } else {
- String enumName = (String) value;
- value = ((net.minecraft.world.level.block.state.properties.EnumProperty>) property).getValue((String) value).orElseThrow(() ->
- new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName)
- );
- }
- }
-
- newState = newState.setValue(property, value);
- }
- return newState;
- }
-
- public static net.minecraft.world.level.block.state.BlockState transmogToMinecraft(BlockState blockState) {
- Block mcBlock = FabricAdapter.adapt(blockState.getBlockType());
- net.minecraft.world.level.block.state.BlockState newState = mcBlock.defaultBlockState();
- Map, Object> states = blockState.getStates();
- return transmogToMinecraftProperties(mcBlock.getStateDefinition(), newState, states);
- }
-
- public static com.sk89q.worldedit.world.block.BlockState transmogToWorldEdit(net.minecraft.world.level.block.state.BlockState blockState) {
- BlockType blockType = FabricAdapter.adapt(blockState.getBlock());
- return blockType.getState(transmogToWorldEditProperties(blockType, blockState));
- }
-
- private FabricTransmogrifier() {
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldEdit.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldEdit.java
new file mode 100644
index 0000000000..0a16849f99
--- /dev/null
+++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldEdit.java
@@ -0,0 +1,137 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.fabric.internal;
+
+import com.sk89q.worldedit.coremc.CoreMcPermissionsProvider;
+import com.sk89q.worldedit.coremc.internal.CoreMcMod;
+import com.sk89q.worldedit.coremc.internal.CoreMcPlatform;
+import com.sk89q.worldedit.coremc.internal.ThreadSafeCache;
+import com.sk89q.worldedit.internal.util.LogManagerCompat;
+import net.fabricmc.api.ModInitializer;
+import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
+import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
+import net.fabricmc.fabric.api.event.player.UseBlockCallback;
+import net.fabricmc.fabric.api.event.player.UseItemCallback;
+import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
+import net.fabricmc.loader.api.FabricLoader;
+import net.fabricmc.loader.api.ModContainer;
+import net.fabricmc.loader.api.Version;
+import net.fabricmc.loader.api.metadata.ModMetadata;
+import net.fabricmc.loader.api.metadata.version.VersionPredicate;
+import net.minecraft.world.InteractionResult;
+import org.apache.logging.log4j.Logger;
+import org.enginehub.worldeditcui.protocol.CUIPacketHandler;
+
+import java.util.Optional;
+
+/**
+ * The Fabric implementation of WorldEdit.
+ */
+public class FabricWorldEdit extends CoreMcMod implements ModInitializer {
+
+ private static final Logger LOGGER = LogManagerCompat.getLogger();
+
+ public static FabricWorldEdit inst;
+
+ private static volatile CoreMcPlatform PLATFORM;
+
+ public static CoreMcPlatform getPlatform() {
+ CoreMcPlatform platform = PLATFORM;
+ if (platform == null) {
+ throw new IllegalStateException("FabricWorldEdit is not initialized");
+ }
+ return platform;
+ }
+
+ private ModContainer container;
+
+ public FabricWorldEdit() {
+ inst = this;
+ }
+
+ @Override
+ public void onInitialize() {
+ this.container = FabricLoader.getInstance().getModContainer("worldedit").orElseThrow(
+ () -> new IllegalStateException("WorldEdit mod missing in Fabric")
+ );
+
+ PLATFORM = new FabricPlatform(this);
+ init(PLATFORM, FabricLoader.getInstance().getConfigDir());
+
+ CUIPacketHandler.instance().registerServerboundHandler(this::onCuiPacket);
+
+ ServerTickEvents.END_SERVER_TICK.register(server -> ThreadSafeCache.getInstance().onEndTick(server));
+ CommandRegistrationCallback.EVENT.register((dispatcher, _, _) -> registerCommands(dispatcher));
+ ServerLifecycleEvents.SERVER_STARTING.register(_ -> serverAboutToStart());
+ ServerLifecycleEvents.SERVER_STARTED.register(this::serverStarted);
+ ServerLifecycleEvents.SERVER_STOPPING.register(_ -> serverStopping());
+ ServerPlayConnectionEvents.DISCONNECT.register((handler, _) -> onPlayerDisconnect(handler.player));
+ AttackBlockCallback.EVENT.register(
+ (playerEntity, _, hand, blockPos, direction) ->
+ onLeftClickBlock(playerEntity, hand, blockPos, direction)
+ ? InteractionResult.SUCCESS : InteractionResult.PASS
+ );
+ UseBlockCallback.EVENT.register(
+ (playerEntity, _, hand, blockHitResult) ->
+ onRightClickBlock(playerEntity, hand, blockHitResult.getBlockPos(), blockHitResult.getDirection())
+ ? InteractionResult.SUCCESS : InteractionResult.PASS
+ );
+ UseItemCallback.EVENT.register((playerEntity, _, hand) -> {
+ Optional result = onRightClickItem(playerEntity, hand);
+ if (result.isPresent()) {
+ return result.get() ? InteractionResult.SUCCESS : InteractionResult.PASS;
+ }
+ return InteractionResult.PASS;
+ });
+ LOGGER.info("WorldEdit for Fabric (version " + getInternalVersion() + ") is loaded");
+ }
+
+ @Override
+ protected String getInternalVersion() {
+ return container.getMetadata().getVersion().getFriendlyString();
+ }
+
+ @Override
+ protected CoreMcPermissionsProvider createPermissionsProvider(CoreMcPlatform platform) {
+ CoreMcPermissionsProvider provider = super.createPermissionsProvider(platform);
+
+ try {
+ Class.forName("me.lucko.fabric.api.permissions.v0.Permissions", false, getClass().getClassLoader());
+ Optional version = FabricLoader.getInstance().getModContainer("fabric-permissions-api-v0")
+ .map(ModContainer::getMetadata)
+ .map(ModMetadata::getVersion);
+
+ if (version.isPresent() && !VersionPredicate.parse(">=0.7.0").test(version.get())) {
+ throw new RuntimeException("Fabric permissions version " + version.get() + " is not supported. Please update Fabric Permissions API");
+ }
+
+ provider = new LuckoFabricPermissionsProvider(provider);
+ } catch (ClassNotFoundException ignored) {
+ // fallback to vanilla
+ } catch (Exception e) {
+ // catch any exception to prevent crashing the server, but still print a warning
+ LOGGER.warn("Failed to load Fabric permissions provider. Falling back to Minecraft", e);
+ }
+
+ return provider;
+ }
+}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldNativeAccess.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldNativeAccess.java
deleted file mode 100644
index 38ac1c61b6..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/FabricWorldNativeAccess.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric.internal;
-
-import com.sk89q.worldedit.fabric.FabricAdapter;
-import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
-import com.sk89q.worldedit.internal.wna.WorldNativeAccess;
-import com.sk89q.worldedit.util.SideEffect;
-import com.sk89q.worldedit.util.SideEffectSet;
-import net.minecraft.core.BlockPos;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.server.level.FullChunkStatus;
-import net.minecraft.server.level.ServerChunkCache;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.block.entity.BlockEntity;
-import net.minecraft.world.level.block.state.BlockState;
-import net.minecraft.world.level.chunk.LevelChunk;
-import net.minecraft.world.level.storage.TagValueInput;
-import org.enginehub.linbus.tree.LinCompoundTag;
-
-import java.lang.ref.WeakReference;
-import java.util.Objects;
-import javax.annotation.Nullable;
-
-public class FabricWorldNativeAccess implements WorldNativeAccess {
- private final WeakReference world;
- private SideEffectSet sideEffectSet;
-
- public FabricWorldNativeAccess(WeakReference world) {
- this.world = world;
- }
-
- private Level getWorld() {
- return Objects.requireNonNull(world.get(), "The reference to the world was lost");
- }
-
- @Override
- public void setCurrentSideEffectSet(SideEffectSet sideEffectSet) {
- this.sideEffectSet = sideEffectSet;
- }
-
- @Override
- public LevelChunk getChunk(int x, int z) {
- return getWorld().getChunk(x, z);
- }
-
- @Override
- public BlockState toNative(com.sk89q.worldedit.world.block.BlockState state) {
- int stateId = BlockStateIdAccess.getBlockStateId(state);
- return BlockStateIdAccess.isValidInternalId(stateId)
- ? Block.stateById(stateId)
- : FabricAdapter.adapt(state);
- }
-
- @Override
- public BlockState getBlockState(LevelChunk chunk, BlockPos position) {
- return chunk.getBlockState(position);
- }
-
- @Nullable
- @Override
- public BlockState setBlockState(LevelChunk chunk, BlockPos position, BlockState state) {
- int flags = 0;
- if (sideEffectSet != null) {
- if (!sideEffectSet.shouldApply(SideEffect.UPDATE)) {
- // We don't skip block entity side-effects as that's likely to cause problems.
- flags |= Block.UPDATE_SKIP_ON_PLACE | Block.UPDATE_SKIP_SHAPE_UPDATE_ON_WIRE;
- }
- }
- return chunk.setBlockState(position, state, flags);
- }
-
- @Override
- public BlockState getValidBlockForPosition(BlockState block, BlockPos position) {
- return Block.updateFromNeighbourShapes(block, getWorld(), position);
- }
-
- @Override
- public BlockPos getPosition(int x, int y, int z) {
- return new BlockPos(x, y, z);
- }
-
- @Override
- public void updateLightingForBlock(BlockPos position) {
- getWorld().getChunkSource().getLightEngine().checkBlock(position);
- }
-
- @Override
- public boolean updateTileEntity(BlockPos position, LinCompoundTag tag) {
- CompoundTag nativeTag = NBTConverter.toNative(tag);
- Level level = getWorld();
- BlockEntity tileEntity = level.getChunkAt(position).getBlockEntity(position);
- if (tileEntity == null) {
- return false;
- }
- return FabricLoggingProblemReporter.with(
- () -> "loading tile entity at " + position,
- reporter -> {
- var tagValueInput = TagValueInput.create(reporter, level.registryAccess(), nativeTag);
- tileEntity.loadWithComponents(tagValueInput);
- tileEntity.setChanged();
- return true;
- }
- );
- }
-
- @Override
- public void notifyBlockUpdate(LevelChunk chunk, BlockPos position, BlockState oldState, BlockState newState) {
- if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) {
- getWorld().sendBlockUpdated(position, oldState, newState, Block.UPDATE_NEIGHBORS | Block.UPDATE_CLIENTS);
- }
- }
-
- @Override
- public boolean isChunkTicking(LevelChunk chunk) {
- return chunk.getFullStatus().isOrAfter(FullChunkStatus.BLOCK_TICKING);
- }
-
- @Override
- public void markBlockChanged(LevelChunk chunk, BlockPos position) {
- if (chunk.getSections()[getWorld().getSectionIndex(position.getY())] != null) {
- ((ServerChunkCache) getWorld().getChunkSource()).blockChanged(position);
- }
- }
-
- @Override
- public void notifyNeighbors(BlockPos pos, BlockState oldState, BlockState newState) {
- getWorld().updateNeighborsAt(pos, oldState.getBlock());
- if (newState.hasAnalogOutputSignal()) {
- getWorld().updateNeighbourForOutputSignal(pos, newState.getBlock());
- }
- }
-
- @Override
- public void updateBlock(BlockPos pos, BlockState oldState, BlockState newState) {
- Level world = getWorld();
- newState.onPlace(world, pos, oldState, false);
- }
-
- @Override
- public void updateNeighbors(BlockPos pos, BlockState oldState, BlockState newState, int recursionLimit) {
- Level world = getWorld();
- oldState.affectNeighborsAfterRemoval((ServerLevel) world, pos, false);
- oldState.updateIndirectNeighbourShapes(world, pos, Block.UPDATE_CLIENTS, recursionLimit);
- newState.updateNeighbourShapes(world, pos, Block.UPDATE_CLIENTS, recursionLimit);
- newState.updateIndirectNeighbourShapes(world, pos, Block.UPDATE_CLIENTS, recursionLimit);
- }
-
- @Override
- public void onBlockStateChange(BlockPos pos, BlockState oldState, BlockState newState) {
- getWorld().updatePOIOnBlockStateChange(pos, oldState, newState);
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/LuckoFabricPermissionsProvider.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/LuckoFabricPermissionsProvider.java
new file mode 100644
index 0000000000..a018a9e575
--- /dev/null
+++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/LuckoFabricPermissionsProvider.java
@@ -0,0 +1,42 @@
+/*
+ * WorldEdit, a Minecraft world manipulation toolkit
+ * Copyright (C) sk89q
+ * Copyright (C) WorldEdit team and contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.fabric.internal;
+
+import com.sk89q.worldedit.coremc.CoreMcPermissionsProvider;
+import me.lucko.fabric.api.permissions.v0.Permissions;
+import net.minecraft.server.level.ServerPlayer;
+
+final class LuckoFabricPermissionsProvider implements CoreMcPermissionsProvider {
+ private final CoreMcPermissionsProvider fallback;
+
+ LuckoFabricPermissionsProvider(CoreMcPermissionsProvider fallback) {
+ this.fallback = fallback;
+ }
+
+ @Override
+ public boolean hasPermission(ServerPlayer player, String permission) {
+ return Permissions.getPermissionValue(player, permission)
+ .orElseGet(() -> fallback.hasPermission(player, permission));
+ }
+
+ @Override
+ public void registerPermission(String permission) {
+ }
+}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/MixinConfigPlugin.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/MixinConfigPlugin.java
deleted file mode 100644
index d3aebc8ad9..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/MixinConfigPlugin.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric.internal;
-
-import com.sk89q.worldedit.internal.util.LogManagerCompat;
-import net.fabricmc.loader.api.FabricLoader;
-import net.fabricmc.loader.api.ModContainer;
-import org.apache.logging.log4j.Logger;
-import org.objectweb.asm.tree.ClassNode;
-import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
-import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
-
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-public class MixinConfigPlugin implements IMixinConfigPlugin {
- private static final Logger LOGGER = LogManagerCompat.getLogger();
-
- @Override
- public void onLoad(String mixinPackage) {
- }
-
- @Override
- public String getRefMapperConfig() {
- return null;
- }
-
- @Override
- public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
- if (mixinClassName.equals("com.sk89q.worldedit.fabric.mixin.MixinLevelChunkSetBlockHook")) {
- List conflictingContainers = Stream.of("carpet", "quickcarpet")
- .map(FabricLoader.getInstance()::getModContainer)
- .filter(Optional::isPresent)
- .map(Optional::get)
- .collect(Collectors.toList());
- if (!conflictingContainers.isEmpty()) {
- List conflictingIds = conflictingContainers.stream()
- .map(mc -> mc.getMetadata().getId())
- .collect(Collectors.toList());
- LOGGER.warn("{} detected, disabling UPDATE mixin {}", conflictingIds, mixinClassName);
- }
- return conflictingContainers.isEmpty();
- }
- return true;
- }
-
- @Override
- public void acceptTargets(Set myTargets, Set otherTargets) {
- }
-
- @Override
- public List getMixins() {
- return null;
- }
-
- @Override
- public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
- }
-
- @Override
- public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
- }
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java
deleted file mode 100644
index c43d28b630..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/NBTConverter.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric.internal;
-
-import net.minecraft.nbt.EndTag;
-import net.minecraft.nbt.Tag;
-import org.enginehub.linbus.common.LinTagId;
-import org.enginehub.linbus.tree.LinByteArrayTag;
-import org.enginehub.linbus.tree.LinByteTag;
-import org.enginehub.linbus.tree.LinCompoundTag;
-import org.enginehub.linbus.tree.LinDoubleTag;
-import org.enginehub.linbus.tree.LinEndTag;
-import org.enginehub.linbus.tree.LinFloatTag;
-import org.enginehub.linbus.tree.LinIntArrayTag;
-import org.enginehub.linbus.tree.LinIntTag;
-import org.enginehub.linbus.tree.LinListTag;
-import org.enginehub.linbus.tree.LinLongArrayTag;
-import org.enginehub.linbus.tree.LinLongTag;
-import org.enginehub.linbus.tree.LinShortTag;
-import org.enginehub.linbus.tree.LinStringTag;
-import org.enginehub.linbus.tree.LinTag;
-import org.enginehub.linbus.tree.LinTagType;
-
-import java.util.Arrays;
-import java.util.Set;
-
-/**
- * Converts between LinBus and Minecraft NBT classes.
- */
-public final class NBTConverter {
-
- private NBTConverter() {
- }
-
- public static net.minecraft.nbt.Tag toNative(LinTag> tag) {
- return switch (tag) {
- case LinIntArrayTag t -> toNative(t);
- case LinListTag> t -> toNative(t);
- case LinLongTag t -> toNative(t);
- case LinLongArrayTag t -> toNative(t);
- case LinStringTag t -> toNative(t);
- case LinIntTag t -> toNative(t);
- case LinByteTag t -> toNative(t);
- case LinByteArrayTag t -> toNative(t);
- case LinCompoundTag t -> toNative(t);
- case LinFloatTag t -> toNative(t);
- case LinShortTag t -> toNative(t);
- case LinDoubleTag t -> toNative(t);
- case LinEndTag ignored -> EndTag.INSTANCE;
- };
- }
-
- public static net.minecraft.nbt.IntArrayTag toNative(LinIntArrayTag tag) {
- int[] value = tag.value();
- return new net.minecraft.nbt.IntArrayTag(Arrays.copyOf(value, value.length));
- }
-
- public static net.minecraft.nbt.ListTag toNative(LinListTag> tag) {
- net.minecraft.nbt.ListTag list = new net.minecraft.nbt.ListTag();
- for (LinTag> child : tag.value()) {
- list.addAndUnwrap(toNative(child));
- }
- return list;
- }
-
- public static net.minecraft.nbt.LongTag toNative(LinLongTag tag) {
- return net.minecraft.nbt.LongTag.valueOf(tag.value());
- }
-
- public static net.minecraft.nbt.LongArrayTag toNative(LinLongArrayTag tag) {
- return new net.minecraft.nbt.LongArrayTag(tag.value().clone());
- }
-
- public static net.minecraft.nbt.StringTag toNative(LinStringTag tag) {
- return net.minecraft.nbt.StringTag.valueOf(tag.value());
- }
-
- public static net.minecraft.nbt.IntTag toNative(LinIntTag tag) {
- return net.minecraft.nbt.IntTag.valueOf(tag.value());
- }
-
- public static net.minecraft.nbt.ByteTag toNative(LinByteTag tag) {
- return net.minecraft.nbt.ByteTag.valueOf(tag.value());
- }
-
- public static net.minecraft.nbt.ByteArrayTag toNative(LinByteArrayTag tag) {
- return new net.minecraft.nbt.ByteArrayTag(tag.value().clone());
- }
-
- public static net.minecraft.nbt.CompoundTag toNative(LinCompoundTag tag) {
- net.minecraft.nbt.CompoundTag compound = new net.minecraft.nbt.CompoundTag();
- tag.value().forEach((key, value) -> compound.put(key, toNative(value)));
- return compound;
- }
-
- public static net.minecraft.nbt.FloatTag toNative(LinFloatTag tag) {
- return net.minecraft.nbt.FloatTag.valueOf(tag.value());
- }
-
- public static net.minecraft.nbt.ShortTag toNative(LinShortTag tag) {
- return net.minecraft.nbt.ShortTag.valueOf(tag.value());
- }
-
- public static net.minecraft.nbt.DoubleTag toNative(LinDoubleTag tag) {
- return net.minecraft.nbt.DoubleTag.valueOf(tag.value());
- }
-
- public static LinTag> fromNative(net.minecraft.nbt.Tag other) {
- return switch (other) {
- case net.minecraft.nbt.IntArrayTag tags -> fromNative(tags);
- case net.minecraft.nbt.ListTag tags -> fromNative(tags);
- case net.minecraft.nbt.EndTag endTag -> fromNative(endTag);
- case net.minecraft.nbt.LongTag longTag -> fromNative(longTag);
- case net.minecraft.nbt.LongArrayTag tags -> fromNative(tags);
- case net.minecraft.nbt.StringTag stringTag -> fromNative(stringTag);
- case net.minecraft.nbt.IntTag intTag -> fromNative(intTag);
- case net.minecraft.nbt.ByteTag byteTag -> fromNative(byteTag);
- case net.minecraft.nbt.ByteArrayTag tags -> fromNative(tags);
- case net.minecraft.nbt.CompoundTag compoundTag -> fromNative(compoundTag);
- case net.minecraft.nbt.FloatTag floatTag -> fromNative(floatTag);
- case net.minecraft.nbt.ShortTag shortTag -> fromNative(shortTag);
- case net.minecraft.nbt.DoubleTag doubleTag -> fromNative(doubleTag);
- };
- }
-
- public static LinIntArrayTag fromNative(net.minecraft.nbt.IntArrayTag other) {
- int[] value = other.getAsIntArray();
- return LinIntArrayTag.of(Arrays.copyOf(value, value.length));
- }
-
- private static byte identifyRawElementType(net.minecraft.nbt.ListTag list) {
- byte b = 0;
-
- for (Tag tag : list) {
- byte c = tag.getId();
- if (b == 0) {
- b = c;
- } else if (b != c) {
- return 10;
- }
- }
-
- return b;
- }
-
- private static net.minecraft.nbt.CompoundTag wrapTag(net.minecraft.nbt.Tag tag) {
- if (tag instanceof net.minecraft.nbt.CompoundTag compoundTag) {
- return compoundTag;
- }
- var compoundTag = new net.minecraft.nbt.CompoundTag();
- compoundTag.put("", tag);
- return compoundTag;
- }
-
- public static LinListTag> fromNative(net.minecraft.nbt.ListTag other) {
- byte rawType = identifyRawElementType(other);
- LinListTag.Builder> list = LinListTag.builder(LinTagType.fromId(
- LinTagId.fromId(rawType)
- ));
- for (net.minecraft.nbt.Tag tag : other) {
- if (rawType == LinTagId.COMPOUND.id() && !(tag instanceof net.minecraft.nbt.CompoundTag)) {
- list.add(fromNative(wrapTag(tag)));
- } else {
- list.add(fromNative(tag));
- }
- }
- return list.build();
- }
-
- public static LinEndTag fromNative(net.minecraft.nbt.EndTag other) {
- return LinEndTag.instance();
- }
-
- public static LinLongTag fromNative(net.minecraft.nbt.LongTag other) {
- return LinLongTag.of(other.value());
- }
-
- public static LinLongArrayTag fromNative(net.minecraft.nbt.LongArrayTag other) {
- return LinLongArrayTag.of(other.getAsLongArray().clone());
- }
-
- public static LinStringTag fromNative(net.minecraft.nbt.StringTag other) {
- return LinStringTag.of(other.value());
- }
-
- public static LinIntTag fromNative(net.minecraft.nbt.IntTag other) {
- return LinIntTag.of(other.value());
- }
-
- public static LinByteTag fromNative(net.minecraft.nbt.ByteTag other) {
- return LinByteTag.of(other.value());
- }
-
- public static LinByteArrayTag fromNative(net.minecraft.nbt.ByteArrayTag other) {
- return LinByteArrayTag.of(other.getAsByteArray().clone());
- }
-
- public static LinCompoundTag fromNative(net.minecraft.nbt.CompoundTag other) {
- Set tags = other.keySet();
- LinCompoundTag.Builder builder = LinCompoundTag.builder();
- for (String tagName : tags) {
- builder.put(tagName, fromNative(other.get(tagName)));
- }
- return builder.build();
- }
-
- public static LinFloatTag fromNative(net.minecraft.nbt.FloatTag other) {
- return LinFloatTag.of(other.value());
- }
-
- public static LinShortTag fromNative(net.minecraft.nbt.ShortTag other) {
- return LinShortTag.of(other.value());
- }
-
- public static LinDoubleTag fromNative(net.minecraft.nbt.DoubleTag other) {
- return LinDoubleTag.of(other.value());
- }
-
-}
diff --git a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinServerGamePacketListenerImpl.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinServerGamePacketListenerImpl.java
deleted file mode 100644
index 99d036a0cc..0000000000
--- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinServerGamePacketListenerImpl.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.fabric.mixin;
-
-import com.google.errorprone.annotations.Keep;
-import com.sk89q.worldedit.fabric.FabricWorldEdit;
-import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
-import net.minecraft.network.protocol.game.ServerboundSwingPacket;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.server.network.ServerGamePacketListenerImpl;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.Unique;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(ServerGamePacketListenerImpl.class)
-public class MixinServerGamePacketListenerImpl {
- @Shadow
- public ServerPlayer player;
-
- @Unique
- private int ignoreSwingPackets;
-
- @Keep
- @SuppressWarnings("UnusedVariable")
- @Inject(method = "handleAnimate", at = @At("HEAD"))
- private void onAnimate(ServerboundSwingPacket packet, CallbackInfo ci) {
- if (!this.player.gameMode.isDestroyingBlock) {
- if (this.ignoreSwingPackets > 0) {
- this.ignoreSwingPackets--;
- } else if (FabricWorldEdit.inst != null) {
- FabricWorldEdit.inst.onLeftClickAir(this.player, packet.getHand());
- }
- }
- }
-
- @Keep
- @SuppressWarnings("UnusedVariable")
- @Inject(method = "handlePlayerAction", at = @At("HEAD"))
- private void onAction(ServerboundPlayerActionPacket packet, CallbackInfo ci) {
- switch (packet.getAction()) {
- case DROP_ITEM, DROP_ALL_ITEMS, START_DESTROY_BLOCK -> this.ignoreSwingPackets++;
- default -> {
- }
- }
- }
-}
diff --git a/worldedit-fabric/src/main/resources/fabric.mod.json b/worldedit-fabric/src/main/resources/fabric.mod.json
index ae1fe696ce..b3c5080b90 100644
--- a/worldedit-fabric/src/main/resources/fabric.mod.json
+++ b/worldedit-fabric/src/main/resources/fabric.mod.json
@@ -26,7 +26,7 @@
"environment": "*",
"entrypoints": {
"main": [
- "com.sk89q.worldedit.fabric.FabricWorldEdit"
+ "com.sk89q.worldedit.fabric.internal.FabricWorldEdit"
]
},
@@ -43,7 +43,6 @@
"fabric-permissions-api-v0": "*"
},
"mixins": [
- "worldedit-fabric.mixins.json"
- ],
- "accessWidener" : "worldedit.accesswidener"
+ "worldedit-coremc.mixins.json"
+ ]
}
diff --git a/worldedit-fabric/src/main/resources/worldedit-fabric.mixins.json b/worldedit-fabric/src/main/resources/worldedit-fabric.mixins.json
deleted file mode 100644
index 1097e53aa4..0000000000
--- a/worldedit-fabric/src/main/resources/worldedit-fabric.mixins.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "required": true,
- "package": "com.sk89q.worldedit.fabric.mixin",
- "compatibilityLevel": "JAVA_8",
- "mixins": [
- "MixinServerGamePacketListenerImpl"
- ],
- "plugin": "com.sk89q.worldedit.fabric.internal.MixinConfigPlugin",
- "server": [
- ],
- "injectors": {
- "defaultRequire": 1
- }
-}
diff --git a/worldedit-fabric/src/main/resources/worldedit.accesswidener b/worldedit-fabric/src/main/resources/worldedit.accesswidener
deleted file mode 100644
index 96d7240b28..0000000000
--- a/worldedit-fabric/src/main/resources/worldedit.accesswidener
+++ /dev/null
@@ -1,18 +0,0 @@
-accessWidener v2 official
-
-accessible class net/minecraft/server/level/ServerChunkCache$MainThreadExecutor
-accessible field net/minecraft/server/level/ServerChunkCache mainThreadProcessor Lnet/minecraft/server/level/ServerChunkCache$MainThreadExecutor;
-
-accessible field net/minecraft/commands/CommandSourceStack source Lnet/minecraft/commands/CommandSource;
-
-accessible field net/minecraft/server/level/ServerPlayerGameMode isDestroyingBlock Z
-
-accessible field net/minecraft/world/level/storage/DerivedLevelData wrapped Lnet/minecraft/world/level/storage/ServerLevelData;
-
-#accessible field net/minecraft/world/level/storage/PrimaryLevelData worldOptions Lnet/minecraft/world/level/levelgen/WorldOptions;
-#mutable field net/minecraft/world/level/storage/PrimaryLevelData worldOptions Lnet/minecraft/world/level/levelgen/WorldOptions;
-
-accessible method net/minecraft/network/protocol/game/ClientboundBlockEntityDataPacket (Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/entity/BlockEntityType;Lnet/minecraft/nbt/CompoundTag;)V
-
-accessible field net/minecraft/server/MinecraftServer nextTickTimeNanos J
-accessible field net/minecraft/server/MinecraftServer storageSource Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;
diff --git a/worldedit-libs/core-mc/build.gradle.kts b/worldedit-libs/core-mc/build.gradle.kts
new file mode 100644
index 0000000000..3f6c7e06cb
--- /dev/null
+++ b/worldedit-libs/core-mc/build.gradle.kts
@@ -0,0 +1,3 @@
+plugins {
+ id("buildlogic.libs")
+}
diff --git a/worldedit-mod/build.gradle.kts b/worldedit-mod/build.gradle.kts
index d381755974..438dad0897 100644
--- a/worldedit-mod/build.gradle.kts
+++ b/worldedit-mod/build.gradle.kts
@@ -108,14 +108,16 @@ tasks.register("jar") {
exclude("org/enginehub/piston/")
exclude("org/enginehub/linbus/")
exclude("net/kyori/examination/")
- // Exclude worldedit-core
+ // Exclude worldedit-core and worldedit-core-mc (already included from fabric side)
exclude {
val pathString = it.relativePath.pathString
pathString.startsWith("com/sk89q/worldedit/") && !pathString.startsWith("com/sk89q/worldedit/neoforge/")
}
// Questionable excludes. So far the two files from each jar are the same.
+ exclude("assets/worldedit/icon.png")
exclude("defaults/worldedit.properties")
exclude("pack.mcmeta")
+ exclude("worldedit-coremc.mixins.json")
}
manifest {
from(mergeManifests.flatMap { it.outputManifest })
diff --git a/worldedit-neoforge/build.gradle.kts b/worldedit-neoforge/build.gradle.kts
index ba74700b2b..70fe733073 100644
--- a/worldedit-neoforge/build.gradle.kts
+++ b/worldedit-neoforge/build.gradle.kts
@@ -27,6 +27,10 @@ jarJar.disableDefaultSources()
repositories {
addEngineHubRepository()
+ maven {
+ name = "FabricMC"
+ url = uri("https://maven.fabricmc.net/")
+ }
mavenCentral()
}
@@ -35,6 +39,7 @@ configurations {
resolvable("coreResourcesResolvable") {
extendsFrom(coreResourcesScope.get())
attributes {
+ // Attributes are related to how `expose-resources` works, see that plugin file for details.
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category::class, Category.VERIFICATION))
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling::class, Bundling.EXTERNAL))
attribute(VerificationType.VERIFICATION_TYPE_ATTRIBUTE, objects.named(VerificationType::class, "resources"))
@@ -46,6 +51,7 @@ withCuiProtocolDependsOnCommonRule(libs.cuiProtocol.neoforge.get().module)
dependencies {
api(project(":worldedit-core"))
+ api(project(":worldedit-core-mc"))
implementation(libs.neoforge)
implementation(libs.cuiProtocol.neoforge)
@@ -56,20 +62,11 @@ dependencies {
}
"coreResourcesScope"(project(":worldedit-core"))
-}
-
-minecraft {
- accessTransformers {
- file("src/main/resources/META-INF/accesstransformer.cfg")
- }
+ "coreResourcesScope"(project(":worldedit-core-mc"))
}
runs {
val runConfig = Action {
- systemProperties(mapOf(
- "forge.logging.markers" to "SCAN,REGISTRIES,REGISTRYDUMP",
- "forge.logging.console.level" to "debug"
- ))
workingDirectory(project.file("run").canonicalPath)
modSources(sourceSets["main"])
dependencies {
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeAdapter.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeAdapter.java
index cf95a130b7..39a5dca62d 100644
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeAdapter.java
+++ b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeAdapter.java
@@ -19,259 +19,29 @@
package com.sk89q.worldedit.neoforge;
-import com.mojang.serialization.Codec;
-import com.sk89q.worldedit.blocks.BaseItemStack;
-import com.sk89q.worldedit.extension.platform.Actor;
-import com.sk89q.worldedit.internal.block.BlockStateIdAccess;
-import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.math.Vector3;
-import com.sk89q.worldedit.neoforge.internal.NBTConverter;
-import com.sk89q.worldedit.neoforge.internal.NeoForgeTransmogrifier;
-import com.sk89q.worldedit.registry.state.Property;
-import com.sk89q.worldedit.util.Direction;
-import com.sk89q.worldedit.util.concurrency.LazyReference;
-import com.sk89q.worldedit.world.World;
-import com.sk89q.worldedit.world.biome.BiomeType;
-import com.sk89q.worldedit.world.biome.BiomeTypes;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BlockType;
-import com.sk89q.worldedit.world.block.BlockTypes;
-import com.sk89q.worldedit.world.item.ItemType;
-import com.sk89q.worldedit.world.item.ItemTypes;
-import net.minecraft.commands.CommandSourceStack;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.component.DataComponentPatch;
-import net.minecraft.core.registries.BuiltInRegistries;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.nbt.NbtOps;
-import net.minecraft.resources.Identifier;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.util.StringRepresentable;
-import net.minecraft.world.item.Item;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.level.BaseCommandBlock;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.phys.Vec3;
-import net.neoforged.neoforge.server.ServerLifecycleHooks;
-import org.enginehub.linbus.tree.LinCompoundTag;
+import com.sk89q.worldedit.coremc.CoreMcAdapter;
+import com.sk89q.worldedit.coremc.internal.CoreMcPlatform;
+import com.sk89q.worldedit.neoforge.internal.NeoForgeWorldEdit;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Objects;
-import java.util.TreeMap;
-import javax.annotation.Nullable;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public final class NeoForgeAdapter {
-
- private NeoForgeAdapter() {
- }
-
- public static World adapt(ServerLevel world) {
- return new NeoForgeWorld(world);
- }
-
- /**
- * Create a Forge world from a WorldEdit world.
- *
- * @param world the WorldEdit world
- * @return a Forge world
- */
- public static ServerLevel adapt(World world) {
- checkNotNull(world);
- if (world instanceof NeoForgeWorld neoForgeWorld) {
- return neoForgeWorld.getWorld();
- } else {
- // TODO introduce a better cross-platform world API to match more easily
- throw new UnsupportedOperationException("Cannot adapt from a " + world.getClass());
- }
- }
-
- public static Biome adapt(BiomeType biomeType) {
- return ServerLifecycleHooks.getCurrentServer()
- .registryAccess()
- .lookupOrThrow(Registries.BIOME)
- .getOptional(Identifier.parse(biomeType.id()))
- .orElseThrow(() -> new IllegalStateException("No biome for " + biomeType.id()));
- }
-
- public static BiomeType adapt(Biome biome) {
- Identifier id = ServerLifecycleHooks.getCurrentServer()
- .registryAccess()
- .lookupOrThrow(Registries.BIOME)
- .getKey(biome);
- Objects.requireNonNull(id, "biome is not registered");
- return BiomeTypes.get(id.toString());
- }
-
- public static Vector3 adapt(Vec3 vector) {
- return Vector3.at(vector.x, vector.y, vector.z);
- }
-
- public static BlockVector3 adapt(BlockPos pos) {
- return BlockVector3.at(pos.getX(), pos.getY(), pos.getZ());
- }
-
- public static Vec3 toVec3(BlockVector3 vector) {
- return new Vec3(vector.x(), vector.y(), vector.z());
- }
-
- public static net.minecraft.core.Direction adapt(Direction face) {
- return switch (face) {
- case NORTH -> net.minecraft.core.Direction.NORTH;
- case SOUTH -> net.minecraft.core.Direction.SOUTH;
- case WEST -> net.minecraft.core.Direction.WEST;
- case EAST -> net.minecraft.core.Direction.EAST;
- case DOWN -> net.minecraft.core.Direction.DOWN;
- default -> net.minecraft.core.Direction.UP;
- };
- }
-
- public static Direction adaptEnumFacing(@Nullable net.minecraft.core.Direction face) {
- if (face == null) {
- return null;
- }
- return switch (face) {
- case NORTH -> Direction.NORTH;
- case SOUTH -> Direction.SOUTH;
- case WEST -> Direction.WEST;
- case EAST -> Direction.EAST;
- case DOWN -> Direction.DOWN;
- default -> Direction.UP;
- };
- }
-
- public static BlockPos toBlockPos(BlockVector3 vector) {
- return new BlockPos(vector.x(), vector.y(), vector.z());
- }
-
- /**
- * Adapts property.
- *
- * @deprecated without replacement, use the block adapter methods
- */
- // Suppress InlineMeSuggester: There is no replacement, so this shouldn't be inlined
- @SuppressWarnings("InlineMeSuggester")
- @Deprecated
- public static Property> adaptProperty(net.minecraft.world.level.block.state.properties.Property> property) {
- return NeoForgeTransmogrifier.transmogToWorldEditProperty(property);
- }
-
- /**
- * Adapts properties.
- *
- * @deprecated without replacement, use the block adapter methods
- */
- @Deprecated
- public static Map, Object> adaptProperties(BlockType block, Map, Comparable>> mcProps) {
- Map, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
- for (Map.Entry, Comparable>> prop : mcProps.entrySet()) {
- Object value = prop.getValue();
- if (prop.getKey() instanceof net.minecraft.world.level.block.state.properties.EnumProperty) {
- if (prop.getKey().getValueClass() == net.minecraft.core.Direction.class) {
- value = adaptEnumFacing((net.minecraft.core.Direction) value);
- } else {
- value = ((StringRepresentable) value).getSerializedName();
- }
- }
- props.put(block.getProperty(prop.getKey().getName()), value);
- }
- return props;
- }
-
- public static net.minecraft.world.level.block.state.BlockState adapt(BlockState blockState) {
- int blockStateId = BlockStateIdAccess.getBlockStateId(blockState);
- if (!BlockStateIdAccess.isValidInternalId(blockStateId)) {
- return NeoForgeTransmogrifier.transmogToMinecraft(blockState);
- }
- return Block.stateById(blockStateId);
- }
-
- public static BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) {
- int blockStateId = Block.getId(blockState);
- BlockState worldEdit = BlockStateIdAccess.getBlockStateById(blockStateId);
- if (worldEdit == null) {
- return NeoForgeTransmogrifier.transmogToWorldEdit(blockState);
- }
- return worldEdit;
- }
-
- public static Block adapt(BlockType blockType) {
- return BuiltInRegistries.BLOCK.getValue(Identifier.parse(blockType.id()));
- }
-
- public static BlockType adapt(Block block) {
- return BlockTypes.get(BuiltInRegistries.BLOCK.getKey(block).toString());
- }
+/**
+ * Public API to adapt between WorldEdit and NeoForge.
+ */
+public final class NeoForgeAdapter extends CoreMcAdapter {
- public static Item adapt(ItemType itemType) {
- return BuiltInRegistries.ITEM.getValue(Identifier.parse(itemType.id()));
- }
-
- public static ItemType adapt(Item item) {
- return ItemTypes.get(BuiltInRegistries.ITEM.getKey(item).toString());
- }
+ private static final NeoForgeAdapter INSTANCE = new NeoForgeAdapter();
/**
- * For serializing and deserializing components.
+ * {@return the NeoForge adapter}
*/
- private static final Codec COMPONENTS_CODEC = DataComponentPatch.CODEC.optionalFieldOf(
- "components", DataComponentPatch.EMPTY
- ).codec();
-
- public static ItemStack adapt(BaseItemStack baseItemStack) {
- final ItemStack itemStack = new ItemStack(adapt(baseItemStack.getType()), baseItemStack.getAmount());
- LinCompoundTag nbt = baseItemStack.getNbt();
- if (nbt != null) {
- DataComponentPatch componentPatch = COMPONENTS_CODEC.parse(
- ServerLifecycleHooks.getCurrentServer().registryAccess().createSerializationContext(NbtOps.INSTANCE),
- NBTConverter.toNative(nbt)
- ).getOrThrow();
- itemStack.applyComponents(componentPatch);
- }
- return itemStack;
- }
-
- public static BaseItemStack adapt(ItemStack itemStack) {
- CompoundTag tag = (CompoundTag) COMPONENTS_CODEC.encodeStart(
- ServerLifecycleHooks.getCurrentServer().registryAccess().createSerializationContext(NbtOps.INSTANCE),
- itemStack.getComponentsPatch()
- ).getOrThrow();
- return new BaseItemStack(
- adapt(itemStack.getItem()), LazyReference.from(() -> NBTConverter.fromNative(tag)), itemStack.getCount()
- );
+ public static NeoForgeAdapter get() {
+ return INSTANCE;
}
- /**
- * Get the WorldEdit proxy for the given player.
- *
- * @param player the player
- * @return the WorldEdit player
- */
- public static NeoForgePlayer adaptPlayer(ServerPlayer player) {
- checkNotNull(player);
- return new NeoForgePlayer(player);
+ private NeoForgeAdapter() {
}
- /**
- * Get the WorldEdit proxy for the given command source.
- *
- * @param commandSourceStack the command source
- * @return the WorldEdit actor
- */
- public static Actor adaptCommandSource(CommandSourceStack commandSourceStack) {
- checkNotNull(commandSourceStack);
- if (commandSourceStack.isPlayer()) {
- return adaptPlayer(commandSourceStack.getPlayer());
- }
- if (NeoForgeWorldEdit.inst.getConfig().commandBlockSupport && commandSourceStack.source instanceof BaseCommandBlock commandBlock) {
- return new NeoForgeBlockCommandSender(commandBlock, commandSourceStack.getLevel(), commandSourceStack.getPosition());
- }
-
- return new NeoForgeCommandSender(commandSourceStack);
+ @Override
+ protected CoreMcPlatform getPlatform() {
+ return NeoForgeWorldEdit.getPlatform();
}
}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeBlockCategoryRegistry.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeBlockCategoryRegistry.java
deleted file mode 100644
index 38ce898b51..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeBlockCategoryRegistry.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import com.google.common.collect.ImmutableSet;
-import com.sk89q.worldedit.world.block.BlockType;
-import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderSet;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.resources.Identifier;
-import net.minecraft.tags.TagKey;
-import net.neoforged.neoforge.server.ServerLifecycleHooks;
-
-import java.util.Set;
-
-public class NeoForgeBlockCategoryRegistry implements BlockCategoryRegistry {
- @Override
- public Set getCategorisedByName(String category) {
- return ServerLifecycleHooks.getCurrentServer().registryAccess().lookupOrThrow(Registries.BLOCK)
- .get(TagKey.create(
- Registries.BLOCK,
- Identifier.parse(category)
- ))
- .stream()
- .flatMap(HolderSet.Named::stream)
- .map(Holder::value)
- .map(NeoForgeAdapter::adapt)
- .collect(ImmutableSet.toImmutableSet());
- }
-}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeBlockMaterial.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeBlockMaterial.java
deleted file mode 100644
index 96db7265e3..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeBlockMaterial.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import com.sk89q.worldedit.world.registry.BlockMaterial;
-import net.minecraft.core.BlockPos;
-import net.minecraft.world.Clearable;
-import net.minecraft.world.level.EmptyBlockGetter;
-import net.minecraft.world.level.block.Block;
-import net.minecraft.world.level.block.EntityBlock;
-import net.minecraft.world.level.block.state.BlockState;
-import net.minecraft.world.level.material.PushReaction;
-
-/**
- * Forge block material that pulls as much info as possible from the Minecraft
- * Material, and passes the rest to another implementation, typically the
- * bundled block info.
- */
-public class NeoForgeBlockMaterial implements BlockMaterial {
-
- private final BlockState block;
-
- public NeoForgeBlockMaterial(BlockState block) {
- this.block = block;
- }
-
- @Override
- public boolean isAir() {
- return block.isAir();
- }
-
- @Override
- public boolean isFullCube() {
- return Block.isShapeFullBlock(block.getShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO));
- }
-
- @Override
- public boolean isOpaque() {
- return block.canOcclude();
- }
-
- @Override
- public boolean isPowerSource() {
- return block.isSignalSource();
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public boolean isLiquid() {
- return block.liquid();
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public boolean isSolid() {
- return block.isSolid();
- }
-
- @Override
- public float getHardness() {
- return block.getDestroySpeed(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public float getResistance() {
- return block.getBlock().getExplosionResistance();
- }
-
- @Override
- public float getSlipperiness() {
- return block.getBlock().getFriction();
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public int getLightValue() {
- return block.getLightEmission();
- }
-
- @Override
- public boolean isFragileWhenPushed() {
- return block.getPistonPushReaction() == PushReaction.DESTROY;
- }
-
- @Override
- public boolean isUnpushable() {
- return block.getPistonPushReaction() == PushReaction.BLOCK;
- }
-
- @Override
- public boolean isTicksRandomly() {
- return block.isRandomlyTicking();
- }
-
- @Override
- @SuppressWarnings("deprecation")
- public boolean isMovementBlocker() {
- return block.blocksMotion();
- }
-
- @SuppressWarnings("deprecation")
- @Override
- public boolean isBurnable() {
- return block.ignitedByLava();
- }
-
- @Override
- public boolean isToolRequired() {
- return block.requiresCorrectToolForDrops();
- }
-
- @Override
- public boolean isReplacedDuringPlacement() {
- return block.canBeReplaced();
- }
-
- @Override
- public boolean isTranslucent() {
- return !block.canOcclude();
- }
-
- @Override
- public boolean hasContainer() {
- return block.getBlock() instanceof EntityBlock entityBlock
- && entityBlock.newBlockEntity(BlockPos.ZERO, block) instanceof Clearable;
- }
-
-}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeCommandSender.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeCommandSender.java
deleted file mode 100644
index 258cc47350..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeCommandSender.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
-import com.sk89q.worldedit.neoforge.internal.ComponentConverter;
-import com.sk89q.worldedit.session.SessionKey;
-import com.sk89q.worldedit.util.formatting.WorldEditText;
-import com.sk89q.worldedit.util.formatting.text.Component;
-import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
-import net.minecraft.ChatFormatting;
-import net.minecraft.commands.CommandSourceStack;
-
-import java.util.Locale;
-import java.util.UUID;
-import javax.annotation.Nullable;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public class NeoForgeCommandSender extends AbstractNonPlayerActor {
-
- /**
- * One time generated ID.
- */
- private static final UUID DEFAULT_ID = UUID.fromString("a233eb4b-4cab-42cd-9fd9-7e7b9a3f74be");
-
- private final CommandSourceStack sender;
-
- public NeoForgeCommandSender(CommandSourceStack sender) {
- checkNotNull(sender);
- checkArgument(!sender.isPlayer(), "Cannot wrap a player");
-
- this.sender = sender;
- }
-
- @Override
- public UUID getUniqueId() {
- return DEFAULT_ID;
- }
-
- @Override
- public String getName() {
- return sender.getTextName();
- }
-
- @Override
- @Deprecated
- public void printRaw(String msg) {
- for (String part : msg.split("\n", 0)) {
- sendMessage(net.minecraft.network.chat.Component.literal(part));
- }
- }
-
- @Override
- @Deprecated
- public void printDebug(String msg) {
- sendColorized(msg, ChatFormatting.GRAY);
- }
-
- @Override
- @Deprecated
- public void print(String msg) {
- sendColorized(msg, ChatFormatting.LIGHT_PURPLE);
- }
-
- @Override
- @Deprecated
- public void printError(String msg) {
- sendColorized(msg, ChatFormatting.RED);
- }
-
- @Override
- public void print(Component component) {
- sendMessage(ComponentConverter.Serializer.fromJson(
- GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale())),
- sender.registryAccess()
- ));
- }
-
- private void sendColorized(String msg, ChatFormatting formatting) {
- for (String part : msg.split("\n", 0)) {
- var component = net.minecraft.network.chat.Component.literal(part);
- component.withStyle(formatting);
- sendMessage(component);
- }
- }
-
- private void sendMessage(net.minecraft.network.chat.Component textComponent) {
- this.sender.sendSystemMessage(textComponent);
- }
-
- @Override
- public String[] getGroups() {
- return new String[0];
- }
-
- @Override
- public boolean hasPermission(String perm) {
- return true;
- }
-
- @Override
- public void checkPermission(String permission) {
- }
-
- @Override
- public Locale getLocale() {
- return WorldEdit.getInstance().getConfiguration().defaultLocale;
- }
-
- public CommandSourceStack getSender() {
- return this.sender;
- }
-
- @Override
- public SessionKey getSessionKey() {
- return new SessionKey() {
- @Nullable
- @Override
- public String getName() {
- return sender.getTextName();
- }
-
- @Override
- public boolean isActive() {
- return true;
- }
-
- @Override
- public boolean isPersistent() {
- return true;
- }
-
- @Override
- public UUID getUniqueId() {
- return DEFAULT_ID;
- }
- };
- }
-}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeDataFixer.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeDataFixer.java
deleted file mode 100644
index 80c693e075..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeDataFixer.java
+++ /dev/null
@@ -1,2724 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import com.google.common.base.Strings;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-import com.mojang.datafixers.DSL.TypeReference;
-import com.mojang.datafixers.DataFixer;
-import com.mojang.datafixers.schemas.Schema;
-import com.mojang.serialization.Dynamic;
-import com.sk89q.worldedit.neoforge.internal.ComponentConverter;
-import com.sk89q.worldedit.neoforge.internal.NBTConverter;
-import net.minecraft.core.Direction;
-import net.minecraft.core.UUIDUtil;
-import net.minecraft.nbt.CompoundTag;
-import net.minecraft.nbt.FloatTag;
-import net.minecraft.nbt.ListTag;
-import net.minecraft.nbt.NbtOps;
-import net.minecraft.nbt.StringTag;
-import net.minecraft.nbt.Tag;
-import net.minecraft.network.chat.Component;
-import net.minecraft.network.chat.MutableComponent;
-import net.minecraft.resources.Identifier;
-import net.minecraft.util.GsonHelper;
-import net.minecraft.util.datafix.DataFixers;
-import net.minecraft.util.datafix.fixes.References;
-import net.minecraft.world.item.DyeColor;
-import net.neoforged.neoforge.server.ServerLifecycleHooks;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.enginehub.linbus.tree.LinCompoundTag;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Random;
-import java.util.Set;
-import java.util.UUID;
-import java.util.stream.Collectors;
-import javax.annotation.Nullable;
-
-/**
- * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2)
- *
- *
- * We register a DFU Fixer per Legacy Data Version and apply the fixes using legacy strategy
- * which is safer, faster and cleaner code.
- *
- *
- *
- * The pre DFU code did not fail when the Source version was unknown.
- *
- *
- *
- * This class also provides util methods for converting compounds to wrap the update call to
- * receive the source version in the compound.
- *
- */
-@SuppressWarnings({
- "UnnecessarilyQualifiedStaticUsage",
- "StringSplitter",
- "ImmutableEnumChecker",
- "MissingOverride",
- "StaticAssignmentInConstructor",
- "EffectivelyPrivate",
- "FallThrough",
- "MutablePublicArray",
- "unused",
- "unchecked",
- "rawtypes"
-})
-class NeoForgeDataFixer implements com.sk89q.worldedit.world.DataFixer {
-
- @SuppressWarnings("unchecked")
- @Override
- public T fixUp(FixType type, T original, int srcVer) {
- if (type == FixTypes.CHUNK) {
- return (T) fixChunk((LinCompoundTag) original, srcVer);
- } else if (type == FixTypes.BLOCK_ENTITY) {
- return (T) fixBlockEntity((LinCompoundTag) original, srcVer);
- } else if (type == FixTypes.ENTITY) {
- return (T) fixEntity((LinCompoundTag) original, srcVer);
- } else if (type == FixTypes.BLOCK_STATE) {
- return (T) fixBlockState((String) original, srcVer);
- } else if (type == FixTypes.ITEM_TYPE) {
- return (T) fixItemType((String) original, srcVer);
- } else if (type == FixTypes.BIOME) {
- return (T) fixBiome((String) original, srcVer);
- }
- return original;
- }
-
- private LinCompoundTag fixChunk(LinCompoundTag originalChunk, int srcVer) {
- net.minecraft.nbt.CompoundTag tag = NBTConverter.toNative(originalChunk);
- net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.CHUNK, tag, srcVer);
- return NBTConverter.fromNative(fixed);
- }
-
- private LinCompoundTag fixBlockEntity(LinCompoundTag origTileEnt, int srcVer) {
- net.minecraft.nbt.CompoundTag tag = NBTConverter.toNative(origTileEnt);
- net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.BLOCK_ENTITY, tag, srcVer);
- return NBTConverter.fromNative(fixed);
- }
-
- private LinCompoundTag fixEntity(LinCompoundTag origEnt, int srcVer) {
- net.minecraft.nbt.CompoundTag tag = NBTConverter.toNative(origEnt);
- net.minecraft.nbt.CompoundTag fixed = convert(LegacyType.ENTITY, tag, srcVer);
- return NBTConverter.fromNative(fixed);
- }
-
- private String fixBlockState(String blockState, int srcVer) {
- net.minecraft.nbt.CompoundTag stateNBT = stateToNBT(blockState);
- Dynamic dynamic = new Dynamic<>(OPS_NBT, stateNBT);
- net.minecraft.nbt.CompoundTag fixed = (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(References.BLOCK_STATE, dynamic, srcVer, DATA_VERSION).getValue();
- return nbtToState(fixed);
- }
-
- private String nbtToState(net.minecraft.nbt.CompoundTag tagCompound) {
- StringBuilder sb = new StringBuilder();
- sb.append(tagCompound.getString("Name").get());
- tagCompound.getCompound("Properties").ifPresent(props -> {
- sb.append('[');
- sb.append(props.keySet().stream().map(k -> k + "=" + props.getString(k).get().replace("\"", "")).collect(Collectors.joining(",")));
- sb.append(']');
- });
- return sb.toString();
- }
-
- private static net.minecraft.nbt.CompoundTag stateToNBT(String blockState) {
- int propIdx = blockState.indexOf('[');
- net.minecraft.nbt.CompoundTag tag = new net.minecraft.nbt.CompoundTag();
- if (propIdx < 0) {
- tag.putString("Name", blockState);
- } else {
- tag.putString("Name", blockState.substring(0, propIdx));
- net.minecraft.nbt.CompoundTag propTag = new net.minecraft.nbt.CompoundTag();
- String props = blockState.substring(propIdx + 1, blockState.length() - 1);
- String[] propArr = props.split(",");
- for (String pair : propArr) {
- final String[] split = pair.split("=");
- propTag.putString(split[0], split[1]);
- }
- tag.put("Properties", propTag);
- }
- return tag;
- }
-
- private String fixBiome(String key, int srcVer) {
- return fixName(key, srcVer, References.BIOME);
- }
-
- private String fixItemType(String key, int srcVer) {
- return fixName(key, srcVer, References.ITEM_NAME);
- }
-
- private static String fixName(String key, int srcVer, TypeReference type) {
- return INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, StringTag.valueOf(key)), srcVer, DATA_VERSION)
- .asString().result().orElse(key);
- }
-
- private static final NbtOps OPS_NBT = NbtOps.INSTANCE;
- private static final int LEGACY_VERSION = 1343;
- private static int DATA_VERSION;
- private static NeoForgeDataFixer INSTANCE;
-
- private final Map> converters = new EnumMap<>(LegacyType.class);
- private final Map> inspectors = new EnumMap<>(LegacyType.class);
-
- // Set on build
- private final DataFixer fixer;
- private static final Map DFU_TO_LEGACY = new HashMap<>();
-
- public enum LegacyType {
- LEVEL(References.LEVEL),
- PLAYER(References.PLAYER),
- CHUNK(References.CHUNK),
- BLOCK_ENTITY(References.BLOCK_ENTITY),
- ENTITY(References.ENTITY),
- ITEM_INSTANCE(References.ITEM_STACK),
- OPTIONS(References.OPTIONS),
- STRUCTURE(References.STRUCTURE);
-
- private final TypeReference type;
-
- LegacyType(TypeReference type) {
- this.type = type;
- DFU_TO_LEGACY.put(type.typeName(), this);
- }
-
- public TypeReference getDFUType() {
- return type;
- }
- }
-
- NeoForgeDataFixer(int dataVersion) {
- DATA_VERSION = dataVersion;
- INSTANCE = this;
- registerConverters();
- registerInspectors();
- this.fixer = new WrappedDataFixer(DataFixers.getDataFixer());
- }
-
- private class WrappedDataFixer implements DataFixer {
- private final DataFixer realFixer;
-
- WrappedDataFixer(DataFixer realFixer) {
- this.realFixer = realFixer;
- }
-
- @Override
- public Dynamic update(TypeReference type, Dynamic dynamic, int sourceVer, int targetVer) {
- LegacyType legacyType = DFU_TO_LEGACY.get(type.typeName());
- if (sourceVer < LEGACY_VERSION && legacyType != null) {
- net.minecraft.nbt.CompoundTag cmp = (net.minecraft.nbt.CompoundTag) dynamic.getValue();
- int desiredVersion = Math.min(targetVer, LEGACY_VERSION);
-
- cmp = convert(legacyType, cmp, sourceVer, desiredVersion);
- sourceVer = desiredVersion;
- dynamic = new Dynamic(OPS_NBT, cmp);
- }
- return realFixer.update(type, dynamic, sourceVer, targetVer);
- }
-
- private net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int desiredVersion) {
- List converters = NeoForgeDataFixer.this.converters.get(type);
- if (converters != null && !converters.isEmpty()) {
- for (DataConverter converter : converters) {
- int dataVersion = converter.getDataVersion();
- if (dataVersion > sourceVer && dataVersion <= desiredVersion) {
- cmp = converter.convert(cmp);
- }
- }
- }
-
- List inspectors = NeoForgeDataFixer.this.inspectors.get(type);
- if (inspectors != null && !inspectors.isEmpty()) {
- for (DataInspector inspector : inspectors) {
- cmp = inspector.inspect(cmp, sourceVer, desiredVersion);
- }
- }
-
- return cmp;
- }
-
- @Override
- public Schema getSchema(int i) {
- return realFixer.getSchema(i);
- }
- }
-
- public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp) {
- return convert(type.getDFUType(), cmp);
- }
-
- public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) {
- return convert(type.getDFUType(), cmp, sourceVer);
- }
-
- public static net.minecraft.nbt.CompoundTag convert(LegacyType type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- return convert(type.getDFUType(), cmp, sourceVer, targetVer);
- }
-
- public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp) {
- int i = cmp.getIntOr("DataVersion", -1);
- return convert(type, cmp, i);
- }
-
- public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer) {
- return convert(type, cmp, sourceVer, DATA_VERSION);
- }
-
- public static net.minecraft.nbt.CompoundTag convert(TypeReference type, net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- if (sourceVer >= targetVer) {
- return cmp;
- }
- return (net.minecraft.nbt.CompoundTag) INSTANCE.fixer.update(type, new Dynamic<>(OPS_NBT, cmp), sourceVer, targetVer).getValue();
- }
-
-
- public interface DataInspector {
- net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer);
- }
-
- public interface DataConverter {
-
- int getDataVersion();
-
- net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp);
- }
-
-
- private void registerInspector(LegacyType type, DataInspector inspector) {
- this.inspectors.computeIfAbsent(type, k -> new ArrayList<>()).add(inspector);
- }
-
- private void registerConverter(LegacyType type, DataConverter converter) {
- int version = converter.getDataVersion();
-
- List list = this.converters.computeIfAbsent(type, k -> new ArrayList<>());
- if (!list.isEmpty() && list.getLast().getDataVersion() > version) {
- for (int j = 0; j < list.size(); ++j) {
- if (list.get(j).getDataVersion() > version) {
- list.add(j, converter);
- break;
- }
- }
- } else {
- list.add(converter);
- }
- }
-
- private void registerInspectors() {
- registerEntityItemList("EntityHorseDonkey", "SaddleItem", "Items");
- registerEntityItemList("EntityHorseMule", "Items");
- registerEntityItemList("EntityMinecartChest", "Items");
- registerEntityItemList("EntityMinecartHopper", "Items");
- registerEntityItemList("EntityVillager", "Inventory");
- registerEntityItemListEquipment("EntityArmorStand");
- registerEntityItemListEquipment("EntityBat");
- registerEntityItemListEquipment("EntityBlaze");
- registerEntityItemListEquipment("EntityCaveSpider");
- registerEntityItemListEquipment("EntityChicken");
- registerEntityItemListEquipment("EntityCow");
- registerEntityItemListEquipment("EntityCreeper");
- registerEntityItemListEquipment("EntityEnderDragon");
- registerEntityItemListEquipment("EntityEnderman");
- registerEntityItemListEquipment("EntityEndermite");
- registerEntityItemListEquipment("EntityEvoker");
- registerEntityItemListEquipment("EntityGhast");
- registerEntityItemListEquipment("EntityGiantZombie");
- registerEntityItemListEquipment("EntityGuardian");
- registerEntityItemListEquipment("EntityGuardianElder");
- registerEntityItemListEquipment("EntityHorse");
- registerEntityItemListEquipment("EntityHorseDonkey");
- registerEntityItemListEquipment("EntityHorseMule");
- registerEntityItemListEquipment("EntityHorseSkeleton");
- registerEntityItemListEquipment("EntityHorseZombie");
- registerEntityItemListEquipment("EntityIronGolem");
- registerEntityItemListEquipment("EntityMagmaCube");
- registerEntityItemListEquipment("EntityMushroomCow");
- registerEntityItemListEquipment("EntityOcelot");
- registerEntityItemListEquipment("EntityPig");
- registerEntityItemListEquipment("EntityPigZombie");
- registerEntityItemListEquipment("EntityRabbit");
- registerEntityItemListEquipment("EntitySheep");
- registerEntityItemListEquipment("EntityShulker");
- registerEntityItemListEquipment("EntitySilverfish");
- registerEntityItemListEquipment("EntitySkeleton");
- registerEntityItemListEquipment("EntitySkeletonStray");
- registerEntityItemListEquipment("EntitySkeletonWither");
- registerEntityItemListEquipment("EntitySlime");
- registerEntityItemListEquipment("EntitySnowman");
- registerEntityItemListEquipment("EntitySpider");
- registerEntityItemListEquipment("EntitySquid");
- registerEntityItemListEquipment("EntityVex");
- registerEntityItemListEquipment("EntityVillager");
- registerEntityItemListEquipment("EntityVindicator");
- registerEntityItemListEquipment("EntityWitch");
- registerEntityItemListEquipment("EntityWither");
- registerEntityItemListEquipment("EntityWolf");
- registerEntityItemListEquipment("EntityZombie");
- registerEntityItemListEquipment("EntityZombieHusk");
- registerEntityItemListEquipment("EntityZombieVillager");
- registerEntityItemSingle("EntityFireworks", "FireworksItem");
- registerEntityItemSingle("EntityHorse", "ArmorItem");
- registerEntityItemSingle("EntityHorse", "SaddleItem");
- registerEntityItemSingle("EntityHorseMule", "SaddleItem");
- registerEntityItemSingle("EntityHorseSkeleton", "SaddleItem");
- registerEntityItemSingle("EntityHorseZombie", "SaddleItem");
- registerEntityItemSingle("EntityItem", "Item");
- registerEntityItemSingle("EntityItemFrame", "Item");
- registerEntityItemSingle("EntityPotion", "Potion");
-
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItem("TileEntityRecordPlayer", "RecordItem"));
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityBrewingStand", "Items"));
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityChest", "Items"));
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDispenser", "Items"));
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityDropper", "Items"));
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityFurnace", "Items"));
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityHopper", "Items"));
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorItemList("TileEntityShulkerBox", "Items"));
- registerInspector(LegacyType.BLOCK_ENTITY, new DataInspectorMobSpawnerMobs());
- registerInspector(LegacyType.CHUNK, new DataInspectorChunks());
- registerInspector(LegacyType.ENTITY, new DataInspectorCommandBlock());
- registerInspector(LegacyType.ENTITY, new DataInspectorEntityPassengers());
- registerInspector(LegacyType.ENTITY, new DataInspectorMobSpawnerMinecart());
- registerInspector(LegacyType.ENTITY, new DataInspectorVillagers());
- registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorBlockEntity());
- registerInspector(LegacyType.ITEM_INSTANCE, new DataInspectorEntity());
- registerInspector(LegacyType.LEVEL, new DataInspectorLevelPlayer());
- registerInspector(LegacyType.PLAYER, new DataInspectorPlayer());
- registerInspector(LegacyType.PLAYER, new DataInspectorPlayerVehicle());
- registerInspector(LegacyType.STRUCTURE, new DataInspectorStructure());
- }
-
- private void registerConverters() {
- registerConverter(LegacyType.ENTITY, new DataConverterEquipment());
- registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterSignText());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterMaterialId());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionId());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterSpawnEgg());
- registerConverter(LegacyType.ENTITY, new DataConverterMinecart());
- registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterMobSpawner());
- registerConverter(LegacyType.ENTITY, new DataConverterUUID());
- registerConverter(LegacyType.ENTITY, new DataConverterHealth());
- registerConverter(LegacyType.ENTITY, new DataConverterSaddle());
- registerConverter(LegacyType.ENTITY, new DataConverterHanging());
- registerConverter(LegacyType.ENTITY, new DataConverterDropChances());
- registerConverter(LegacyType.ENTITY, new DataConverterRiding());
- registerConverter(LegacyType.ENTITY, new DataConverterArmorStand());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBook());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterCookedFish());
- registerConverter(LegacyType.ENTITY, new DataConverterZombie());
- registerConverter(LegacyType.OPTIONS, new DataConverterVBO());
- registerConverter(LegacyType.ENTITY, new DataConverterGuardian());
- registerConverter(LegacyType.ENTITY, new DataConverterSkeleton());
- registerConverter(LegacyType.ENTITY, new DataConverterZombieType());
- registerConverter(LegacyType.ENTITY, new DataConverterHorse());
- registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterTileEntity());
- registerConverter(LegacyType.ENTITY, new DataConverterEntity());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBanner());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterPotionWater());
- registerConverter(LegacyType.ENTITY, new DataConverterShulker());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterShulkerBoxItem());
- registerConverter(LegacyType.BLOCK_ENTITY, new DataConverterShulkerBoxBlock());
- registerConverter(LegacyType.OPTIONS, new DataConverterLang());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterTotem());
- registerConverter(LegacyType.CHUNK, new DataConverterBedBlock());
- registerConverter(LegacyType.ITEM_INSTANCE, new DataConverterBedItem());
- }
-
- private void registerEntityItemList(String type, String... keys) {
- registerInspector(LegacyType.ENTITY, new DataInspectorItemList(type, keys));
- }
-
- private void registerEntityItemSingle(String type, String key) {
- registerInspector(LegacyType.ENTITY, new DataInspectorItem(type, key));
- }
-
- private void registerEntityItemListEquipment(String type) {
- registerEntityItemList(type, "ArmorItems", "HandItems");
- }
-
- private static final Map OLD_ID_TO_KEY_MAP = new HashMap<>();
-
- static {
- final Map map = OLD_ID_TO_KEY_MAP;
- map.put("EntityItem", Identifier.parse("item"));
- map.put("EntityExperienceOrb", Identifier.parse("xp_orb"));
- map.put("EntityAreaEffectCloud", Identifier.parse("area_effect_cloud"));
- map.put("EntityGuardianElder", Identifier.parse("elder_guardian"));
- map.put("EntitySkeletonWither", Identifier.parse("wither_skeleton"));
- map.put("EntitySkeletonStray", Identifier.parse("stray"));
- map.put("EntityEgg", Identifier.parse("egg"));
- map.put("EntityLeash", Identifier.parse("leash_knot"));
- map.put("EntityPainting", Identifier.parse("painting"));
- map.put("EntityTippedArrow", Identifier.parse("arrow"));
- map.put("EntitySnowball", Identifier.parse("snowball"));
- map.put("EntityLargeFireball", Identifier.parse("fireball"));
- map.put("EntitySmallFireball", Identifier.parse("small_fireball"));
- map.put("EntityEnderPearl", Identifier.parse("ender_pearl"));
- map.put("EntityEnderSignal", Identifier.parse("eye_of_ender_signal"));
- map.put("EntityPotion", Identifier.parse("potion"));
- map.put("EntityThrownExpBottle", Identifier.parse("xp_bottle"));
- map.put("EntityItemFrame", Identifier.parse("item_frame"));
- map.put("EntityWitherSkull", Identifier.parse("wither_skull"));
- map.put("EntityTNTPrimed", Identifier.parse("tnt"));
- map.put("EntityFallingBlock", Identifier.parse("falling_block"));
- map.put("EntityFireworks", Identifier.parse("fireworks_rocket"));
- map.put("EntityZombieHusk", Identifier.parse("husk"));
- map.put("EntitySpectralArrow", Identifier.parse("spectral_arrow"));
- map.put("EntityShulkerBullet", Identifier.parse("shulker_bullet"));
- map.put("EntityDragonFireball", Identifier.parse("dragon_fireball"));
- map.put("EntityZombieVillager", Identifier.parse("zombie_villager"));
- map.put("EntityHorseSkeleton", Identifier.parse("skeleton_horse"));
- map.put("EntityHorseZombie", Identifier.parse("zombie_horse"));
- map.put("EntityArmorStand", Identifier.parse("armor_stand"));
- map.put("EntityHorseDonkey", Identifier.parse("donkey"));
- map.put("EntityHorseMule", Identifier.parse("mule"));
- map.put("EntityEvokerFangs", Identifier.parse("evocation_fangs"));
- map.put("EntityEvoker", Identifier.parse("evocation_illager"));
- map.put("EntityVex", Identifier.parse("vex"));
- map.put("EntityVindicator", Identifier.parse("vindication_illager"));
- map.put("EntityIllagerIllusioner", Identifier.parse("illusion_illager"));
- map.put("EntityMinecartCommandBlock", Identifier.parse("commandblock_minecart"));
- map.put("EntityBoat", Identifier.parse("boat"));
- map.put("EntityMinecartRideable", Identifier.parse("minecart"));
- map.put("EntityMinecartChest", Identifier.parse("chest_minecart"));
- map.put("EntityMinecartFurnace", Identifier.parse("furnace_minecart"));
- map.put("EntityMinecartTNT", Identifier.parse("tnt_minecart"));
- map.put("EntityMinecartHopper", Identifier.parse("hopper_minecart"));
- map.put("EntityMinecartMobSpawner", Identifier.parse("spawner_minecart"));
- map.put("EntityCreeper", Identifier.parse("creeper"));
- map.put("EntitySkeleton", Identifier.parse("skeleton"));
- map.put("EntitySpider", Identifier.parse("spider"));
- map.put("EntityGiantZombie", Identifier.parse("giant"));
- map.put("EntityZombie", Identifier.parse("zombie"));
- map.put("EntitySlime", Identifier.parse("slime"));
- map.put("EntityGhast", Identifier.parse("ghast"));
- map.put("EntityPigZombie", Identifier.parse("zombie_pigman"));
- map.put("EntityEnderman", Identifier.parse("enderman"));
- map.put("EntityCaveSpider", Identifier.parse("cave_spider"));
- map.put("EntitySilverfish", Identifier.parse("silverfish"));
- map.put("EntityBlaze", Identifier.parse("blaze"));
- map.put("EntityMagmaCube", Identifier.parse("magma_cube"));
- map.put("EntityEnderDragon", Identifier.parse("ender_dragon"));
- map.put("EntityWither", Identifier.parse("wither"));
- map.put("EntityBat", Identifier.parse("bat"));
- map.put("EntityWitch", Identifier.parse("witch"));
- map.put("EntityEndermite", Identifier.parse("endermite"));
- map.put("EntityGuardian", Identifier.parse("guardian"));
- map.put("EntityShulker", Identifier.parse("shulker"));
- map.put("EntityPig", Identifier.parse("pig"));
- map.put("EntitySheep", Identifier.parse("sheep"));
- map.put("EntityCow", Identifier.parse("cow"));
- map.put("EntityChicken", Identifier.parse("chicken"));
- map.put("EntitySquid", Identifier.parse("squid"));
- map.put("EntityWolf", Identifier.parse("wolf"));
- map.put("EntityMushroomCow", Identifier.parse("mooshroom"));
- map.put("EntitySnowman", Identifier.parse("snowman"));
- map.put("EntityOcelot", Identifier.parse("ocelot"));
- map.put("EntityIronGolem", Identifier.parse("villager_golem"));
- map.put("EntityHorse", Identifier.parse("horse"));
- map.put("EntityRabbit", Identifier.parse("rabbit"));
- map.put("EntityPolarBear", Identifier.parse("polar_bear"));
- map.put("EntityLlama", Identifier.parse("llama"));
- map.put("EntityLlamaSpit", Identifier.parse("llama_spit"));
- map.put("EntityParrot", Identifier.parse("parrot"));
- map.put("EntityVillager", Identifier.parse("villager"));
- map.put("EntityEnderCrystal", Identifier.parse("ender_crystal"));
- map.put("TileEntityFurnace", Identifier.parse("furnace"));
- map.put("TileEntityChest", Identifier.parse("chest"));
- map.put("TileEntityEnderChest", Identifier.parse("ender_chest"));
- map.put("TileEntityRecordPlayer", Identifier.parse("jukebox"));
- map.put("TileEntityDispenser", Identifier.parse("dispenser"));
- map.put("TileEntityDropper", Identifier.parse("dropper"));
- map.put("TileEntitySign", Identifier.parse("sign"));
- map.put("TileEntityMobSpawner", Identifier.parse("mob_spawner"));
- map.put("TileEntityNote", Identifier.parse("noteblock"));
- map.put("TileEntityPiston", Identifier.parse("piston"));
- map.put("TileEntityBrewingStand", Identifier.parse("brewing_stand"));
- map.put("TileEntityEnchantTable", Identifier.parse("enchanting_table"));
- map.put("TileEntityEnderPortal", Identifier.parse("end_portal"));
- map.put("TileEntityBeacon", Identifier.parse("beacon"));
- map.put("TileEntitySkull", Identifier.parse("skull"));
- map.put("TileEntityLightDetector", Identifier.parse("daylight_detector"));
- map.put("TileEntityHopper", Identifier.parse("hopper"));
- map.put("TileEntityComparator", Identifier.parse("comparator"));
- map.put("TileEntityFlowerPot", Identifier.parse("flower_pot"));
- map.put("TileEntityBanner", Identifier.parse("banner"));
- map.put("TileEntityStructure", Identifier.parse("structure_block"));
- map.put("TileEntityEndGateway", Identifier.parse("end_gateway"));
- map.put("TileEntityCommand", Identifier.parse("command_block"));
- map.put("TileEntityShulkerBox", Identifier.parse("shulker_box"));
- map.put("TileEntityBed", Identifier.parse("bed"));
- }
-
- private static Identifier getKey(String type) {
- final Identifier key = OLD_ID_TO_KEY_MAP.get(type);
- if (key == null) {
- throw new IllegalArgumentException("Unknown mapping for " + type);
- }
- return key;
- }
-
- private static void convertCompound(LegacyType type, net.minecraft.nbt.CompoundTag cmp, String key, int sourceVer, int targetVer) {
- cmp.put(key, convert(type, cmp.getCompoundOrEmpty(key), sourceVer, targetVer));
- }
-
- private static void convertItem(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) {
- if (nbttagcompound.getCompound(key).isPresent()) {
- convertCompound(LegacyType.ITEM_INSTANCE, nbttagcompound, key, sourceVer, targetVer);
- }
- }
-
- private static void convertItems(net.minecraft.nbt.CompoundTag nbttagcompound, String key, int sourceVer, int targetVer) {
- nbttagcompound.getList(key).ifPresent(nbttaglist -> {
- for (int j = 0; j < nbttaglist.size(); ++j) {
- nbttaglist.set(j, convert(LegacyType.ITEM_INSTANCE, nbttaglist.getCompoundOrEmpty(j), sourceVer, targetVer));
- }
- });
- }
-
- private static class DataConverterEquipment implements DataConverter {
-
- DataConverterEquipment() {
- }
-
- @Override
- public int getDataVersion() {
- return 100;
- }
-
- @Override
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- ListTag nbttaglist = cmp.getListOrEmpty("Equipment");
-
- if (!nbttaglist.isEmpty() && cmp.getCompound("HandItems").isEmpty()) {
- ListTag nbttaglist1 = new ListTag();
- nbttaglist1.add(nbttaglist.get(0));
- nbttaglist1.add(new net.minecraft.nbt.CompoundTag());
- cmp.put("HandItems", nbttaglist1);
- }
-
- if (nbttaglist.size() > 1 && cmp.getCompound("ArmorItem").isEmpty()) {
- ListTag nbttaglist1 = new ListTag();
- nbttaglist1.add(nbttaglist.get(1));
- nbttaglist1.add(nbttaglist.get(2));
- nbttaglist1.add(nbttaglist.get(3));
- nbttaglist1.add(nbttaglist.get(4));
- cmp.put("ArmorItems", nbttaglist1);
- }
-
- cmp.remove("Equipment");
- cmp.getList("DropChances").ifPresent(nbttaglist1 -> {
- ListTag nbttaglist2;
-
- if (cmp.getCompound("HandDropChances").isEmpty()) {
- nbttaglist2 = new ListTag();
- nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloatOr(0, 0F)));
- nbttaglist2.add(FloatTag.valueOf(0.0F));
- cmp.put("HandDropChances", nbttaglist2);
- }
-
- if (cmp.getCompound("ArmorDropChances").isEmpty()) {
- nbttaglist2 = new ListTag();
- nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloatOr(1, 0F)));
- nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloatOr(2, 0F)));
- nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloatOr(3, 0F)));
- nbttaglist2.add(FloatTag.valueOf(nbttaglist1.getFloatOr(4, 0F)));
- cmp.put("ArmorDropChances", nbttaglist2);
- }
-
- cmp.remove("DropChances");
- });
-
- return cmp;
- }
- }
-
- private static class DataInspectorBlockEntity implements DataInspector {
-
- private static final Map b = Maps.newHashMap();
- private static final Map c = Maps.newHashMap();
-
- DataInspectorBlockEntity() {
- }
-
- @Nullable
- private static String convertEntityId(int i, String s) {
- String key = Identifier.parse(s).toString();
- if (i < 515 && DataInspectorBlockEntity.b.containsKey(key)) {
- return DataInspectorBlockEntity.b.get(key);
- } else {
- return DataInspectorBlockEntity.c.get(key);
- }
- }
-
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- Optional nbttagcompound1Optional = cmp.getCompound("tag");
-
- if (nbttagcompound1Optional.isPresent()) {
- var nbttagcompound1 = nbttagcompound1Optional.get();
-
- nbttagcompound1.getCompound("BlockEntityTag").ifPresent(nbttagcompound2 -> {
- String s = cmp.getString("id").get();
- String s1 = convertEntityId(sourceVer, s);
- boolean flag;
-
- if (s1 == null) {
- // CraftBukkit - Remove unnecessary warning (occurs when deserializing a Shulker Box item)
- // DataInspectorBlockEntity.a.warn("Unable to resolve BlockEntity for ItemInstance: {}", s);
- flag = false;
- } else {
- flag = !nbttagcompound2.contains("id");
- nbttagcompound2.putString("id", s1);
- }
-
- convert(LegacyType.BLOCK_ENTITY, nbttagcompound2, sourceVer, targetVer);
- if (flag) {
- nbttagcompound2.remove("id");
- }
- });
- }
-
- return cmp;
- }
-
- static {
- Map map = DataInspectorBlockEntity.b;
-
- map.put("minecraft:furnace", "Furnace");
- map.put("minecraft:lit_furnace", "Furnace");
- map.put("minecraft:chest", "Chest");
- map.put("minecraft:trapped_chest", "Chest");
- map.put("minecraft:ender_chest", "EnderChest");
- map.put("minecraft:jukebox", "RecordPlayer");
- map.put("minecraft:dispenser", "Trap");
- map.put("minecraft:dropper", "Dropper");
- map.put("minecraft:sign", "Sign");
- map.put("minecraft:mob_spawner", "MobSpawner");
- map.put("minecraft:noteblock", "Music");
- map.put("minecraft:brewing_stand", "Cauldron");
- map.put("minecraft:enhanting_table", "EnchantTable");
- map.put("minecraft:command_block", "CommandBlock");
- map.put("minecraft:beacon", "Beacon");
- map.put("minecraft:skull", "Skull");
- map.put("minecraft:daylight_detector", "DLDetector");
- map.put("minecraft:hopper", "Hopper");
- map.put("minecraft:banner", "Banner");
- map.put("minecraft:flower_pot", "FlowerPot");
- map.put("minecraft:repeating_command_block", "CommandBlock");
- map.put("minecraft:chain_command_block", "CommandBlock");
- map.put("minecraft:standing_sign", "Sign");
- map.put("minecraft:wall_sign", "Sign");
- map.put("minecraft:piston_head", "Piston");
- map.put("minecraft:daylight_detector_inverted", "DLDetector");
- map.put("minecraft:unpowered_comparator", "Comparator");
- map.put("minecraft:powered_comparator", "Comparator");
- map.put("minecraft:wall_banner", "Banner");
- map.put("minecraft:standing_banner", "Banner");
- map.put("minecraft:structure_block", "Structure");
- map.put("minecraft:end_portal", "Airportal");
- map.put("minecraft:end_gateway", "EndGateway");
- map.put("minecraft:shield", "Shield");
- map = DataInspectorBlockEntity.c;
- map.put("minecraft:furnace", "minecraft:furnace");
- map.put("minecraft:lit_furnace", "minecraft:furnace");
- map.put("minecraft:chest", "minecraft:chest");
- map.put("minecraft:trapped_chest", "minecraft:chest");
- map.put("minecraft:ender_chest", "minecraft:enderchest");
- map.put("minecraft:jukebox", "minecraft:jukebox");
- map.put("minecraft:dispenser", "minecraft:dispenser");
- map.put("minecraft:dropper", "minecraft:dropper");
- map.put("minecraft:sign", "minecraft:sign");
- map.put("minecraft:mob_spawner", "minecraft:mob_spawner");
- map.put("minecraft:noteblock", "minecraft:noteblock");
- map.put("minecraft:brewing_stand", "minecraft:brewing_stand");
- map.put("minecraft:enhanting_table", "minecraft:enchanting_table");
- map.put("minecraft:command_block", "minecraft:command_block");
- map.put("minecraft:beacon", "minecraft:beacon");
- map.put("minecraft:skull", "minecraft:skull");
- map.put("minecraft:daylight_detector", "minecraft:daylight_detector");
- map.put("minecraft:hopper", "minecraft:hopper");
- map.put("minecraft:banner", "minecraft:banner");
- map.put("minecraft:flower_pot", "minecraft:flower_pot");
- map.put("minecraft:repeating_command_block", "minecraft:command_block");
- map.put("minecraft:chain_command_block", "minecraft:command_block");
- map.put("minecraft:shulker_box", "minecraft:shulker_box");
- map.put("minecraft:white_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:orange_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:magenta_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:light_blue_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:yellow_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:lime_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:pink_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:gray_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:silver_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:cyan_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:purple_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:blue_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:brown_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:green_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:red_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:black_shulker_box", "minecraft:shulker_box");
- map.put("minecraft:bed", "minecraft:bed");
- map.put("minecraft:standing_sign", "minecraft:sign");
- map.put("minecraft:wall_sign", "minecraft:sign");
- map.put("minecraft:piston_head", "minecraft:piston");
- map.put("minecraft:daylight_detector_inverted", "minecraft:daylight_detector");
- map.put("minecraft:unpowered_comparator", "minecraft:comparator");
- map.put("minecraft:powered_comparator", "minecraft:comparator");
- map.put("minecraft:wall_banner", "minecraft:banner");
- map.put("minecraft:standing_banner", "minecraft:banner");
- map.put("minecraft:structure_block", "minecraft:structure_block");
- map.put("minecraft:end_portal", "minecraft:end_portal");
- map.put("minecraft:end_gateway", "minecraft:end_gateway");
- map.put("minecraft:shield", "minecraft:shield");
- }
- }
-
- private static class DataInspectorEntity implements DataInspector {
-
- private static final Logger a = LogManager.getLogger(NeoForgeDataFixer.class);
-
- DataInspectorEntity() {
- }
-
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- cmp.getCompound("tag").flatMap(nbttagcompound1 -> nbttagcompound1.getCompound("EntityTag")).ifPresent(nbttagcompound2 -> {
- String s = cmp.getString("id").orElse(null);
- String s1;
-
- if ("minecraft:armor_stand".equals(s)) {
- s1 = sourceVer < 515 ? "ArmorStand" : "minecraft:armor_stand";
- } else {
- if (!"minecraft:spawn_egg".equals(s)) {
- return;
- }
-
- s1 = nbttagcompound2.getString("id").orElse(null);
- }
-
- boolean flag;
-
- if (s1 == null) {
- DataInspectorEntity.a.warn("Unable to resolve Entity for ItemInstance: {}", s);
- flag = false;
- } else {
- flag = nbttagcompound2.getString("id").isEmpty();
- nbttagcompound2.putString("id", s1);
- }
-
- convert(LegacyType.ENTITY, nbttagcompound2, sourceVer, targetVer);
- if (flag) {
- nbttagcompound2.remove("id");
- }
- });
-
- return cmp;
- }
- }
-
-
- private abstract static class DataInspectorTagged implements DataInspector {
-
- private final Identifier key;
-
- DataInspectorTagged(String type) {
- this.key = getKey(type);
- }
-
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- if (cmp.getString("id").isPresent() && this.key.equals(Identifier.parse(cmp.getString("id").get()))) {
- cmp = this.inspectChecked(cmp, sourceVer, targetVer);
- }
-
- return cmp;
- }
-
- abstract net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer);
- }
-
- private static class DataInspectorItemList extends DataInspectorTagged {
-
- private final String[] keys;
-
- DataInspectorItemList(String oclass, String... astring) {
- super(oclass);
- this.keys = astring;
- }
-
- net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) {
- for (String s : this.keys) {
- NeoForgeDataFixer.convertItems(nbttagcompound, s, sourceVer, targetVer);
- }
-
- return nbttagcompound;
- }
- }
-
- private static class DataInspectorItem extends DataInspectorTagged {
-
- private final String[] keys;
-
- DataInspectorItem(String oclass, String... astring) {
- super(oclass);
- this.keys = astring;
- }
-
- net.minecraft.nbt.CompoundTag inspectChecked(net.minecraft.nbt.CompoundTag nbttagcompound, int sourceVer, int targetVer) {
- for (String key : this.keys) {
- NeoForgeDataFixer.convertItem(nbttagcompound, key, sourceVer, targetVer);
- }
-
- return nbttagcompound;
- }
- }
-
- private static class DataConverterMaterialId implements DataConverter {
-
- private static final String[] materials = new String[2268];
-
- DataConverterMaterialId() {
- }
-
- public int getDataVersion() {
- return 102;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- cmp.getShort("id").ifPresent(short0 -> {
- if (short0 > 0 && short0 < materials.length && materials[short0] != null) {
- cmp.putString("id", materials[short0]);
- }
- });
-
- return cmp;
- }
-
- static {
- materials[1] = "minecraft:stone";
- materials[2] = "minecraft:grass";
- materials[3] = "minecraft:dirt";
- materials[4] = "minecraft:cobblestone";
- materials[5] = "minecraft:planks";
- materials[6] = "minecraft:sapling";
- materials[7] = "minecraft:bedrock";
- materials[8] = "minecraft:flowing_water";
- materials[9] = "minecraft:water";
- materials[10] = "minecraft:flowing_lava";
- materials[11] = "minecraft:lava";
- materials[12] = "minecraft:sand";
- materials[13] = "minecraft:gravel";
- materials[14] = "minecraft:gold_ore";
- materials[15] = "minecraft:iron_ore";
- materials[16] = "minecraft:coal_ore";
- materials[17] = "minecraft:log";
- materials[18] = "minecraft:leaves";
- materials[19] = "minecraft:sponge";
- materials[20] = "minecraft:glass";
- materials[21] = "minecraft:lapis_ore";
- materials[22] = "minecraft:lapis_block";
- materials[23] = "minecraft:dispenser";
- materials[24] = "minecraft:sandstone";
- materials[25] = "minecraft:noteblock";
- materials[27] = "minecraft:golden_rail";
- materials[28] = "minecraft:detector_rail";
- materials[29] = "minecraft:sticky_piston";
- materials[30] = "minecraft:web";
- materials[31] = "minecraft:tallgrass";
- materials[32] = "minecraft:deadbush";
- materials[33] = "minecraft:piston";
- materials[35] = "minecraft:wool";
- materials[37] = "minecraft:yellow_flower";
- materials[38] = "minecraft:red_flower";
- materials[39] = "minecraft:brown_mushroom";
- materials[40] = "minecraft:red_mushroom";
- materials[41] = "minecraft:gold_block";
- materials[42] = "minecraft:iron_block";
- materials[43] = "minecraft:double_stone_slab";
- materials[44] = "minecraft:stone_slab";
- materials[45] = "minecraft:brick_block";
- materials[46] = "minecraft:tnt";
- materials[47] = "minecraft:bookshelf";
- materials[48] = "minecraft:mossy_cobblestone";
- materials[49] = "minecraft:obsidian";
- materials[50] = "minecraft:torch";
- materials[51] = "minecraft:fire";
- materials[52] = "minecraft:mob_spawner";
- materials[53] = "minecraft:oak_stairs";
- materials[54] = "minecraft:chest";
- materials[56] = "minecraft:diamond_ore";
- materials[57] = "minecraft:diamond_block";
- materials[58] = "minecraft:crafting_table";
- materials[60] = "minecraft:farmland";
- materials[61] = "minecraft:furnace";
- materials[62] = "minecraft:lit_furnace";
- materials[65] = "minecraft:ladder";
- materials[66] = "minecraft:rail";
- materials[67] = "minecraft:stone_stairs";
- materials[69] = "minecraft:lever";
- materials[70] = "minecraft:stone_pressure_plate";
- materials[72] = "minecraft:wooden_pressure_plate";
- materials[73] = "minecraft:redstone_ore";
- materials[76] = "minecraft:redstone_torch";
- materials[77] = "minecraft:stone_button";
- materials[78] = "minecraft:snow_layer";
- materials[79] = "minecraft:ice";
- materials[80] = "minecraft:snow";
- materials[81] = "minecraft:cactus";
- materials[82] = "minecraft:clay";
- materials[84] = "minecraft:jukebox";
- materials[85] = "minecraft:fence";
- materials[86] = "minecraft:pumpkin";
- materials[87] = "minecraft:netherrack";
- materials[88] = "minecraft:soul_sand";
- materials[89] = "minecraft:glowstone";
- materials[90] = "minecraft:portal";
- materials[91] = "minecraft:lit_pumpkin";
- materials[95] = "minecraft:stained_glass";
- materials[96] = "minecraft:trapdoor";
- materials[97] = "minecraft:monster_egg";
- materials[98] = "minecraft:stonebrick";
- materials[99] = "minecraft:brown_mushroom_block";
- materials[100] = "minecraft:red_mushroom_block";
- materials[101] = "minecraft:iron_bars";
- materials[102] = "minecraft:glass_pane";
- materials[103] = "minecraft:melon_block";
- materials[106] = "minecraft:vine";
- materials[107] = "minecraft:fence_gate";
- materials[108] = "minecraft:brick_stairs";
- materials[109] = "minecraft:stone_brick_stairs";
- materials[110] = "minecraft:mycelium";
- materials[111] = "minecraft:waterlily";
- materials[112] = "minecraft:nether_brick";
- materials[113] = "minecraft:nether_brick_fence";
- materials[114] = "minecraft:nether_brick_stairs";
- materials[116] = "minecraft:enchanting_table";
- materials[119] = "minecraft:end_portal";
- materials[120] = "minecraft:end_portal_frame";
- materials[121] = "minecraft:end_stone";
- materials[122] = "minecraft:dragon_egg";
- materials[123] = "minecraft:redstone_lamp";
- materials[125] = "minecraft:double_wooden_slab";
- materials[126] = "minecraft:wooden_slab";
- materials[127] = "minecraft:cocoa";
- materials[128] = "minecraft:sandstone_stairs";
- materials[129] = "minecraft:emerald_ore";
- materials[130] = "minecraft:ender_chest";
- materials[131] = "minecraft:tripwire_hook";
- materials[133] = "minecraft:emerald_block";
- materials[134] = "minecraft:spruce_stairs";
- materials[135] = "minecraft:birch_stairs";
- materials[136] = "minecraft:jungle_stairs";
- materials[137] = "minecraft:command_block";
- materials[138] = "minecraft:beacon";
- materials[139] = "minecraft:cobblestone_wall";
- materials[141] = "minecraft:carrots";
- materials[142] = "minecraft:potatoes";
- materials[143] = "minecraft:wooden_button";
- materials[145] = "minecraft:anvil";
- materials[146] = "minecraft:trapped_chest";
- materials[147] = "minecraft:light_weighted_pressure_plate";
- materials[148] = "minecraft:heavy_weighted_pressure_plate";
- materials[151] = "minecraft:daylight_detector";
- materials[152] = "minecraft:redstone_block";
- materials[153] = "minecraft:quartz_ore";
- materials[154] = "minecraft:hopper";
- materials[155] = "minecraft:quartz_block";
- materials[156] = "minecraft:quartz_stairs";
- materials[157] = "minecraft:activator_rail";
- materials[158] = "minecraft:dropper";
- materials[159] = "minecraft:stained_hardened_clay";
- materials[160] = "minecraft:stained_glass_pane";
- materials[161] = "minecraft:leaves2";
- materials[162] = "minecraft:log2";
- materials[163] = "minecraft:acacia_stairs";
- materials[164] = "minecraft:dark_oak_stairs";
- materials[170] = "minecraft:hay_block";
- materials[171] = "minecraft:carpet";
- materials[172] = "minecraft:hardened_clay";
- materials[173] = "minecraft:coal_block";
- materials[174] = "minecraft:packed_ice";
- materials[175] = "minecraft:double_plant";
- materials[256] = "minecraft:iron_shovel";
- materials[257] = "minecraft:iron_pickaxe";
- materials[258] = "minecraft:iron_axe";
- materials[259] = "minecraft:flint_and_steel";
- materials[260] = "minecraft:apple";
- materials[261] = "minecraft:bow";
- materials[262] = "minecraft:arrow";
- materials[263] = "minecraft:coal";
- materials[264] = "minecraft:diamond";
- materials[265] = "minecraft:iron_ingot";
- materials[266] = "minecraft:gold_ingot";
- materials[267] = "minecraft:iron_sword";
- materials[268] = "minecraft:wooden_sword";
- materials[269] = "minecraft:wooden_shovel";
- materials[270] = "minecraft:wooden_pickaxe";
- materials[271] = "minecraft:wooden_axe";
- materials[272] = "minecraft:stone_sword";
- materials[273] = "minecraft:stone_shovel";
- materials[274] = "minecraft:stone_pickaxe";
- materials[275] = "minecraft:stone_axe";
- materials[276] = "minecraft:diamond_sword";
- materials[277] = "minecraft:diamond_shovel";
- materials[278] = "minecraft:diamond_pickaxe";
- materials[279] = "minecraft:diamond_axe";
- materials[280] = "minecraft:stick";
- materials[281] = "minecraft:bowl";
- materials[282] = "minecraft:mushroom_stew";
- materials[283] = "minecraft:golden_sword";
- materials[284] = "minecraft:golden_shovel";
- materials[285] = "minecraft:golden_pickaxe";
- materials[286] = "minecraft:golden_axe";
- materials[287] = "minecraft:string";
- materials[288] = "minecraft:feather";
- materials[289] = "minecraft:gunpowder";
- materials[290] = "minecraft:wooden_hoe";
- materials[291] = "minecraft:stone_hoe";
- materials[292] = "minecraft:iron_hoe";
- materials[293] = "minecraft:diamond_hoe";
- materials[294] = "minecraft:golden_hoe";
- materials[295] = "minecraft:wheat_seeds";
- materials[296] = "minecraft:wheat";
- materials[297] = "minecraft:bread";
- materials[298] = "minecraft:leather_helmet";
- materials[299] = "minecraft:leather_chestplate";
- materials[300] = "minecraft:leather_leggings";
- materials[301] = "minecraft:leather_boots";
- materials[302] = "minecraft:chainmail_helmet";
- materials[303] = "minecraft:chainmail_chestplate";
- materials[304] = "minecraft:chainmail_leggings";
- materials[305] = "minecraft:chainmail_boots";
- materials[306] = "minecraft:iron_helmet";
- materials[307] = "minecraft:iron_chestplate";
- materials[308] = "minecraft:iron_leggings";
- materials[309] = "minecraft:iron_boots";
- materials[310] = "minecraft:diamond_helmet";
- materials[311] = "minecraft:diamond_chestplate";
- materials[312] = "minecraft:diamond_leggings";
- materials[313] = "minecraft:diamond_boots";
- materials[314] = "minecraft:golden_helmet";
- materials[315] = "minecraft:golden_chestplate";
- materials[316] = "minecraft:golden_leggings";
- materials[317] = "minecraft:golden_boots";
- materials[318] = "minecraft:flint";
- materials[319] = "minecraft:porkchop";
- materials[320] = "minecraft:cooked_porkchop";
- materials[321] = "minecraft:painting";
- materials[322] = "minecraft:golden_apple";
- materials[323] = "minecraft:sign";
- materials[324] = "minecraft:wooden_door";
- materials[325] = "minecraft:bucket";
- materials[326] = "minecraft:water_bucket";
- materials[327] = "minecraft:lava_bucket";
- materials[328] = "minecraft:minecart";
- materials[329] = "minecraft:saddle";
- materials[330] = "minecraft:iron_door";
- materials[331] = "minecraft:redstone";
- materials[332] = "minecraft:snowball";
- materials[333] = "minecraft:boat";
- materials[334] = "minecraft:leather";
- materials[335] = "minecraft:milk_bucket";
- materials[336] = "minecraft:brick";
- materials[337] = "minecraft:clay_ball";
- materials[338] = "minecraft:reeds";
- materials[339] = "minecraft:paper";
- materials[340] = "minecraft:book";
- materials[341] = "minecraft:slime_ball";
- materials[342] = "minecraft:chest_minecart";
- materials[343] = "minecraft:furnace_minecart";
- materials[344] = "minecraft:egg";
- materials[345] = "minecraft:compass";
- materials[346] = "minecraft:fishing_rod";
- materials[347] = "minecraft:clock";
- materials[348] = "minecraft:glowstone_dust";
- materials[349] = "minecraft:fish";
- materials[350] = "minecraft:cooked_fish"; // Paper - cooked_fished -> cooked_fish
- materials[351] = "minecraft:dye";
- materials[352] = "minecraft:bone";
- materials[353] = "minecraft:sugar";
- materials[354] = "minecraft:cake";
- materials[355] = "minecraft:bed";
- materials[356] = "minecraft:repeater";
- materials[357] = "minecraft:cookie";
- materials[358] = "minecraft:filled_map";
- materials[359] = "minecraft:shears";
- materials[360] = "minecraft:melon";
- materials[361] = "minecraft:pumpkin_seeds";
- materials[362] = "minecraft:melon_seeds";
- materials[363] = "minecraft:beef";
- materials[364] = "minecraft:cooked_beef";
- materials[365] = "minecraft:chicken";
- materials[366] = "minecraft:cooked_chicken";
- materials[367] = "minecraft:rotten_flesh";
- materials[368] = "minecraft:ender_pearl";
- materials[369] = "minecraft:blaze_rod";
- materials[370] = "minecraft:ghast_tear";
- materials[371] = "minecraft:gold_nugget";
- materials[372] = "minecraft:nether_wart";
- materials[373] = "minecraft:potion";
- materials[374] = "minecraft:glass_bottle";
- materials[375] = "minecraft:spider_eye";
- materials[376] = "minecraft:fermented_spider_eye";
- materials[377] = "minecraft:blaze_powder";
- materials[378] = "minecraft:magma_cream";
- materials[379] = "minecraft:brewing_stand";
- materials[380] = "minecraft:cauldron";
- materials[381] = "minecraft:ender_eye";
- materials[382] = "minecraft:speckled_melon";
- materials[383] = "minecraft:spawn_egg";
- materials[384] = "minecraft:experience_bottle";
- materials[385] = "minecraft:fire_charge";
- materials[386] = "minecraft:writable_book";
- materials[387] = "minecraft:written_book";
- materials[388] = "minecraft:emerald";
- materials[389] = "minecraft:item_frame";
- materials[390] = "minecraft:flower_pot";
- materials[391] = "minecraft:carrot";
- materials[392] = "minecraft:potato";
- materials[393] = "minecraft:baked_potato";
- materials[394] = "minecraft:poisonous_potato";
- materials[395] = "minecraft:map";
- materials[396] = "minecraft:golden_carrot";
- materials[397] = "minecraft:skull";
- materials[398] = "minecraft:carrot_on_a_stick";
- materials[399] = "minecraft:nether_star";
- materials[400] = "minecraft:pumpkin_pie";
- materials[401] = "minecraft:fireworks";
- materials[402] = "minecraft:firework_charge";
- materials[403] = "minecraft:enchanted_book";
- materials[404] = "minecraft:comparator";
- materials[405] = "minecraft:netherbrick";
- materials[406] = "minecraft:quartz";
- materials[407] = "minecraft:tnt_minecart";
- materials[408] = "minecraft:hopper_minecart";
- materials[417] = "minecraft:iron_horse_armor";
- materials[418] = "minecraft:golden_horse_armor";
- materials[419] = "minecraft:diamond_horse_armor";
- materials[420] = "minecraft:lead";
- materials[421] = "minecraft:name_tag";
- materials[422] = "minecraft:command_block_minecart";
- materials[2256] = "minecraft:record_13";
- materials[2257] = "minecraft:record_cat";
- materials[2258] = "minecraft:record_blocks";
- materials[2259] = "minecraft:record_chirp";
- materials[2260] = "minecraft:record_far";
- materials[2261] = "minecraft:record_mall";
- materials[2262] = "minecraft:record_mellohi";
- materials[2263] = "minecraft:record_stal";
- materials[2264] = "minecraft:record_strad";
- materials[2265] = "minecraft:record_ward";
- materials[2266] = "minecraft:record_11";
- materials[2267] = "minecraft:record_wait";
- }
- }
-
- private static class DataConverterArmorStand implements DataConverter {
-
- DataConverterArmorStand() {
- }
-
- public int getDataVersion() {
- return 147;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("ArmorStand".equals(cmp.getString("id").orElse(null)) && cmp.getBoolean("Silent").orElse(false) && !cmp.getBoolean("Marker").orElse(false)) {
- cmp.remove("Silent");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterBanner implements DataConverter {
-
- DataConverterBanner() {
- }
-
- public int getDataVersion() {
- return 804;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:banner".equals(cmp.getString("id").orElse(null))) {
- cmp.getCompound("tag").ifPresent(nbttagcompound1 -> nbttagcompound1.getCompound("BlockEntityTag").ifPresent(nbttagcompound2 -> {
- if (nbttagcompound2.getShort("Base").isPresent()) {
- cmp.putShort("Damage", (short) (nbttagcompound2.getShort("Base").get() & 15));
- if (nbttagcompound1.getCompound("display").isPresent()) {
- CompoundTag nbttagcompound3 = nbttagcompound1.getCompound("display").get();
-
- if (nbttagcompound3.getList("Lore").isPresent()) {
- ListTag nbttaglist = nbttagcompound3.getList("Lore").get();
-
- if (nbttaglist.size() == 1 && "(+NBT)".equals(nbttaglist.getString(0).orElse(null))) {
- return;
- }
- }
- }
-
- nbttagcompound2.remove("Base");
- if (nbttagcompound2.isEmpty()) {
- nbttagcompound1.remove("BlockEntityTag");
- }
-
- if (nbttagcompound1.isEmpty()) {
- cmp.remove("tag");
- }
- }
- }));
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterPotionId implements DataConverter {
-
- private static final String[] potions = new String[128];
-
- DataConverterPotionId() {
- }
-
- public int getDataVersion() {
- return 102;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:potion".equals(cmp.getString("id").orElse(null))) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompoundOrEmpty("tag");
- short short0 = cmp.getShortOr("Damage", (short) 0);
-
- if (nbttagcompound1.getString("Potion").isEmpty()) {
- String s = DataConverterPotionId.potions[short0 & 127];
-
- nbttagcompound1.putString("Potion", s == null ? "minecraft:water" : s);
- cmp.put("tag", nbttagcompound1);
- if ((short0 & 16384) == 16384) {
- cmp.putString("id", "minecraft:splash_potion");
- }
- }
-
- if (short0 != 0) {
- cmp.putShort("Damage", (short) 0);
- }
- }
-
- return cmp;
- }
-
- static {
- DataConverterPotionId.potions[0] = "minecraft:water";
- DataConverterPotionId.potions[1] = "minecraft:regeneration";
- DataConverterPotionId.potions[2] = "minecraft:swiftness";
- DataConverterPotionId.potions[3] = "minecraft:fire_resistance";
- DataConverterPotionId.potions[4] = "minecraft:poison";
- DataConverterPotionId.potions[5] = "minecraft:healing";
- DataConverterPotionId.potions[6] = "minecraft:night_vision";
- DataConverterPotionId.potions[7] = null;
- DataConverterPotionId.potions[8] = "minecraft:weakness";
- DataConverterPotionId.potions[9] = "minecraft:strength";
- DataConverterPotionId.potions[10] = "minecraft:slowness";
- DataConverterPotionId.potions[11] = "minecraft:leaping";
- DataConverterPotionId.potions[12] = "minecraft:harming";
- DataConverterPotionId.potions[13] = "minecraft:water_breathing";
- DataConverterPotionId.potions[14] = "minecraft:invisibility";
- DataConverterPotionId.potions[15] = null;
- DataConverterPotionId.potions[16] = "minecraft:awkward";
- DataConverterPotionId.potions[17] = "minecraft:regeneration";
- DataConverterPotionId.potions[18] = "minecraft:swiftness";
- DataConverterPotionId.potions[19] = "minecraft:fire_resistance";
- DataConverterPotionId.potions[20] = "minecraft:poison";
- DataConverterPotionId.potions[21] = "minecraft:healing";
- DataConverterPotionId.potions[22] = "minecraft:night_vision";
- DataConverterPotionId.potions[23] = null;
- DataConverterPotionId.potions[24] = "minecraft:weakness";
- DataConverterPotionId.potions[25] = "minecraft:strength";
- DataConverterPotionId.potions[26] = "minecraft:slowness";
- DataConverterPotionId.potions[27] = "minecraft:leaping";
- DataConverterPotionId.potions[28] = "minecraft:harming";
- DataConverterPotionId.potions[29] = "minecraft:water_breathing";
- DataConverterPotionId.potions[30] = "minecraft:invisibility";
- DataConverterPotionId.potions[31] = null;
- DataConverterPotionId.potions[32] = "minecraft:thick";
- DataConverterPotionId.potions[33] = "minecraft:strong_regeneration";
- DataConverterPotionId.potions[34] = "minecraft:strong_swiftness";
- DataConverterPotionId.potions[35] = "minecraft:fire_resistance";
- DataConverterPotionId.potions[36] = "minecraft:strong_poison";
- DataConverterPotionId.potions[37] = "minecraft:strong_healing";
- DataConverterPotionId.potions[38] = "minecraft:night_vision";
- DataConverterPotionId.potions[39] = null;
- DataConverterPotionId.potions[40] = "minecraft:weakness";
- DataConverterPotionId.potions[41] = "minecraft:strong_strength";
- DataConverterPotionId.potions[42] = "minecraft:slowness";
- DataConverterPotionId.potions[43] = "minecraft:strong_leaping";
- DataConverterPotionId.potions[44] = "minecraft:strong_harming";
- DataConverterPotionId.potions[45] = "minecraft:water_breathing";
- DataConverterPotionId.potions[46] = "minecraft:invisibility";
- DataConverterPotionId.potions[47] = null;
- DataConverterPotionId.potions[48] = null;
- DataConverterPotionId.potions[49] = "minecraft:strong_regeneration";
- DataConverterPotionId.potions[50] = "minecraft:strong_swiftness";
- DataConverterPotionId.potions[51] = "minecraft:fire_resistance";
- DataConverterPotionId.potions[52] = "minecraft:strong_poison";
- DataConverterPotionId.potions[53] = "minecraft:strong_healing";
- DataConverterPotionId.potions[54] = "minecraft:night_vision";
- DataConverterPotionId.potions[55] = null;
- DataConverterPotionId.potions[56] = "minecraft:weakness";
- DataConverterPotionId.potions[57] = "minecraft:strong_strength";
- DataConverterPotionId.potions[58] = "minecraft:slowness";
- DataConverterPotionId.potions[59] = "minecraft:strong_leaping";
- DataConverterPotionId.potions[60] = "minecraft:strong_harming";
- DataConverterPotionId.potions[61] = "minecraft:water_breathing";
- DataConverterPotionId.potions[62] = "minecraft:invisibility";
- DataConverterPotionId.potions[63] = null;
- DataConverterPotionId.potions[64] = "minecraft:mundane";
- DataConverterPotionId.potions[65] = "minecraft:long_regeneration";
- DataConverterPotionId.potions[66] = "minecraft:long_swiftness";
- DataConverterPotionId.potions[67] = "minecraft:long_fire_resistance";
- DataConverterPotionId.potions[68] = "minecraft:long_poison";
- DataConverterPotionId.potions[69] = "minecraft:healing";
- DataConverterPotionId.potions[70] = "minecraft:long_night_vision";
- DataConverterPotionId.potions[71] = null;
- DataConverterPotionId.potions[72] = "minecraft:long_weakness";
- DataConverterPotionId.potions[73] = "minecraft:long_strength";
- DataConverterPotionId.potions[74] = "minecraft:long_slowness";
- DataConverterPotionId.potions[75] = "minecraft:long_leaping";
- DataConverterPotionId.potions[76] = "minecraft:harming";
- DataConverterPotionId.potions[77] = "minecraft:long_water_breathing";
- DataConverterPotionId.potions[78] = "minecraft:long_invisibility";
- DataConverterPotionId.potions[79] = null;
- DataConverterPotionId.potions[80] = "minecraft:awkward";
- DataConverterPotionId.potions[81] = "minecraft:long_regeneration";
- DataConverterPotionId.potions[82] = "minecraft:long_swiftness";
- DataConverterPotionId.potions[83] = "minecraft:long_fire_resistance";
- DataConverterPotionId.potions[84] = "minecraft:long_poison";
- DataConverterPotionId.potions[85] = "minecraft:healing";
- DataConverterPotionId.potions[86] = "minecraft:long_night_vision";
- DataConverterPotionId.potions[87] = null;
- DataConverterPotionId.potions[88] = "minecraft:long_weakness";
- DataConverterPotionId.potions[89] = "minecraft:long_strength";
- DataConverterPotionId.potions[90] = "minecraft:long_slowness";
- DataConverterPotionId.potions[91] = "minecraft:long_leaping";
- DataConverterPotionId.potions[92] = "minecraft:harming";
- DataConverterPotionId.potions[93] = "minecraft:long_water_breathing";
- DataConverterPotionId.potions[94] = "minecraft:long_invisibility";
- DataConverterPotionId.potions[95] = null;
- DataConverterPotionId.potions[96] = "minecraft:thick";
- DataConverterPotionId.potions[97] = "minecraft:regeneration";
- DataConverterPotionId.potions[98] = "minecraft:swiftness";
- DataConverterPotionId.potions[99] = "minecraft:long_fire_resistance";
- DataConverterPotionId.potions[100] = "minecraft:poison";
- DataConverterPotionId.potions[101] = "minecraft:strong_healing";
- DataConverterPotionId.potions[102] = "minecraft:long_night_vision";
- DataConverterPotionId.potions[103] = null;
- DataConverterPotionId.potions[104] = "minecraft:long_weakness";
- DataConverterPotionId.potions[105] = "minecraft:strength";
- DataConverterPotionId.potions[106] = "minecraft:long_slowness";
- DataConverterPotionId.potions[107] = "minecraft:leaping";
- DataConverterPotionId.potions[108] = "minecraft:strong_harming";
- DataConverterPotionId.potions[109] = "minecraft:long_water_breathing";
- DataConverterPotionId.potions[110] = "minecraft:long_invisibility";
- DataConverterPotionId.potions[111] = null;
- DataConverterPotionId.potions[112] = null;
- DataConverterPotionId.potions[113] = "minecraft:regeneration";
- DataConverterPotionId.potions[114] = "minecraft:swiftness";
- DataConverterPotionId.potions[115] = "minecraft:long_fire_resistance";
- DataConverterPotionId.potions[116] = "minecraft:poison";
- DataConverterPotionId.potions[117] = "minecraft:strong_healing";
- DataConverterPotionId.potions[118] = "minecraft:long_night_vision";
- DataConverterPotionId.potions[119] = null;
- DataConverterPotionId.potions[120] = "minecraft:long_weakness";
- DataConverterPotionId.potions[121] = "minecraft:strength";
- DataConverterPotionId.potions[122] = "minecraft:long_slowness";
- DataConverterPotionId.potions[123] = "minecraft:leaping";
- DataConverterPotionId.potions[124] = "minecraft:strong_harming";
- DataConverterPotionId.potions[125] = "minecraft:long_water_breathing";
- DataConverterPotionId.potions[126] = "minecraft:long_invisibility";
- DataConverterPotionId.potions[127] = null;
- }
- }
-
- private static class DataConverterSpawnEgg implements DataConverter {
-
- private static final String[] eggs = new String[256];
-
- DataConverterSpawnEgg() {
- }
-
- public int getDataVersion() {
- return 105;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:spawn_egg".equals(cmp.getString("id").orElse(null))) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompoundOrEmpty("tag");
- net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttagcompound1.getCompoundOrEmpty("EntityTag");
- short short0 = cmp.getShortOr("Damage", (short) 0);
-
- if (nbttagcompound2.getString("id").isEmpty()) {
- String s = DataConverterSpawnEgg.eggs[short0 & 255];
-
- if (s != null) {
- nbttagcompound2.putString("id", s);
- nbttagcompound1.put("EntityTag", nbttagcompound2);
- cmp.put("tag", nbttagcompound1);
- }
- }
-
- if (short0 != 0) {
- cmp.putShort("Damage", (short) 0);
- }
- }
-
- return cmp;
- }
-
- static {
-
- DataConverterSpawnEgg.eggs[1] = "Item";
- DataConverterSpawnEgg.eggs[2] = "XPOrb";
- DataConverterSpawnEgg.eggs[7] = "ThrownEgg";
- DataConverterSpawnEgg.eggs[8] = "LeashKnot";
- DataConverterSpawnEgg.eggs[9] = "Painting";
- DataConverterSpawnEgg.eggs[10] = "Arrow";
- DataConverterSpawnEgg.eggs[11] = "Snowball";
- DataConverterSpawnEgg.eggs[12] = "Fireball";
- DataConverterSpawnEgg.eggs[13] = "SmallFireball";
- DataConverterSpawnEgg.eggs[14] = "ThrownEnderpearl";
- DataConverterSpawnEgg.eggs[15] = "EyeOfEnderSignal";
- DataConverterSpawnEgg.eggs[16] = "ThrownPotion";
- DataConverterSpawnEgg.eggs[17] = "ThrownExpBottle";
- DataConverterSpawnEgg.eggs[18] = "ItemFrame";
- DataConverterSpawnEgg.eggs[19] = "WitherSkull";
- DataConverterSpawnEgg.eggs[20] = "PrimedTnt";
- DataConverterSpawnEgg.eggs[21] = "FallingSand";
- DataConverterSpawnEgg.eggs[22] = "FireworksRocketEntity";
- DataConverterSpawnEgg.eggs[23] = "TippedArrow";
- DataConverterSpawnEgg.eggs[24] = "SpectralArrow";
- DataConverterSpawnEgg.eggs[25] = "ShulkerBullet";
- DataConverterSpawnEgg.eggs[26] = "DragonFireball";
- DataConverterSpawnEgg.eggs[30] = "ArmorStand";
- DataConverterSpawnEgg.eggs[41] = "Boat";
- DataConverterSpawnEgg.eggs[42] = "MinecartRideable";
- DataConverterSpawnEgg.eggs[43] = "MinecartChest";
- DataConverterSpawnEgg.eggs[44] = "MinecartFurnace";
- DataConverterSpawnEgg.eggs[45] = "MinecartTNT";
- DataConverterSpawnEgg.eggs[46] = "MinecartHopper";
- DataConverterSpawnEgg.eggs[47] = "MinecartSpawner";
- DataConverterSpawnEgg.eggs[40] = "MinecartCommandBlock";
- DataConverterSpawnEgg.eggs[48] = "Mob";
- DataConverterSpawnEgg.eggs[49] = "Monster";
- DataConverterSpawnEgg.eggs[50] = "Creeper";
- DataConverterSpawnEgg.eggs[51] = "Skeleton";
- DataConverterSpawnEgg.eggs[52] = "Spider";
- DataConverterSpawnEgg.eggs[53] = "Giant";
- DataConverterSpawnEgg.eggs[54] = "Zombie";
- DataConverterSpawnEgg.eggs[55] = "Slime";
- DataConverterSpawnEgg.eggs[56] = "Ghast";
- DataConverterSpawnEgg.eggs[57] = "PigZombie";
- DataConverterSpawnEgg.eggs[58] = "Enderman";
- DataConverterSpawnEgg.eggs[59] = "CaveSpider";
- DataConverterSpawnEgg.eggs[60] = "Silverfish";
- DataConverterSpawnEgg.eggs[61] = "Blaze";
- DataConverterSpawnEgg.eggs[62] = "LavaSlime";
- DataConverterSpawnEgg.eggs[63] = "EnderDragon";
- DataConverterSpawnEgg.eggs[64] = "WitherBoss";
- DataConverterSpawnEgg.eggs[65] = "Bat";
- DataConverterSpawnEgg.eggs[66] = "Witch";
- DataConverterSpawnEgg.eggs[67] = "Endermite";
- DataConverterSpawnEgg.eggs[68] = "Guardian";
- DataConverterSpawnEgg.eggs[69] = "Shulker";
- DataConverterSpawnEgg.eggs[90] = "Pig";
- DataConverterSpawnEgg.eggs[91] = "Sheep";
- DataConverterSpawnEgg.eggs[92] = "Cow";
- DataConverterSpawnEgg.eggs[93] = "Chicken";
- DataConverterSpawnEgg.eggs[94] = "Squid";
- DataConverterSpawnEgg.eggs[95] = "Wolf";
- DataConverterSpawnEgg.eggs[96] = "MushroomCow";
- DataConverterSpawnEgg.eggs[97] = "SnowMan";
- DataConverterSpawnEgg.eggs[98] = "Ozelot";
- DataConverterSpawnEgg.eggs[99] = "VillagerGolem";
- DataConverterSpawnEgg.eggs[100] = "EntityHorse";
- DataConverterSpawnEgg.eggs[101] = "Rabbit";
- DataConverterSpawnEgg.eggs[120] = "Villager";
- DataConverterSpawnEgg.eggs[200] = "EnderCrystal";
- }
- }
-
- private static class DataConverterMinecart implements DataConverter {
-
- private static final List a = List.of("MinecartRideable", "MinecartChest", "MinecartFurnace", "MinecartTNT", "MinecartSpawner", "MinecartHopper", "MinecartCommandBlock");
-
- DataConverterMinecart() {
- }
-
- public int getDataVersion() {
- return 106;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("Minecart".equals(cmp.getString("id").orElse(null))) {
- String s = "MinecartRideable";
- int i = cmp.getIntOr("Type", 0);
-
- if (i > 0 && i < DataConverterMinecart.a.size()) {
- s = DataConverterMinecart.a.get(i);
- }
-
- cmp.putString("id", s);
- cmp.remove("Type");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterMobSpawner implements DataConverter {
-
- DataConverterMobSpawner() {
- }
-
- public int getDataVersion() {
- return 107;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("MobSpawner".equals(cmp.getString("id").orElse(null))) {
- cmp.getString("EntityId").ifPresent(s -> {
- CompoundTag nbttagcompound1 = cmp.getCompoundOrEmpty("SpawnData");
-
- nbttagcompound1.putString("id", s.isEmpty() ? "Pig" : s);
- cmp.put("SpawnData", nbttagcompound1);
- cmp.remove("EntityId");
- });
-
- cmp.getList("SpawnPotentials").ifPresent(nbttaglist -> {
- for (int i = 0; i < nbttaglist.size(); ++i) {
- CompoundTag nbttagcompound2 = nbttaglist.getCompoundOrEmpty(i);
-
- if (nbttagcompound2.getString("Type").isPresent()) {
- CompoundTag nbttagcompound3 = nbttagcompound2.getCompoundOrEmpty("Properties");
-
- nbttagcompound3.putString("id", nbttagcompound2.getString("Type").get());
- nbttagcompound2.put("Entity", nbttagcompound3);
- nbttagcompound2.remove("Type");
- nbttagcompound2.remove("Properties");
- }
- }
- });
-
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterUUID implements DataConverter {
-
- DataConverterUUID() {
- }
-
- public int getDataVersion() {
- return 108;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- cmp.getString("UUID").ifPresent(uuid -> {
- cmp.putIntArray("UUID", UUIDUtil.uuidToIntArray(UUID.fromString(uuid)));
- });
-
- return cmp;
- }
- }
-
- private static class DataConverterHealth implements DataConverter {
-
- private static final Set a = Sets.newHashSet("ArmorStand", "Bat", "Blaze", "CaveSpider", "Chicken", "Cow", "Creeper", "EnderDragon", "Enderman", "Endermite", "EntityHorse", "Ghast", "Giant", "Guardian", "LavaSlime", "MushroomCow", "Ozelot", "Pig", "PigZombie", "Rabbit", "Sheep", "Shulker", "Silverfish", "Skeleton", "Slime", "SnowMan", "Spider", "Squid", "Villager", "VillagerGolem", "Witch", "WitherBoss", "Wolf", "Zombie");
-
- DataConverterHealth() {
- }
-
- public int getDataVersion() {
- return 109;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if (DataConverterHealth.a.contains(cmp.getString("id").orElse(null))) {
- float f;
-
- if (cmp.getFloat("HealF").isPresent()) {
- f = cmp.getFloat("HealF").get();
- cmp.remove("HealF");
- } else {
- if (cmp.getFloat("Health").isEmpty()) {
- return cmp;
- }
-
- f = cmp.getFloat("Health").get();
- }
-
- cmp.putFloat("Health", f);
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterSaddle implements DataConverter {
-
- DataConverterSaddle() {
- }
-
- public int getDataVersion() {
- return 110;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("EntityHorse".equals(cmp.getString("id").orElse(null)) && cmp.getCompound("SaddleItem").isEmpty() && cmp.getBoolean("Saddle").orElse(false)) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = new net.minecraft.nbt.CompoundTag();
-
- nbttagcompound1.putString("id", "minecraft:saddle");
- nbttagcompound1.putByte("Count", (byte) 1);
- nbttagcompound1.putShort("Damage", (short) 0);
- cmp.put("SaddleItem", nbttagcompound1);
- cmp.remove("Saddle");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterHanging implements DataConverter {
-
- DataConverterHanging() {
- }
-
- public int getDataVersion() {
- return 111;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- String s = cmp.getString("id").orElse(null);
- boolean flag = "Painting".equals(s);
- boolean flag1 = "ItemFrame".equals(s);
-
- if ((flag || flag1) && cmp.getByte("Facing").isEmpty()) {
- Direction enumdirection;
-
- if (cmp.getByte("Direction").isPresent()) {
- enumdirection = Direction.from2DDataValue(cmp.getByte("Direction").get());
- cmp.putInt("TileX", cmp.getIntOr("TileX", 0) + enumdirection.getStepX());
- cmp.putInt("TileY", cmp.getIntOr("TileY", 0) + enumdirection.getStepY());
- cmp.putInt("TileZ", cmp.getIntOr("TileZ", 0) + enumdirection.getStepZ());
- cmp.remove("Direction");
- if (flag1 && cmp.getByte("ItemRotation").isPresent()) {
- cmp.putByte("ItemRotation", (byte) (cmp.getByte("ItemRotation").get() * 2));
- }
- } else {
- enumdirection = Direction.from2DDataValue(cmp.getByte("Dir").get());
- cmp.remove("Dir");
- }
-
- cmp.putByte("Facing", (byte) enumdirection.get2DDataValue());
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterDropChances implements DataConverter {
-
- DataConverterDropChances() {
- }
-
- public int getDataVersion() {
- return 113;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- cmp.getList("HandDropChances").ifPresent(nbttaglist -> {
- if (nbttaglist.size() == 2 && nbttaglist.getFloatOr(0, 0.0F) == 0.0F && nbttaglist.getFloatOr(1, 0.0F) == 0.0F) {
- cmp.remove("HandDropChances");
- }
- });
-
- cmp.getList("ArmorDropChances").ifPresent(nbttaglist -> {
- if (nbttaglist.size() == 4 && nbttaglist.getFloatOr(0, 0.0F) == 0.0F && nbttaglist.getFloatOr(1, 0.0F) == 0.0F && nbttaglist.getFloatOr(2, 0.0F) == 0.0F && nbttaglist.getFloatOr(3, 0.0F) == 0.0F) {
- cmp.remove("ArmorDropChances");
- }
- });
-
- return cmp;
- }
- }
-
- private static class DataConverterRiding implements DataConverter {
-
- DataConverterRiding() {
- }
-
- public int getDataVersion() {
- return 135;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- while (cmp.getCompound("Riding").isPresent()) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = this.b(cmp);
-
- this.convert(cmp, nbttagcompound1);
- cmp = nbttagcompound1;
- }
-
- return cmp;
- }
-
- protected void convert(net.minecraft.nbt.CompoundTag nbttagcompound, net.minecraft.nbt.CompoundTag nbttagcompound1) {
- ListTag nbttaglist = new ListTag();
-
- nbttaglist.add(nbttagcompound);
- nbttagcompound1.put("Passengers", nbttaglist);
- }
-
- protected net.minecraft.nbt.CompoundTag b(net.minecraft.nbt.CompoundTag nbttagcompound) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttagcompound.getCompoundOrEmpty("Riding");
-
- nbttagcompound.remove("Riding");
- return nbttagcompound1;
- }
- }
-
- private static class DataConverterBook implements DataConverter {
-
- DataConverterBook() {
- }
-
- public int getDataVersion() {
- return 165;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:written_book".equals(cmp.getString("id").orElse(null))) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompoundOrEmpty("tag");
-
- nbttagcompound1.getList("pages").ifPresent(nbttaglist -> {
- for (int i = 0; i < nbttaglist.size(); ++i) {
- String s = nbttaglist.getString(i).orElse(null);
- Object object = null;
-
- if (!"null".equals(s) && !Strings.isNullOrEmpty(s)) {
- if ((s.charAt(0) != 34 || s.charAt(s.length() - 1) != 34) && (s.charAt(0) != 123 || s.charAt(s.length() - 1) != 125)) {
- object = Component.literal(s);
- } else {
- try {
- object = GsonHelper.fromJson(DataConverterSignText.a, s, Component.class);
- if (object == null) {
- object = Component.literal("");
- }
- } catch (JsonParseException jsonparseexception) {
- ;
- }
-
- if (object == null) {
- try {
- object = ComponentConverter.Serializer.fromJson(s, ServerLifecycleHooks.getCurrentServer().registryAccess());
- } catch (JsonParseException jsonparseexception1) {
- ;
- }
- }
-
- if (object == null) {
- try {
- object = ComponentConverter.Serializer.fromJsonLenient(s, ServerLifecycleHooks.getCurrentServer().registryAccess());
- } catch (JsonParseException jsonparseexception2) {
- ;
- }
- }
-
- if (object == null) {
- object = Component.literal(s);
- }
- }
- } else {
- object = Component.literal("");
- }
-
- nbttaglist.set(i, StringTag.valueOf(ComponentConverter.Serializer.toJson((Component) object, ServerLifecycleHooks.getCurrentServer().registryAccess())));
- }
-
- nbttagcompound1.put("pages", nbttaglist);
- });
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterCookedFish implements DataConverter {
-
- private static final Identifier a = Identifier.parse("cooked_fished");
-
- DataConverterCookedFish() {
- }
-
- public int getDataVersion() {
- return 502;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if (cmp.getString("id").isPresent() && DataConverterCookedFish.a.equals(Identifier.parse(cmp.getString("id").get()))) {
- cmp.putString("id", "minecraft:cooked_fish");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterZombie implements DataConverter {
-
- private static final Random a = new Random();
-
- DataConverterZombie() {
- }
-
- public int getDataVersion() {
- return 502;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("Zombie".equals(cmp.getString("id").orElse(null)) && cmp.getBoolean("IsVillager").orElse(false)) {
- if (!cmp.contains("ZombieType")) {
- int i = -1;
-
- i = cmp.getInt("VillagerProfession").flatMap(profession -> {
- try {
- return Optional.of(this.convert(profession));
- } catch (RuntimeException runtimeexception) {
- return Optional.empty();
- }
- }).orElse(i);
-
- if (i == -1) {
- i = this.convert(DataConverterZombie.a.nextInt(6));
- }
-
- cmp.putInt("ZombieType", i);
- }
-
- cmp.remove("IsVillager");
- }
-
- return cmp;
- }
-
- private int convert(int i) {
- return i >= 0 && i < 6 ? i : -1;
- }
- }
-
- private static class DataConverterVBO implements DataConverter {
-
- DataConverterVBO() {
- }
-
- public int getDataVersion() {
- return 505;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- cmp.putString("useVbo", "true");
- return cmp;
- }
- }
-
- private static class DataConverterGuardian implements DataConverter {
-
- DataConverterGuardian() {
- }
-
- public int getDataVersion() {
- return 700;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("Guardian".equals(cmp.getString("id").orElse(null))) {
- if (cmp.getBoolean("Elder").orElse(false)) {
- cmp.putString("id", "ElderGuardian");
- }
-
- cmp.remove("Elder");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterSkeleton implements DataConverter {
-
- DataConverterSkeleton() {
- }
-
- public int getDataVersion() {
- return 701;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- String s = cmp.getString("id").orElse(null);
-
- if ("Skeleton".equals(s)) {
- int i = cmp.getIntOr("SkeletonType", 0);
-
- if (i == 1) {
- cmp.putString("id", "WitherSkeleton");
- } else if (i == 2) {
- cmp.putString("id", "Stray");
- }
-
- cmp.remove("SkeletonType");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterZombieType implements DataConverter {
-
- DataConverterZombieType() {
- }
-
- public int getDataVersion() {
- return 702;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("Zombie".equals(cmp.getString("id").orElse(null))) {
- int i = cmp.getIntOr("ZombieType", 0);
-
- switch (i) {
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- cmp.putString("id", "ZombieVillager");
- cmp.putInt("Profession", i - 1);
- break;
- case 6:
- cmp.putString("id", "Husk");
- case 0:
- default:
- break;
- }
-
- cmp.remove("ZombieType");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterHorse implements DataConverter {
-
- DataConverterHorse() {
- }
-
- public int getDataVersion() {
- return 703;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("EntityHorse".equals(cmp.getString("id").orElse(null))) {
- int i = cmp.getIntOr("Type", 0);
-
- switch (i) {
- case 1:
- cmp.putString("id", "Donkey");
- break;
-
- case 2:
- cmp.putString("id", "Mule");
- break;
-
- case 3:
- cmp.putString("id", "ZombieHorse");
- break;
-
- case 4:
- cmp.putString("id", "SkeletonHorse");
- break;
-
- case 0:
- default:
- cmp.putString("id", "Horse");
- break;
- }
-
- cmp.remove("Type");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterTileEntity implements DataConverter {
-
- private static final Map a = Maps.newHashMap();
-
- DataConverterTileEntity() {
- }
-
- public int getDataVersion() {
- return 704;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- String s = DataConverterTileEntity.a.get(cmp.getString("id").orElse(null));
-
- if (s != null) {
- cmp.putString("id", s);
- }
-
- return cmp;
- }
-
- static {
- DataConverterTileEntity.a.put("Airportal", "minecraft:end_portal");
- DataConverterTileEntity.a.put("Banner", "minecraft:banner");
- DataConverterTileEntity.a.put("Beacon", "minecraft:beacon");
- DataConverterTileEntity.a.put("Cauldron", "minecraft:brewing_stand");
- DataConverterTileEntity.a.put("Chest", "minecraft:chest");
- DataConverterTileEntity.a.put("Comparator", "minecraft:comparator");
- DataConverterTileEntity.a.put("Control", "minecraft:command_block");
- DataConverterTileEntity.a.put("DLDetector", "minecraft:daylight_detector");
- DataConverterTileEntity.a.put("Dropper", "minecraft:dropper");
- DataConverterTileEntity.a.put("EnchantTable", "minecraft:enchanting_table");
- DataConverterTileEntity.a.put("EndGateway", "minecraft:end_gateway");
- DataConverterTileEntity.a.put("EnderChest", "minecraft:ender_chest");
- DataConverterTileEntity.a.put("FlowerPot", "minecraft:flower_pot");
- DataConverterTileEntity.a.put("Furnace", "minecraft:furnace");
- DataConverterTileEntity.a.put("Hopper", "minecraft:hopper");
- DataConverterTileEntity.a.put("MobSpawner", "minecraft:mob_spawner");
- DataConverterTileEntity.a.put("Music", "minecraft:noteblock");
- DataConverterTileEntity.a.put("Piston", "minecraft:piston");
- DataConverterTileEntity.a.put("RecordPlayer", "minecraft:jukebox");
- DataConverterTileEntity.a.put("Sign", "minecraft:sign");
- DataConverterTileEntity.a.put("Skull", "minecraft:skull");
- DataConverterTileEntity.a.put("Structure", "minecraft:structure_block");
- DataConverterTileEntity.a.put("Trap", "minecraft:dispenser");
- }
- }
-
- private static class DataConverterEntity implements DataConverter {
-
- private static final Map a = Maps.newHashMap();
-
- DataConverterEntity() {
- }
-
- public int getDataVersion() {
- return 704;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- String s = DataConverterEntity.a.get(cmp.getString("id").orElse(null));
-
- if (s != null) {
- cmp.putString("id", s);
- }
-
- return cmp;
- }
-
- static {
- DataConverterEntity.a.put("AreaEffectCloud", "minecraft:area_effect_cloud");
- DataConverterEntity.a.put("ArmorStand", "minecraft:armor_stand");
- DataConverterEntity.a.put("Arrow", "minecraft:arrow");
- DataConverterEntity.a.put("Bat", "minecraft:bat");
- DataConverterEntity.a.put("Blaze", "minecraft:blaze");
- DataConverterEntity.a.put("Boat", "minecraft:boat");
- DataConverterEntity.a.put("CaveSpider", "minecraft:cave_spider");
- DataConverterEntity.a.put("Chicken", "minecraft:chicken");
- DataConverterEntity.a.put("Cow", "minecraft:cow");
- DataConverterEntity.a.put("Creeper", "minecraft:creeper");
- DataConverterEntity.a.put("Donkey", "minecraft:donkey");
- DataConverterEntity.a.put("DragonFireball", "minecraft:dragon_fireball");
- DataConverterEntity.a.put("ElderGuardian", "minecraft:elder_guardian");
- DataConverterEntity.a.put("EnderCrystal", "minecraft:ender_crystal");
- DataConverterEntity.a.put("EnderDragon", "minecraft:ender_dragon");
- DataConverterEntity.a.put("Enderman", "minecraft:enderman");
- DataConverterEntity.a.put("Endermite", "minecraft:endermite");
- DataConverterEntity.a.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal");
- DataConverterEntity.a.put("FallingSand", "minecraft:falling_block");
- DataConverterEntity.a.put("Fireball", "minecraft:fireball");
- DataConverterEntity.a.put("FireworksRocketEntity", "minecraft:fireworks_rocket");
- DataConverterEntity.a.put("Ghast", "minecraft:ghast");
- DataConverterEntity.a.put("Giant", "minecraft:giant");
- DataConverterEntity.a.put("Guardian", "minecraft:guardian");
- DataConverterEntity.a.put("Horse", "minecraft:horse");
- DataConverterEntity.a.put("Husk", "minecraft:husk");
- DataConverterEntity.a.put("Item", "minecraft:item");
- DataConverterEntity.a.put("ItemFrame", "minecraft:item_frame");
- DataConverterEntity.a.put("LavaSlime", "minecraft:magma_cube");
- DataConverterEntity.a.put("LeashKnot", "minecraft:leash_knot");
- DataConverterEntity.a.put("MinecartChest", "minecraft:chest_minecart");
- DataConverterEntity.a.put("MinecartCommandBlock", "minecraft:commandblock_minecart");
- DataConverterEntity.a.put("MinecartFurnace", "minecraft:furnace_minecart");
- DataConverterEntity.a.put("MinecartHopper", "minecraft:hopper_minecart");
- DataConverterEntity.a.put("MinecartRideable", "minecraft:minecart");
- DataConverterEntity.a.put("MinecartSpawner", "minecraft:spawner_minecart");
- DataConverterEntity.a.put("MinecartTNT", "minecraft:tnt_minecart");
- DataConverterEntity.a.put("Mule", "minecraft:mule");
- DataConverterEntity.a.put("MushroomCow", "minecraft:mooshroom");
- DataConverterEntity.a.put("Ozelot", "minecraft:ocelot");
- DataConverterEntity.a.put("Painting", "minecraft:painting");
- DataConverterEntity.a.put("Pig", "minecraft:pig");
- DataConverterEntity.a.put("PigZombie", "minecraft:zombie_pigman");
- DataConverterEntity.a.put("PolarBear", "minecraft:polar_bear");
- DataConverterEntity.a.put("PrimedTnt", "minecraft:tnt");
- DataConverterEntity.a.put("Rabbit", "minecraft:rabbit");
- DataConverterEntity.a.put("Sheep", "minecraft:sheep");
- DataConverterEntity.a.put("Shulker", "minecraft:shulker");
- DataConverterEntity.a.put("ShulkerBullet", "minecraft:shulker_bullet");
- DataConverterEntity.a.put("Silverfish", "minecraft:silverfish");
- DataConverterEntity.a.put("Skeleton", "minecraft:skeleton");
- DataConverterEntity.a.put("SkeletonHorse", "minecraft:skeleton_horse");
- DataConverterEntity.a.put("Slime", "minecraft:slime");
- DataConverterEntity.a.put("SmallFireball", "minecraft:small_fireball");
- DataConverterEntity.a.put("SnowMan", "minecraft:snowman");
- DataConverterEntity.a.put("Snowball", "minecraft:snowball");
- DataConverterEntity.a.put("SpectralArrow", "minecraft:spectral_arrow");
- DataConverterEntity.a.put("Spider", "minecraft:spider");
- DataConverterEntity.a.put("Squid", "minecraft:squid");
- DataConverterEntity.a.put("Stray", "minecraft:stray");
- DataConverterEntity.a.put("ThrownEgg", "minecraft:egg");
- DataConverterEntity.a.put("ThrownEnderpearl", "minecraft:ender_pearl");
- DataConverterEntity.a.put("ThrownExpBottle", "minecraft:xp_bottle");
- DataConverterEntity.a.put("ThrownPotion", "minecraft:potion");
- DataConverterEntity.a.put("Villager", "minecraft:villager");
- DataConverterEntity.a.put("VillagerGolem", "minecraft:villager_golem");
- DataConverterEntity.a.put("Witch", "minecraft:witch");
- DataConverterEntity.a.put("WitherBoss", "minecraft:wither");
- DataConverterEntity.a.put("WitherSkeleton", "minecraft:wither_skeleton");
- DataConverterEntity.a.put("WitherSkull", "minecraft:wither_skull");
- DataConverterEntity.a.put("Wolf", "minecraft:wolf");
- DataConverterEntity.a.put("XPOrb", "minecraft:xp_orb");
- DataConverterEntity.a.put("Zombie", "minecraft:zombie");
- DataConverterEntity.a.put("ZombieHorse", "minecraft:zombie_horse");
- DataConverterEntity.a.put("ZombieVillager", "minecraft:zombie_villager");
- }
- }
-
- private static class DataConverterPotionWater implements DataConverter {
-
- DataConverterPotionWater() {
- }
-
- public int getDataVersion() {
- return 806;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- String s = cmp.getString("id").orElse(null);
-
- if ("minecraft:potion".equals(s) || "minecraft:splash_potion".equals(s) || "minecraft:lingering_potion".equals(s) || "minecraft:tipped_arrow".equals(s)) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompoundOrEmpty("tag");
-
- if (nbttagcompound1.getString("Potion").isEmpty()) {
- nbttagcompound1.putString("Potion", "minecraft:water");
- }
-
- if (cmp.getCompound("tag").isEmpty()) {
- cmp.put("tag", nbttagcompound1);
- }
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterShulker implements DataConverter {
-
- DataConverterShulker() {
- }
-
- public int getDataVersion() {
- return 808;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:shulker".equals(cmp.getString("id").orElse(null)) && cmp.getByte("Color").isEmpty()) {
- cmp.putByte("Color", (byte) 10);
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterShulkerBoxItem implements DataConverter {
-
- public static final String[] a = new String[] { "minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box", "minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box", "minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box", "minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box" };
-
- DataConverterShulkerBoxItem() {
- }
-
- public int getDataVersion() {
- return 813;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:shulker_box".equals(cmp.getString("id").orElse(null)) ) {
- cmp.getCompound("tag").ifPresent(nbttagcompound1 -> {
- nbttagcompound1.getCompound("BlockEntityTag").ifPresent(nbttagcompound2 -> {
- if (nbttagcompound2.getList("Items").map(ListTag::isEmpty).orElse(true)) {
- nbttagcompound2.remove("Items");
- }
-
- int i = nbttagcompound2.getIntOr("Color", 0);
-
- nbttagcompound2.remove("Color");
- if (nbttagcompound2.isEmpty()) {
- nbttagcompound1.remove("BlockEntityTag");
- }
-
- if (nbttagcompound1.isEmpty()) {
- cmp.remove("tag");
- }
-
- cmp.putString("id", DataConverterShulkerBoxItem.a[i % 16]);
- });
- });
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterShulkerBoxBlock implements DataConverter {
-
- DataConverterShulkerBoxBlock() {
- }
-
- public int getDataVersion() {
- return 813;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:shulker".equals(cmp.getString("id").orElse(null))) {
- cmp.remove("Color");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterLang implements DataConverter {
-
- DataConverterLang() {
- }
-
- public int getDataVersion() {
- return 816;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- cmp.getString("lang").ifPresent(lang -> {
- cmp.putString("lang", lang.toLowerCase(Locale.ROOT));
- });
-
- return cmp;
- }
- }
-
- private static class DataConverterTotem implements DataConverter {
-
- DataConverterTotem() {
- }
-
- public int getDataVersion() {
- return 820;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:totem".equals(cmp.getString("id").orElse(null))) {
- cmp.putString("id", "minecraft:totem_of_undying");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterBedBlock implements DataConverter {
-
- private static final Logger a = LogManager.getLogger(NeoForgeDataFixer.class);
-
- DataConverterBedBlock() {
- }
-
- public int getDataVersion() {
- return 1125;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- boolean flag = true;
-
- try {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = cmp.getCompoundOrEmpty("Level");
- int i = nbttagcompound1.getIntOr("xPos", 0);
- int j = nbttagcompound1.getIntOr("zPos", 0);
- ListTag nbttaglist = nbttagcompound1.getListOrEmpty("TileEntities");
- ListTag nbttaglist1 = nbttagcompound1.getListOrEmpty("Sections");
-
- for (int k = 0; k < nbttaglist1.size(); ++k) {
- net.minecraft.nbt.CompoundTag nbttagcompound2 = nbttaglist1.getCompoundOrEmpty(k);
- byte b0 = nbttagcompound2.getByteOr("Y", (byte) 0);
- byte[] abyte = nbttagcompound2.getByteArray("Blocks").orElse(new byte[]{});
-
- for (int l = 0; l < abyte.length; ++l) {
- if (416 == (abyte[l] & 255) << 4) {
- int i1 = l & 15;
- int j1 = l >> 8 & 15;
- int k1 = l >> 4 & 15;
- net.minecraft.nbt.CompoundTag nbttagcompound3 = new net.minecraft.nbt.CompoundTag();
-
- nbttagcompound3.putString("id", "bed");
- nbttagcompound3.putInt("x", i1 + (i << 4));
- nbttagcompound3.putInt("y", j1 + (b0 << 4));
- nbttagcompound3.putInt("z", k1 + (j << 4));
- nbttaglist.add(nbttagcompound3);
- }
- }
- }
- } catch (Exception exception) {
- DataConverterBedBlock.a.warn("Unable to datafix Bed blocks, level format may be missing tags.");
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterBedItem implements DataConverter {
-
- DataConverterBedItem() {
- }
-
- public int getDataVersion() {
- return 1125;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("minecraft:bed".equals(cmp.getString("id").orElse(null)) && cmp.getShortOr("Damage", (short) 0) == 0) {
- cmp.putShort("Damage", (short) DyeColor.RED.getId());
- }
-
- return cmp;
- }
- }
-
- private static class DataConverterSignText implements DataConverter {
-
- public static final Gson a = new GsonBuilder().registerTypeAdapter(Component.class, new JsonDeserializer() {
- MutableComponent a(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException {
- if (jsonelement.isJsonPrimitive()) {
- return Component.literal(jsonelement.getAsString());
- } else if (jsonelement.isJsonArray()) {
- JsonArray jsonarray = jsonelement.getAsJsonArray();
- MutableComponent iTextComponent = null;
- Iterator iterator = jsonarray.iterator();
-
- while (iterator.hasNext()) {
- JsonElement jsonelement1 = iterator.next();
- MutableComponent iTextComponent1 = this.a(jsonelement1, jsonelement1.getClass(), jsondeserializationcontext);
-
- if (iTextComponent == null) {
- iTextComponent = iTextComponent1;
- } else {
- iTextComponent.append(iTextComponent1);
- }
- }
-
- return iTextComponent;
- } else {
- throw new JsonParseException("Don't know how to turn " + jsonelement + " into a Component");
- }
- }
-
- public Object deserialize(JsonElement jsonelement, Type type, JsonDeserializationContext jsondeserializationcontext) throws JsonParseException {
- return this.a(jsonelement, type, jsondeserializationcontext);
- }
- }).create();
-
- DataConverterSignText() {
- }
-
- public int getDataVersion() {
- return 101;
- }
-
- public net.minecraft.nbt.CompoundTag convert(net.minecraft.nbt.CompoundTag cmp) {
- if ("Sign".equals(cmp.getString("id").orElse(null))) {
- this.convert(cmp, "Text1");
- this.convert(cmp, "Text2");
- this.convert(cmp, "Text3");
- this.convert(cmp, "Text4");
- }
-
- return cmp;
- }
-
- private void convert(net.minecraft.nbt.CompoundTag nbttagcompound, String s) {
- String s1 = nbttagcompound.getString(s).orElse(null);
- Object object = null;
-
- if (!"null".equals(s1) && !Strings.isNullOrEmpty(s1)) {
- if ((s1.charAt(0) != 34 || s1.charAt(s1.length() - 1) != 34) && (s1.charAt(0) != 123 || s1.charAt(s1.length() - 1) != 125)) {
- object = Component.literal(s1);
- } else {
- try {
- object = GsonHelper.fromJson(DataConverterSignText.a, s1, Component.class);
- if (object == null) {
- object = Component.literal("");
- }
- } catch (JsonParseException jsonparseexception) {
- ;
- }
-
- if (object == null) {
- try {
- object = ComponentConverter.Serializer.fromJson(s1, ServerLifecycleHooks.getCurrentServer().registryAccess());
- } catch (JsonParseException jsonparseexception1) {
- ;
- }
- }
-
- if (object == null) {
- try {
- object = ComponentConverter.Serializer.fromJsonLenient(s1, ServerLifecycleHooks.getCurrentServer().registryAccess());
- } catch (JsonParseException jsonparseexception2) {
- ;
- }
- }
-
- if (object == null) {
- object = Component.literal(s1);
- }
- }
- } else {
- object = Component.literal("");
- }
-
- nbttagcompound.putString(s, ComponentConverter.Serializer.toJson((Component) object, ServerLifecycleHooks.getCurrentServer().registryAccess()));
- }
- }
-
- private static class DataInspectorPlayerVehicle implements DataInspector {
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- cmp.getCompound("RootVehicle").ifPresent(nbttagcompound1 -> {
- if (nbttagcompound1.getCompound("Entity").isPresent()) {
- convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer);
- }
- });
-
- return cmp;
- }
- }
-
- private static class DataInspectorLevelPlayer implements DataInspector {
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- if (cmp.getCompound("Player").isPresent()) {
- convertCompound(LegacyType.PLAYER, cmp, "Player", sourceVer, targetVer);
- }
-
- return cmp;
- }
- }
-
- private static class DataInspectorStructure implements DataInspector {
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- cmp.getList("entities").ifPresent(nbttaglist -> {
- for (int j = 0; j < nbttaglist.size(); ++j) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j);
- if (nbttagcompound1.getCompound("nbt").isPresent()) {
- convertCompound(LegacyType.ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer);
- }
- }
- });
-
- cmp.getList("blocks").ifPresent(nbttaglist -> {
- for (int j = 0; j < nbttaglist.size(); ++j) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = (net.minecraft.nbt.CompoundTag) nbttaglist.get(j);
- if (nbttagcompound1.getCompound("nbt").isPresent()) {
- convertCompound(LegacyType.BLOCK_ENTITY, nbttagcompound1, "nbt", sourceVer, targetVer);
- }
- }
- });
-
- return cmp;
- }
- }
-
- private static class DataInspectorChunks implements DataInspector {
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- cmp.getCompound("Level").ifPresent(nbttagcompound1 -> {
- nbttagcompound1.getList("Entities").ifPresent(nbttaglist -> {
- for (int j = 0; j < nbttaglist.size(); ++j) {
- nbttaglist.set(j, convert(LegacyType.ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer));
- }
- });
-
- nbttagcompound1.getList("TileEntities").ifPresent(nbttaglist -> {
- for (int j = 0; j < nbttaglist.size(); ++j) {
- nbttaglist.set(j, convert(LegacyType.BLOCK_ENTITY, (net.minecraft.nbt.CompoundTag) nbttaglist.get(j), sourceVer, targetVer));
- }
- });
- });
-
- return cmp;
- }
- }
-
- private static class DataInspectorEntityPassengers implements DataInspector {
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- cmp.getList("Passengers").ifPresent(nbttaglist -> {
- for (int j = 0; j < nbttaglist.size(); ++j) {
- nbttaglist.set(j, convert(LegacyType.ENTITY, nbttaglist.getCompoundOrEmpty(j), sourceVer, targetVer));
- }
- });
-
- return cmp;
- }
- }
-
- private static class DataInspectorPlayer implements DataInspector {
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- convertItems(cmp, "Inventory", sourceVer, targetVer);
- convertItems(cmp, "EnderItems", sourceVer, targetVer);
- if (cmp.getCompound("ShoulderEntityLeft").isPresent()) {
- convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityLeft", sourceVer, targetVer);
- }
-
- if (cmp.getCompound("ShoulderEntityRight").isPresent()) {
- convertCompound(LegacyType.ENTITY, cmp, "ShoulderEntityRight", sourceVer, targetVer);
- }
-
- return cmp;
- }
- }
-
- private static class DataInspectorVillagers implements DataInspector {
- Identifier entityVillager = getKey("EntityVillager");
-
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- if (cmp.getString("id").isPresent() && entityVillager.equals(Identifier.parse(cmp.getString("id").get()))) {
- cmp.getCompound("Offers").flatMap(nbttagcompound1 -> nbttagcompound1.getList("Recipes")).ifPresent(nbttaglist -> {
- for (int j = 0; j < nbttaglist.size(); ++j) {
- CompoundTag nbttagcompound2 = nbttaglist.getCompoundOrEmpty(j);
-
- convertItem(nbttagcompound2, "buy", sourceVer, targetVer);
- convertItem(nbttagcompound2, "buyB", sourceVer, targetVer);
- convertItem(nbttagcompound2, "sell", sourceVer, targetVer);
- nbttaglist.set(j, nbttagcompound2);
- }
- });
- }
-
- return cmp;
- }
- }
-
- private static class DataInspectorMobSpawnerMinecart implements DataInspector {
- Identifier entityMinecartMobSpawner = getKey("EntityMinecartMobSpawner");
- Identifier tileEntityMobSpawner = getKey("TileEntityMobSpawner");
-
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- String s = cmp.getString("id").get();
- if (entityMinecartMobSpawner.equals(Identifier.parse(s))) {
- cmp.putString("id", tileEntityMobSpawner.toString());
- convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer);
- cmp.putString("id", s);
- }
-
- return cmp;
- }
- }
-
- private static class DataInspectorMobSpawnerMobs implements DataInspector {
- Identifier tileEntityMobSpawner = getKey("TileEntityMobSpawner");
-
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- if (cmp.getString("id").isPresent() && tileEntityMobSpawner.equals(Identifier.parse(cmp.getString("id").get()))) {
- cmp.getList("SpawnPotentials").ifPresent(nbttaglist -> {
- for (int j = 0; j < nbttaglist.size(); ++j) {
- net.minecraft.nbt.CompoundTag nbttagcompound1 = nbttaglist.getCompoundOrEmpty(j);
-
- convertCompound(LegacyType.ENTITY, nbttagcompound1, "Entity", sourceVer, targetVer);
- }
- });
-
- convertCompound(LegacyType.ENTITY, cmp, "SpawnData", sourceVer, targetVer);
- }
-
- return cmp;
- }
- }
-
- private static class DataInspectorCommandBlock implements DataInspector {
- Identifier tileEntityCommand = getKey("TileEntityCommand");
-
- @Override
- public net.minecraft.nbt.CompoundTag inspect(net.minecraft.nbt.CompoundTag cmp, int sourceVer, int targetVer) {
- if (cmp.getString("id").isPresent() && tileEntityCommand.equals(Identifier.parse(cmp.getString("id").get()))) {
- cmp.putString("id", "Control");
- convert(LegacyType.BLOCK_ENTITY, cmp, sourceVer, targetVer);
- cmp.putString("id", "MinecartCommandBlock");
- }
-
- return cmp;
- }
- }
-}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeItemCategoryRegistry.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeItemCategoryRegistry.java
deleted file mode 100644
index c834d1b75d..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeItemCategoryRegistry.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import com.google.common.collect.ImmutableSet;
-import com.sk89q.worldedit.world.item.ItemType;
-import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
-import net.minecraft.core.Holder;
-import net.minecraft.core.HolderSet;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.resources.Identifier;
-import net.minecraft.tags.TagKey;
-import net.neoforged.neoforge.server.ServerLifecycleHooks;
-
-import java.util.Set;
-
-public class NeoForgeItemCategoryRegistry implements ItemCategoryRegistry {
- @Override
- public Set getCategorisedByName(String category) {
- return ServerLifecycleHooks.getCurrentServer().registryAccess().lookupOrThrow(Registries.ITEM)
- .get(TagKey.create(
- Registries.ITEM,
- Identifier.parse(category)
- ))
- .stream()
- .flatMap(HolderSet.Named::stream)
- .map(Holder::value)
- .map(NeoForgeAdapter::adapt)
- .collect(ImmutableSet.toImmutableSet());
- }
-}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgePermissionsProvider.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgePermissionsProvider.java
deleted file mode 100644
index f62752133e..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgePermissionsProvider.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.world.level.GameType;
-import net.neoforged.neoforge.server.ServerLifecycleHooks;
-
-public interface NeoForgePermissionsProvider {
-
- boolean hasPermission(ServerPlayer player, String permission);
-
- void registerPermission(String permission);
-
- class VanillaPermissionsProvider implements NeoForgePermissionsProvider {
-
- private final NeoForgePlatform platform;
-
- public VanillaPermissionsProvider(NeoForgePlatform platform) {
- this.platform = platform;
- }
-
- @Override
- public boolean hasPermission(ServerPlayer player, String permission) {
- NeoForgeConfiguration configuration = platform.getConfiguration();
- return configuration.cheatMode
- || ServerLifecycleHooks.getCurrentServer().getPlayerList().isOp(player.nameAndId())
- || (configuration.creativeEnable && player.gameMode.getGameModeForPlayer() == GameType.CREATIVE);
- }
-
- @Override
- public void registerPermission(String permission) {
- }
- }
-}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgePlayer.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgePlayer.java
deleted file mode 100644
index af8090b8aa..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgePlayer.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import com.sk89q.worldedit.blocks.BaseItemStack;
-import com.sk89q.worldedit.entity.BaseEntity;
-import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
-import com.sk89q.worldedit.extent.inventory.BlockBag;
-import com.sk89q.worldedit.internal.cui.CUIEvent;
-import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.math.Vector3;
-import com.sk89q.worldedit.neoforge.internal.ComponentConverter;
-import com.sk89q.worldedit.neoforge.internal.NBTConverter;
-import com.sk89q.worldedit.session.SessionKey;
-import com.sk89q.worldedit.util.HandSide;
-import com.sk89q.worldedit.util.Location;
-import com.sk89q.worldedit.util.formatting.WorldEditText;
-import com.sk89q.worldedit.util.formatting.component.TextUtils;
-import com.sk89q.worldedit.util.formatting.text.Component;
-import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
-import com.sk89q.worldedit.world.World;
-import com.sk89q.worldedit.world.block.BaseBlock;
-import com.sk89q.worldedit.world.block.BlockStateHolder;
-import com.sk89q.worldedit.world.block.BlockTypes;
-import net.minecraft.ChatFormatting;
-import net.minecraft.core.BlockPos;
-import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
-import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.server.level.ServerPlayer;
-import net.minecraft.world.InteractionHand;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.level.block.entity.BlockEntityType;
-import net.neoforged.neoforge.network.PacketDistributor;
-import org.enginehub.linbus.tree.LinCompoundTag;
-import org.enginehub.worldeditcui.protocol.CUIPacket;
-
-import java.util.Locale;
-import java.util.Set;
-import java.util.UUID;
-import javax.annotation.Nullable;
-
-public class NeoForgePlayer extends AbstractPlayerActor {
-
- private final ServerPlayer player;
-
- protected NeoForgePlayer(ServerPlayer player) {
- this.player = player;
-
- if (getUniqueId() == null) {
- throw new AssertionError("Player UUID cannot be null");
- }
-
- ThreadSafeCache.getInstance().getOnlineIds().add(getUniqueId());
- }
-
- @Override
- public UUID getUniqueId() {
- return player.getUUID();
- }
-
- @Override
- public BaseItemStack getItemInHand(HandSide handSide) {
- ItemStack is = this.player.getItemInHand(
- handSide == HandSide.MAIN_HAND
- ? InteractionHand.MAIN_HAND
- : InteractionHand.OFF_HAND
- );
- return NeoForgeAdapter.adapt(is);
- }
-
- @Override
- public String getName() {
- return this.player.getName().getString();
- }
-
- @Override
- public BaseEntity getState() {
- throw new UnsupportedOperationException("Cannot create a state from this object");
- }
-
- @Override
- public Location getLocation() {
- Vector3 position = Vector3.at(this.player.getX(), this.player.getY(), this.player.getZ());
- return new Location(
- NeoForgeWorldEdit.inst.getWorld(this.player.level()),
- position,
- this.player.getYRot(),
- this.player.getXRot());
- }
-
- @Override
- public boolean setLocation(Location location) {
- ServerLevel level = NeoForgeAdapter.adapt((World) location.getExtent());
- this.player.teleportTo(
- level,
- location.getX(), location.getY(), location.getZ(),
- Set.of(),
- location.getYaw(), location.getPitch(),
- true
- );
- // This may be false if the teleport was cancelled by a mod
- return this.player.level() == level;
- }
-
- @Override
- public World getWorld() {
- return NeoForgeWorldEdit.inst.getWorld(this.player.level());
- }
-
- @Override
- public void giveItem(BaseItemStack itemStack) {
- this.player.getInventory().add(NeoForgeAdapter.adapt(itemStack));
- }
-
- @Override
- public void dispatchCUIEvent(CUIEvent event) {
- PacketDistributor.sendToPlayer(this.player, new CUIPacket(event.getTypeId(), event.getParameters()));
- }
-
- private void sendMessage(net.minecraft.network.chat.Component textComponent) {
- this.player.sendSystemMessage(textComponent);
- }
-
- @Override
- @Deprecated
- public void printRaw(String msg) {
- for (String part : msg.split("\n", 0)) {
- sendMessage(net.minecraft.network.chat.Component.literal(part));
- }
- }
-
- @Override
- @Deprecated
- public void printDebug(String msg) {
- sendColorized(msg, ChatFormatting.GRAY);
- }
-
- @Override
- @Deprecated
- public void print(String msg) {
- sendColorized(msg, ChatFormatting.LIGHT_PURPLE);
- }
-
- @Override
- @Deprecated
- public void printError(String msg) {
- sendColorized(msg, ChatFormatting.RED);
- }
-
- @Override
- public void print(Component component) {
- sendMessage(ComponentConverter.Serializer.fromJson(
- GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component, getLocale())),
- this.player.registryAccess()
- ));
- }
-
- private void sendColorized(String msg, ChatFormatting formatting) {
- for (String part : msg.split("\n", 0)) {
- var component = net.minecraft.network.chat.Component.literal(part);
- component.withStyle(formatting);
- sendMessage(component);
- }
- }
-
- @Override
- public boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
- this.player.connection.teleport(pos.x(), pos.y(), pos.z(), yaw, pitch);
- return true;
- }
-
- @Override
- public String[] getGroups() {
- return new String[] {}; // WorldEditMod.inst.getPermissionsResolver().getGroups(this.player.username);
- }
-
- @Override
- public BlockBag getInventoryBlockBag() {
- return null;
- }
-
- @Override
- public boolean hasPermission(String perm) {
- return NeoForgeWorldEdit.inst.getPermissionsProvider().hasPermission(player, perm);
- }
-
- @Nullable
- @Override
- public T getFacet(Class extends T> cls) {
- return null;
- }
-
- @Override
- public boolean isAllowedToFly() {
- return player.mayFly();
- }
-
- @Override
- public void setFlying(boolean flying) {
- if (player.getAbilities().flying != flying) {
- player.getAbilities().flying = flying;
- player.onUpdateAbilities();
- }
- }
-
- @Override
- public Locale getLocale() {
- return TextUtils.getLocaleByMinecraftTag(player.getLanguage());
- }
-
- @Override
- public > void sendFakeBlock(BlockVector3 pos, B block) {
- World world = getWorld();
- if (!(world instanceof NeoForgeWorld neoForgeWorld)) {
- return;
- }
- BlockPos loc = NeoForgeAdapter.toBlockPos(pos);
- if (block == null) {
- final ClientboundBlockUpdatePacket packetOut = new ClientboundBlockUpdatePacket(
- neoForgeWorld.getWorld(),
- loc
- );
- player.connection.send(packetOut);
- } else {
- player.connection.send(new ClientboundBlockUpdatePacket(
- loc, NeoForgeAdapter.adapt(block.toImmutableState())
- ));
- if (block instanceof BaseBlock baseBlock && block.getBlockType().equals(BlockTypes.STRUCTURE_BLOCK)) {
- final LinCompoundTag nbtData = baseBlock.getNbt();
- if (nbtData != null) {
- player.connection.send(new ClientboundBlockEntityDataPacket(
- new BlockPos(pos.x(), pos.y(), pos.z()),
- BlockEntityType.STRUCTURE_BLOCK,
- NBTConverter.toNative(nbtData)
- ));
- }
- }
- }
- }
-
- @Override
- public SessionKey getSessionKey() {
- return new SessionKeyImpl(player);
- }
-
- static class SessionKeyImpl implements SessionKey {
- // If not static, this will leak a reference
-
- private final UUID uuid;
- private final String name;
-
- SessionKeyImpl(ServerPlayer player) {
- this.uuid = player.getUUID();
- this.name = player.getName().getString();
- }
-
- @Override
- public UUID getUniqueId() {
- return uuid;
- }
-
- @Nullable
- @Override
- public String getName() {
- return name;
- }
-
- @Override
- public boolean isActive() {
- // We can't directly check if the player is online because
- // the list of players is not thread safe
- return ThreadSafeCache.getInstance().getOnlineIds().contains(uuid);
- }
-
- @Override
- public boolean isPersistent() {
- return true;
- }
-
- }
-
-}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeRegistries.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeRegistries.java
deleted file mode 100644
index 2aa4bb7604..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeRegistries.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import com.sk89q.worldedit.world.registry.BiomeRegistry;
-import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
-import com.sk89q.worldedit.world.registry.BlockRegistry;
-import com.sk89q.worldedit.world.registry.BundledRegistries;
-import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
-import com.sk89q.worldedit.world.registry.ItemRegistry;
-
-/**
- * World data for the Forge platform.
- */
-class NeoForgeRegistries extends BundledRegistries {
-
- private static final NeoForgeRegistries INSTANCE = new NeoForgeRegistries();
- private final BlockRegistry blockRegistry = new NeoForgeBlockRegistry();
- private final BiomeRegistry biomeRegistry = new NeoForgeBiomeRegistry();
- private final ItemRegistry itemRegistry = new NeoForgeItemRegistry();
- private final BlockCategoryRegistry blockCategoryRegistry = new NeoForgeBlockCategoryRegistry();
- private final ItemCategoryRegistry itemCategoryRegistry = new NeoForgeItemCategoryRegistry();
-
- @Override
- public BlockRegistry getBlockRegistry() {
- return blockRegistry;
- }
-
- @Override
- public BiomeRegistry getBiomeRegistry() {
- return biomeRegistry;
- }
-
- @Override
- public ItemRegistry getItemRegistry() {
- return itemRegistry;
- }
-
- @Override
- public BlockCategoryRegistry getBlockCategoryRegistry() {
- return blockCategoryRegistry;
- }
-
- @Override
- public ItemCategoryRegistry getItemCategoryRegistry() {
- return itemCategoryRegistry;
- }
-
- /**
- * Get a static instance.
- *
- * @return an instance
- */
- public static NeoForgeRegistries getInstance() {
- return INSTANCE;
- }
-
-}
diff --git a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeWorld.java b/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeWorld.java
deleted file mode 100644
index b59c68be4d..0000000000
--- a/worldedit-neoforge/src/main/java/com/sk89q/worldedit/neoforge/NeoForgeWorld.java
+++ /dev/null
@@ -1,774 +0,0 @@
-/*
- * WorldEdit, a Minecraft world manipulation toolkit
- * Copyright (C) sk89q
- * Copyright (C) WorldEdit team and contributors
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-
-package com.sk89q.worldedit.neoforge;
-
-import com.google.common.cache.CacheBuilder;
-import com.google.common.cache.CacheLoader;
-import com.google.common.cache.LoadingCache;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Streams;
-import com.google.common.util.concurrent.Futures;
-import com.sk89q.worldedit.EditSession;
-import com.sk89q.worldedit.MaxChangedBlocksException;
-import com.sk89q.worldedit.WorldEdit;
-import com.sk89q.worldedit.WorldEditException;
-import com.sk89q.worldedit.blocks.BaseItem;
-import com.sk89q.worldedit.blocks.BaseItemStack;
-import com.sk89q.worldedit.entity.BaseEntity;
-import com.sk89q.worldedit.entity.Entity;
-import com.sk89q.worldedit.extent.Extent;
-import com.sk89q.worldedit.function.mask.AbstractExtentMask;
-import com.sk89q.worldedit.function.mask.Mask;
-import com.sk89q.worldedit.internal.Constants;
-import com.sk89q.worldedit.math.BlockVector2;
-import com.sk89q.worldedit.math.BlockVector3;
-import com.sk89q.worldedit.math.Vector3;
-import com.sk89q.worldedit.neoforge.internal.NBTConverter;
-import com.sk89q.worldedit.neoforge.internal.NeoForgeEntity;
-import com.sk89q.worldedit.neoforge.internal.NeoForgeLoggingProblemReporter;
-import com.sk89q.worldedit.neoforge.internal.NeoForgeServerLevelDelegateProxy;
-import com.sk89q.worldedit.neoforge.internal.NeoForgeWorldNativeAccess;
-import com.sk89q.worldedit.regions.Region;
-import com.sk89q.worldedit.util.Direction;
-import com.sk89q.worldedit.util.Location;
-import com.sk89q.worldedit.util.SideEffect;
-import com.sk89q.worldedit.util.SideEffectSet;
-import com.sk89q.worldedit.util.concurrency.LazyReference;
-import com.sk89q.worldedit.util.io.file.SafeFiles;
-import com.sk89q.worldedit.world.AbstractWorld;
-import com.sk89q.worldedit.world.RegenOptions;
-import com.sk89q.worldedit.world.biome.BiomeType;
-import com.sk89q.worldedit.world.block.BaseBlock;
-import com.sk89q.worldedit.world.block.BlockState;
-import com.sk89q.worldedit.world.block.BlockStateHolder;
-import com.sk89q.worldedit.world.generation.ConfiguredFeatureType;
-import com.sk89q.worldedit.world.generation.StructureType;
-import com.sk89q.worldedit.world.generation.WorldEditTreeGeneration;
-import com.sk89q.worldedit.world.item.ItemTypes;
-import com.sk89q.worldedit.world.weather.WeatherType;
-import com.sk89q.worldedit.world.weather.WeatherTypes;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Holder;
-import net.minecraft.core.Registry;
-import net.minecraft.core.SectionPos;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.data.worldgen.placement.EndPlacements;
-import net.minecraft.data.worldgen.placement.TreePlacements;
-import net.minecraft.resources.Identifier;
-import net.minecraft.resources.ResourceKey;
-import net.minecraft.server.level.ServerChunkCache;
-import net.minecraft.server.level.ServerLevel;
-import net.minecraft.util.RandomSource;
-import net.minecraft.util.Util;
-import net.minecraft.util.thread.BlockableEventLoop;
-import net.minecraft.world.Clearable;
-import net.minecraft.world.InteractionHand;
-import net.minecraft.world.InteractionResult;
-import net.minecraft.world.entity.EntitySpawnReason;
-import net.minecraft.world.entity.EntityType;
-import net.minecraft.world.entity.item.ItemEntity;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.context.UseOnContext;
-import net.minecraft.world.level.ChunkPos;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.biome.Biome;
-import net.minecraft.world.level.block.LiquidBlock;
-import net.minecraft.world.level.block.entity.BlockEntity;
-import net.minecraft.world.level.chunk.ChunkAccess;
-import net.minecraft.world.level.chunk.LevelChunk;
-import net.minecraft.world.level.chunk.PalettedContainer;
-import net.minecraft.world.level.chunk.status.ChunkStatus;
-import net.minecraft.world.level.dimension.LevelStem;
-import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
-import net.minecraft.world.level.levelgen.placement.PlacedFeature;
-import net.minecraft.world.level.levelgen.structure.BoundingBox;
-import net.minecraft.world.level.levelgen.structure.Structure;
-import net.minecraft.world.level.levelgen.structure.StructureStart;
-import net.minecraft.world.level.saveddata.WeatherData;
-import net.minecraft.world.level.storage.LevelStorageSource;
-import net.minecraft.world.level.storage.ServerLevelData;
-import net.minecraft.world.level.storage.TagValueOutput;
-import net.minecraft.world.phys.AABB;
-import net.minecraft.world.phys.BlockHitResult;
-import org.enginehub.linbus.tree.LinCompoundTag;
-
-import java.lang.ref.WeakReference;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ThreadLocalRandom;
-import javax.annotation.Nullable;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-
-/**
- * An adapter to Minecraft worlds for WorldEdit.
- */
-public class NeoForgeWorld extends AbstractWorld {
-
- private static final RandomSource random = RandomSource.create();
-
- private static Identifier getDimensionRegistryKey(ServerLevel world) {
- return Objects.requireNonNull(world.getServer(), "server cannot be null")
- .registryAccess()
- .lookupOrThrow(Registries.DIMENSION_TYPE)
- .getKey(world.dimensionType());
- }
-
- private final WeakReference worldRef;
- private final NeoForgeWorldNativeAccess nativeAccess;
-
- /**
- * Construct a new world.
- *
- * @param world the world
- */
- NeoForgeWorld(ServerLevel world) {
- checkNotNull(world);
- this.worldRef = new WeakReference<>(world);
- this.nativeAccess = new NeoForgeWorldNativeAccess(worldRef);
- }
-
- /**
- * Get the underlying handle to the world.
- *
- * @return the world
- * @throws RuntimeException thrown if a reference to the world was lost (i.e. world was unloaded)
- */
- public ServerLevel getWorld() {
- ServerLevel world = worldRef.get();
- if (world != null) {
- return world;
- } else {
- throw new RuntimeException("The reference to the world was lost (i.e. the world may have been unloaded)");
- }
- }
-
- @Override
- public String getName() {
- return ((ServerLevelData) getWorld().getLevelData()).getLevelName();
- }
-
- @Override
- public String id() {
- return getName() + "_" + getDimensionRegistryKey(getWorld());
- }
-
- @Override
- public Path getStoragePath() {
- final ServerLevel world = getWorld();
- return world.getServer().storageSource.getDimensionPath(world.dimension());
- }
-
- @Override
- public > boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) throws WorldEditException {
- clearContainerBlockContents(position);
- return nativeAccess.setBlock(position, block, sideEffects);
- }
-
- @Override
- public Set applySideEffects(BlockVector3 position, BlockState previousType, SideEffectSet sideEffectSet) {
- nativeAccess.applySideEffects(position, previousType, sideEffectSet);
- return Sets.intersection(NeoForgeWorldEdit.inst.getPlatform().getSupportedSideEffects(), sideEffectSet.getSideEffectsToApply());
- }
-
- @Override
- public int getBlockLightLevel(BlockVector3 position) {
- checkNotNull(position);
- return getWorld().getLightEmission(NeoForgeAdapter.toBlockPos(position));
- }
-
- @Override
- public boolean clearContainerBlockContents(BlockVector3 position) {
- checkNotNull(position);
-
- BlockEntity tile = getWorld().getBlockEntity(NeoForgeAdapter.toBlockPos(position));
- if (tile instanceof Clearable clearable) {
- clearable.clearContent();
- return true;
- }
- return false;
- }
-
- @Override
- public BiomeType getBiome(BlockVector3 position) {
- checkNotNull(position);
-
- LevelChunk chunk = getWorld().getChunk(position.x() >> 4, position.z() >> 4);
- return getBiomeInChunk(position, chunk);
- }
-
- private BiomeType getBiomeInChunk(BlockVector3 position, ChunkAccess chunk) {
- return NeoForgeAdapter.adapt(
- chunk.getNoiseBiome(position.x() >> 2, position.y() >> 2, position.z() >> 2).value()
- );
- }
-
- @Override
- public boolean setBiome(BlockVector3 position, BiomeType biome) {
- checkNotNull(position);
- checkNotNull(biome);
-
- LevelChunk chunk = getWorld().getChunk(position.x() >> 4, position.z() >> 4);
- var biomes = (PalettedContainer>) chunk.getSection(chunk.getSectionIndex(position.y())).getBiomes();
- biomes.getAndSetUnchecked(
- (position.x() >> 2) & 3, (position.y() >> 2) & 3, (position.z() >> 2) & 3,
- getWorld().registryAccess().lookupOrThrow(Registries.BIOME)
- .getOrThrow(ResourceKey.create(Registries.BIOME, Identifier.parse(biome.id())))
- );
- chunk.markUnsaved();
- return true;
- }
-
- private static final LoadingCache fakePlayers
- = CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(NeoForgeFakePlayer::new));
-
- @Override
- public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
- ItemStack stack = NeoForgeAdapter.adapt(new BaseItemStack(item.getType(), item.getNbtReference(), 1));
- ServerLevel world = getWorld();
- final NeoForgeFakePlayer fakePlayer;
- try {
- fakePlayer = fakePlayers.get(world);
- } catch (ExecutionException ignored) {
- return false;
- }
- fakePlayer.setItemInHand(InteractionHand.MAIN_HAND, stack);
- fakePlayer.absSnapTo(position.x(), position.y(), position.z(),
- (float) face.toVector().toYaw(), (float) face.toVector().toPitch());
- final BlockPos blockPos = NeoForgeAdapter.toBlockPos(position);
- final BlockHitResult rayTraceResult = new BlockHitResult(NeoForgeAdapter.toVec3(position),
- NeoForgeAdapter.adapt(face), blockPos, false);
- UseOnContext itemUseContext = new UseOnContext(fakePlayer, InteractionHand.MAIN_HAND, rayTraceResult);
- InteractionResult used = stack.onItemUseFirst(itemUseContext);
- if (used != InteractionResult.SUCCESS) {
- // try activating the block
- InteractionResult resultType = getWorld().getBlockState(blockPos).useItemOn(stack, world, fakePlayer, InteractionHand.MAIN_HAND, rayTraceResult);
- if (resultType.consumesAction()) {
- used = resultType;
- } else {
- used = stack.getItem().use(world, fakePlayer, InteractionHand.MAIN_HAND);
- }
- }
- return used == InteractionResult.SUCCESS;
- }
-
- @Override
- public void dropItem(Vector3 position, BaseItemStack item) {
- checkNotNull(position);
- checkNotNull(item);
-
- if (item.getType() == ItemTypes.AIR) {
- return;
- }
-
- ItemEntity entity = new ItemEntity(getWorld(), position.x(), position.y(), position.z(), NeoForgeAdapter.adapt(item));
- entity.setPickUpDelay(10);
- getWorld().addFreshEntity(entity);
- }
-
- @Override
- public void simulateBlockMine(BlockVector3 position) {
- BlockPos pos = NeoForgeAdapter.toBlockPos(position);
- getWorld().destroyBlock(pos, true);
- }
-
- @Override
- public boolean canPlaceAt(BlockVector3 position, BlockState blockState) {
- return NeoForgeAdapter.adapt(blockState).canSurvive(getWorld(), NeoForgeAdapter.toBlockPos(position));
- }
-
- // For unmapped regen names, see Fabric!
-
- @Override
- public boolean regenerate(Region region, Extent extent, RegenOptions options) {
- if (options.getSeed().isPresent()) {
- throw new UnsupportedOperationException("26.1+ worldgen does not support overriding the seed for regen");
- }
-
- try {
- doRegen(region, extent, options);
- } catch (Exception e) {
- throw new IllegalStateException("Regen failed", e);
- }
-
- return true;
- }
-
- private void doRegen(Region region, Extent extent, RegenOptions options) throws Exception {
- Path tempDir = Files.createTempDirectory("WorldEditWorldGen");
- LevelStorageSource levelStorage = LevelStorageSource.createDefault(tempDir);
- try (LevelStorageSource.LevelStorageAccess session = levelStorage.createAccess("WorldEditTempGen")) {
- ServerLevel originalWorld = getWorld();
-
- ResourceKey worldRegKey = originalWorld.dimension();
- try (ServerLevel serverWorld = new ServerLevel(
- originalWorld.getServer(), Util.backgroundExecutor(), session,
- ((ServerLevelData) originalWorld.getLevelData()),
- worldRegKey,
- new LevelStem(
- originalWorld.dimensionTypeRegistration(),
- originalWorld.getChunkSource().getGenerator()
- ),
- originalWorld.isDebug(),
- originalWorld.getSeed(),
- // No spawners are needed for this world.
- ImmutableList.of(),
- // This controls ticking, we don't need it so set it to false.
- false
- )) {
- regenForWorld(region, extent, serverWorld, options);
-
- // drive the server executor until all tasks are popped off
- originalWorld.getServer().managedBlock(() -> originalWorld.getServer().getPendingTasksCount() == 0);
- }
- } finally {
- SafeFiles.tryHardToDeleteDir(tempDir);
- }
- }
-
- private void regenForWorld(Region region, Extent extent, ServerLevel serverWorld,
- RegenOptions options) throws WorldEditException {
- List> chunkLoadings = submitChunkLoadTasks(region, serverWorld);
-
- // drive executor until loading finishes
- BlockableEventLoop executor = serverWorld.getChunkSource().mainThreadProcessor;
- executor.managedBlock(() -> {
- // bail out early if a future fails
- if (chunkLoadings.stream().anyMatch(ftr ->
- ftr.isDone() && Futures.getUnchecked(ftr) == null
- )) {
- return false;
- }
- return chunkLoadings.stream().allMatch(CompletableFuture::isDone);
- });
-
- Map chunks = new HashMap<>();
- for (CompletableFuture future : chunkLoadings) {
- @Nullable
- ChunkAccess chunk = future.getNow(null);
- checkState(chunk != null, "Failed to generate a chunk, regen failed.");
- chunks.put(chunk.getPos(), chunk);
- }
-
- for (BlockVector3 vec : region) {
- BlockPos pos = NeoForgeAdapter.toBlockPos(vec);
- ChunkAccess chunk = chunks.get(ChunkPos.containing(pos));
- BlockStateHolder> state = NeoForgeAdapter.adapt(chunk.getBlockState(pos));
- BlockEntity blockEntity = chunk.getBlockEntity(pos);
- if (blockEntity != null) {
- net.minecraft.nbt.CompoundTag tag = NeoForgeLoggingProblemReporter.with(
- () -> "serializing block entity at " + pos,
- reporter -> {
- var tagValueOutput = TagValueOutput.createWithContext(reporter, getWorld().registryAccess());
- blockEntity.saveWithId(tagValueOutput);
- return tagValueOutput.buildResult();
- }
- );
- state = state.toBaseBlock(LazyReference.from(() -> NBTConverter.fromNative(tag)));
- }
- extent.setBlock(vec, state.toBaseBlock());
-
- if (options.shouldRegenBiomes()) {
- BiomeType biome = getBiomeInChunk(vec, chunk);
- extent.setBiome(vec, biome);
- }
- }
- }
-
- private List> submitChunkLoadTasks(Region region, ServerLevel world) {
- List