// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.server.core.io.handlers.game;

import java.lang.invoke.CallSite;
import java.lang.reflect.UndeclaredThrowableException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.StringConcatFactory;
import java.lang.invoke.MethodType;
import java.lang.invoke.MethodHandles;
import com.hypixel.hytale.protocol.packets.camera.SetFlyCameraMode;
import com.hypixel.hytale.server.core.entity.movement.MovementStatesComponent;
import java.util.Collections;
import java.util.concurrent.Executor;
import com.hypixel.hytale.math.vector.Vector3f;
import com.hypixel.hytale.math.vector.Transform;
import com.hypixel.hytale.server.core.universe.world.WorldMapTracker;
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
import com.hypixel.hytale.server.core.util.PositionUtil;
import com.hypixel.hytale.protocol.packets.worldmap.MapMarker;
import com.hypixel.hytale.server.core.NameMatching;
import java.util.Objects;
import com.hypixel.hytale.protocol.packets.machinima.SetMachinimaActorModel;
import com.hypixel.hytale.server.core.asset.type.model.config.Model;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.protocol.HostAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.CopyOnWriteArrayList;
import com.hypixel.hytale.server.core.modules.singleplayer.SingleplayerModule;
import com.hypixel.hytale.server.core.Constants;
import com.hypixel.hytale.server.core.entity.entities.player.data.PlayerWorldData;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.universe.world.chunk.section.BlockSection;
import com.hypixel.hytale.server.core.inventory.Inventory;
import com.hypixel.hytale.server.core.modules.interaction.BlockPlaceUtils;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.universe.world.chunk.BlockChunk;
import com.hypixel.hytale.server.core.universe.world.storage.ChunkStore;
import com.hypixel.hytale.math.util.ChunkUtil;
import com.hypixel.hytale.math.vector.Vector3d;
import com.hypixel.hytale.protocol.GameMode;
import com.hypixel.hytale.server.core.modules.entity.component.TransformComponent;
import com.hypixel.hytale.protocol.BlockRotation;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.component.ComponentType;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerCreativeSettings;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSettings;
import com.hypixel.hytale.server.core.modules.entity.EntityModule;
import com.hypixel.hytale.server.core.entity.entities.player.windows.ValidatedWindow;
import com.hypixel.hytale.protocol.packets.window.UpdateWindow;
import com.hypixel.hytale.server.core.entity.entities.player.windows.Window;
import java.util.function.Supplier;
import com.hypixel.hytale.server.core.modules.i18n.I18nModule;
import com.hypixel.hytale.math.util.MathUtil;
import com.hypixel.hytale.server.core.modules.entity.tracker.EntityTrackerSystems;
import com.hypixel.hytale.server.core.entity.entities.player.pages.PageManager;
import com.hypixel.hytale.protocol.Packet;
import com.hypixel.hytale.protocol.packets.interface_.SetPage;
import com.hypixel.hytale.protocol.packets.interface_.Page;
import com.hypixel.hytale.server.core.asset.common.CommonAssetModule;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import com.hypixel.hytale.server.core.console.ConsoleModule;
import com.hypixel.hytale.server.core.util.MessageUtil;
import com.hypixel.hytale.server.core.event.events.player.PlayerChatEvent;
import java.util.concurrent.CompletableFuture;
import java.util.Collection;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.command.system.CommandSender;
import com.hypixel.hytale.server.core.command.system.CommandManager;
import com.hypixel.hytale.server.core.modules.entity.teleport.PendingTeleport;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerInput;
import com.hypixel.hytale.server.core.util.ValidateUtil;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.server.core.modules.interaction.InteractionModule;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.protocol.io.netty.ProtocolUtil;
import java.util.logging.Level;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.server.core.universe.Universe;
import io.netty.channel.ChannelHandlerContext;
import com.hypixel.hytale.server.core.io.handlers.SubPacketHandler;
import com.hypixel.hytale.protocol.packets.camera.RequestFlyCameraMode;
import com.hypixel.hytale.protocol.packets.world.SetPaused;
import com.hypixel.hytale.protocol.packets.interaction.SyncInteractionChains;
import com.hypixel.hytale.protocol.packets.worldmap.TeleportToWorldMapPosition;
import com.hypixel.hytale.protocol.packets.worldmap.TeleportToWorldMapMarker;
import com.hypixel.hytale.protocol.packets.worldmap.UpdateWorldMapVisible;
import com.hypixel.hytale.protocol.packets.player.RemoveMapMarker;
import com.hypixel.hytale.protocol.packets.player.ClientPlaceBlock;
import com.hypixel.hytale.protocol.packets.player.SyncPlayerPreferences;
import com.hypixel.hytale.protocol.packets.entities.MountMovement;
import com.hypixel.hytale.protocol.packets.player.ClientReady;
import com.hypixel.hytale.protocol.packets.machinima.UpdateMachinimaScene;
import com.hypixel.hytale.protocol.packets.machinima.RequestMachinimaActorModel;
import com.hypixel.hytale.protocol.packets.window.CloseWindow;
import com.hypixel.hytale.protocol.packets.window.SendWindowAction;
import com.hypixel.hytale.protocol.packets.window.ClientOpenWindow;
import com.hypixel.hytale.protocol.packets.serveraccess.SetServerAccess;
import com.hypixel.hytale.protocol.packets.serveraccess.UpdateServerAccess;
import com.hypixel.hytale.protocol.packets.player.MouseInteraction;
import com.hypixel.hytale.protocol.packets.interface_.UpdateLanguage;
import com.hypixel.hytale.protocol.packets.setup.ViewRadius;
import com.hypixel.hytale.protocol.packets.interface_.CustomPageEvent;
import com.hypixel.hytale.protocol.packets.setup.RequestAssets;
import com.hypixel.hytale.protocol.packets.interface_.ChatMessage;
import com.hypixel.hytale.protocol.packets.player.ClientMovement;
import com.hypixel.hytale.protocol.packets.connection.Pong;
import com.hypixel.hytale.protocol.packets.connection.Disconnect;
import com.hypixel.hytale.server.core.HytaleServerConfig;
import com.hypixel.hytale.server.core.HytaleServer;
import com.hypixel.hytale.server.core.io.PacketHandler;
import com.hypixel.hytale.server.core.io.netty.NettyUtil;
import com.hypixel.hytale.server.core.io.ServerManager;
import java.util.concurrent.ConcurrentLinkedDeque;
import com.hypixel.hytale.server.core.auth.PlayerAuthentication;
import com.hypixel.hytale.server.core.io.ProtocolVersion;
import io.netty.channel.Channel;
import javax.annotation.Nonnull;
import com.hypixel.hytale.protocol.packets.interaction.SyncInteractionChain;
import java.util.Deque;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.io.handlers.IPacketHandler;
import com.hypixel.hytale.server.core.io.handlers.GenericPacketHandler;

