From 77a5ae9c6fe097c4f92344e952f14b927e3e8644 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Sun, 12 Jul 2020 17:18:38 +0800 Subject: [PATCH] Allow cancelling changing dimension. --- .../core/world/server/ServerWorldMixin.java | 7 +++++++ .../player/ServerPlayerEntityMixin_1_15.java | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) 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 c3d7fa6c..8e4e972a 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 @@ -5,6 +5,7 @@ import io.izzel.arclight.common.bridge.entity.EntityBridge; import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.inventory.IInventoryBridge; import io.izzel.arclight.common.bridge.world.ExplosionBridge; +import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge; import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge; import io.izzel.arclight.common.bridge.world.storage.MapDataBridge; import io.izzel.arclight.common.bridge.world.storage.WorldInfoBridge; @@ -39,6 +40,7 @@ import net.minecraft.world.chunk.listener.IChunkStatusListener; import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.server.ServerChunkProvider; import net.minecraft.world.server.ServerWorld; +import net.minecraft.world.spawner.WanderingTraderSpawner; import net.minecraft.world.storage.MapData; import net.minecraft.world.storage.SaveHandler; import net.minecraft.world.storage.WorldInfo; @@ -56,6 +58,7 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Interface; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -86,6 +89,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld @Shadow @Final private List players; @Shadow @Final public Int2ObjectMap entitiesById; @Shadow public abstract ServerChunkProvider getChunkProvider(); + @Shadow @Final @Mutable @Nullable private WanderingTraderSpawner wanderingTraderSpawner; // @formatter:on public void arclight$constructor(MinecraftServer serverIn, Executor executor, SaveHandler saveHandler, WorldInfo worldInfo, DimensionType dimType, IProfiler profiler, IChunkStatusListener listener) { @@ -190,6 +194,9 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld @Inject(method = "", at = @At("RETURN")) public void arclight$init(MinecraftServer serverIn, Executor executor, SaveHandler saveHandler, WorldInfo worldInfo, DimensionType dimType, IProfiler profiler, IChunkStatusListener listener, CallbackInfo ci) { ((WorldInfoBridge) worldInfo).bridge$setWorld((ServerWorld) (Object) this); + if (this.wanderingTraderSpawner == null && ((DimensionTypeBridge) this.dimension.getType()).bridge$getType() == DimensionType.OVERWORLD) { + this.wanderingTraderSpawner = new WanderingTraderSpawner((ServerWorld) (Object) this); + } } private transient boolean arclight$force; diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/entity/player/ServerPlayerEntityMixin_1_15.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/entity/player/ServerPlayerEntityMixin_1_15.java index a5174cad..245ab3bd 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/entity/player/ServerPlayerEntityMixin_1_15.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/entity/player/ServerPlayerEntityMixin_1_15.java @@ -44,7 +44,6 @@ import org.bukkit.block.BlockState; import org.bukkit.craftbukkit.v.CraftWorld; import org.bukkit.craftbukkit.v.entity.CraftPlayer; import org.bukkit.craftbukkit.v.util.BlockStateListPopulator; -import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerTeleportEvent; @@ -90,7 +89,7 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1 @Overwrite(remap = false) @Nullable public Entity changeDimension(DimensionType dim, ITeleporter teleporter) { - final DimensionType[] destination = {dim}; + DimensionType[] destination = {dim}; if (this.isSleeping()) return (ServerPlayerEntity) (Object) this; if (!ForgeHooks.onTravelToDimension((ServerPlayerEntity) (Object) this, destination[0])) return null; @@ -112,7 +111,7 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1 } else { ServerWorld serverworld = this.server.getWorld(dimensiontype); // this.dimension = destination; - final ServerWorld[] serverworld1 = {this.server.getWorld(destination[0])}; + ServerWorld[] serverworld1 = {this.server.getWorld(destination[0])}; /* WorldInfo worldinfo = serverworld1.getWorldInfo(); @@ -124,7 +123,7 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1 serverworld.removeEntity((ServerPlayerEntity) (Object) this, true); //Forge: the player entity is moved to the new world, NOT cloned. So keep the data alive with no matching invalidate call. this.revive(); */ - final PlayerList[] playerlist = new PlayerList[1]; + PlayerList[] playerlist = new PlayerList[1]; Entity e = teleporter.placeEntity((ServerPlayerEntity) (Object) this, serverworld, serverworld1[0], this.rotationYaw, spawnPortal -> {//Forge: Start vanilla logic double d0 = this.getPosX(); @@ -154,7 +153,7 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1 Location enter = this.bridge$getBukkitEntity().getLocation(); Location exit = (serverworld1[0] == null) ? null : new Location(((ServerWorldBridge) serverworld1[0]).bridge$getWorld(), d0, d1, d2, f1, f); - PlayerPortalEvent event = new PlayerPortalEvent((Player) this.bridge$getBukkitEntity(), enter, exit, cause, 128, true, ((DimensionTypeBridge) destination[0]).bridge$getType() == DimensionType.THE_END ? 0 : 16); + PlayerPortalEvent event = new PlayerPortalEvent(this.bridge$getBukkitEntity(), enter, exit, cause, 128, true, ((DimensionTypeBridge) destination[0]).bridge$getType() == DimensionType.THE_END ? 0 : 16); Bukkit.getServer().getPluginManager().callEvent(event); if (event.isCancelled() || event.getTo() == null) { return null; @@ -240,7 +239,7 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1 serverworld.getProfiler().endSection(); - final PlayerTeleportEvent tpEvent = new PlayerTeleportEvent((Player) this.bridge$getBukkitEntity(), enter, exit, cause); + PlayerTeleportEvent tpEvent = new PlayerTeleportEvent(this.bridge$getBukkitEntity(), enter, exit, cause); Bukkit.getServer().getPluginManager().callEvent(tpEvent); if (tpEvent.isCancelled() || tpEvent.getTo() == null) { return null; @@ -278,8 +277,11 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1 return (ServerPlayerEntity) (Object) this;//forge: this is part of the ITeleporter patch });//Forge: End vanilla logic - if (e != (Object) this) + if (e == null) { + return (ServerPlayerEntity) (Object) this; + } else if (e != (Object) this) { throw new IllegalArgumentException(String.format("Teleporter %s returned not the player entity but instead %s, expected PlayerEntity %s", teleporter, e, this)); + } this.interactionManager.setWorld(serverworld1[0]); this.connection.sendPacket(new SPlayerAbilitiesPacket(this.abilities)); playerlist[0].sendWorldInfo((ServerPlayerEntity) (Object) this, serverworld1[0]); @@ -295,7 +297,7 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1 this.lastFoodLevel = -1; BasicEventHooks.firePlayerChangedDimensionEvent((ServerPlayerEntity) (Object) this, dimensiontype, destination[0]); - PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent((Player) this.bridge$getBukkitEntity(), ((WorldBridge) serverworld).bridge$getWorld()); + PlayerChangedWorldEvent changeEvent = new PlayerChangedWorldEvent(this.bridge$getBukkitEntity(), ((WorldBridge) serverworld).bridge$getWorld()); Bukkit.getPluginManager().callEvent(changeEvent); return (ServerPlayerEntity) (Object) this; }