From 6507484079c477e8bc0e649d4050e1d8bf63f7ee Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Sat, 11 Jul 2020 18:41:33 +0800 Subject: [PATCH] Fix 1.14 NoSuchMethodError. Dramatically improved multi world plugin compatibility. (#14) --- .../core/server/MinecraftServerMixin.java | 105 ++++++++++++++++-- .../common/mixin/core/world/WorldMixin.java | 12 +- .../core/world/server/ServerWorldMixin.java | 2 +- .../dimension/DimensionTypeMixin_1_15.java | 10 ++ .../common/mod/server/BukkitRegistry.java | 2 +- .../dimension/DimensionTypeMixin_1_14.java | 10 ++ 6 files changed, 128 insertions(+), 13 deletions(-) diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/MinecraftServerMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/MinecraftServerMixin.java index 99583f21..37cae164 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/MinecraftServerMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/MinecraftServerMixin.java @@ -9,9 +9,11 @@ import com.mojang.datafixers.DataFixer; import io.izzel.arclight.common.bridge.command.ICommandSourceBridge; import io.izzel.arclight.common.bridge.server.MinecraftServerBridge; import io.izzel.arclight.common.bridge.world.WorldBridge; +import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge; import io.izzel.arclight.common.mod.ArclightConstants; import io.izzel.arclight.common.mod.server.BukkitRegistry; import io.izzel.arclight.common.mod.util.BukkitOptionParser; +import it.unimi.dsi.fastutil.longs.LongIterator; import joptsimple.OptionParser; import joptsimple.OptionSet; import net.minecraft.command.CommandSource; @@ -23,15 +25,24 @@ import net.minecraft.profiler.DebugProfiler; import net.minecraft.server.MinecraftServer; import net.minecraft.server.management.PlayerProfileCache; import net.minecraft.util.SharedConstants; +import net.minecraft.util.Unit; import net.minecraft.util.Util; import net.minecraft.util.concurrent.RecursiveEventLoop; import net.minecraft.util.concurrent.TickDelayedTask; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.ForcedChunksSaveData; import net.minecraft.world.WorldSettings; import net.minecraft.world.WorldType; import net.minecraft.world.chunk.listener.IChunkStatusListener; import net.minecraft.world.chunk.listener.IChunkStatusListenerFactory; +import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.server.ServerChunkProvider; import net.minecraft.world.server.ServerWorld; +import net.minecraft.world.server.TicketType; import net.minecraft.world.storage.SaveHandler; import net.minecraft.world.storage.WorldInfo; import net.minecraftforge.fml.StartupQuery; @@ -53,6 +64,7 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import javax.annotation.Nullable; @@ -94,12 +106,16 @@ public abstract class MinecraftServerMixin extends RecursiveEventLoop cir) { + if (this.forceTicks) cir.setReturnValue(true); + } + + @Inject(method = "loadWorlds", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/server/MinecraftServer;func_213204_a(Lnet/minecraft/world/storage/DimensionSavedDataManager;)V")) + private void arclight$worldInit(SaveHandler p_213194_1_, WorldInfo info, WorldSettings p_213194_3_, IChunkStatusListener p_213194_4_, CallbackInfo ci, ServerWorld serverWorld) { + if (((CraftServer) Bukkit.getServer()).scoreboardManager == null) { + ((CraftServer) Bukkit.getServer()).scoreboardManager = new CraftScoreboardManager((MinecraftServer) (Object) this, serverWorld.getScoreboard()); + } + if (((WorldBridge) serverWorld).bridge$getGenerator() != null) { + ((WorldBridge) serverWorld).bridge$getWorld().getPopulators().addAll( + ((WorldBridge) serverWorld).bridge$getGenerator().getDefaultPopulators( + ((WorldBridge) serverWorld).bridge$getWorld())); + } + } + + @Inject(method = "loadWorlds", locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/management/PlayerList;func_212504_a(Lnet/minecraft/world/server/ServerWorld;)V")) + private void arclight$initEvent(SaveHandler saveHandlerIn, WorldInfo info, WorldSettings worldSettingsIn, IChunkStatusListener chunkStatusListenerIn, CallbackInfo ci, ServerWorld serverWorld) { + Bukkit.getPluginManager().callEvent(new WorldInitEvent(((WorldBridge) serverWorld).bridge$getWorld())); } @Inject(method = "updateTimeLightAndEntities", at = @At("HEAD")) diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/WorldMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/WorldMixin.java index 49e23eb5..f3f6868c 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/WorldMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/WorldMixin.java @@ -1,5 +1,6 @@ package io.izzel.arclight.common.mixin.core.world; +import io.izzel.arclight.api.ArclightVersion; import io.izzel.arclight.common.bridge.world.WorldBridge; import io.izzel.arclight.common.bridge.world.border.WorldBorderBridge; import io.izzel.arclight.common.mod.util.ArclightCaptures; @@ -76,8 +77,13 @@ public abstract class WorldMixin implements WorldBridge { ((WorldBorderBridge) this.worldBorder).bridge$setWorld((ServerWorld) (Object) this); this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); - this.ticksPerWaterSpawns = this.getServer().getTicksPerWaterSpawns(); - this.ticksPerAmbientSpawns = this.getServer().getTicksPerAmbientSpawns(); + if (ArclightVersion.atLeast(ArclightVersion.v1_15)) { + this.ticksPerWaterSpawns = this.getServer().getTicksPerWaterSpawns(); + this.ticksPerAmbientSpawns = this.getServer().getTicksPerAmbientSpawns(); + } else { + this.ticksPerWaterSpawns = 1; + this.ticksPerAmbientSpawns = 1; + } } @Override @@ -200,7 +206,7 @@ public abstract class WorldMixin implements WorldBridge { @Override public CraftWorld bridge$getWorld() { - return this.world; + return this.getWorld(); } @Override diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/server/ServerWorldMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/server/ServerWorldMixin.java index 22075606..c3d7fa6c 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/server/ServerWorldMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/world/server/ServerWorldMixin.java @@ -92,7 +92,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld throw new RuntimeException(); } - public void arclight$constructor(MinecraftServer serverIn, Executor executor, SaveHandler saveHandler, WorldInfo worldInfo, DimensionType dimType, IProfiler profiler, IChunkStatusListener listener, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { + public void arclight$constructor(MinecraftServer serverIn, Executor executor, SaveHandler saveHandler, WorldInfo worldInfo, DimensionType dimType, IProfiler profiler, IChunkStatusListener listener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) { arclight$constructor(serverIn, executor, saveHandler, worldInfo, dimType, profiler, listener); this.generator = gen; this.environment = env; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/world/dimension/DimensionTypeMixin_1_15.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/world/dimension/DimensionTypeMixin_1_15.java index 6ccccab3..9665f47e 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/world/dimension/DimensionTypeMixin_1_15.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/world/dimension/DimensionTypeMixin_1_15.java @@ -6,6 +6,9 @@ import net.minecraft.world.biome.IBiomeMagnifier; import net.minecraft.world.dimension.Dimension; import net.minecraft.world.dimension.DimensionType; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.function.BiFunction; @@ -36,4 +39,11 @@ public class DimensionTypeMixin_1_15 implements DimensionTypeBridge { public DimensionType bridge$getType() { return getType(); } + + @Inject(method = "isVanilla", remap = false, cancellable = true, at = @At("HEAD")) + private void arclight$vanillaCheck(CallbackInfoReturnable cir) { + if (this.type != null) { + cir.setReturnValue(this.type.isVanilla()); + } + } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/BukkitRegistry.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/BukkitRegistry.java index 661153bb..f8fb1ad1 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/BukkitRegistry.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/BukkitRegistry.java @@ -56,7 +56,7 @@ public class BukkitRegistry { private static void loadEntities() { int origin = EntityType.values().length; int i = origin; - List newTypes = new ArrayList<>(ForgeRegistries.ENTITIES.getEntries().size() - origin); + List newTypes = new ArrayList<>(ForgeRegistries.ENTITIES.getEntries().size() - origin + 1); // UNKNOWN for (Map.Entry> entry : ForgeRegistries.ENTITIES.getEntries()) { ResourceLocation location = entry.getKey(); net.minecraft.entity.EntityType type = entry.getValue(); diff --git a/arclight-forge-1.14/src/main/java/io/izzel/arclight/impl/mixin/v1_14/core/world/dimension/DimensionTypeMixin_1_14.java b/arclight-forge-1.14/src/main/java/io/izzel/arclight/impl/mixin/v1_14/core/world/dimension/DimensionTypeMixin_1_14.java index bcae5e1d..59ba6a28 100644 --- a/arclight-forge-1.14/src/main/java/io/izzel/arclight/impl/mixin/v1_14/core/world/dimension/DimensionTypeMixin_1_14.java +++ b/arclight-forge-1.14/src/main/java/io/izzel/arclight/impl/mixin/v1_14/core/world/dimension/DimensionTypeMixin_1_14.java @@ -5,6 +5,9 @@ import net.minecraft.world.World; import net.minecraft.world.dimension.Dimension; import net.minecraft.world.dimension.DimensionType; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.function.BiFunction; @@ -35,4 +38,11 @@ public class DimensionTypeMixin_1_14 implements DimensionTypeBridge { public DimensionType bridge$getType() { return getType(); } + + @Inject(method = "isVanilla", remap = false, cancellable = true, at = @At("HEAD")) + private void arclight$vanillaCheck(CallbackInfoReturnable cir) { + if (this.type != null) { + cir.setReturnValue(this.type.isVanilla()); + } + } }