public class GamePacketHandler extends GenericPacketHandler implements IPacketHandler
{
    private static final double RELATIVE_POSITION_DELTA_SCALE = 10000.0;
    private PlayerRef playerRef;
    @Deprecated
    private Player playerComponent;
    @Nonnull
    private final Deque<SyncInteractionChain> interactionPacketQueue;
    static final /* synthetic */ boolean $assertionsDisabled;
    
    public GamePacketHandler(@Nonnull final Channel channel, @Nonnull final ProtocolVersion protocolVersion, @Nonnull final PlayerAuthentication auth) {
        super(channel, protocolVersion);
        this.interactionPacketQueue = new ConcurrentLinkedDeque<SyncInteractionChain>();
        this.auth = auth;
        ServerManager.get().populateSubPacketHandlers(this);
        this.registerHandlers();
    }
    
    @Nonnull
    public Deque<SyncInteractionChain> getInteractionPacketQueue() {
        return this.interactionPacketQueue;
    }
    
    @Nonnull
    @Override
    public PlayerRef getPlayerRef() {
        return this.playerRef;
    }
    
    public void setPlayerRef(@Nonnull final PlayerRef playerRef, @Nonnull final Player playerComponent) {
        this.playerRef = playerRef;
        this.playerComponent = playerComponent;
    }
    
    @Nonnull
    @Override
    public String getIdentifier() {
        return "{Playing(" + NettyUtil.formatRemoteAddress(this.channel) + "), " + ((this.playerRef != null) ? /* invokedynamic(!) */ProcyonInvokeDynamicHelper_9.invoke(String.valueOf(this.playerRef.getUuid()), this.playerRef.getUsername()) : "null player");
    }
    
    @Override
    protected void registered0(final PacketHandler oldHandler) {
        final HytaleServerConfig.TimeoutProfile timeouts = HytaleServer.get().getConfig().getConnectionTimeouts();
        this.enterStage("play", timeouts.getPlay());
    }
    
