package net.minecraft.server.level; import org.apache.logging.log4j.LogManager; import net.minecraft.network.chat.Style; import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.TextComponent; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.network.protocol.game.ClientboundAddPlayerPacket; import net.minecraft.network.protocol.game.ClientboundSoundPacket; import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundEvent; import net.minecraft.network.protocol.game.ClientboundForgetLevelChunkPacket; import net.minecraft.world.level.ChunkPos; import net.minecraft.network.protocol.game.ClientboundSetCameraPacket; import net.minecraft.network.protocol.game.ClientboundResourcePackPacket; import net.minecraft.world.entity.HumanoidArm; import net.minecraft.network.protocol.game.ServerboundClientInformationPacket; import net.minecraft.network.protocol.game.ClientboundRemoveMobEffectPacket; import net.minecraft.world.effect.MobEffects; import net.minecraft.stats.RecipeBook; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.protocol.game.ClientboundPlayerLookAtPacket; import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.network.protocol.game.ClientboundEntityEventPacket; import net.minecraft.network.protocol.game.ClientboundChatPacket; import net.minecraft.network.chat.ChatType; import java.util.function.Consumer; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.crafting.Recipe; import java.util.Collection; import net.minecraft.network.protocol.game.ClientboundContainerClosePacket; import net.minecraft.network.protocol.game.ClientboundContainerSetDataPacket; import net.minecraft.network.protocol.game.ClientboundContainerSetContentPacket; import net.minecraft.core.NonNullList; import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; import net.minecraft.world.inventory.ResultSlot; import net.minecraft.world.level.block.entity.CommandBlockEntity; import net.minecraft.world.item.Item; import net.minecraft.network.protocol.game.ClientboundOpenBookPacket; import net.minecraft.world.item.WrittenBookItem; import net.minecraft.world.item.Items; import net.minecraft.world.InteractionHand; import net.minecraft.world.inventory.HorseInventoryMenu; import net.minecraft.network.protocol.game.ClientboundHorseScreenOpenPacket; import net.minecraft.world.Container; import net.minecraft.world.entity.animal.horse.AbstractHorse; import net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket; import net.minecraft.world.item.trading.MerchantOffers; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.TranslatableComponent; import java.util.OptionalInt; import net.minecraft.world.MenuProvider; import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket; import net.minecraft.world.level.block.entity.SignBlockEntity; import net.minecraft.network.protocol.game.ClientboundAnimatePacket; import net.minecraft.util.Unit; import com.mojang.datafixers.util.Either; import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.server.players.PlayerList; import net.minecraft.network.protocol.game.ClientboundLevelEventPacket; import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket; import net.minecraft.world.level.block.Blocks; import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket; import net.minecraft.network.protocol.game.ClientboundRespawnPacket; import net.minecraft.world.level.storage.LevelData; import net.minecraft.network.protocol.game.ClientboundGameEventPacket; import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.damagesource.EntityDamageSource; import net.minecraft.world.scores.PlayerTeam; import net.minecraft.world.entity.LivingEntity; import net.minecraft.network.chat.Component; import net.minecraft.stats.Stat; import net.minecraft.stats.Stats; import net.minecraft.world.scores.Score; import net.minecraft.world.scores.Team; import io.netty.util.concurrent.Future; import io.netty.util.concurrent.GenericFutureListener; import net.minecraft.world.level.GameRules; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.CrashReportCategory; import net.minecraft.ReportedException; import net.minecraft.CrashReport; import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket; import net.minecraft.world.scores.criteria.ObjectiveCriteria; import net.minecraft.network.protocol.game.ClientboundSetHealthPacket; import net.minecraft.world.item.ComplexItem; import java.util.Iterator; import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket; import net.minecraft.world.item.ServerItemCooldowns; import net.minecraft.world.item.ItemCooldowns; import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientboundPlayerCombatPacket; import net.minecraft.world.item.ItemStack; import net.minecraft.nbt.Tag; import net.minecraft.nbt.CompoundTag; import net.minecraft.core.BlockPos; import java.util.Random; import net.minecraft.util.Mth; import net.minecraft.world.level.GameType; import net.minecraft.Util; import com.google.common.collect.Lists; import net.minecraft.world.level.Level; import com.mojang.authlib.GameProfile; import net.minecraft.core.SectionPos; import javax.annotation.Nullable; import net.minecraft.world.phys.Vec3; import net.minecraft.stats.ServerRecipeBook; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.ChatVisiblity; import net.minecraft.stats.ServerStatsCounter; import net.minecraft.server.PlayerAdvancements; import java.util.List; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerGamePacketListenerImpl; import org.apache.logging.log4j.Logger; import net.minecraft.world.inventory.ContainerListener; import net.minecraft.world.entity.player.Player; public class ServerPlayer extends Player implements ContainerListener { private static final Logger LOGGER; private String language; public ServerGamePacketListenerImpl connection; public final MinecraftServer server; public final ServerPlayerGameMode gameMode; private final List entitiesToRemove; private final PlayerAdvancements advancements; private final ServerStatsCounter stats; private float lastRecordedHealthAndAbsorption; private int lastRecordedFoodLevel; private int lastRecordedAirLevel; private int lastRecordedArmor; private int lastRecordedLevel; private int lastRecordedExperience; private float lastSentHealth; private int lastSentFood; private boolean lastFoodSaturationZero; private int lastSentExp; private int spawnInvulnerableTime; private ChatVisiblity chatVisibility; private boolean canChatColor; private long lastActionTime; private Entity camera; private boolean isChangingDimension; private boolean seenCredits; private final ServerRecipeBook recipeBook; private Vec3 levitationStartPos; private int levitationStartTime; private boolean disconnected; @Nullable private Vec3 enteredNetherPosition; private SectionPos lastSectionPos; private int containerCounter; public boolean ignoreSlotUpdateHack; public int latency; public boolean wonGame; public ServerPlayer(final MinecraftServer minecraftServer, final ServerLevel xd, final GameProfile gameProfile, final ServerPlayerGameMode xf) { super(xd, gameProfile); this.language = "en_US"; this.entitiesToRemove = Lists.newLinkedList(); this.lastRecordedHealthAndAbsorption = Float.MIN_VALUE; this.lastRecordedFoodLevel = Integer.MIN_VALUE; this.lastRecordedAirLevel = Integer.MIN_VALUE; this.lastRecordedArmor = Integer.MIN_VALUE; this.lastRecordedLevel = Integer.MIN_VALUE; this.lastRecordedExperience = Integer.MIN_VALUE; this.lastSentHealth = -1.0E8f; this.lastSentFood = -99999999; this.lastFoodSaturationZero = true; this.lastSentExp = -99999999; this.spawnInvulnerableTime = 60; this.canChatColor = true; this.lastActionTime = Util.getMillis(); this.lastSectionPos = SectionPos.of(0, 0, 0); xf.player = this; this.gameMode = xf; this.server = minecraftServer; this.recipeBook = new ServerRecipeBook(minecraftServer.getRecipeManager()); this.stats = minecraftServer.getPlayerList().getPlayerStats(this); this.advancements = minecraftServer.getPlayerList().getPlayerAdvancements(this); this.maxUpStep = 1.0f; this.fudgeSpawnLocation(xd); } private void fudgeSpawnLocation(final ServerLevel xd) { final BlockPos fk3 = xd.getSharedSpawnPos(); if (xd.dimension.isHasSkyLight() && xd.getLevelData().getGameType() != GameType.ADVENTURE) { int integer4 = Math.max(0, this.server.getSpawnRadius(xd)); final int integer5 = Mth.floor(xd.getWorldBorder().getDistanceToBorder(fk3.getX(), fk3.getZ())); if (integer5 < integer4) { integer4 = integer5; } if (integer5 <= 1) { integer4 = 1; } final long long6 = integer4 * 2 + 1; final long long7 = long6 * long6; final int integer6 = (long7 > 2147483647L) ? Integer.MAX_VALUE : ((int)long7); final int integer7 = this.getCoprime(integer6); final int integer8 = new Random().nextInt(integer6); for (int integer9 = 0; integer9 < integer6; ++integer9) { final int integer10 = (integer8 + integer7 * integer9) % integer6; final int integer11 = integer10 % (integer4 * 2 + 1); final int integer12 = integer10 / (integer4 * 2 + 1); final BlockPos fk4 = xd.getDimension().getValidSpawnPosition(fk3.getX() + integer11 - integer4, fk3.getZ() + integer12 - integer4, false); if (fk4 != null) { this.moveTo(fk4, 0.0f, 0.0f); if (xd.noCollision(this)) { break; } } } } else { this.moveTo(fk3, 0.0f, 0.0f); while (!xd.noCollision(this) && this.getY() < 255.0) { this.setPos(this.getX(), this.getY() + 1.0, this.getZ()); } } } private int getCoprime(final int integer) { return (integer <= 16) ? (integer - 1) : 17; } @Override public void readAdditionalSaveData(final CompoundTag jt) { super.readAdditionalSaveData(jt); if (jt.contains("playerGameType", 99)) { if (this.getServer().getForceGameType()) { this.gameMode.setGameModeForPlayer(this.getServer().getDefaultGameType()); } else { this.gameMode.setGameModeForPlayer(GameType.byId(jt.getInt("playerGameType"))); } } if (jt.contains("enteredNetherPosition", 10)) { final CompoundTag jt2 = jt.getCompound("enteredNetherPosition"); this.enteredNetherPosition = new Vec3(jt2.getDouble("x"), jt2.getDouble("y"), jt2.getDouble("z")); } this.seenCredits = jt.getBoolean("seenCredits"); if (jt.contains("recipeBook", 10)) { this.recipeBook.fromNbt(jt.getCompound("recipeBook")); } if (this.isSleeping()) { this.stopSleeping(); } } @Override public void addAdditionalSaveData(final CompoundTag jt) { super.addAdditionalSaveData(jt); jt.putInt("playerGameType", this.gameMode.getGameModeForPlayer().getId()); jt.putBoolean("seenCredits", this.seenCredits); if (this.enteredNetherPosition != null) { final CompoundTag jt2 = new CompoundTag(); jt2.putDouble("x", this.enteredNetherPosition.x); jt2.putDouble("y", this.enteredNetherPosition.y); jt2.putDouble("z", this.enteredNetherPosition.z); jt.put("enteredNetherPosition", jt2); } final Entity akn3 = this.getRootVehicle(); final Entity akn4 = this.getVehicle(); if (akn4 != null && akn3 != this && akn3.hasOnePlayerPassenger()) { final CompoundTag jt3 = new CompoundTag(); final CompoundTag jt4 = new CompoundTag(); akn3.save(jt4); jt3.putUUID("Attach", akn4.getUUID()); jt3.put("Entity", jt4); jt.put("RootVehicle", jt3); } jt.put("recipeBook", this.recipeBook.toNbt()); } public void setExperiencePoints(final int integer) { final float float3 = (float)this.getXpNeededForNextLevel(); final float float4 = (float3 - 1.0f) / float3; this.experienceProgress = Mth.clamp(integer / float3, 0.0f, float4); this.lastSentExp = -1; } public void setExperienceLevels(final int integer) { this.experienceLevel = integer; this.lastSentExp = -1; } @Override public void giveExperienceLevels(final int integer) { super.giveExperienceLevels(integer); this.lastSentExp = -1; } @Override public void onEnchantmentPerformed(final ItemStack bek, final int integer) { super.onEnchantmentPerformed(bek, integer); this.lastSentExp = -1; } public void initMenu() { this.containerMenu.addSlotListener(this); } @Override public void onEnterCombat() { super.onEnterCombat(); this.connection.send(new ClientboundPlayerCombatPacket(this.getCombatTracker(), ClientboundPlayerCombatPacket.Event.ENTER_COMBAT)); } @Override public void onLeaveCombat() { super.onLeaveCombat(); this.connection.send(new ClientboundPlayerCombatPacket(this.getCombatTracker(), ClientboundPlayerCombatPacket.Event.END_COMBAT)); } @Override protected void onInsideBlock(final BlockState byg) { CriteriaTriggers.ENTER_BLOCK.trigger(this, byg); } @Override protected ItemCooldowns createItemCooldowns() { return new ServerItemCooldowns(this); } @Override public void tick() { this.gameMode.tick(); --this.spawnInvulnerableTime; if (this.invulnerableTime > 0) { --this.invulnerableTime; } this.containerMenu.broadcastChanges(); if (!this.level.isClientSide && !this.containerMenu.stillValid(this)) { this.closeContainer(); this.containerMenu = this.inventoryMenu; } while (!this.entitiesToRemove.isEmpty()) { final int integer2 = Math.min(this.entitiesToRemove.size(), Integer.MAX_VALUE); final int[] arr3 = new int[integer2]; final Iterator iterator4 = this.entitiesToRemove.iterator(); int integer3 = 0; while (iterator4.hasNext() && integer3 < integer2) { arr3[integer3++] = iterator4.next(); iterator4.remove(); } this.connection.send(new ClientboundRemoveEntitiesPacket(arr3)); } final Entity akn2 = this.getCamera(); if (akn2 != this) { if (akn2.isAlive()) { this.absMoveTo(akn2.getX(), akn2.getY(), akn2.getZ(), akn2.yRot, akn2.xRot); this.getLevel().getChunkSource().move(this); if (this.wantsToStopRiding()) { this.setCamera(this); } } else { this.setCamera(this); } } CriteriaTriggers.TICK.trigger(this); if (this.levitationStartPos != null) { CriteriaTriggers.LEVITATION.trigger(this, this.levitationStartPos, this.tickCount - this.levitationStartTime); } this.advancements.flushDirty(this); } public void doTick() { try { if (!this.isSpectator() || this.level.hasChunkAt(new BlockPos(this))) { super.tick(); } for (int integer2 = 0; integer2 < this.inventory.getContainerSize(); ++integer2) { final ItemStack bek3 = this.inventory.getItem(integer2); if (bek3.getItem().isComplex()) { final Packet lt4 = ((ComplexItem)bek3.getItem()).getUpdatePacket(bek3, this.level, this); if (lt4 != null) { this.connection.send(lt4); } } } if (this.getHealth() != this.lastSentHealth || this.lastSentFood != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0f != this.lastFoodSaturationZero) { this.connection.send(new ClientboundSetHealthPacket(this.getHealth(), this.foodData.getFoodLevel(), this.foodData.getSaturationLevel())); this.lastSentHealth = this.getHealth(); this.lastSentFood = this.foodData.getFoodLevel(); this.lastFoodSaturationZero = (this.foodData.getSaturationLevel() == 0.0f); } if (this.getHealth() + this.getAbsorptionAmount() != this.lastRecordedHealthAndAbsorption) { this.lastRecordedHealthAndAbsorption = this.getHealth() + this.getAbsorptionAmount(); this.updateScoreForCriteria(ObjectiveCriteria.HEALTH, Mth.ceil(this.lastRecordedHealthAndAbsorption)); } if (this.foodData.getFoodLevel() != this.lastRecordedFoodLevel) { this.lastRecordedFoodLevel = this.foodData.getFoodLevel(); this.updateScoreForCriteria(ObjectiveCriteria.FOOD, Mth.ceil((float)this.lastRecordedFoodLevel)); } if (this.getAirSupply() != this.lastRecordedAirLevel) { this.lastRecordedAirLevel = this.getAirSupply(); this.updateScoreForCriteria(ObjectiveCriteria.AIR, Mth.ceil((float)this.lastRecordedAirLevel)); } if (this.getArmorValue() != this.lastRecordedArmor) { this.lastRecordedArmor = this.getArmorValue(); this.updateScoreForCriteria(ObjectiveCriteria.ARMOR, Mth.ceil((float)this.lastRecordedArmor)); } if (this.totalExperience != this.lastRecordedExperience) { this.lastRecordedExperience = this.totalExperience; this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil((float)this.lastRecordedExperience)); } if (this.experienceLevel != this.lastRecordedLevel) { this.lastRecordedLevel = this.experienceLevel; this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil((float)this.lastRecordedLevel)); } if (this.totalExperience != this.lastSentExp) { this.lastSentExp = this.totalExperience; this.connection.send(new ClientboundSetExperiencePacket(this.experienceProgress, this.totalExperience, this.experienceLevel)); } if (this.tickCount % 20 == 0) { CriteriaTriggers.LOCATION.trigger(this); } } catch (Throwable throwable2) { final CrashReport h3 = CrashReport.forThrowable(throwable2, "Ticking player"); final CrashReportCategory i4 = h3.addCategory("Player being ticked"); this.fillCrashReportCategory(i4); throw new ReportedException(h3); } } private void updateScoreForCriteria(final ObjectiveCriteria cwl, final int integer) { this.getScoreboard().forAllObjectives(cwl, this.getScoreboardName(), cwh -> cwh.setScore(integer)); } @Override public void die(final DamageSource ajw) { final boolean boolean3 = this.level.getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); if (boolean3) { final Component lf4 = this.getCombatTracker().getDeathMessage(); this.connection.send(new ClientboundPlayerCombatPacket(this.getCombatTracker(), ClientboundPlayerCombatPacket.Event.ENTITY_DIED, lf4), (future -> { if (!future.isSuccess()) { final int integer4 = 256; final String string5 = lf4.getString(256); final Component lf2 = new TranslatableComponent("death.attack.message_too_long", new Object[] { new TextComponent(string5).withStyle(ChatFormatting.YELLOW) }); final Component lf3 = new TranslatableComponent("death.attack.even_more_magic", new Object[] { this.getDisplayName() }).withStyle(ln -> ln.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, lf2))); this.connection.send(new ClientboundPlayerCombatPacket(this.getCombatTracker(), ClientboundPlayerCombatPacket.Event.ENTITY_DIED, lf3)); } })); final Team cwk5 = this.getTeam(); if (cwk5 == null || cwk5.getDeathMessageVisibility() == Team.Visibility.ALWAYS) { this.server.getPlayerList().broadcastMessage(lf4); } else if (cwk5.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OTHER_TEAMS) { this.server.getPlayerList().broadcastToTeam(this, lf4); } else if (cwk5.getDeathMessageVisibility() == Team.Visibility.HIDE_FOR_OWN_TEAM) { this.server.getPlayerList().broadcastToAllExceptTeam(this, lf4); } } else { this.connection.send(new ClientboundPlayerCombatPacket(this.getCombatTracker(), ClientboundPlayerCombatPacket.Event.ENTITY_DIED)); } this.removeEntitiesOnShoulder(); if (!this.isSpectator()) { this.dropAllDeathLoot(ajw); } this.getScoreboard().forAllObjectives(ObjectiveCriteria.DEATH_COUNT, this.getScoreboardName(), Score::increment); final LivingEntity akw4 = this.getKillCredit(); if (akw4 != null) { this.awardStat(Stats.ENTITY_KILLED_BY.get(akw4.getType())); akw4.awardKillScore(this, this.deathScore, ajw); this.createWitherRose(akw4); } this.level.broadcastEntityEvent(this, (byte)3); this.awardStat(Stats.DEATHS); this.resetStat(Stats.CUSTOM.get(Stats.TIME_SINCE_DEATH)); this.resetStat(Stats.CUSTOM.get(Stats.TIME_SINCE_REST)); this.clearFire(); this.setSharedFlag(0, false); this.getCombatTracker().recheckStatus(); } @Override public void awardKillScore(final Entity akn, final int integer, final DamageSource ajw) { if (akn == this) { return; } super.awardKillScore(akn, integer, ajw); this.increaseScore(integer); final String string5 = this.getScoreboardName(); final String string6 = akn.getScoreboardName(); this.getScoreboard().forAllObjectives(ObjectiveCriteria.KILL_COUNT_ALL, string5, Score::increment); if (akn instanceof Player) { this.awardStat(Stats.PLAYER_KILLS); this.getScoreboard().forAllObjectives(ObjectiveCriteria.KILL_COUNT_PLAYERS, string5, Score::increment); } else { this.awardStat(Stats.MOB_KILLS); } this.handleTeamKill(string5, string6, ObjectiveCriteria.TEAM_KILL); this.handleTeamKill(string6, string5, ObjectiveCriteria.KILLED_BY_TEAM); CriteriaTriggers.PLAYER_KILLED_ENTITY.trigger(this, akn, ajw); } private void handleTeamKill(final String string1, final String string2, final ObjectiveCriteria[] arr) { final PlayerTeam cwg5 = this.getScoreboard().getPlayersTeam(string2); if (cwg5 != null) { final int integer6 = cwg5.getColor().getId(); if (integer6 >= 0 && integer6 < arr.length) { this.getScoreboard().forAllObjectives(arr[integer6], string1, Score::increment); } } } @Override public boolean hurt(final DamageSource ajw, final float float2) { if (this.isInvulnerableTo(ajw)) { return false; } final boolean boolean4 = this.server.isDedicatedServer() && this.isPvpAllowed() && "fall".equals(ajw.msgId); if (!boolean4 && this.spawnInvulnerableTime > 0 && ajw != DamageSource.OUT_OF_WORLD) { return false; } if (ajw instanceof EntityDamageSource) { final Entity akn5 = ajw.getEntity(); if (akn5 instanceof Player && !this.canHarmPlayer((Player)akn5)) { return false; } if (akn5 instanceof AbstractArrow) { final AbstractArrow ayk6 = (AbstractArrow)akn5; final Entity akn6 = ayk6.getOwner(); if (akn6 instanceof Player && !this.canHarmPlayer((Player)akn6)) { return false; } } } return super.hurt(ajw, float2); } @Override public boolean canHarmPlayer(final Player ayg) { return this.isPvpAllowed() && super.canHarmPlayer(ayg); } private boolean isPvpAllowed() { return this.server.isPvpAllowed(); } @Nullable @Override public Entity changeDimension(final DimensionType cbf) { this.isChangingDimension = true; final DimensionType cbf2 = this.dimension; if (cbf2 == DimensionType.THE_END && cbf == DimensionType.OVERWORLD) { this.unRide(); this.getLevel().removePlayerImmediately(this); if (!this.wonGame) { this.wonGame = true; this.connection.send(new ClientboundGameEventPacket(4, this.seenCredits ? 0.0f : 1.0f)); this.seenCredits = true; } return this; } final ServerLevel xd4 = this.server.getLevel(cbf2); this.dimension = cbf; final ServerLevel xd5 = this.server.getLevel(cbf); final LevelData crj6 = xd5.getLevelData(); this.connection.send(new ClientboundRespawnPacket(cbf, LevelData.obfuscateSeed(crj6.getSeed()), crj6.getGeneratorType(), this.gameMode.getGameModeForPlayer())); this.connection.send(new ClientboundChangeDifficultyPacket(crj6.getDifficulty(), crj6.isDifficultyLocked())); final PlayerList zo7 = this.server.getPlayerList(); zo7.sendPlayerPermissionLevel(this); xd4.removePlayerImmediately(this); this.removed = false; double double8 = this.getX(); double double9 = this.getY(); double double10 = this.getZ(); float float14 = this.xRot; float float15 = this.yRot; final double double11 = 8.0; final float float16 = float15; xd4.getProfiler().push("moving"); if (cbf2 == DimensionType.OVERWORLD && cbf == DimensionType.NETHER) { this.enteredNetherPosition = this.position(); double8 /= 8.0; double10 /= 8.0; } else if (cbf2 == DimensionType.NETHER && cbf == DimensionType.OVERWORLD) { double8 *= 8.0; double10 *= 8.0; } else if (cbf2 == DimensionType.OVERWORLD && cbf == DimensionType.THE_END) { final BlockPos fk19 = xd5.getDimensionSpecificSpawn(); double8 = fk19.getX(); double9 = fk19.getY(); double10 = fk19.getZ(); float15 = 90.0f; float14 = 0.0f; } this.moveTo(double8, double9, double10, float15, float14); xd4.getProfiler().pop(); xd4.getProfiler().push("placing"); final double double12 = Math.min(-2.9999872E7, xd5.getWorldBorder().getMinX() + 16.0); final double double13 = Math.min(-2.9999872E7, xd5.getWorldBorder().getMinZ() + 16.0); final double double14 = Math.min(2.9999872E7, xd5.getWorldBorder().getMaxX() - 16.0); final double double15 = Math.min(2.9999872E7, xd5.getWorldBorder().getMaxZ() - 16.0); double8 = Mth.clamp(double8, double12, double14); double10 = Mth.clamp(double10, double13, double15); this.moveTo(double8, double9, double10, float15, float14); if (cbf == DimensionType.THE_END) { final int integer27 = Mth.floor(this.getX()); final int integer28 = Mth.floor(this.getY()) - 1; final int integer29 = Mth.floor(this.getZ()); final int integer30 = 1; final int integer31 = 0; for (int integer32 = -2; integer32 <= 2; ++integer32) { for (int integer33 = -2; integer33 <= 2; ++integer33) { for (int integer34 = -1; integer34 < 3; ++integer34) { final int integer35 = integer27 + integer33 * 1 + integer32 * 0; final int integer36 = integer28 + integer34; final int integer37 = integer29 + integer33 * 0 - integer32 * 1; final boolean boolean38 = integer34 < 0; xd5.setBlockAndUpdate(new BlockPos(integer35, integer36, integer37), boolean38 ? Blocks.OBSIDIAN.defaultBlockState() : Blocks.AIR.defaultBlockState()); } } } this.moveTo(integer27, integer28, integer29, float15, 0.0f); this.setDeltaMovement(Vec3.ZERO); } else if (!xd5.getPortalForcer().findAndMoveToPortal(this, float16)) { xd5.getPortalForcer().createPortal(this); xd5.getPortalForcer().findAndMoveToPortal(this, float16); } xd4.getProfiler().pop(); this.setLevel(xd5); xd5.addDuringPortalTeleport(this); this.triggerDimensionChangeTriggers(xd4); this.connection.teleport(this.getX(), this.getY(), this.getZ(), float15, float14); this.gameMode.setLevel(xd5); this.connection.send(new ClientboundPlayerAbilitiesPacket(this.abilities)); zo7.sendLevelInfo(this, xd5); zo7.sendAllPlayerInfo(this); for (final MobEffectInstance akh28 : this.getActiveEffects()) { this.connection.send(new ClientboundUpdateMobEffectPacket(this.getId(), akh28)); } this.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false)); this.lastSentExp = -1; this.lastSentHealth = -1.0f; this.lastSentFood = -1; return this; } private void triggerDimensionChangeTriggers(final ServerLevel xd) { final DimensionType cbf3 = xd.dimension.getType(); final DimensionType cbf4 = this.level.dimension.getType(); CriteriaTriggers.CHANGED_DIMENSION.trigger(this, cbf3, cbf4); if (cbf3 == DimensionType.NETHER && cbf4 == DimensionType.OVERWORLD && this.enteredNetherPosition != null) { CriteriaTriggers.NETHER_TRAVEL.trigger(this, this.enteredNetherPosition); } if (cbf4 != DimensionType.NETHER) { this.enteredNetherPosition = null; } } @Override public boolean broadcastToPlayer(final ServerPlayer xe) { if (xe.isSpectator()) { return this.getCamera() == this; } return !this.isSpectator() && super.broadcastToPlayer(xe); } private void broadcast(final BlockEntity bwi) { if (bwi != null) { final ClientboundBlockEntityDataPacket mh3 = bwi.getUpdatePacket(); if (mh3 != null) { this.connection.send(mh3); } } } @Override public void take(final Entity akn, final int integer) { super.take(akn, integer); this.containerMenu.broadcastChanges(); } @Override public Either startSleepInBed(final BlockPos fk) { return (Either)super.startSleepInBed(fk).ifRight(aca -> { this.awardStat(Stats.SLEEP_IN_BED); CriteriaTriggers.SLEPT_IN_BED.trigger(this); }); } @Override public void stopSleepInBed(final boolean boolean1, final boolean boolean2) { if (this.isSleeping()) { this.getLevel().getChunkSource().broadcastAndSend(this, new ClientboundAnimatePacket(this, 2)); } super.stopSleepInBed(boolean1, boolean2); if (this.connection != null) { this.connection.teleport(this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot); } } @Override public boolean startRiding(final Entity akn, final boolean boolean2) { final Entity akn2 = this.getVehicle(); if (!super.startRiding(akn, boolean2)) { return false; } final Entity akn3 = this.getVehicle(); if (akn3 != akn2 && this.connection != null) { this.connection.teleport(this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot); } return true; } @Override public void stopRiding() { final Entity akn2 = this.getVehicle(); super.stopRiding(); final Entity akn3 = this.getVehicle(); if (akn3 != akn2 && this.connection != null) { this.connection.teleport(this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot); } } @Override public boolean isInvulnerableTo(final DamageSource ajw) { return super.isInvulnerableTo(ajw) || this.isChangingDimension() || (this.abilities.invulnerable && ajw == DamageSource.WITHER); } @Override protected void checkFallDamage(final double double1, final boolean boolean2, final BlockState byg, final BlockPos fk) { } @Override protected void onChangedBlock(final BlockPos fk) { if (!this.isSpectator()) { super.onChangedBlock(fk); } } public void doCheckFallDamage(final double double1, final boolean boolean2) { final BlockPos fk5 = this.getOnPos(); if (!this.level.hasChunkAt(fk5)) { return; } final BlockState byg6 = this.level.getBlockState(fk5); super.checkFallDamage(double1, boolean2, byg6, fk5); } @Override public void openTextEdit(final SignBlockEntity bxe) { bxe.setAllowedPlayerEditor(this); this.connection.send(new ClientboundOpenSignEditorPacket(bxe.getBlockPos())); } private void nextContainerCounter() { this.containerCounter = this.containerCounter % 100 + 1; } @Override public OptionalInt openMenu(@Nullable final MenuProvider ajl) { if (ajl == null) { return OptionalInt.empty(); } if (this.containerMenu != this.inventoryMenu) { this.closeContainer(); } this.nextContainerCounter(); final AbstractContainerMenu bak3 = ajl.createMenu(this.containerCounter, this.inventory, this); if (bak3 == null) { if (this.isSpectator()) { this.displayClientMessage(new TranslatableComponent("container.spectatorCantOpen", new Object[0]).withStyle(ChatFormatting.RED), true); } return OptionalInt.empty(); } this.connection.send(new ClientboundOpenScreenPacket(bak3.containerId, bak3.getType(), ajl.getDisplayName())); bak3.addSlotListener(this); this.containerMenu = bak3; return OptionalInt.of(this.containerCounter); } @Override public void sendMerchantOffers(final int integer1, final MerchantOffers bix, final int integer3, final int integer4, final boolean boolean5, final boolean boolean6) { this.connection.send(new ClientboundMerchantOffersPacket(integer1, bix, integer3, integer4, boolean5, boolean6)); } @Override public void openHorseInventory(final AbstractHorse aub, final Container ajb) { if (this.containerMenu != this.inventoryMenu) { this.closeContainer(); } this.nextContainerCounter(); this.connection.send(new ClientboundHorseScreenOpenPacket(this.containerCounter, ajb.getContainerSize(), aub.getId())); (this.containerMenu = new HorseInventoryMenu(this.containerCounter, this.inventory, ajb, aub)).addSlotListener(this); } @Override public void openItemGui(final ItemStack bek, final InteractionHand ajh) { final Item bef4 = bek.getItem(); if (bef4 == Items.WRITTEN_BOOK) { if (WrittenBookItem.resolveBookComponents(bek, this.createCommandSourceStack(), this)) { this.containerMenu.broadcastChanges(); } this.connection.send(new ClientboundOpenBookPacket(ajh)); } } @Override public void openCommandBlock(final CommandBlockEntity bwn) { bwn.setSendToClient(true); this.broadcast(bwn); } @Override public void slotChanged(final AbstractContainerMenu bak, final int integer, final ItemStack bek) { if (bak.getSlot(integer) instanceof ResultSlot) { return; } if (bak == this.inventoryMenu) { CriteriaTriggers.INVENTORY_CHANGED.trigger(this, this.inventory); } if (this.ignoreSlotUpdateHack) { return; } this.connection.send(new ClientboundContainerSetSlotPacket(bak.containerId, integer, bek)); } public void refreshContainer(final AbstractContainerMenu bak) { this.refreshContainer(bak, bak.getItems()); } @Override public void refreshContainer(final AbstractContainerMenu bak, final NonNullList fy) { this.connection.send(new ClientboundContainerSetContentPacket(bak.containerId, fy)); this.connection.send(new ClientboundContainerSetSlotPacket(-1, -1, this.inventory.getCarried())); } @Override public void setContainerData(final AbstractContainerMenu bak, final int integer2, final int integer3) { this.connection.send(new ClientboundContainerSetDataPacket(bak.containerId, integer2, integer3)); } public void closeContainer() { this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId)); this.doCloseContainer(); } public void broadcastCarriedItem() { if (this.ignoreSlotUpdateHack) { return; } this.connection.send(new ClientboundContainerSetSlotPacket(-1, -1, this.inventory.getCarried())); } public void doCloseContainer() { this.containerMenu.removed(this); this.containerMenu = this.inventoryMenu; } public void setPlayerInput(final float float1, final float float2, final boolean boolean3, final boolean boolean4) { if (this.isPassenger()) { if (float1 >= -1.0f && float1 <= 1.0f) { this.xxa = float1; } if (float2 >= -1.0f && float2 <= 1.0f) { this.zza = float2; } this.jumping = boolean3; this.setShiftKeyDown(boolean4); } } @Override public void awardStat(final Stat aao, final int integer) { this.stats.increment(this, aao, integer); this.getScoreboard().forAllObjectives(aao, this.getScoreboardName(), cwh -> cwh.add(integer)); } @Override public void resetStat(final Stat aao) { this.stats.setValue(this, aao, 0); this.getScoreboard().forAllObjectives(aao, this.getScoreboardName(), Score::reset); } @Override public int awardRecipes(final Collection> collection) { return this.recipeBook.addRecipes(collection, this); } @Override public void awardRecipesByKey(final ResourceLocation[] arr) { final List> list3 = Lists.newArrayList(); for (final ResourceLocation sm7 : arr) { this.server.getRecipeManager().byKey(sm7).ifPresent(list3::add); } this.awardRecipes(list3); } @Override public int resetRecipes(final Collection> collection) { return this.recipeBook.removeRecipes(collection, this); } @Override public void giveExperiencePoints(final int integer) { super.giveExperiencePoints(integer); this.lastSentExp = -1; } public void disconnect() { this.disconnected = true; this.ejectPassengers(); if (this.isSleeping()) { this.stopSleepInBed(true, false); } } public boolean hasDisconnected() { return this.disconnected; } public void resetSentInfo() { this.lastSentHealth = -1.0E8f; } @Override public void displayClientMessage(final Component lf, final boolean boolean2) { this.connection.send(new ClientboundChatPacket(lf, boolean2 ? ChatType.GAME_INFO : ChatType.CHAT)); } @Override protected void completeUsingItem() { if (!this.useItem.isEmpty() && this.isUsingItem()) { this.connection.send(new ClientboundEntityEventPacket(this, (byte)9)); super.completeUsingItem(); } } @Override public void lookAt(final EntityAnchorArgument.Anchor a, final Vec3 cvi) { super.lookAt(a, cvi); this.connection.send(new ClientboundPlayerLookAtPacket(a, cvi.x, cvi.y, cvi.z)); } public void lookAt(final EntityAnchorArgument.Anchor a1, final Entity akn, final EntityAnchorArgument.Anchor a3) { final Vec3 cvi5 = a3.apply(akn); super.lookAt(a1, cvi5); this.connection.send(new ClientboundPlayerLookAtPacket(a1, akn, a3)); } public void restoreFrom(final ServerPlayer xe, final boolean boolean2) { if (boolean2) { this.inventory.replaceWith(xe.inventory); this.setHealth(xe.getHealth()); this.foodData = xe.foodData; this.experienceLevel = xe.experienceLevel; this.totalExperience = xe.totalExperience; this.experienceProgress = xe.experienceProgress; this.setScore(xe.getScore()); this.portalEntranceBlock = xe.portalEntranceBlock; this.portalEntranceOffset = xe.portalEntranceOffset; this.portalEntranceForwards = xe.portalEntranceForwards; } else if (this.level.getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || xe.isSpectator()) { this.inventory.replaceWith(xe.inventory); this.experienceLevel = xe.experienceLevel; this.totalExperience = xe.totalExperience; this.experienceProgress = xe.experienceProgress; this.setScore(xe.getScore()); } this.enchantmentSeed = xe.enchantmentSeed; this.enderChestInventory = xe.enderChestInventory; this.getEntityData().set(ServerPlayer.DATA_PLAYER_MODE_CUSTOMISATION, (Byte)xe.getEntityData().get((EntityDataAccessor)ServerPlayer.DATA_PLAYER_MODE_CUSTOMISATION)); this.lastSentExp = -1; this.lastSentHealth = -1.0f; this.lastSentFood = -1; this.recipeBook.copyOverData(xe.recipeBook); this.entitiesToRemove.addAll(xe.entitiesToRemove); this.seenCredits = xe.seenCredits; this.enteredNetherPosition = xe.enteredNetherPosition; this.setShoulderEntityLeft(xe.getShoulderEntityLeft()); this.setShoulderEntityRight(xe.getShoulderEntityRight()); } @Override protected void onEffectAdded(final MobEffectInstance akh) { super.onEffectAdded(akh); this.connection.send(new ClientboundUpdateMobEffectPacket(this.getId(), akh)); if (akh.getEffect() == MobEffects.LEVITATION) { this.levitationStartTime = this.tickCount; this.levitationStartPos = this.position(); } CriteriaTriggers.EFFECTS_CHANGED.trigger(this); } @Override protected void onEffectUpdated(final MobEffectInstance akh, final boolean boolean2) { super.onEffectUpdated(akh, boolean2); this.connection.send(new ClientboundUpdateMobEffectPacket(this.getId(), akh)); CriteriaTriggers.EFFECTS_CHANGED.trigger(this); } @Override protected void onEffectRemoved(final MobEffectInstance akh) { super.onEffectRemoved(akh); this.connection.send(new ClientboundRemoveMobEffectPacket(this.getId(), akh.getEffect())); if (akh.getEffect() == MobEffects.LEVITATION) { this.levitationStartPos = null; } CriteriaTriggers.EFFECTS_CHANGED.trigger(this); } @Override public void teleportTo(final double double1, final double double2, final double double3) { this.connection.teleport(double1, double2, double3, this.yRot, this.xRot); } @Override public void forceMove(final double double1, final double double2, final double double3) { this.connection.teleport(double1, double2, double3, this.yRot, this.xRot); this.connection.resetPosition(); } @Override public void crit(final Entity akn) { this.getLevel().getChunkSource().broadcastAndSend(this, new ClientboundAnimatePacket(akn, 4)); } @Override public void magicCrit(final Entity akn) { this.getLevel().getChunkSource().broadcastAndSend(this, new ClientboundAnimatePacket(akn, 5)); } @Override public void onUpdateAbilities() { if (this.connection == null) { return; } this.connection.send(new ClientboundPlayerAbilitiesPacket(this.abilities)); this.updateInvisibilityStatus(); } public ServerLevel getLevel() { return (ServerLevel)this.level; } @Override public void setGameMode(final GameType bjq) { this.gameMode.setGameModeForPlayer(bjq); this.connection.send(new ClientboundGameEventPacket(3, (float)bjq.getId())); if (bjq == GameType.SPECTATOR) { this.removeEntitiesOnShoulder(); this.stopRiding(); } else { this.setCamera(this); } this.onUpdateAbilities(); this.updateEffectVisibility(); } @Override public boolean isSpectator() { return this.gameMode.getGameModeForPlayer() == GameType.SPECTATOR; } @Override public boolean isCreative() { return this.gameMode.getGameModeForPlayer() == GameType.CREATIVE; } @Override public void sendMessage(final Component lf) { this.sendMessage(lf, ChatType.SYSTEM); } public void sendMessage(final Component lf, final ChatType ld) { this.connection.send(new ClientboundChatPacket(lf, ld), (future -> { if (!future.isSuccess() && (ld == ChatType.GAME_INFO || ld == ChatType.SYSTEM)) { final int integer5 = 256; final String string6 = lf.getString(256); final Component lf2 = new TextComponent(string6).withStyle(ChatFormatting.YELLOW); this.connection.send(new ClientboundChatPacket(new TranslatableComponent("multiplayer.message_not_delivered", new Object[] { lf2 }).withStyle(ChatFormatting.RED), ChatType.SYSTEM)); } })); } public String getIpAddress() { String string2 = this.connection.connection.getRemoteAddress().toString(); string2 = string2.substring(string2.indexOf("/") + 1); string2 = string2.substring(0, string2.indexOf(":")); return string2; } public void updateOptions(final ServerboundClientInformationPacket pr) { this.language = pr.getLanguage(); this.chatVisibility = pr.getChatVisibility(); this.canChatColor = pr.getChatColors(); this.getEntityData().set(ServerPlayer.DATA_PLAYER_MODE_CUSTOMISATION, (byte)pr.getModelCustomisation()); this.getEntityData().set(ServerPlayer.DATA_PLAYER_MAIN_HAND, (byte)((pr.getMainHand() != HumanoidArm.LEFT) ? 1 : 0)); } public ChatVisiblity getChatVisibility() { return this.chatVisibility; } public void sendTexturePack(final String string1, final String string2) { this.connection.send(new ClientboundResourcePackPacket(string1, string2)); } @Override protected int getPermissionLevel() { return this.server.getProfilePermissions(this.getGameProfile()); } public void resetLastActionTime() { this.lastActionTime = Util.getMillis(); } public ServerStatsCounter getStats() { return this.stats; } public ServerRecipeBook getRecipeBook() { return this.recipeBook; } public void sendRemoveEntity(final Entity akn) { if (akn instanceof Player) { this.connection.send(new ClientboundRemoveEntitiesPacket(new int[] { akn.getId() })); } else { this.entitiesToRemove.add(akn.getId()); } } public void cancelRemoveEntity(final Entity akn) { this.entitiesToRemove.remove(akn.getId()); } @Override protected void updateInvisibilityStatus() { if (this.isSpectator()) { this.removeEffectParticles(); this.setInvisible(true); } else { super.updateInvisibilityStatus(); } } public Entity getCamera() { return (this.camera == null) ? this : this.camera; } public void setCamera(final Entity akn) { final Entity akn2 = this.getCamera(); this.camera = ((akn == null) ? this : akn); if (akn2 != this.camera) { this.connection.send(new ClientboundSetCameraPacket(this.camera)); this.teleportTo(this.camera.getX(), this.camera.getY(), this.camera.getZ()); } } @Override protected void processDimensionDelay() { if (this.changingDimensionDelay > 0 && !this.isChangingDimension) { --this.changingDimensionDelay; } } @Override public void attack(final Entity akn) { if (this.gameMode.getGameModeForPlayer() == GameType.SPECTATOR) { this.setCamera(akn); } else { super.attack(akn); } } public long getLastActionTime() { return this.lastActionTime; } @Nullable public Component getTabListDisplayName() { return null; } @Override public void swing(final InteractionHand ajh) { super.swing(ajh); this.resetAttackStrengthTicker(); } public boolean isChangingDimension() { return this.isChangingDimension; } public void hasChangedDimension() { this.isChangingDimension = false; } public PlayerAdvancements getAdvancements() { return this.advancements; } public void teleportTo(final ServerLevel xd, final double double2, final double double3, final double double4, final float float5, final float float6) { this.setCamera(this); this.stopRiding(); if (xd == this.level) { this.connection.teleport(double2, double3, double4, float5, float6); } else { final ServerLevel xd2 = this.getLevel(); this.dimension = xd.dimension.getType(); final LevelData crj12 = xd.getLevelData(); this.connection.send(new ClientboundRespawnPacket(this.dimension, LevelData.obfuscateSeed(crj12.getSeed()), crj12.getGeneratorType(), this.gameMode.getGameModeForPlayer())); this.connection.send(new ClientboundChangeDifficultyPacket(crj12.getDifficulty(), crj12.isDifficultyLocked())); this.server.getPlayerList().sendPlayerPermissionLevel(this); xd2.removePlayerImmediately(this); this.removed = false; this.moveTo(double2, double3, double4, float5, float6); this.setLevel(xd); xd.addDuringCommandTeleport(this); this.triggerDimensionChangeTriggers(xd2); this.connection.teleport(double2, double3, double4, float5, float6); this.gameMode.setLevel(xd); this.server.getPlayerList().sendLevelInfo(this, xd); this.server.getPlayerList().sendAllPlayerInfo(this); } } public void trackChunk(final ChunkPos bje, final Packet lt2, final Packet lt3) { this.connection.send(lt3); this.connection.send(lt2); } public void untrackChunk(final ChunkPos bje) { if (this.isAlive()) { this.connection.send(new ClientboundForgetLevelChunkPacket(bje.x, bje.z)); } } public SectionPos getLastSectionPos() { return this.lastSectionPos; } public void setLastSectionPos(final SectionPos gd) { this.lastSectionPos = gd; } @Override public void playNotifySound(final SoundEvent aah, final SoundSource aaj, final float float3, final float float4) { this.connection.send(new ClientboundSoundPacket(aah, aaj, this.getX(), this.getY(), this.getZ(), float3, float4)); } @Override public Packet getAddEntityPacket() { return new ClientboundAddPlayerPacket(this); } @Override public ItemEntity drop(final ItemStack bek, final boolean boolean2, final boolean boolean3) { final ItemEntity avy5 = super.drop(bek, boolean2, boolean3); if (avy5 == null) { return null; } this.level.addFreshEntity(avy5); final ItemStack bek2 = avy5.getItem(); if (boolean3) { if (!bek2.isEmpty()) { this.awardStat(Stats.ITEM_DROPPED.get(bek2.getItem()), bek.getCount()); } this.awardStat(Stats.DROP); } return avy5; } static { LOGGER = LogManager.getLogger(); } }