From b1265fc24048dd6fc691c348e65cdd4f7694d817 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Sun, 12 Jul 2020 16:52:51 +0800 Subject: [PATCH] Fix cross-world teleport not tracking player. Close #14. --- .../server/management/PlayerListMixin.java | 166 +++++++++++++++--- .../mixin/v1_15/entity/EntityMixin_1_15.java | 94 +++++----- .../management/PlayerListMixin_1_15.java | 11 ++ .../resources/META-INF/accesstransformer.cfg | 2 + .../management/PlayerListMixin_1_14.java | 11 ++ 5 files changed, 214 insertions(+), 70 deletions(-) diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java index b5e25980..480e79cd 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/server/management/PlayerListMixin.java @@ -3,6 +3,8 @@ package io.izzel.arclight.common.mixin.core.server.management; import com.google.common.collect.Lists; import com.mojang.authlib.GameProfile; import io.izzel.arclight.api.ArclightVersion; +import io.izzel.arclight.common.bridge.entity.EntityBridge; +import io.izzel.arclight.common.bridge.entity.InternalEntityBridge; import io.izzel.arclight.common.bridge.entity.player.PlayerEntityBridge; import io.izzel.arclight.common.bridge.entity.player.ServerPlayerEntityBridge; import io.izzel.arclight.common.bridge.network.NetworkManagerBridge; @@ -12,9 +14,11 @@ import io.izzel.arclight.common.bridge.server.MinecraftServerBridge; import io.izzel.arclight.common.bridge.server.management.PlayerListBridge; import io.izzel.arclight.common.bridge.world.WorldBridge; import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge; +import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge; import io.izzel.arclight.common.mod.ArclightMod; import io.izzel.arclight.common.mod.server.BukkitRegistry; import io.izzel.arclight.common.mod.util.ArclightCaptures; +import net.minecraft.entity.MobEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.network.IPacket; @@ -23,10 +27,13 @@ import net.minecraft.network.login.ServerLoginNetHandler; import net.minecraft.network.play.server.SChangeGameStatePacket; import net.minecraft.network.play.server.SChatPacket; import net.minecraft.network.play.server.SEntityStatusPacket; +import net.minecraft.network.play.server.SPlayEntityEffectPacket; +import net.minecraft.network.play.server.SRespawnPacket; import net.minecraft.network.play.server.SServerDifficultyPacket; import net.minecraft.network.play.server.SSetExperiencePacket; import net.minecraft.network.play.server.SSpawnPositionPacket; import net.minecraft.network.play.server.SUpdateViewDistancePacket; +import net.minecraft.potion.EffectInstance; import net.minecraft.server.MinecraftServer; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.management.BanList; @@ -110,6 +117,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { @Shadow public abstract void updatePermissionLevel(ServerPlayerEntity player); @Shadow(remap = false) public abstract boolean addPlayer(ServerPlayerEntity player); @Shadow @Final private Map uuidToPlayerMap; + @Shadow public abstract void sendInventory(ServerPlayerEntity playerIn); // @formatter:on private CraftServer cserver; @@ -207,10 +215,101 @@ public abstract class PlayerListMixin implements PlayerListBridge { return entity; } - public ServerPlayerEntity moveToWorld(ServerPlayerEntity playerIn, DimensionType dimension, boolean conqueredEnd, Location location, boolean avoidSuffocation) { - arclight$loc = location; - arclight$suffo = avoidSuffocation; - return recreatePlayerEntity(playerIn, dimension, conqueredEnd); + public ServerPlayerEntity moveToWorld(ServerPlayerEntity playerIn, DimensionType type, boolean flag, Location location, boolean avoidSuffocation) { + if (!net.minecraftforge.common.ForgeHooks.onTravelToDimension(playerIn, type)) return playerIn; + playerIn.stopRiding(); + this.players.remove(playerIn); + // this.playersByName.remove(playerIn.getScoreboardName().toLowerCase(Locale.ROOT)); + playerIn.getServerWorld().removePlayer(playerIn, true); + BlockPos pos = playerIn.getBedLocation(type); + boolean flag2 = playerIn.isSpawnForced(type); + org.bukkit.World fromWorld = ((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity().getWorld(); + playerIn.queuedEndExit = false; + playerIn.copyFrom(playerIn, flag); + playerIn.setEntityId(playerIn.getEntityId()); + playerIn.setPrimaryHand(playerIn.getPrimaryHand()); + for (String s : playerIn.getTags()) { + playerIn.addTag(s); + } + if (location == null) { + boolean isBedSpawn = false; + CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(((ServerPlayerEntityBridge) playerIn).bridge$getSpawnWorld()); + if (cworld != null && pos != null) { + Optional optional = PlayerEntity.checkBedValidRespawnPosition(cworld.getHandle(), pos, flag2); + if (optional.isPresent()) { + Vec3d vec3d = optional.get(); + isBedSpawn = true; + location = new Location(cworld, vec3d.x, vec3d.y, vec3d.z); + } else { + playerIn.setRespawnPosition(null, true, false); + playerIn.connection.sendPacket(new SChangeGameStatePacket(0, 0.0f)); + } + } + if (location == null) { + cworld = (CraftWorld) Bukkit.getServer().getWorlds().get(0); + pos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(cworld.getHandle()); + location = new Location(cworld, pos.getX() + 0.5f, pos.getY() + 0.1f, pos.getZ() + 0.5f); + } + Player respawnPlayer = this.cserver.getPlayer(playerIn); + PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn); + this.cserver.getPluginManager().callEvent(respawnEvent); + if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { + return playerIn; + } + location = respawnEvent.getRespawnLocation(); + if (!flag) { + ((ServerPlayerEntityBridge) playerIn).bridge$reset(); + } + } else { + location.setWorld(((WorldBridge) this.server.getWorld(type)).bridge$getWorld()); + } + ServerWorld serverWorld = ((CraftWorld) location.getWorld()).getHandle(); + playerIn.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + playerIn.connection.captureCurrentPosition(); + while (avoidSuffocation && !serverWorld.hasNoCollisions(playerIn) && playerIn.getPosY() < 256.0) { + playerIn.setPosition(playerIn.getPosX(), playerIn.getPosY() + 1.0, playerIn.getPosZ()); + } + if (fromWorld.getEnvironment() == ((WorldBridge) serverWorld).bridge$getWorld().getEnvironment()) { + playerIn.connection.sendPacket(new SRespawnPacket((serverWorld.dimension.getType().getId() >= 0) ? DimensionType.THE_NETHER : DimensionType.OVERWORLD, WorldInfo.byHashing(serverWorld.getWorldInfo().getSeed()), serverWorld.getWorldInfo().getGenerator(), playerIn.interactionManager.getGameType())); + } + WorldInfo worldInfo = serverWorld.getWorldInfo(); + net.minecraftforge.fml.network.NetworkHooks.sendDimensionDataPacket(playerIn.connection.netManager, playerIn); + playerIn.connection.sendPacket(new SRespawnPacket(((DimensionTypeBridge) serverWorld.dimension.getType()).bridge$getType(), WorldInfo.byHashing(serverWorld.getWorldInfo().getSeed()), serverWorld.getWorldInfo().getGenerator(), playerIn.interactionManager.getGameType())); + playerIn.connection.sendPacket(new SUpdateViewDistancePacket(((ServerWorldBridge) serverWorld).bridge$spigotConfig().viewDistance)); + playerIn.setWorld(serverWorld); + playerIn.interactionManager.setWorld(serverWorld); + playerIn.revive(); + ((ServerPlayNetHandlerBridge) playerIn.connection).bridge$teleport(new Location(((WorldBridge) serverWorld).bridge$getWorld(), playerIn.getPosX(), playerIn.getPosY(), playerIn.getPosZ(), playerIn.rotationYaw, playerIn.rotationPitch)); + playerIn.setSneaking(false); + BlockPos pos1 = serverWorld.getSpawnPoint(); + playerIn.connection.sendPacket(new SSpawnPositionPacket(pos1)); + playerIn.connection.sendPacket(new SServerDifficultyPacket(worldInfo.getDifficulty(), worldInfo.isDifficultyLocked())); + playerIn.connection.sendPacket(new SSetExperiencePacket(playerIn.experience, playerIn.experienceTotal, playerIn.experienceLevel)); + this.sendWorldInfo(playerIn, serverWorld); + this.updatePermissionLevel(playerIn); + if (!((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { + serverWorld.addRespawnedPlayer(playerIn); + this.players.add(playerIn); + //this.playersByName.put(entityplayer2.getScoreboardName().toLowerCase(Locale.ROOT), entityplayer2); + this.uuidToPlayerMap.put(playerIn.getUniqueID(), playerIn); + } + playerIn.setHealth(playerIn.getHealth()); + this.sendInventory(playerIn); + playerIn.sendPlayerAbilities(); + for (Object o1 : playerIn.getActivePotionEffects()) { + EffectInstance mobEffect = (EffectInstance) o1; + playerIn.connection.sendPacket(new SPlayEntityEffectPacket(playerIn.getEntityId(), mobEffect)); + } + playerIn.func_213846_b(((CraftWorld) fromWorld).getHandle()); + if (fromWorld != location.getWorld()) { + PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity(), fromWorld); + Bukkit.getPluginManager().callEvent(event); + } + if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { + this.writePlayerData(playerIn); + } + net.minecraftforge.fml.hooks.BasicEventHooks.firePlayerRespawnEvent(playerIn, flag); + return playerIn; } private transient Location arclight$loc; @@ -241,7 +340,7 @@ public abstract class PlayerListMixin implements PlayerListBridge { playerIn.getServerWorld().removePlayer(playerIn, true); // Forge: keep data until copyFrom called BlockPos blockpos = playerIn.getBedLocation(dimension); boolean flag = playerIn.isSpawnForced(dimension); - playerIn.dimension = dimension; + // playerIn.dimension = dimension; PlayerInteractionManager playerinteractionmanager; if (this.server.isDemo()) { playerinteractionmanager = new DemoPlayerInteractionManager(this.server.getWorld(playerIn.dimension)); @@ -251,18 +350,6 @@ public abstract class PlayerListMixin implements PlayerListBridge { playerIn.queuedEndExit = false; - ServerPlayerEntity serverplayerentity = new ServerPlayerEntity(this.server, this.server.getWorld(playerIn.dimension), playerIn.getGameProfile(), playerinteractionmanager); - serverplayerentity.connection = playerIn.connection; - serverplayerentity.copyFrom(playerIn, conqueredEnd); - playerIn.remove(false); // Forge: clone event had a chance to see old data, now discard it - serverplayerentity.dimension = dimension; - serverplayerentity.setEntityId(playerIn.getEntityId()); - serverplayerentity.setPrimaryHand(playerIn.getPrimaryHand()); - - for (String s : playerIn.getTags()) { - serverplayerentity.addTag(s); - } - if (location == null) { boolean isBedSpawn = false; CraftWorld cworld = (CraftWorld) Bukkit.getWorld(((PlayerEntityBridge) playerIn).bridge$getSpawnWorld()); @@ -273,22 +360,26 @@ public abstract class PlayerListMixin implements PlayerListBridge { isBedSpawn = true; location = new Location(cworld, vec3d.x, vec3d.y, vec3d.z); } else { - this.bridge$setSpawnPoint(serverplayerentity, null, true, serverplayerentity.dimension, false); - serverplayerentity.connection.sendPacket(new SChangeGameStatePacket(0, 0.0f)); + this.bridge$setSpawnPoint(playerIn, null, true, playerIn.dimension, false); + playerIn.connection.sendPacket(new SChangeGameStatePacket(0, 0.0f)); } } if (location == null) { cworld = (CraftWorld) Bukkit.getWorlds().get(0); - blockpos = ((ServerPlayerEntityBridge) serverplayerentity).bridge$getSpawnPoint(cworld.getHandle()); + blockpos = ((ServerPlayerEntityBridge) playerIn).bridge$getSpawnPoint(cworld.getHandle()); location = new Location(cworld, blockpos.getX() + 0.5f, blockpos.getY() + 0.1f, blockpos.getZ() + 0.5f); } - Player respawnPlayer = this.cserver.getPlayer(serverplayerentity); + Player respawnPlayer = this.cserver.getPlayer(playerIn); PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn); this.cserver.getPluginManager().callEvent(respawnEvent); if (((ServerPlayNetHandlerBridge) playerIn.connection).bridge$isDisconnected()) { return playerIn; } location = respawnEvent.getRespawnLocation(); + if (location.getWorld() == null) { + location.setWorld(((WorldBridge) this.server.getWorld(dimension)).bridge$getWorld()); + } + dimension = ((CraftWorld) location.getWorld()).getHandle().dimension.getType(); if (!flag) { ((ServerPlayerEntityBridge) playerIn).bridge$reset(); } @@ -296,6 +387,28 @@ public abstract class PlayerListMixin implements PlayerListBridge { location.setWorld(((WorldBridge) this.server.getWorld(dimension)).bridge$getWorld()); } + playerIn.dimension = dimension; + + ServerPlayerEntity serverplayerentity = new ServerPlayerEntity(this.server, this.server.getWorld(playerIn.dimension), playerIn.getGameProfile(), playerinteractionmanager); + + // Forward to new player instance + ((InternalEntityBridge) playerIn).internal$getBukkitEntity().setHandle(serverplayerentity); + ((EntityBridge) serverplayerentity).bridge$setBukkitEntity(((InternalEntityBridge) playerIn).internal$getBukkitEntity()); + if ((Object) serverplayerentity instanceof MobEntity) { + ((MobEntity) (Object) serverplayerentity).clearLeashed(true, false); + } + + serverplayerentity.connection = playerIn.connection; + serverplayerentity.copyFrom(playerIn, conqueredEnd); + playerIn.remove(false); // Forge: clone event had a chance to see old data, now discard it + serverplayerentity.dimension = dimension; + serverplayerentity.setEntityId(playerIn.getEntityId()); + serverplayerentity.setPrimaryHand(playerIn.getPrimaryHand()); + + for (String s : playerIn.getTags()) { + serverplayerentity.addTag(s); + } + ServerWorld serverworld = ((CraftWorld) location.getWorld()).getHandle(); serverplayerentity.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); serverplayerentity.connection.captureCurrentPosition(); @@ -331,12 +444,17 @@ public abstract class PlayerListMixin implements PlayerListBridge { serverplayerentity.connection.sendPacket(new SSetExperiencePacket(serverplayerentity.experience, serverplayerentity.experienceTotal, serverplayerentity.experienceLevel)); this.sendWorldInfo(serverplayerentity, serverworld); this.updatePermissionLevel(serverplayerentity); - serverworld.addRespawnedPlayer(serverplayerentity); - this.addPlayer(serverplayerentity); - this.uuidToPlayerMap.put(serverplayerentity.getUniqueID(), serverplayerentity); + if (!((ServerPlayNetHandlerBridge) serverplayerentity.connection).bridge$isDisconnected()) { + serverworld.addRespawnedPlayer(serverplayerentity); + this.addPlayer(serverplayerentity); + this.uuidToPlayerMap.put(serverplayerentity.getUniqueID(), serverplayerentity); + } serverplayerentity.addSelfToInternalCraftingInventory(); serverplayerentity.setHealth(serverplayerentity.getHealth()); + this.sendInventory(serverplayerentity); + serverplayerentity.sendPlayerAbilities(); + serverplayerentity.func_213846_b(((CraftWorld) fromWorld).getHandle()); if (fromWorld != location.getWorld()) { PlayerChangedWorldEvent event = new PlayerChangedWorldEvent(((ServerPlayerEntityBridge) playerIn).bridge$getBukkitEntity(), fromWorld); Bukkit.getPluginManager().callEvent(event); diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/entity/EntityMixin_1_15.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/entity/EntityMixin_1_15.java index 7e6b5478..53867d68 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/entity/EntityMixin_1_15.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/entity/EntityMixin_1_15.java @@ -123,55 +123,57 @@ public abstract class EntityMixin_1_15 implements EntityBridge { Entity transportedEntity = teleporter.placeEntity((Entity) (Object) this, serverworld, serverworld1[0], this.rotationYaw, spawnPortal -> { //Forge: Start vanilla logic Vec3d vec3d = this.getMotion(); float f = 0.0F; - BlockPos blockpos; - if (dimensiontype == DimensionType.THE_END && destination == DimensionType.OVERWORLD) { - EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], serverworld1[0].getHeight(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, serverworld1[0].getSpawnPoint()), 0); - if (event == null) { - return null; - } - serverworld1[0] = ((CraftWorld) event.getTo().getWorld()).getHandle(); - blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); - //blockpos = serverworld1[0].getHeight(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, serverworld1[0].getSpawnPoint()); - } else if (destination == DimensionType.THE_END) { - EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], (serverworld1[0].getSpawnCoordinate() != null) ? serverworld1[0].getSpawnCoordinate() : serverworld1[0].getSpawnPoint(), 0); - if (event == null) { - return null; - } - serverworld1[0] = ((CraftWorld) event.getTo().getWorld()).getHandle(); - blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); - //blockpos = serverworld1[0].getSpawnCoordinate(); - } else { - double movementFactor = serverworld.getDimension().getMovementFactor() / serverworld1[0].getDimension().getMovementFactor(); - double d0 = this.getPosX() * movementFactor; - double d1 = this.getPosZ() * movementFactor; - - double d3 = Math.min(-2.9999872E7D, serverworld1[0].getWorldBorder().minX() + 16.0D); - double d4 = Math.min(-2.9999872E7D, serverworld1[0].getWorldBorder().minZ() + 16.0D); - double d5 = Math.min(2.9999872E7D, serverworld1[0].getWorldBorder().maxX() - 16.0D); - double d6 = Math.min(2.9999872E7D, serverworld1[0].getWorldBorder().maxZ() - 16.0D); - d0 = MathHelper.clamp(d0, d3, d5); - d1 = MathHelper.clamp(d1, d4, d6); - Vec3d vec3d1 = this.getLastPortalVec(); - blockpos = new BlockPos(d0, this.getPosY(), d1); - - EntityPortalEvent event2 = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], blockpos, 128); - if (event2 == null) { - return null; - } - serverworld1[0] = ((CraftWorld) event2.getTo().getWorld()).getHandle(); - blockpos = new BlockPos(event2.getTo().getX(), event2.getTo().getY(), event2.getTo().getZ()); - int searchRadius = event2.getSearchRadius(); - // todo 实现 radius - - if (spawnPortal) { - BlockPattern.PortalInfo blockpattern$portalinfo = serverworld1[0].getDefaultTeleporter().placeInExistingPortal(blockpos, vec3d, this.getTeleportDirection(), vec3d1.x, vec3d1.y, (Object) this instanceof PlayerEntity); - if (blockpattern$portalinfo == null) { + BlockPos blockpos = location; + if (blockpos == null) { + if (dimensiontype == DimensionType.THE_END && destination == DimensionType.OVERWORLD) { + EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], serverworld1[0].getHeight(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, serverworld1[0].getSpawnPoint()), 0); + if (event == null) { return null; } + serverworld1[0] = ((CraftWorld) event.getTo().getWorld()).getHandle(); + blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); + //blockpos = serverworld1[0].getHeight(Heightmap.Type.MOTION_BLOCKING_NO_LEAVES, serverworld1[0].getSpawnPoint()); + } else if (destination == DimensionType.THE_END) { + EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], (serverworld1[0].getSpawnCoordinate() != null) ? serverworld1[0].getSpawnCoordinate() : serverworld1[0].getSpawnPoint(), 0); + if (event == null) { + return null; + } + serverworld1[0] = ((CraftWorld) event.getTo().getWorld()).getHandle(); + blockpos = new BlockPos(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); + //blockpos = serverworld1[0].getSpawnCoordinate(); + } else { + double movementFactor = serverworld.getDimension().getMovementFactor() / serverworld1[0].getDimension().getMovementFactor(); + double d0 = this.getPosX() * movementFactor; + double d1 = this.getPosZ() * movementFactor; - blockpos = new BlockPos(blockpattern$portalinfo.pos); - vec3d = blockpattern$portalinfo.motion; - f = (float) blockpattern$portalinfo.rotation; + double d3 = Math.min(-2.9999872E7D, serverworld1[0].getWorldBorder().minX() + 16.0D); + double d4 = Math.min(-2.9999872E7D, serverworld1[0].getWorldBorder().minZ() + 16.0D); + double d5 = Math.min(2.9999872E7D, serverworld1[0].getWorldBorder().maxX() - 16.0D); + double d6 = Math.min(2.9999872E7D, serverworld1[0].getWorldBorder().maxZ() - 16.0D); + d0 = MathHelper.clamp(d0, d3, d5); + d1 = MathHelper.clamp(d1, d4, d6); + Vec3d vec3d1 = this.getLastPortalVec(); + blockpos = new BlockPos(d0, this.getPosY(), d1); + + EntityPortalEvent event2 = CraftEventFactory.callEntityPortalEvent((Entity) (Object) this, serverworld1[0], blockpos, 128); + if (event2 == null) { + return null; + } + serverworld1[0] = ((CraftWorld) event2.getTo().getWorld()).getHandle(); + blockpos = new BlockPos(event2.getTo().getX(), event2.getTo().getY(), event2.getTo().getZ()); + int searchRadius = event2.getSearchRadius(); + // todo 实现 radius + + if (spawnPortal) { + BlockPattern.PortalInfo blockpattern$portalinfo = serverworld1[0].getDefaultTeleporter().placeInExistingPortal(blockpos, vec3d, this.getTeleportDirection(), vec3d1.x, vec3d1.y, (Object) this instanceof PlayerEntity); + if (blockpattern$portalinfo == null) { + return null; + } + + blockpos = new BlockPos(blockpattern$portalinfo.pos); + vec3d = blockpattern$portalinfo.motion; + f = (float) blockpattern$portalinfo.rotation; + } } } diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/server/management/PlayerListMixin_1_15.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/server/management/PlayerListMixin_1_15.java index ce965a71..c2810b37 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/server/management/PlayerListMixin_1_15.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/v1_15/server/management/PlayerListMixin_1_15.java @@ -1,8 +1,12 @@ package io.izzel.arclight.common.mixin.v1_15.server.management; import io.izzel.arclight.common.bridge.server.management.PlayerListBridge; +import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge; +import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge; import net.minecraft.entity.Entity; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.play.server.SJoinGamePacket; import net.minecraft.network.play.server.SRespawnPacket; import net.minecraft.server.management.PlayerList; import net.minecraft.util.math.BlockPos; @@ -11,6 +15,8 @@ import net.minecraft.world.WorldType; import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.server.ServerWorld; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(PlayerList.class) public abstract class PlayerListMixin_1_15 implements PlayerListBridge { @@ -29,4 +35,9 @@ public abstract class PlayerListMixin_1_15 implements PlayerListBridge { public SRespawnPacket bridge$respawnPacket(DimensionType type, long seed, WorldType worldType, GameType gameType) { return new SRespawnPacket(type, seed, worldType, gameType); } + + @Redirect(method = "initializeConnectionToPlayer", at = @At(value = "NEW", target = "net/minecraft/network/play/server/SJoinGamePacket")) + private SJoinGamePacket arclight$spawnPacket(int playerId, GameType gameType, long hashedSeed, boolean hardcoreMode, DimensionType dimensionType, int maxPlayers, WorldType worldType, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, NetworkManager netManager, ServerPlayerEntity playerIn) { + return new SJoinGamePacket(playerId, gameType, hashedSeed, hardcoreMode, ((DimensionTypeBridge) dimensionType).bridge$getType(), maxPlayers, worldType, ((ServerWorldBridge) playerIn.getServerWorld()).bridge$spigotConfig().viewDistance, reducedDebugInfo, enableRespawnScreen); + } } diff --git a/arclight-common/src/main/resources/META-INF/accesstransformer.cfg b/arclight-common/src/main/resources/META-INF/accesstransformer.cfg index 615a1bf9..7892e0a2 100644 --- a/arclight-common/src/main/resources/META-INF/accesstransformer.cfg +++ b/arclight-common/src/main/resources/META-INF/accesstransformer.cfg @@ -19,6 +19,8 @@ public net.minecraft.block.ComposterBlock$EmptyInventory public net.minecraft.tileentity.SkullTileEntity field_184299_k #sessionService public net.minecraft.item.crafting.Ingredient (Ljava/util/stream/Stream;)V public net.minecraft.world.server.TicketManager field_219377_e #tickets +public net.minecraft.world.server.TicketManager$PlayerChunkTracker +public net.minecraft.world.server.TicketManager$PlayerTicketTracker # Arclight 1.15 public net.minecraft.entity.Entity field_70165_t #posX public net.minecraft.entity.Entity field_70163_u #posY diff --git a/arclight-forge-1.14/src/main/java/io/izzel/arclight/impl/mixin/v1_14/core/server/management/PlayerListMixin_1_14.java b/arclight-forge-1.14/src/main/java/io/izzel/arclight/impl/mixin/v1_14/core/server/management/PlayerListMixin_1_14.java index 4b484690..3ec81095 100644 --- a/arclight-forge-1.14/src/main/java/io/izzel/arclight/impl/mixin/v1_14/core/server/management/PlayerListMixin_1_14.java +++ b/arclight-forge-1.14/src/main/java/io/izzel/arclight/impl/mixin/v1_14/core/server/management/PlayerListMixin_1_14.java @@ -1,8 +1,12 @@ package io.izzel.arclight.impl.mixin.v1_14.core.server.management; import io.izzel.arclight.common.bridge.server.management.PlayerListBridge; +import io.izzel.arclight.common.bridge.world.dimension.DimensionTypeBridge; +import io.izzel.arclight.common.bridge.world.server.ServerWorldBridge; import net.minecraft.entity.Entity; import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.play.server.SJoinGamePacket; import net.minecraft.network.play.server.SRespawnPacket; import net.minecraft.server.management.PlayerList; import net.minecraft.util.math.BlockPos; @@ -11,6 +15,8 @@ import net.minecraft.world.WorldType; import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.server.ServerWorld; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(PlayerList.class) public abstract class PlayerListMixin_1_14 implements PlayerListBridge { @@ -29,4 +35,9 @@ public abstract class PlayerListMixin_1_14 implements PlayerListBridge { public SRespawnPacket bridge$respawnPacket(DimensionType type, long seed, WorldType worldType, GameType gameType) { return new SRespawnPacket(type, worldType, gameType); } + + @Redirect(method = "initializeConnectionToPlayer", at = @At(value = "NEW", target = "net/minecraft/network/play/server/SJoinGamePacket")) + private SJoinGamePacket arclight$spawnPacket(int playerId, GameType gameType, boolean hardcoreMode, DimensionType dimensionType, int maxPlayers, WorldType worldType, int viewDistance, boolean reducedDebugInfo, NetworkManager netManager, ServerPlayerEntity playerIn) { + return new SJoinGamePacket(playerId, gameType, hardcoreMode, ((DimensionTypeBridge) dimensionType).bridge$getType(), maxPlayers, worldType, ((ServerWorldBridge) playerIn.func_71121_q()).bridge$spigotConfig().viewDistance, reducedDebugInfo); + } }