    protected void registerHandlers() {
        this.registerHandler(1, p -> this.handle((Disconnect)p));
        this.registerHandler(3, p -> this.handlePong((Pong)p));
        this.registerHandler(108, p -> this.handle((ClientMovement)p));
        this.registerHandler(211, p -> this.handle((ChatMessage)p));
        this.registerHandler(23, p -> this.handle((RequestAssets)p));
        this.registerHandler(219, p -> this.handle((CustomPageEvent)p));
        this.registerHandler(32, p -> this.handle((ViewRadius)p));
        this.registerHandler(232, p -> this.handle((UpdateLanguage)p));
        this.registerHandler(111, p -> this.handle((MouseInteraction)p));
        this.registerHandler(251, p -> this.handle((UpdateServerAccess)p));
        this.registerHandler(252, p -> this.handle((SetServerAccess)p));
        this.registerHandler(204, p -> this.handle((ClientOpenWindow)p));
        this.registerHandler(203, p -> this.handle((SendWindowAction)p));
        this.registerHandler(202, p -> this.handle((CloseWindow)p));
        this.registerHandler(260, p -> this.handle((RequestMachinimaActorModel)p));
        this.registerHandler(262, p -> this.handle((UpdateMachinimaScene)p));
        this.registerHandler(105, p -> this.handle((ClientReady)p));
        this.registerHandler(166, p -> this.handle((MountMovement)p));
        this.registerHandler(116, p -> this.handle((SyncPlayerPreferences)p));
        this.registerHandler(117, p -> this.handle((ClientPlaceBlock)p));
        this.registerHandler(119, p -> this.handle((RemoveMapMarker)p));
        this.registerHandler(243, p -> this.handle((UpdateWorldMapVisible)p));
        this.registerHandler(244, p -> this.handle((TeleportToWorldMapMarker)p));
        this.registerHandler(245, p -> this.handle((TeleportToWorldMapPosition)p));
        this.registerHandler(290, p -> this.handle((SyncInteractionChains)p));
        this.registerHandler(158, p -> this.handle((SetPaused)p));
        this.registerHandler(282, p -> this.handle((RequestFlyCameraMode)p));
        this.packetHandlers.forEach(SubPacketHandler::registerHandlers);
    }
    
    @Override
    public void closed(final ChannelHandlerContext ctx) {
        super.closed(ctx);
        Universe.get().removePlayer(this.playerRef);
    }
    
    @Override
    public void disconnect(@Nonnull final String message) {
        this.disconnectReason.setServerDisconnectReason(message);
        if (this.playerRef != null) {
            HytaleLogger.getLogger().at(Level.INFO).log("Disconnecting %s at %s with the message: %s", this.playerRef.getUsername(), NettyUtil.formatRemoteAddress(this.channel), message);
            this.disconnect0(message);
            Universe.get().removePlayer(this.playerRef);
        }
        else {
            super.disconnect(message);
        }
    }
    
    public void handle(@Nonnull final Disconnect packet) {
        this.disconnectReason.setClientDisconnectType(packet.type);
        HytaleLogger.getLogger().at(Level.INFO).log("%s - %s at %s left with reason: %s - %s", this.playerRef.getUuid(), this.playerRef.getUsername(), NettyUtil.formatRemoteAddress(this.channel), packet.type.name(), packet.reason);
        ProtocolUtil.closeApplicationConnection(this.channel);
    }
    
