Fix couples issues related to respawn and cross-world teleport (#752)

This commit is contained in:
sandtechnology 2022-10-21 10:35:48 +08:00 committed by IzzelAliz
parent 67052c1a1e
commit d623d5f569

View File

@ -82,6 +82,7 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@ -162,11 +163,11 @@ public abstract class PlayerListMixin implements PlayerListBridge {
this.players.add(playerIn); this.players.add(playerIn);
this.playersByUUID.put(playerIn.getUUID(), playerIn); this.playersByUUID.put(playerIn.getUUID(), playerIn);
this.cserver.getPluginManager().callEvent(playerJoinEvent); this.cserver.getPluginManager().callEvent(playerJoinEvent);
this.players.remove(playerIn);
if (!playerIn.connection.connection.isConnected()) { if (!playerIn.connection.connection.isConnected()) {
ci.cancel(); ci.cancel();
return; return;
} }
this.players.remove(playerIn);
String joinMessage = playerJoinEvent.getJoinMessage(); String joinMessage = playerJoinEvent.getJoinMessage();
if (joinMessage != null && joinMessage.length() > 0) { if (joinMessage != null && joinMessage.length() > 0) {
for (Component line : CraftChatMessage.fromString(joinMessage)) { for (Component line : CraftChatMessage.fromString(joinMessage)) {
@ -175,6 +176,18 @@ public abstract class PlayerListMixin implements PlayerListBridge {
} }
} }
@Redirect(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ServerLevel;addNewPlayer(Lnet/minecraft/server/level/ServerPlayer;)V"))
private void arclight$addNewPlayer(ServerLevel instance, ServerPlayer player) {
if (player.level == instance && !instance.players().contains(player)) {
instance.addNewPlayer(player);
}
}
@ModifyVariable(method = "placeNewPlayer", ordinal = 1, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/server/level/ServerLevel;addNewPlayer(Lnet/minecraft/server/level/ServerPlayer;)V"))
private ServerLevel arclight$handleWorldChanges(ServerLevel value, Connection connection, ServerPlayer player) {
return player.getLevel();
}
@Inject(method = "save", cancellable = true, at = @At("HEAD")) @Inject(method = "save", cancellable = true, at = @At("HEAD"))
private void arclight$returnIfNotPersist(ServerPlayer playerIn, CallbackInfo ci) { private void arclight$returnIfNotPersist(ServerPlayer playerIn, CallbackInfo ci) {
if (!((ServerPlayerEntityBridge) playerIn).bridge$isPersist()) { if (!((ServerPlayerEntityBridge) playerIn).bridge$isPersist()) {
@ -314,9 +327,9 @@ public abstract class PlayerListMixin implements PlayerListBridge {
location.setWorld(((WorldBridge) worldIn).bridge$getWorld()); location.setWorld(((WorldBridge) worldIn).bridge$getWorld());
} }
ServerLevel serverWorld = ((CraftWorld) location.getWorld()).getHandle(); ServerLevel serverWorld = ((CraftWorld) location.getWorld()).getHandle();
playerIn.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); playerIn.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
playerIn.connection.resetPosition(); playerIn.connection.resetPosition();
while (avoidSuffocation && !serverWorld.noCollision(playerIn) && playerIn.getY() < 256.0) { while (avoidSuffocation && !serverWorld.noCollision(playerIn) && playerIn.getY() < serverWorld.getMaxBuildHeight()) {
playerIn.setPos(playerIn.getX(), playerIn.getY() + 1.0, playerIn.getZ()); playerIn.setPos(playerIn.getX(), playerIn.getY() + 1.0, playerIn.getZ());
} }
LevelData worlddata = serverWorld.getLevelData(); LevelData worlddata = serverWorld.getLevelData();
@ -332,7 +345,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
this.sendLevelInfo(playerIn, serverWorld); this.sendLevelInfo(playerIn, serverWorld);
this.sendPlayerPermissionLevel(playerIn); this.sendPlayerPermissionLevel(playerIn);
if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) {
serverWorld.addDuringCommandTeleport(playerIn); serverWorld.addRespawnedPlayer(playerIn);
this.players.add(playerIn); this.players.add(playerIn);
this.playersByUUID.put(playerIn.getUUID(), playerIn); this.playersByUUID.put(playerIn.getUUID(), playerIn);
} }
@ -458,7 +471,7 @@ public abstract class PlayerListMixin implements PlayerListBridge {
serverplayerentity.addTag(s); serverplayerentity.addTag(s);
} }
serverplayerentity.absMoveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); serverplayerentity.moveTo(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
serverplayerentity.connection.resetPosition(); serverplayerentity.connection.resetPosition();
while (avoidSuffocation && !serverWorld.noCollision(serverplayerentity) && serverplayerentity.getY() < serverWorld.getMaxBuildHeight()) { while (avoidSuffocation && !serverWorld.noCollision(serverplayerentity) && serverplayerentity.getY() < serverWorld.getMaxBuildHeight()) {