package com.hypixel.hytale.server.core.entity.entities;
import com.hypixel.hytale.codec.Codec;
import com.hypixel.hytale.codec.KeyedCodec;
import com.hypixel.hytale.codec.builder.BuilderCodec;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.component.Holder;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.event.IEventDispatcher;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.math.shape.Box;
import com.hypixel.hytale.math.vector.Transform;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.metrics.MetricProvider;
import com.hypixel.hytale.metrics.MetricResults;
import com.hypixel.hytale.metrics.MetricsRegistry;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.protocol.InteractionType;
import com.hypixel.hytale.protocol.ItemWithAllMetadata;
import com.hypixel.hytale.protocol.MovementStates;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.protocol.SavedMovementStates;
import com.hypixel.hytale.protocol.SoundCategory;
import com.hypixel.hytale.protocol.packets.player.SetBlockPlacementOverride;
import com.hypixel.hytale.protocol.packets.player.SetGameMode;
import com.hypixel.hytale.protocol.packets.player.SetMovementStates;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.type.gamemode.GameModeType;
import com.hypixel.hytale.server.core.codec.ProtocolCodecs;
import com.hypixel.hytale.server.core.command.system.CommandSender;
import com.hypixel.hytale.server.core.entity.Entity;
import com.hypixel.hytale.server.core.entity.InteractionChain;
import com.hypixel.hytale.server.core.entity.InteractionContext;
import com.hypixel.hytale.server.core.entity.InteractionManager;
import com.hypixel.hytale.server.core.entity.LivingEntity;
import com.hypixel.hytale.server.core.entity.UUIDComponent;
import com.hypixel.hytale.server.core.entity.entities.player.CameraManager;
import com.hypixel.hytale.server.core.entity.entities.player.HotbarManager;
import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerConfigData;
import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerRespawnPointData;
import com.hypixel.hytale.server.core.entity.entities.player.hud.HudManager;
import com.hypixel.hytale.server.core.entity.entities.player.movement.MovementManager;
import com.hypixel.hytale.server.core.entity.entities.player.pages.PageManager;
import com.hypixel.hytale.server.core.entity.entities.player.windows.WindowManager;
import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent;
import com.hypixel.hytale.server.core.event.events.ecs.ChangeGameModeEvent;
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.inventory.container.ItemContainer;
import com.hypixel.hytale.server.core.inventory.transaction.ItemStackSlotTransaction;
import com.hypixel.hytale.server.core.io.PacketHandler;
import com.hypixel.hytale.server.core.modules.collision.CollisionModule;
import com.hypixel.hytale.server.core.modules.collision.CollisionResult;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.modules.entity.component.BoundingBox;
import com.hypixel.hytale.server.core.modules.entity.component.CollisionResultComponent;
import com.hypixel.hytale.server.core.modules.entity.component.Invulnerable;
import com.hypixel.hytale.server.core.modules.entity.component.RespondToHit;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.server.core.modules.entity.player.ChunkTracker;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
import com.hypixel.hytale.server.core.modules.entity.tracker.LegacyEntityTrackerSystems;
import com.hypixel.hytale.server.core.modules.interaction.InteractionModule;
import com.hypixel.hytale.server.core.modules.interaction.interaction.config.RootInteraction;
import com.hypixel.hytale.server.core.modules.physics.component.Velocity;
import com.hypixel.hytale.server.core.permissions.PermissionHolder;
import com.hypixel.hytale.server.core.permissions.PermissionsModule;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.Universe;
import com.hypixel.hytale.server.core.universe.world.SoundUtil;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.WorldMapTracker;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.server.core.util.NotificationUtil;
import com.hypixel.hytale.server.core.util.TempAssetIdUtil;
import it.unimi.dsi.fastutil.Pair;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class Player extends LivingEntity implements CommandSender, PermissionHolder, MetricProvider {
@Nonnull
public static final MetricsRegistry<Player> METRICS_REGISTRY;
@Nonnull
public static final KeyedCodec<PlayerConfigData> PLAYER_CONFIG_DATA;
@Nonnull
public static final BuilderCodec<Player> CODEC;
public static final int DEFAULT_VIEW_RADIUS_CHUNKS = 6;
public static final long RESPAWN_INVULNERABILITY_TIME_NANOS;
public static final long MAX_TELEPORT_INVULNERABILITY_MILLIS = 10000L;
@Deprecated(
forRemoval = true
)
private PlayerRef playerRef;
@Nonnull
private PlayerConfigData data = new PlayerConfigData();
@Nonnull
private final WorldMapTracker worldMapTracker = new WorldMapTracker(this);
@Nonnull
private final WindowManager windowManager = new WindowManager();
@Nonnull
private final PageManager pageManager = new PageManager();
@Nonnull
private final HudManager hudManager = new HudManager();
@Nonnull
private HotbarManager hotbarManager = new HotbarManager();
private GameMode gameMode;
private int clientViewRadius = 6;
protected long lastSpawnTimeNanos;
private static final int MAX_VELOCITY_SAMPLE_COUNT = 2;
private static final int VELOCITY_SAMPLE_LENGTH = 12;
private static final double[][] velocitySampleWeights;
private final double[] velocitySamples = new double[12];
private int velocitySampleCount;
private int velocitySampleIndex = 4;
private boolean overrideBlockPlacementRestrictions;
private final AtomicInteger readyId = new AtomicInteger();
private final AtomicReference<ScheduledFuture<?>> waitingForClientReady = new AtomicReference();
public boolean executeTriggers;
public boolean executeBlockDamage;
private boolean firstSpawn;
private int mountEntityId;
@Nonnull
public static ComponentType<EntityStore, Player> getComponentType() {
return EntityModule.get().getPlayerComponentType();
}
public Player() {
}
public void copyFrom(@Nonnull Player oldPlayerComponent) {
this.init(this.legacyUuid, this.playerRef);
this.worldMapTracker.copyFrom(oldPlayerComponent.worldMapTracker);
this.clientViewRadius = oldPlayerComponent.clientViewRadius;
this.readyId.set(oldPlayerComponent.readyId.get());
}
public void init(@Nonnull UUID uuid, @Nonnull PlayerRef playerRef) {
this.legacyUuid = uuid;
this.playerRef = playerRef;
this.windowManager.init(playerRef);
this.pageManager.init(playerRef, this.windowManager);
}
public void setNetworkId(int id) {
this.networkId = id;
}
@Nonnull
protected Inventory createDefaultInventory() {
return new Inventory();
}
@Nonnull
public Inventory setInventory(Inventory inventory) {
return super.setInventory(inventory, true);
}
public boolean remove() {
if (this.wasRemoved.getAndSet(true)) {
return false;
} else {
this.removedBy = new Throwable();
if (this.world != null && this.world.isAlive()) {
if (this.world.isInThread()) {
Ref<EntityStore> ref = this.playerRef.getReference();
if (ref != null) {
Store<EntityStore> store = ref.getStore();
ChunkTracker tracker = (ChunkTracker)store.getComponent(ref, ChunkTracker.getComponentType());
if (tracker != null) {
tracker.clear();
}
this.playerRef.removeFromStore();
}
} else {
this.world.execute(() -> {
Ref<EntityStore> ref = this.playerRef.getReference();
if (ref != null) {
Store<EntityStore> store = ref.getStore();
ChunkTracker tracker = (ChunkTracker)store.getComponent(ref, ChunkTracker.getComponentType());
if (tracker != null) {
tracker.clear();
}
this.playerRef.removeFromStore();
}
});
}
}
if (this.playerRef.getPacketHandler().getChannel().isActive()) {
this.playerRef.getPacketHandler().disconnect("Player removed from world!");
((HytaleLogger.Api)LOGGER.at(Level.WARNING).withCause(this.removedBy)).log("Player removed from world! %s", this);
}
ScheduledFuture<?> task;
if ((task = (ScheduledFuture)this.waitingForClientReady.getAndSet((Object)null)) != null) {
task.cancel(false);
}
return true;
}
}
public void moveTo(@Nonnull Ref<EntityStore> ref, double locX, double locY, double locZ, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
TransformComponent transformComponent = (TransformComponent)componentAccessor.getComponent(ref, TransformComponent.getComponentType());
assert transformComponent != null;
Vector3d position = transformComponent.getPosition();
this.addLocationChange(ref, locX - position.getX(), locY - position.getY(), locZ - position.getZ(), componentAccessor);
super.moveTo(ref, locX, locY, locZ, componentAccessor);
this.windowManager.validateWindows();
}
@Nonnull
public PlayerConfigData getPlayerConfigData() {
return this.data;
}
public void markNeedsSave() {
this.data.markChanged();
}
public void unloadFromWorld() {
super.unloadFromWorld();
}
public void applyMovementStates(@Nonnull Ref<EntityStore> ref, @Nonnull SavedMovementStates savedMovementStates, @Nonnull MovementStates movementStates, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
movementStates.flying = savedMovementStates.flying;
PlayerRef playerRefComponent = (PlayerRef)componentAccessor.getComponent(ref, PlayerRef.getComponentType());
assert playerRefComponent != null;
playerRefComponent.getPacketHandler().writeNoCache(new SetMovementStates(new SavedMovementStates(movementStates.flying)));
}
public void startClientReadyTimeout() {
ScheduledFuture<?> task = HytaleServer.SCHEDULED_EXECUTOR.schedule(() -> this.handleClientReady(true), 10000L, TimeUnit.MILLISECONDS);
ScheduledFuture<?> oldTask = (ScheduledFuture)this.waitingForClientReady.getAndSet(task);
if (oldTask != null) {
oldTask.cancel(false);
}
}
public void handleClientReady(boolean forced) {
ScheduledFuture<?> task;
if ((task = (ScheduledFuture)this.waitingForClientReady.getAndSet((Object)null)) != null) {
task.cancel(false);
if (this.world == null) {
return;
}
IEventDispatcher<PlayerReadyEvent, PlayerReadyEvent> dispatcher = HytaleServer.get().getEventBus().dispatchFor(PlayerReadyEvent.class, this.world.getName());
if (dispatcher.hasListener()) {
dispatcher.dispatch(new PlayerReadyEvent(this.reference, this, this.readyId.getAndIncrement()));
}
}
}
public void sendInventory() {
this.getInventory().consumeIsDirty();
this.playerRef.getPacketHandler().write((Packet)this.getInventory().toPacket());
}
@Nonnull
public CompletableFuture<Void> saveConfig(@Nonnull World world, @Nonnull Holder<EntityStore> holder) {
MovementStatesComponent movementStatesComponent = (MovementStatesComponent)holder.getComponent(MovementStatesComponent.getComponentType());
assert movementStatesComponent != null;
UUIDComponent uuidComponent = (UUIDComponent)holder.getComponent(UUIDComponent.getComponentType());
assert uuidComponent != null;
this.data.getPerWorldData(world.getName()).setLastMovementStates(movementStatesComponent.getMovementStates(), false);
return Universe.get().getPlayerStorage().save(uuidComponent.getUuid(), holder);
}
@Deprecated(
forRemoval = true
)
public PacketHandler getPlayerConnection() {
return this.playerRef.getPacketHandler();
}
@Nonnull
public WorldMapTracker getWorldMapTracker() {
return this.worldMapTracker;
}
@Nonnull
public WindowManager getWindowManager() {
return this.windowManager;
}
@Nonnull
public PageManager getPageManager() {
return this.pageManager;
}
@Nonnull
public HudManager getHudManager() {
return this.hudManager;
}
@Nonnull
public HotbarManager getHotbarManager() {
return this.hotbarManager;
}
public boolean isFirstSpawn() {
return this.firstSpawn;
}
public void setFirstSpawn(boolean firstSpawn) {
this.firstSpawn = firstSpawn;
}
public void resetManagers(@Nonnull Holder<EntityStore> holder) {
PlayerRef playerRef = this.playerRef;
LegacyEntityTrackerSystems.clear(this, holder);
this.worldMapTracker.clear();
this.windowManager.closeAllWindows();
this.hudManager.resetUserInterface(this.playerRef);
this.hudManager.resetHud(this.playerRef);
CameraManager cameraManagerComponent = (CameraManager)playerRef.getComponent(CameraManager.getComponentType());
assert cameraManagerComponent != null;
cameraManagerComponent.resetCamera(playerRef);
MovementManager movementManagerComponent = (MovementManager)playerRef.getComponent(MovementManager.getComponentType());
assert movementManagerComponent != null;
movementManagerComponent.applyDefaultSettings();
movementManagerComponent.update(playerRef.getPacketHandler());
}
public void notifyPickupItem(@Nonnull Ref<EntityStore> ref, @Nonnull ItemStack itemStack, @Nullable Vector3d position, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
World world = ((EntityStore)componentAccessor.getExternalData()).getWorld();
if (world.getGameplayConfig().getShowItemPickupNotifications()) {
PlayerRef playerRefComponent = (PlayerRef)componentAccessor.getComponent(ref, PlayerRef.getComponentType());
assert playerRefComponent != null;
Message itemNameMessage = Message.translation(itemStack.getItem().getTranslationKey());
NotificationUtil.sendNotification(playerRefComponent.getPacketHandler(), Message.translation("server.general.pickedUpItem").param("item", itemNameMessage), (Message)null, (ItemWithAllMetadata)itemStack.toPacket());
}
if (position != null) {
SoundUtil.playSoundEvent3dToPlayer(ref, TempAssetIdUtil.getSoundEventIndex("SFX_Player_Pickup_Item"), SoundCategory.UI, position, componentAccessor);
} else {
SoundUtil.playSoundEvent2d(ref, TempAssetIdUtil.getSoundEventIndex("SFX_Player_Pickup_Item"), SoundCategory.UI, componentAccessor);
}
}
public boolean isOverrideBlockPlacementRestrictions() {
return this.overrideBlockPlacementRestrictions;
}
public void setOverrideBlockPlacementRestrictions(@Nonnull Ref<EntityStore> ref, boolean overrideBlockPlacementRestrictions, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
this.overrideBlockPlacementRestrictions = overrideBlockPlacementRestrictions;
PlayerRef playerRefComponent = (PlayerRef)componentAccessor.getComponent(ref, PlayerRef.getComponentType());
assert playerRefComponent != null;
playerRefComponent.getPacketHandler().writeNoCache(new SetBlockPlacementOverride(overrideBlockPlacementRestrictions));
}
public void sendMessage(@Nonnull Message message) {
this.playerRef.sendMessage(message);
}
public boolean hasPermission(@Nonnull String id) {
return PermissionsModule.get().hasPermission(this.getUuid(), id);
}
public boolean hasPermission(@Nonnull String id, boolean def) {
return PermissionsModule.get().hasPermission(this.getUuid(), id, def);
}
public void addLocationChange(@Nonnull Ref<EntityStore> ref, double deltaX, double deltaY, double deltaZ, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
CollisionResultComponent collisionResultComponent = (CollisionResultComponent)componentAccessor.getComponent(ref, CollisionResultComponent.getComponentType());
assert collisionResultComponent != null;
collisionResultComponent.getCollisionPositionOffset().add(deltaX, deltaY, deltaZ);
if (!collisionResultComponent.isPendingCollisionCheck()) {
TransformComponent transformComponent = (TransformComponent)componentAccessor.getComponent(ref, TransformComponent.getComponentType());
assert transformComponent != null;
Vector3d position = transformComponent.getPosition();
collisionResultComponent.getCollisionStartPosition().assign(position);
collisionResultComponent.markPendingCollisionCheck();
}
}
public void configTriggerBlockProcessing(boolean triggers, boolean blockDamage, @Nonnull CollisionResultComponent collisionResultComponent) {
this.executeTriggers = triggers;
this.executeBlockDamage = blockDamage;
if (!triggers && !blockDamage) {
collisionResultComponent.getCollisionResult().disableTriggerBlocks();
} else {
collisionResultComponent.getCollisionResult().enableTriggerBlocks();
}
}
public void resetVelocity(@Nonnull Velocity velocity) {
Arrays.fill(this.velocitySamples, 0.0);
this.velocitySampleIndex = 4;
this.velocitySampleCount = 0;
velocity.setZero();
}
public void processVelocitySample(double dt, @Nonnull Vector3d position, @Nonnull Velocity velocity) {
double x = position.x;
double y = position.y;
double z = position.z;
if (dt != 0.0) {
this.velocitySamples[this.velocitySampleIndex] = x;
this.velocitySamples[this.velocitySampleIndex + 1] = y;
this.velocitySamples[this.velocitySampleIndex + 2] = z;
this.velocitySamples[this.velocitySampleIndex + 3] = dt;
int index = this.velocitySampleIndex;
this.velocitySampleIndex += 4;
if (this.velocitySampleIndex >= 12) {
this.velocitySampleIndex = 4;
}
if (this.velocitySampleCount < 2) {
++this.velocitySampleCount;
}
if (this.velocitySampleCount < 2) {
velocity.setZero();
} else {
for(int i = 0; i < 4; ++i) {
this.velocitySamples[i] = 0.0;
}
double[] weights = velocitySampleWeights[this.velocitySampleCount - 2];
for(int i = 0; i < this.velocitySampleCount - 1; ++i) {
int previousIndex = index - 4;
if (previousIndex < 4) {
previousIndex = 8;
}
double k = weights[i] / this.velocitySamples[index + 3];
double[] var10000 = this.velocitySamples;
var10000[0] += k * (this.velocitySamples[index] - this.velocitySamples[previousIndex]);
var10000 = this.velocitySamples;
var10000[1] += k * (this.velocitySamples[index + 1] - this.velocitySamples[previousIndex + 1]);
var10000 = this.velocitySamples;
var10000[2] += k * (this.velocitySamples[index + 2] - this.velocitySamples[previousIndex + 2]);
index = previousIndex;
}
velocity.set(this.velocitySamples[0], this.velocitySamples[1], this.velocitySamples[2]);
}
}
}
@Nonnull
public static Transform getRespawnPosition(@Nonnull Ref<EntityStore> ref, @Nonnull String worldName, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
Player playerComponent = (Player)componentAccessor.getComponent(ref, getComponentType());
assert playerComponent != null;
World world = ((EntityStore)componentAccessor.getExternalData()).getWorld();
PlayerConfigData playerConfigData = playerComponent.data;
PlayerRespawnPointData[] respawnPoints = playerConfigData.getPerWorldData(worldName).getRespawnPoints();
if (respawnPoints != null && respawnPoints.length != 0) {
TransformComponent transformComponent = (TransformComponent)componentAccessor.getComponent(ref, TransformComponent.getComponentType());
assert transformComponent != null;
Vector3d playerPosition = transformComponent.getPosition();
List<PlayerRespawnPointData> sortedRespawnPoints = Arrays.stream(respawnPoints).sorted((a, b) -> {
Vector3d posA = a.getRespawnPosition();
Vector3d posB = b.getRespawnPosition();
double distA = playerPosition.distanceSquaredTo(posA.x, playerPosition.y, posA.z);
double distB = playerPosition.distanceSquaredTo(posB.x, playerPosition.y, posB.z);
return Double.compare(distA, distB);
}).toList();
BoundingBox playerBoundingBoxComponent = (BoundingBox)componentAccessor.getComponent(ref, BoundingBox.getComponentType());
if (playerBoundingBoxComponent == null) {
return new Transform(((PlayerRespawnPointData)sortedRespawnPoints.getFirst()).getRespawnPosition());
} else {
for(PlayerRespawnPointData respawnPoint : sortedRespawnPoints) {
Pair<Boolean, Vector3d> respawnPointResult = ensureNoCollisionAtRespawnPosition(respawnPoint, playerBoundingBoxComponent.getBoundingBox(), world);
if ((Boolean)respawnPointResult.left()) {
return new Transform(respawnPointResult.right(), Vector3f.ZERO);
}
playerComponent.sendMessage(Message.translation("server.general.respawnPointObstructed").param("respawnPointName", respawnPoint.getName()));
}
playerComponent.sendMessage(Message.translation("server.general.allRespawnPointsObstructed"));
Transform worldSpawnPoint = world.getWorldConfig().getSpawnProvider().getSpawnPoint(ref, componentAccessor);
worldSpawnPoint.setRotation(Vector3f.ZERO);
return worldSpawnPoint;
}
} else {
Transform worldSpawnPoint = world.getWorldConfig().getSpawnProvider().getSpawnPoint(ref, componentAccessor);
worldSpawnPoint.setRotation(Vector3f.ZERO);
return worldSpawnPoint;
}
}
private static Pair<Boolean, Vector3d> ensureNoCollisionAtRespawnPosition(PlayerRespawnPointData playerRespawnPointData, Box playerHitbox, World world) {
Vector3d respawnPosition = new Vector3d(playerRespawnPointData.getRespawnPosition());
if (CollisionModule.get().validatePosition(world, playerHitbox, respawnPosition, new CollisionResult()) != -1) {
return Pair.<Boolean, Vector3d>of(Boolean.TRUE, respawnPosition);
} else {
respawnPosition.x = (double)((float)playerRespawnPointData.getBlockPosition().x + 0.5F);
respawnPosition.y = (double)playerRespawnPointData.getBlockPosition().y;
respawnPosition.z = (double)((float)playerRespawnPointData.getBlockPosition().z + 0.5F);
for(int distance = 1; distance <= 2; ++distance) {
for(int offset = -distance; offset <= distance; ++offset) {
Vector3d newPosition = new Vector3d(respawnPosition.x + (double)offset, respawnPosition.y, respawnPosition.z - (double)distance);
if (CollisionModule.get().validatePosition(world, playerHitbox, newPosition, new CollisionResult()) != -1) {
return Pair.<Boolean, Vector3d>of(Boolean.TRUE, newPosition);
}
newPosition = new Vector3d(respawnPosition.x + (double)offset, respawnPosition.y, respawnPosition.z + (double)distance);
if (CollisionModule.get().validatePosition(world, playerHitbox, newPosition, new CollisionResult()) != -1) {
return Pair.<Boolean, Vector3d>of(Boolean.TRUE, newPosition);
}
}
for(int offset = -distance + 1; offset < distance; ++offset) {
Vector3d newPosition = new Vector3d(respawnPosition.x - (double)distance, respawnPosition.y, respawnPosition.z + (double)offset);
if (CollisionModule.get().validatePosition(world, playerHitbox, newPosition, new CollisionResult()) != -1) {
return Pair.<Boolean, Vector3d>of(Boolean.TRUE, newPosition);
}
newPosition = new Vector3d(respawnPosition.x + (double)distance, respawnPosition.y, respawnPosition.z + (double)offset);
if (CollisionModule.get().validatePosition(world, playerHitbox, newPosition, new CollisionResult()) != -1) {
return Pair.<Boolean, Vector3d>of(Boolean.TRUE, newPosition);
}
}
}
return Pair.<Boolean, Vector3d>of(Boolean.FALSE, respawnPosition);
}
}
public boolean hasSpawnProtection() {
return System.nanoTime() - this.lastSpawnTimeNanos <= RESPAWN_INVULNERABILITY_TIME_NANOS || this.waitingForClientReady.get() != null;
}
public boolean isWaitingForClientReady() {
return this.waitingForClientReady.get() != null;
}
public boolean isHiddenFromLivingEntity(@Nonnull Ref<EntityStore> ref, @Nonnull Ref<EntityStore> targetRef, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
UUIDComponent uuidComponent = (UUIDComponent)componentAccessor.getComponent(ref, UUIDComponent.getComponentType());
assert uuidComponent != null;
PlayerRef targetPlayerComponent = (PlayerRef)componentAccessor.getComponent(targetRef, PlayerRef.getComponentType());
return targetPlayerComponent != null && targetPlayerComponent.getHiddenPlayersManager().isPlayerHidden(uuidComponent.getUuid());
}
public void setClientViewRadius(int clientViewRadius) {
this.clientViewRadius = clientViewRadius;
}
public int getClientViewRadius() {
return this.clientViewRadius;
}
public int getViewRadius() {
return Math.min(this.clientViewRadius, HytaleServer.get().getConfig().getMaxViewRadius());
}
public boolean canDecreaseItemStackDurability(@Nonnull Ref<EntityStore> ref, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
Player playerComponent = (Player)componentAccessor.getComponent(ref, getComponentType());
assert playerComponent != null;
return playerComponent.gameMode != GameMode.Creative;
}
public boolean canApplyItemStackPenalties(@Nonnull Ref<EntityStore> ref, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
Player playerComponent = (Player)componentAccessor.getComponent(ref, getComponentType());
assert playerComponent != null;
return playerComponent.gameMode != GameMode.Creative;
}
@Nullable
public ItemStackSlotTransaction updateItemStackDurability(@Nonnull Ref<EntityStore> ref, @Nonnull ItemStack itemStack, ItemContainer container, int slotId, double durabilityChange, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
ItemStackSlotTransaction transaction = super.updateItemStackDurability(ref, itemStack, container, slotId, durabilityChange, componentAccessor);
if (transaction != null && transaction.getSlotAfter().isBroken() && !itemStack.isBroken()) {
Message itemNameMessage = Message.translation(itemStack.getItem().getTranslationKey());
this.sendMessage(Message.translation("server.general.repair.itemBroken").param("itemName", itemNameMessage).color("#ff5555"));
PlayerRef playerRefComponent = (PlayerRef)componentAccessor.getComponent(ref, PlayerRef.getComponentType());
assert playerRefComponent != null;
int soundEventIndex = TempAssetIdUtil.getSoundEventIndex("SFX_Item_Break");
SoundUtil.playSoundEvent2dToPlayer(playerRefComponent, soundEventIndex, SoundCategory.SFX);
}
return transaction;
}
@Nonnull
public MetricResults toMetricResults() {
return METRICS_REGISTRY.toMetricResults(this);
}
public void setLastSpawnTimeNanos(long lastSpawnTimeNanos) {
this.lastSpawnTimeNanos = lastSpawnTimeNanos;
}
public long getSinceLastSpawnNanos() {
return System.nanoTime() - this.lastSpawnTimeNanos;
}
@Deprecated(
forRemoval = true
)
public PlayerRef getPlayerRef() {
return this.playerRef;
}
public int getMountEntityId() {
return this.mountEntityId;
}
public void setMountEntityId(int mountEntityId) {
this.mountEntityId = mountEntityId;
}
public GameMode getGameMode() {
return this.gameMode;
}
public static void setGameMode(@Nonnull Ref<EntityStore> playerRef, @Nonnull GameMode gameMode, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
MovementManager movementManagerComponent = (MovementManager)componentAccessor.getComponent(playerRef, MovementManager.getComponentType());
assert movementManagerComponent != null;
Player playerComponent = (Player)componentAccessor.getComponent(playerRef, getComponentType());
assert playerComponent != null;
GameMode oldGameMode = playerComponent.gameMode;
if (oldGameMode != gameMode) {
ChangeGameModeEvent event = new ChangeGameModeEvent(gameMode);
componentAccessor.invoke(playerRef, event);
if (event.isCancelled()) {
return;
}
setGameModeInternal(playerRef, event.getGameMode(), movementManagerComponent, componentAccessor);
runOnSwitchToGameMode(playerRef, gameMode);
}
}
public static void initGameMode(@Nonnull Ref<EntityStore> playerRef, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
MovementManager movementManagerComponent = (MovementManager)componentAccessor.getComponent(playerRef, MovementManager.getComponentType());
assert movementManagerComponent != null;
Player playerComponent = (Player)componentAccessor.getComponent(playerRef, getComponentType());
assert playerComponent != null;
GameMode gameMode = playerComponent.gameMode;
if (gameMode == null) {
World world = ((EntityStore)componentAccessor.getExternalData()).getWorld();
gameMode = world.getWorldConfig().getGameMode();
LOGGER.at(Level.INFO).log("Assigning default gamemode %s to player!", gameMode);
}
setGameModeInternal(playerRef, gameMode, movementManagerComponent, componentAccessor);
}
private static void setGameModeInternal(@Nonnull Ref<EntityStore> playerRef, @Nonnull GameMode gameMode, @Nonnull MovementManager movementManager, @Nonnull ComponentAccessor<EntityStore> componentAccessor) {
Player playerComponent = (Player)componentAccessor.getComponent(playerRef, getComponentType());
assert playerComponent != null;
PlayerRef playerRefComponent = (PlayerRef)componentAccessor.getComponent(playerRef, PlayerRef.getComponentType());
assert playerRefComponent != null;
GameMode oldGameMode = playerComponent.gameMode;
playerComponent.gameMode = gameMode;
playerRefComponent.getPacketHandler().writeNoCache(new SetGameMode(gameMode));
if (movementManager.getDefaultSettings() != null) {
movementManager.getDefaultSettings().canFly = gameMode == GameMode.Creative;
movementManager.getSettings().canFly = gameMode == GameMode.Creative;
movementManager.update(playerRefComponent.getPacketHandler());
}
PermissionsModule permissionsModule = PermissionsModule.get();
if (oldGameMode != null) {
GameModeType oldGameModeType = GameModeType.fromGameMode(oldGameMode);
for(String group : oldGameModeType.getPermissionGroups()) {
permissionsModule.removeUserFromGroup(playerRefComponent.getUuid(), group);
}
}
GameModeType gameModeType = GameModeType.fromGameMode(gameMode);
for(String group : gameModeType.getPermissionGroups()) {
permissionsModule.addUserToGroup(playerRefComponent.getUuid(), group);
}
if (gameMode == GameMode.Creative) {
componentAccessor.putComponent(playerRef, Invulnerable.getComponentType(), Invulnerable.INSTANCE);
} else {
componentAccessor.tryRemoveComponent(playerRef, Invulnerable.getComponentType());
}
if (gameMode == GameMode.Creative) {
PlayerSettings settings = (PlayerSettings)componentAccessor.getComponent(playerRef, PlayerSettings.getComponentType());
if (settings == null) {
settings = PlayerSettings.defaults();
}
if (settings.creativeSettings().respondToHit()) {
componentAccessor.putComponent(playerRef, RespondToHit.getComponentType(), RespondToHit.INSTANCE);
} else {
componentAccessor.tryRemoveComponent(playerRef, RespondToHit.getComponentType());
}
} else {
componentAccessor.tryRemoveComponent(playerRef, RespondToHit.getComponentType());
}
World world = ((EntityStore)componentAccessor.getExternalData()).getWorld();
playerComponent.worldMapTracker.sendSettings(world);
}
private static void runOnSwitchToGameMode(@Nonnull Ref<EntityStore> ref, @Nonnull GameMode gameMode) {
Store<EntityStore> store = ref.getStore();
GameModeType gameModeType = GameModeType.fromGameMode(gameMode);
InteractionManager interactionManagerComponent = (InteractionManager)store.getComponent(ref, InteractionModule.get().getInteractionManagerComponent());
if (interactionManagerComponent != null) {
String interactions = gameModeType.getInteractionsOnEnter();
if (interactions != null) {
InteractionContext context = InteractionContext.forInteraction(interactionManagerComponent, ref, InteractionType.GameModeSwap, store);
RootInteraction rootInteraction = RootInteraction.getRootInteractionOrUnknown(interactions);
if (rootInteraction != null) {
InteractionChain chain = interactionManagerComponent.initChain(InteractionType.EntityStatEffect, context, rootInteraction, true);
interactionManagerComponent.queueExecuteChain(chain);
}
}
}
}
public int hashCode() {
int result = super.hashCode();
result = 31 * result + (this.getUuid() != null ? this.getUuid().hashCode() : 0);
return result;
}
public boolean equals(@Nullable Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
if (!super.equals(o)) {
return false;
} else {
Player player = (Player)o;
return this.getUuid() != null ? this.getUuid().equals(player.getUuid()) : player.getUuid() == null;
}
} else {
return false;
}
}
@Nonnull
public String toString() {
String var10000 = String.valueOf(this.getUuid());
return "Player{uuid=" + var10000 + ", clientViewRadius='" + this.clientViewRadius + "', " + super.toString() + "}";
}
public String getDisplayName() {
return this.playerRef.getUsername();
}
static {
METRICS_REGISTRY = (new MetricsRegistry()).register("Uuid", Entity::getUuid, Codec.UUID_STRING).register("ClientViewRadius", Player::getClientViewRadius, Codec.INTEGER);
PLAYER_CONFIG_DATA = new KeyedCodec<PlayerConfigData>("PlayerData", PlayerConfigData.CODEC);
CODEC = ((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)((BuilderCodec.Builder)BuilderCodec.builder(Player.class, Player::new, LivingEntity.CODEC).append(PLAYER_CONFIG_DATA, (player, data) -> player.data = data, (player) -> player.data).add()).append(new KeyedCodec("BlockPlacementOverride", Codec.BOOLEAN), (player, blockPlacementOverride) -> player.overrideBlockPlacementRestrictions = blockPlacementOverride, (player) -> player.overrideBlockPlacementRestrictions).add()).append(new KeyedCodec("HotbarManager", HotbarManager.CODEC), (player, hotbarManager) -> player.hotbarManager = hotbarManager, (player) -> player.hotbarManager).add()).appendInherited(new KeyedCodec("GameMode", ProtocolCodecs.GAMEMODE_LEGACY), (player, s) -> player.gameMode = s, (player) -> player.gameMode, (player, parent) -> player.gameMode = parent.gameMode).documentation("The last known game-mode of the entity.").add()).build();
RESPAWN_INVULNERABILITY_TIME_NANOS = TimeUnit.MILLISECONDS.toNanos(3000L);
velocitySampleWeights = new double[][]{{1.0}, {0.9, 0.1}};
}
}