From 56c891946ddbd380990d46a1ca89d86c228b4ffa Mon Sep 17 00:00:00 2001 From: Octavia Togami Date: Wed, 27 Jan 2021 15:33:51 -0800 Subject: [PATCH] Allow UPDATE mixin to soft-fail on Fabric (#1654) This allows Carpet's mixin to take priorty, and UPDATE will simply be disabled on Fabric in that case. Fixes #1605 --- .../worldedit/fabric/FabricPlatform.java | 20 +++-- .../fabric/internal/MixinConfigPlugin.java | 73 +++++++++++++++++++ ....java => MixinWorldChunkSetBlockHook.java} | 5 +- .../src/main/resources/worldedit.mixins.json | 3 +- 4 files changed, 92 insertions(+), 9 deletions(-) create mode 100644 worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/MixinConfigPlugin.java rename worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/{MixinWorldChunk.java => MixinWorldChunkSetBlockHook.java} (94%) 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 index 746a5fc72..eed8ede8b 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/FabricPlatform.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.fabric; +import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.mojang.brigadier.CommandDispatcher; import com.sk89q.worldedit.command.util.PermissionCondition; @@ -29,6 +30,7 @@ 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.ExtendedChunk; import com.sk89q.worldedit.util.SideEffect; import com.sk89q.worldedit.world.DataFixer; import com.sk89q.worldedit.world.World; @@ -42,6 +44,7 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; +import net.minecraft.world.chunk.WorldChunk; import net.minecraft.world.level.ServerWorldProperties; import org.enginehub.piston.Command; import org.enginehub.piston.CommandManager; @@ -212,17 +215,22 @@ public Map getCapabilities() { return capabilities; } + private static final Set SUPPORTED_SIDE_EFFECTS_NO_MIXIN = Sets.immutableEnumSet( + SideEffect.VALIDATION, + SideEffect.ENTITY_AI, + SideEffect.LIGHTING, + SideEffect.NEIGHBORS + ); + private static final Set SUPPORTED_SIDE_EFFECTS = Sets.immutableEnumSet( - SideEffect.VALIDATION, - SideEffect.ENTITY_AI, - SideEffect.LIGHTING, - SideEffect.NEIGHBORS, - SideEffect.UPDATE + Iterables.concat(SUPPORTED_SIDE_EFFECTS_NO_MIXIN, Collections.singleton(SideEffect.UPDATE)) ); @Override public Set getSupportedSideEffects() { - return SUPPORTED_SIDE_EFFECTS; + return ExtendedChunk.class.isAssignableFrom(WorldChunk.class) + ? SUPPORTED_SIDE_EFFECTS + : SUPPORTED_SIDE_EFFECTS_NO_MIXIN; } @Override 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 new file mode 100644 index 000000000..48f933c36 --- /dev/null +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/internal/MixinConfigPlugin.java @@ -0,0 +1,73 @@ +/* + * 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.fabricmc.loader.api.FabricLoader; +import org.objectweb.asm.tree.ClassNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.spongepowered.asm.mixin.Mixins; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +import java.util.List; +import java.util.Set; + +public class MixinConfigPlugin implements IMixinConfigPlugin { + private static final Logger LOGGER = LoggerFactory.getLogger(MixinConfigPlugin.class); + + @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.MixinWorldChunkSetBlockHook")) { + boolean carpet = FabricLoader.getInstance().getModContainer("carpet").isPresent(); + if (carpet) { + LOGGER.warn("Carpet detected, disabling UPDATE mixin " + mixinClassName); + } + return !carpet; + } + 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/mixin/MixinWorldChunk.java b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinWorldChunkSetBlockHook.java similarity index 94% rename from worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinWorldChunk.java rename to worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinWorldChunkSetBlockHook.java index 4bfea3b8d..1773ab694 100644 --- a/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinWorldChunk.java +++ b/worldedit-fabric/src/main/java/com/sk89q/worldedit/fabric/mixin/MixinWorldChunkSetBlockHook.java @@ -26,6 +26,7 @@ import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.WorldChunk; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -33,8 +34,8 @@ import javax.annotation.Nullable; -@Mixin(WorldChunk.class) -public abstract class MixinWorldChunk implements Chunk, ExtendedChunk { +@Mixin(value = WorldChunk.class) +public abstract class MixinWorldChunkSetBlockHook implements Chunk, ExtendedChunk { private boolean shouldUpdate = true; @Nullable diff --git a/worldedit-fabric/src/main/resources/worldedit.mixins.json b/worldedit-fabric/src/main/resources/worldedit.mixins.json index 31d013a87..e58972154 100644 --- a/worldedit-fabric/src/main/resources/worldedit.mixins.json +++ b/worldedit-fabric/src/main/resources/worldedit.mixins.json @@ -6,11 +6,12 @@ "MixinBiomeArray", "MixinServerPlayerEntity", "MixinMinecraftServer", - "MixinWorldChunk", + "MixinWorldChunkSetBlockHook", "AccessorClientSettingsC2SPacket", "AccessorLevelProperties", "AccessorServerChunkManager" ], + "plugin": "com.sk89q.worldedit.fabric.internal.MixinConfigPlugin", "server": [ ], "injectors": {