1294 lines
53 KiB
Java
1294 lines
53 KiB
Java
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<Integer> 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<Integer> 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<BedSleepingProblem, Unit> startSleepInBed(final BlockPos fk) {
|
|
return (Either<BedSleepingProblem, Unit>)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<ItemStack> 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<Recipe<?>> collection) {
|
|
return this.recipeBook.addRecipes(collection, this);
|
|
}
|
|
|
|
@Override
|
|
public void awardRecipesByKey(final ResourceLocation[] arr) {
|
|
final List<Recipe<?>> 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<Recipe<?>> 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().<Byte>set(ServerPlayer.DATA_PLAYER_MODE_CUSTOMISATION, (Byte)xe.getEntityData().<T>get((EntityDataAccessor<T>)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().<Byte>set(ServerPlayer.DATA_PLAYER_MODE_CUSTOMISATION, (byte)pr.getModelCustomisation());
|
|
this.getEntityData().<Byte>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();
|
|
}
|
|
}
|