    public void handle(@Nonnull final MouseInteraction packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                InteractionModule.get().doMouseInteraction(ref, store, packet, playerComponent, this.playerRef);
            }
        });
    }
    
    public void handle(@Nonnull final ClientMovement packet) {
        if (packet.absolutePosition != null && !ValidateUtil.isSafePosition(packet.absolutePosition)) {
            this.disconnect("Sent impossible position data!");
            return;
        }
        if ((packet.bodyOrientation != null && !ValidateUtil.isSafeDirection(packet.bodyOrientation)) || (packet.lookOrientation != null && !ValidateUtil.isSafeDirection(packet.lookOrientation))) {
            this.disconnect("Sent impossible orientation data!");
            return;
        }
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            if (!(!ref.isValid())) {
                final Player playerComponent = store.getComponent(ref, Player.getComponentType());
                if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                    throw new AssertionError();
                }
                else if (!playerComponent.isWaitingForClientReady()) {
                    final PlayerInput playerInputComponent = store.getComponent(ref, PlayerInput.getComponentType());
                    if (playerInputComponent != null) {
                        if (packet.movementStates != null) {
                            playerInputComponent.queue(new PlayerInput.SetMovementStates(packet.movementStates));
                        }
                        if (packet.velocity != null) {
                            playerInputComponent.queue(new PlayerInput.SetClientVelocity(packet.velocity));
                        }
                        final PendingTeleport pendingTeleport = store.getComponent(ref, PendingTeleport.getComponentType());
                        if (pendingTeleport != null) {
                            if (packet.teleportAck == null) {
                                return;
                            }
                            else {
                                switch (pendingTeleport.validate(packet.teleportAck.teleportId, packet.absolutePosition)) {
                                    case INVALID_ID: {
                                        this.disconnect("Incorrect teleportId");
                                        return;
                                    }
                                    case INVALID_POSITION: {
                                        this.disconnect("Invalid teleport");
                                        return;
                                    }
                                }
                                if (!pendingTeleport.isEmpty()) {
                                    return;
                                }
                                else {
                                    store.removeComponent(ref, PendingTeleport.getComponentType());
                                }
                            }
                        }
                        if (packet.mountedTo != 0) {
                            if (packet.mountedTo != playerInputComponent.getMountId()) {
                                return;
                            }
                            else if (packet.riderMovementStates != null) {
                                playerInputComponent.queue(new PlayerInput.SetRiderMovementStates(packet.riderMovementStates));
                            }
                        }
                        if (packet.bodyOrientation != null) {
                            playerInputComponent.queue(new PlayerInput.SetBody(packet.bodyOrientation));
                        }
                        if (packet.lookOrientation != null) {
                            playerInputComponent.queue(new PlayerInput.SetHead(packet.lookOrientation));
                        }
                        if (packet.wishMovement != null) {
                            playerInputComponent.queue(new PlayerInput.WishMovement(packet.wishMovement.x, packet.wishMovement.y, packet.wishMovement.z));
                        }
                        if (packet.absolutePosition != null) {
                            playerInputComponent.queue(new PlayerInput.AbsoluteMovement(packet.absolutePosition.x, packet.absolutePosition.y, packet.absolutePosition.z));
                        }
                        else if (packet.relativePosition != null && (packet.relativePosition.x != 0 || packet.relativePosition.y != 0 || packet.relativePosition.z != 0 || packet.movementStates != null)) {
                            playerInputComponent.queue(new PlayerInput.RelativeMovement(packet.relativePosition.x / 10000.0, packet.relativePosition.y / 10000.0, packet.relativePosition.z / 10000.0));
                        }
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final ChatMessage packet) {
        if (packet.message == null || packet.message.isEmpty()) {
            this.disconnect("Invalid chat message packet! Message was empty.");
            return;
        }
        final String message = packet.message;
        final char firstChar = message.charAt(0);
        if (firstChar == '/') {
            CommandManager.get().handleCommand(this.playerComponent, message.substring(1));
        }
        else if (firstChar == '.') {
            this.playerRef.sendMessage(Message.translation("server.io.gamepackethandler.localCommandDenied").param("msg", message));
        }
        else {
            final Ref<EntityStore> ref = this.playerRef.getReference();
            if (ref == null || !ref.isValid()) {
                return;
            }
            final UUID playerUUID = this.playerRef.getUuid();
            final List<PlayerRef> targetPlayerRefs = new ObjectArrayList<PlayerRef>(Universe.get().getPlayers());
            targetPlayerRefs.removeIf(targetPlayerRef -> targetPlayerRef.getHiddenPlayersManager().isPlayerHidden(playerUUID));
            HytaleServer.get().getEventBus().dispatchForAsync((Class<? super PlayerChatEvent>)PlayerChatEvent.class).dispatch(new PlayerChatEvent(this.playerRef, targetPlayerRefs, message)).whenComplete((playerChatEvent, throwable) -> {
                if (throwable != null) {
                    HytaleLogger.getLogger().at(Level.SEVERE).withCause(throwable).log("An error occurred while dispatching PlayerChatEvent for player %s", this.playerRef.getUsername());
                }
                else if (!playerChatEvent.isCancelled()) {
                    final Message sentMessage = playerChatEvent.getFormatter().format(this.playerRef, playerChatEvent.getContent());
                    HytaleLogger.getLogger().at(Level.INFO).log(MessageUtil.toAnsiString(sentMessage).toAnsi(ConsoleModule.get().getTerminal()));
                    for (final PlayerRef targetPlayerRef2 : playerChatEvent.getTargets()) {
                        targetPlayerRef2.sendMessage(sentMessage);
                    }
                }
            });
        }
    }
    
    public void handle(@Nonnull final RequestAssets packet) {
        CommonAssetModule.get().sendAssetsToPlayer(this, packet.assets, true);
    }
    
    public void handle(@Nonnull final CustomPageEvent packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            this.playerRef.getPacketHandler().writeNoCache(new SetPage(Page.None, true));
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final PageManager pageManager = playerComponent.getPageManager();
                pageManager.handleEvent(ref, store, packet);
            }
        });
    }
    
    public void handle(@Nonnull final ViewRadius packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final EntityTrackerSystems.EntityViewer entityViewerComponent = store.getComponent(ref, EntityTrackerSystems.EntityViewer.getComponentType());
                if (!GamePacketHandler.$assertionsDisabled && entityViewerComponent == null) {
                    throw new AssertionError();
                }
                else {
                    final int viewRadiusChunks = MathUtil.ceil(packet.value / 32.0f);
                    playerComponent.setClientViewRadius(viewRadiusChunks);
                    entityViewerComponent.viewRadiusBlocks = playerComponent.getViewRadius() * 32;
                }
            }
        });
    }
    
    public void handle(@Nonnull final UpdateLanguage packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        this.playerRef.setLanguage(packet.language);
        I18nModule.get().sendTranslations(this, packet.language);
    }
    
    protected void handle(@Nonnull final ClientOpenWindow packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Supplier<? extends Window> supplier = Window.CLIENT_REQUESTABLE_WINDOW_TYPES.get(packet.type);
        if (supplier == null) {
            throw new RuntimeException("Unable to process ClientOpenWindow packet. Window type is not supported!");
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final UpdateWindow updateWindowPacket = playerComponent.getWindowManager().clientOpenWindow(ref, supplier.get(), store);
                if (updateWindowPacket != null) {
                    this.writeNoCache(updateWindowPacket);
                }
            }
        });
    }
    
    public void handle(@Nonnull final SendWindowAction packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Window window = playerComponent.getWindowManager().getWindow(packet.id);
                if (window != null) {
                    if (window instanceof final ValidatedWindow validatedWindow) {
                        if (!validatedWindow.validate(ref, store)) {
                            window.close(ref, store);
                            return;
                        }
                    }
                    window.handleAction(this.playerRef.getReference(), store, packet.action);
                }
            }
        });
    }
    
    public void handle(@Nonnull final SyncPlayerPreferences packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final ComponentType<EntityStore, PlayerSettings> playerSettingsComponentType;
            final ComponentType<EntityStore, PlayerSettings> componentType = playerSettingsComponentType = EntityModule.get().getPlayerSettingsComponentType();
            new PlayerSettings(packet.showEntityMarkers, packet.armorItemsPreferredPickupLocation, packet.weaponAndToolItemsPreferredPickupLocation, packet.usableItemsItemsPreferredPickupLocation, packet.solidBlockItemsPreferredPickupLocation, packet.miscItemsPreferredPickupLocation, new PlayerCreativeSettings(packet.allowNPCDetection, packet.respondToHit), packet.hideHelmet, packet.hideCuirass, packet.hideGauntlets, packet.hidePants);
            final PlayerSettings component;
            store.putComponent(ref, playerSettingsComponentType, component);
            store.getComponent(ref, Player.getComponentType()).invalidateEquipmentNetwork();
        });
    }
    
    public void handle(@Nonnull final ClientPlaceBlock packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Inventory inventory = playerComponent.getInventory();
                final Vector3i targetBlock = new Vector3i(packet.position.x, packet.position.y, packet.position.z);
                final BlockRotation blockRotation = new BlockRotation(packet.rotation.rotationYaw, packet.rotation.rotationPitch, packet.rotation.rotationRoll);
                final TransformComponent transformComponent = store.getComponent(ref, TransformComponent.getComponentType());
                if (transformComponent != null && playerComponent.getGameMode() != GameMode.Creative) {
                    final Vector3d position = transformComponent.getPosition();
                    final Vector3d blockCenter = new Vector3d(targetBlock.x + 0.5, targetBlock.y + 0.5, targetBlock.z + 0.5);
                    if (position.distanceSquaredTo(blockCenter) > 36.0) {
                        return;
                    }
                }
                final Store<ChunkStore> chunkStore = world.getChunkStore().getStore();
                final long chunkIndex = ChunkUtil.indexChunkFromBlock(targetBlock.x, targetBlock.z);
                final Ref<ChunkStore> chunkReference = chunkStore.getExternalData().getChunkReference(chunkIndex);
                if (chunkReference != null) {
                    final BlockChunk blockChunk = chunkStore.getComponent(chunkReference, BlockChunk.getComponentType());
                    if (blockChunk != null) {
                        final BlockSection section = blockChunk.getSectionAtBlockY(targetBlock.y);
                        if (section != null) {
                            final ItemStack itemInHand = playerComponent.getInventory().getItemInHand();
                            if (itemInHand == null) {
                                section.invalidateBlock(targetBlock.x, targetBlock.y, targetBlock.z);
                            }
                            else {
                                String heldBlockKey = itemInHand.getBlockKey();
                                if (heldBlockKey == null) {
                                    section.invalidateBlock(targetBlock.x, targetBlock.y, targetBlock.z);
                                }
                                else {
                                    if (packet.placedBlockId != -1) {
                                        final String clientPlacedBlockTypeKey = BlockType.getAssetMap().getAsset(packet.placedBlockId).getId();
                                        final BlockType heldBlockType = BlockType.getAssetMap().getAsset(heldBlockKey);
                                        if (heldBlockType != null && BlockPlaceUtils.canPlaceBlock(heldBlockType, clientPlacedBlockTypeKey)) {
                                            heldBlockKey = clientPlacedBlockTypeKey;
                                        }
                                    }
                                    BlockPlaceUtils.placeBlock(ref, itemInHand, heldBlockKey, inventory.getHotbar(), Vector3i.ZERO, targetBlock, blockRotation, inventory, inventory.getActiveHotbarSlot(), playerComponent.getGameMode() != GameMode.Creative, chunkReference, chunkStore, store);
                                }
                            }
                        }
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final RemoveMapMarker packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final PlayerWorldData perWorldData = playerComponent.getPlayerConfigData().getPerWorldData(world.getName());
                perWorldData.removeLastDeath(packet.markerId);
            }
        });
    }
    
    public void handle(@Nonnull final CloseWindow packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                playerComponent.getWindowManager().closeWindow(ref, packet.id, store);
            }
        });
    }
    
    public void handle(@Nonnull final UpdateServerAccess packet) {
        if (!Constants.SINGLEPLAYER) {
            throw new IllegalArgumentException("UpdateServerAccess can only be used in singleplayer!");
        }
        if (!SingleplayerModule.isOwner(this.playerRef)) {
            throw new IllegalArgumentException("UpdateServerAccess can only be by the owner of the singleplayer world!");
        }
        final List<InetSocketAddress> publicAddresses = new CopyOnWriteArrayList<InetSocketAddress>();
        for (final HostAddress host : packet.hosts) {
            publicAddresses.add(InetSocketAddress.createUnresolved(host.host, host.port & 0xFFFF));
        }
        final SingleplayerModule singleplayerModule = SingleplayerModule.get();
        singleplayerModule.setPublicAddresses(publicAddresses);
        singleplayerModule.updateAccess(packet.access);
    }
    
    public void handle(@Nonnull final SetServerAccess packet) {
        if (!Constants.SINGLEPLAYER) {
            throw new IllegalArgumentException("SetServerAccess can only be used in singleplayer!");
        }
        if (!SingleplayerModule.isOwner(this.playerRef)) {
            throw new IllegalArgumentException("SetServerAccess can only be used by the owner of the singleplayer world!");
        }
        final HytaleServerConfig config = HytaleServer.get().getConfig();
        if (config != null) {
            config.setPassword((packet.password != null) ? packet.password : "");
            HytaleServerConfig.save(config);
        }
        SingleplayerModule.get().requestServerAccess(packet.access);
    }
    
    public void handle(@Nonnull final RequestMachinimaActorModel packet) {
        final ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset(packet.modelId);
        this.writeNoCache(new SetMachinimaActorModel(Model.createUnitScaleModel(modelAsset).toPacket(), packet.sceneName, packet.actorName));
    }
    
    public void handle(@Nonnull final UpdateMachinimaScene packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final UpdateMachinimaScene updatePacket = new UpdateMachinimaScene(this.playerRef.getUsername(), packet.sceneName, packet.frame, packet.updateType, packet.scene);
            if ("*".equals(packet.player)) {
                for (final PlayerRef otherPlayerRef : world.getPlayerRefs()) {
                    if (!Objects.equals(otherPlayerRef, this.playerRef)) {
                        otherPlayerRef.getPacketHandler().writeNoCache(updatePacket);
                    }
                }
                this.playerRef.sendMessage(Message.translation("server.io.gamepackethandler.sceneUpdateSent"));
            }
            else {
                final PlayerRef target = NameMatching.DEFAULT.find(Universe.get().getPlayers(), packet.player, PlayerRef::getUsername);
                if (target != null && target.getReference().getStore().getExternalData().getWorld() == world) {
                    target.getPacketHandler().write(updatePacket);
                    this.playerRef.sendMessage(Message.translation("server.io.gamepackethander.sceneUpdateSentToPlayer").param("name", target.getUsername()));
                }
                else {
                    this.playerRef.sendMessage(Message.translation("server.io.gamepackethandler.playerNotFound").param("name", packet.player));
                }
            }
        });
    }
    
    public void handle(@Nonnull final ClientReady packet) {
        HytaleLogger.getLogger().at(Level.WARNING).log("%s: Received %s", this.getIdentifier(), packet);
        final CompletableFuture<Void> future = this.clientReadyForChunksFuture;
        if (packet.readyForChunks && !packet.readyForGameplay && future != null) {
            this.clientReadyForChunksFutureStack = null;
            this.clientReadyForChunksFuture = null;
            future.completeAsync(() -> null);
        }
        if (packet.readyForGameplay) {
            final Ref<EntityStore> ref = this.playerRef.getReference();
            if (ref == null || !ref.isValid()) {
                return;
            }
            final Store<EntityStore> store = ref.getStore();
            final World world = store.getExternalData().getWorld();
            world.execute(() -> {
                final Player playerComponent = store.getComponent(ref, Player.getComponentType());
                if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                    throw new AssertionError();
                }
                else {
                    playerComponent.handleClientReady(false);
                }
            });
        }
    }
    
    public void handle(@Nonnull final UpdateWorldMapVisible packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                playerComponent.getWorldMapTracker().setClientHasWorldMapVisible(packet.visible);
            }
        });
    }
    
    public void handle(@Nonnull final TeleportToWorldMapMarker packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final WorldMapTracker worldMapTracker = playerComponent.getWorldMapTracker();
                if (!worldMapTracker.isAllowTeleportToMarkers()) {
                    this.disconnect("You are not allowed to use TeleportToWorldMapMarker!");
                }
                else {
                    final MapMarker marker = worldMapTracker.getSentMarkers().get(packet.id);
                    if (marker != null) {
                        final Transform transform = PositionUtil.toTransform(marker.transform);
                        final Teleport teleportComponent = Teleport.createForPlayer(transform);
                        world.getEntityStore().getStore().addComponent(this.playerRef.getReference(), Teleport.getComponentType(), teleportComponent);
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final TeleportToWorldMapPosition packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final WorldMapTracker worldMapTracker = playerComponent.getWorldMapTracker();
                if (!worldMapTracker.isAllowTeleportToCoordinates()) {
                    this.disconnect("You are not allowed to use TeleportToWorldMapMarker!");
                }
                else {
                    world.getChunkStore().getChunkReferenceAsync(ChunkUtil.indexChunkFromBlock(packet.x, packet.y)).thenAcceptAsync(chunkRef -> {
                        final BlockChunk blockChunkComponent = world.getChunkStore().getStore().getComponent(chunkRef, BlockChunk.getComponentType());
                        if (!GamePacketHandler.$assertionsDisabled && blockChunkComponent == null) {
                            throw new AssertionError();
                        }
                        else {
                            final Vector3d position = new Vector3d(packet.x, blockChunkComponent.getHeight(packet.x, packet.y) + 2, packet.y);
                            final Teleport teleportComponent = Teleport.createForPlayer(null, position, new Vector3f(0.0f, 0.0f, 0.0f));
                            world.getEntityStore().getStore().addComponent(this.playerRef.getReference(), Teleport.getComponentType(), teleportComponent);
                        }
                    }, (Executor)world);
                }
            }
        });
    }
    
    public void handle(@Nonnull final SyncInteractionChains packet) {
        Collections.addAll(this.interactionPacketQueue, packet.updates);
    }
    
    public void handle(@Nonnull final MountMovement packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else {
                final Ref<EntityStore> entityReference = world.getEntityStore().getRefFromNetworkId(playerComponent.getMountEntityId());
                if (entityReference != null && entityReference.isValid()) {
                    final TransformComponent transformComponent = store.getComponent(entityReference, TransformComponent.getComponentType());
                    if (!GamePacketHandler.$assertionsDisabled && transformComponent == null) {
                        throw new AssertionError();
                    }
                    else {
                        transformComponent.setPosition(PositionUtil.toVector3d(packet.absolutePosition));
                        transformComponent.setRotation(PositionUtil.toRotation(packet.bodyOrientation));
                        final MovementStatesComponent movementStatesComponent = store.getComponent(entityReference, MovementStatesComponent.getComponentType());
                        if (!GamePacketHandler.$assertionsDisabled && movementStatesComponent == null) {
                            throw new AssertionError();
                        }
                        else {
                            movementStatesComponent.setMovementStates(packet.movementStates);
                        }
                    }
                }
            }
        });
    }
    
    public void handle(@Nonnull final SetPaused packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            if (world.getPlayerCount() == 1 && Constants.SINGLEPLAYER) {
                world.setPaused(packet.paused);
            }
        });
    }
    
    public void handle(@Nonnull final RequestFlyCameraMode packet) {
        final Ref<EntityStore> ref = this.playerRef.getReference();
        if (ref == null || !ref.isValid()) {
            return;
        }
        final Store<EntityStore> store = ref.getStore();
        final World world = store.getExternalData().getWorld();
        world.execute(() -> {
            final Player playerComponent = store.getComponent(ref, Player.getComponentType());
            if (!GamePacketHandler.$assertionsDisabled && playerComponent == null) {
                throw new AssertionError();
            }
            else if (playerComponent.hasPermission("hytale.camera.flycam")) {
                this.writeNoCache(new SetFlyCameraMode(packet.entering));
                if (packet.entering) {
                    this.playerRef.sendMessage(Message.translation("server.general.flyCamera.enabled"));
                }
                else {
                    this.playerRef.sendMessage(Message.translation("server.general.flyCamera.disabled"));
                }
            }
            else {
                this.playerRef.sendMessage(Message.translation("server.general.flyCamera.noPermission"));
            }
        });
    }
    
    // This helper class was generated by Procyon to approximate the behavior of an
    // 'invokedynamic' instruction that it doesn't know how to interpret.
    private static final class ProcyonInvokeDynamicHelper_9
    {
        private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
        private static MethodHandle handle;
        private static volatile int fence;
        
        private static MethodHandle handle() {
            final MethodHandle handle = ProcyonInvokeDynamicHelper_9.handle;
            if (handle != null)
                return handle;
            return ProcyonInvokeDynamicHelper_9.ensureHandle();
        }
        
        private static MethodHandle ensureHandle() {
            ProcyonInvokeDynamicHelper_9.fence = 0;
            MethodHandle handle = ProcyonInvokeDynamicHelper_9.handle;
            if (handle == null) {
                MethodHandles.Lookup lookup = ProcyonInvokeDynamicHelper_9.LOOKUP;
                try {
                    handle = ((CallSite)StringConcatFactory.makeConcatWithConstants(lookup, "makeConcatWithConstants", MethodType.methodType(String.class, String.class, String.class), "\u0001, \u0001")).dynamicInvoker();
                }
                catch (Throwable t) {
                    throw new UndeclaredThrowableException(t);
                }
                ProcyonInvokeDynamicHelper_9.fence = 1;
                ProcyonInvokeDynamicHelper_9.handle = handle;
                ProcyonInvokeDynamicHelper_9.fence = 0;
            }
            return handle;
        }
        
        private static String invoke(String p0, String p1) {
            try {
                return ProcyonInvokeDynamicHelper_9.handle().invokeExact(p0, p1);
            }
            catch (Throwable t) {
                throw new UndeclaredThrowableException(t);
            }
        }
    }
}
