Allow cancelling changing dimension.

This commit is contained in:
IzzelAliz 2020-07-12 17:18:38 +08:00
parent b1265fc240
commit 77a5ae9c6f
2 changed files with 17 additions and 8 deletions

View File

@ -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.entity.player.ServerPlayerEntityBridge;
import io.izzel.arclight.common.bridge.inventory.IInventoryBridge; import io.izzel.arclight.common.bridge.inventory.IInventoryBridge;
import io.izzel.arclight.common.bridge.world.ExplosionBridge; 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.server.ServerWorldBridge;
import io.izzel.arclight.common.bridge.world.storage.MapDataBridge; import io.izzel.arclight.common.bridge.world.storage.MapDataBridge;
import io.izzel.arclight.common.bridge.world.storage.WorldInfoBridge; 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.dimension.DimensionType;
import net.minecraft.world.server.ServerChunkProvider; import net.minecraft.world.server.ServerChunkProvider;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.spawner.WanderingTraderSpawner;
import net.minecraft.world.storage.MapData; import net.minecraft.world.storage.MapData;
import net.minecraft.world.storage.SaveHandler; import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo; 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.Implements;
import org.spongepowered.asm.mixin.Interface; import org.spongepowered.asm.mixin.Interface;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -86,6 +89,7 @@ public abstract class ServerWorldMixin extends WorldMixin implements ServerWorld
@Shadow @Final private List<ServerPlayerEntity> players; @Shadow @Final private List<ServerPlayerEntity> players;
@Shadow @Final public Int2ObjectMap<Entity> entitiesById; @Shadow @Final public Int2ObjectMap<Entity> entitiesById;
@Shadow public abstract ServerChunkProvider getChunkProvider(); @Shadow public abstract ServerChunkProvider getChunkProvider();
@Shadow @Final @Mutable @Nullable private WanderingTraderSpawner wanderingTraderSpawner;
// @formatter:on // @formatter:on
public void arclight$constructor(MinecraftServer serverIn, Executor executor, SaveHandler saveHandler, WorldInfo worldInfo, DimensionType dimType, IProfiler profiler, IChunkStatusListener listener) { 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 = "<init>", at = @At("RETURN")) @Inject(method = "<init>", at = @At("RETURN"))
public void arclight$init(MinecraftServer serverIn, Executor executor, SaveHandler saveHandler, WorldInfo worldInfo, DimensionType dimType, IProfiler profiler, IChunkStatusListener listener, CallbackInfo ci) { 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); ((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; private transient boolean arclight$force;

View File

@ -44,7 +44,6 @@ import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.v.CraftWorld; import org.bukkit.craftbukkit.v.CraftWorld;
import org.bukkit.craftbukkit.v.entity.CraftPlayer; import org.bukkit.craftbukkit.v.entity.CraftPlayer;
import org.bukkit.craftbukkit.v.util.BlockStateListPopulator; import org.bukkit.craftbukkit.v.util.BlockStateListPopulator;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
@ -90,7 +89,7 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1
@Overwrite(remap = false) @Overwrite(remap = false)
@Nullable @Nullable
public Entity changeDimension(DimensionType dim, ITeleporter teleporter) { public Entity changeDimension(DimensionType dim, ITeleporter teleporter) {
final DimensionType[] destination = {dim}; DimensionType[] destination = {dim};
if (this.isSleeping()) return (ServerPlayerEntity) (Object) this; if (this.isSleeping()) return (ServerPlayerEntity) (Object) this;
if (!ForgeHooks.onTravelToDimension((ServerPlayerEntity) (Object) this, destination[0])) return null; 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 { } else {
ServerWorld serverworld = this.server.getWorld(dimensiontype); ServerWorld serverworld = this.server.getWorld(dimensiontype);
// this.dimension = destination; // this.dimension = destination;
final ServerWorld[] serverworld1 = {this.server.getWorld(destination[0])}; ServerWorld[] serverworld1 = {this.server.getWorld(destination[0])};
/* /*
WorldInfo worldinfo = serverworld1.getWorldInfo(); 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. 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(); 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 Entity e = teleporter.placeEntity((ServerPlayerEntity) (Object) this, serverworld, serverworld1[0], this.rotationYaw, spawnPortal -> {//Forge: Start vanilla logic
double d0 = this.getPosX(); 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 enter = this.bridge$getBukkitEntity().getLocation();
Location exit = (serverworld1[0] == null) ? null : new Location(((ServerWorldBridge) serverworld1[0]).bridge$getWorld(), d0, d1, d2, f1, f); 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); Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled() || event.getTo() == null) { if (event.isCancelled() || event.getTo() == null) {
return null; return null;
@ -240,7 +239,7 @@ public abstract class ServerPlayerEntityMixin_1_15 extends PlayerEntityMixin_1_1
serverworld.getProfiler().endSection(); 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); Bukkit.getServer().getPluginManager().callEvent(tpEvent);
if (tpEvent.isCancelled() || tpEvent.getTo() == null) { if (tpEvent.isCancelled() || tpEvent.getTo() == null) {
return 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 return (ServerPlayerEntity) (Object) this;//forge: this is part of the ITeleporter patch
});//Forge: End vanilla logic });//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)); 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.interactionManager.setWorld(serverworld1[0]);
this.connection.sendPacket(new SPlayerAbilitiesPacket(this.abilities)); this.connection.sendPacket(new SPlayerAbilitiesPacket(this.abilities));
playerlist[0].sendWorldInfo((ServerPlayerEntity) (Object) this, serverworld1[0]); 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; this.lastFoodLevel = -1;
BasicEventHooks.firePlayerChangedDimensionEvent((ServerPlayerEntity) (Object) this, dimensiontype, destination[0]); 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); Bukkit.getPluginManager().callEvent(changeEvent);
return (ServerPlayerEntity) (Object) this; return (ServerPlayerEntity) (Object) this;
} }