package client.network;

import java.util.List;
import java.util.Map.Entry;
import client.Client;
import client.gui.Gui;
import client.gui.GuiConsole;
import client.gui.character.GuiChar;
import client.gui.character.GuiCharacters;
import client.gui.container.GuiChest;
import client.gui.container.GuiCrafting;
import client.gui.container.GuiEnchant;
import client.gui.container.GuiEntity;
import client.gui.container.GuiDevice;
import client.gui.container.GuiMerchant;
import client.gui.container.GuiRepair;
import client.gui.ingame.GuiSign;
import client.init.DimensionMapping;
import client.gui.ingame.GuiForm;
import client.renderer.texture.EntityTexManager;
import client.util.PlayerController;
import client.world.ChunkClient;
import common.block.Block;
import common.block.tech.BlockAnvil;
import common.block.tech.BlockChest;
import common.block.tech.BlockWorkbench;
import common.dimension.DimType;
import common.dimension.Dimension;
import common.dimension.Space;
import common.effect.StatusEffect;
import common.entity.DataWatcher;
import common.entity.Entity;
import common.entity.effect.EntityLightning;
import common.entity.item.EntityBoat;
import common.entity.item.EntityCamera;
import common.entity.item.EntityXp;
import common.entity.npc.EntityNPC;
import common.entity.npc.PlayerCharacter;
import common.entity.projectile.EntityProjectile;
import common.entity.types.EntityLiving;
import common.init.BlockRegistry;
import common.init.Blocks;
import common.init.EntityRegistry;
import common.init.ItemRegistry;
import common.init.Items;
import common.init.SoundEvent;
import common.inventory.Container;
import common.inventory.InventoryBasic;
import common.inventory.InventoryWarpChest;
import common.item.ItemStack;
import common.item.material.ItemGrindedBones;
import common.log.Log;
import common.network.IClientPlayer;
import common.network.NetConnection;
import common.network.NetHandler;
import common.network.Packet;
import common.packet.CPacketPlayerPosLook;
import common.packet.CPacketAction;
import common.packet.CPacketKeepAlive;
import common.packet.SPacketEntity;
import common.packet.SPacketEntityTeleport;
import common.packet.SPacketEntityHeadLook;
import common.packet.SPacketEntityStatus;
import common.packet.SPacketEntityAttach;
import common.packet.SPacketEntityMetadata;
import common.packet.SPacketEntityEffect;
import common.packet.SPacketRemoveEntityEffect;
import common.packet.SPacketExplosion;
import common.packet.SPacketEffect;
import common.packet.SPacketSoundEffect;
import common.packet.SPacketParticles;
import common.packet.SPacketChangeGameState;
import common.packet.SPacketSpawnGlobalEntity;
import common.packet.SPacketOpenWindow;
import common.packet.SPacketCloseWindow;
import common.packet.SPacketSetSlot;
import common.packet.SPacketWindowItems;
import common.packet.SPacketWindowProperty;
import common.packet.SPacketConfirmTransaction;
import common.packet.SPacketUpdateSign;
import common.packet.SPacketUpdateDevice;
import common.packet.SPacketSignEditorOpen;
import common.packet.SPacketPlayerListItem;
import common.packet.SPacketPlayerAbilities;
import common.packet.SPacketTabComplete;
import common.packet.SPacketUpdateEntityTags;
import common.packet.SPacketAnimation;
import common.packet.SPacketBlockBreakAnim;
import common.packet.SPacketBlockChange;
import common.packet.SPacketCamera;
import common.packet.SPacketCelestials;
import common.packet.SPacketCharacterList;
import common.packet.SPacketChunkData;
import common.packet.SPacketCollectItem;
import common.packet.SPacketDestroyEntities;
import common.packet.SPacketDimensionName;
import common.packet.SPacketDimensions;
import common.packet.SPacketDimensions.DimData;
import common.packet.SPacketDisconnect;
import common.packet.SPacketDisplayForm;
import common.packet.SPacketEntityEquipment;
import common.packet.SPacketEntityVelocity;
import common.packet.SPacketHeldItemChange;
import common.packet.SPacketJoinGame;
import common.packet.SPacketKeepAlive;
import common.packet.SPacketMapChunkBulk;
import common.packet.SPacketMessage;
import common.packet.SPacketMultiBlockChange;
import common.packet.SPacketPlayerPosLook;
import common.packet.SPacketRespawn;
import common.packet.SPacketServerConfig;
import common.packet.SPacketServerTick;
import common.packet.SPacketSetExperience;
import common.packet.SPacketSkin;
import common.packet.SPacketSpawnMob;
import common.packet.SPacketSpawnObject;
import common.packet.SPacketSpawnPlayer;
import common.packet.SPacketTimeUpdate;
import common.packet.SPacketTrades;
import common.packet.SPacketUpdateDisplay;
import common.packet.SPacketUpdateHealth;
import common.packet.SPacketUpdatePipe;
import common.rng.Random;
import common.sound.PositionedSound;
import common.sound.Sound;
import common.tileentity.TileEntity;
import common.tileentity.TileEntityChest;
import common.tileentity.Device;
import common.tileentity.TileEntityDisplay;
import common.tileentity.TileEntityItemPipe;
import common.tileentity.TileEntitySign;
import common.util.BlockPos;
import common.util.Pair;
import common.util.ParticleType;
import common.util.BlockPos.MutableBlockPos;
import common.util.Equipment;
import common.village.MerchantRecipeList;
import common.world.State;
import common.world.Weather;
import common.world.World;

public class ClientPlayer implements IClientPlayer
{
	protected final Client gm;
    private final NetConnection connection;
    private World world;
    private boolean loaded;
    private final Random rand = new Random();

    public ClientPlayer(Client gm, NetConnection connection)
    {
		this.gm = gm;
        this.connection = connection;
    }

    
	public final boolean isJumping() {
		return this.gm.jump;
	}

	public final boolean isSprinting() {
		return this.gm.sprint;
	}

	public final boolean isSneaking() {
		return this.gm.sneak;
	}

	public final float getMoveForward() {
		return this.gm.moveForward;
	}

	public final float getMoveStrafe() {
		return this.gm.moveStrafe;
	}

	public final void setMoveForward(float value) {
		this.gm.moveForward = value;
	}

	public final void setMoveStrafe(float value) {
		this.gm.moveStrafe = value;
	}

	public final boolean isRenderViewEntity(Entity entity) {
		return this.gm.getRenderViewEntity() == entity;
	}

	public final void updatePlayerMoveState() {
		this.gm.updatePlayerMoveState();
	}
    
    public final NetConnection getConnection() {
        return this.connection;
    }

	
	public void playSound(Sound sound) {
		this.gm.getSoundManager().playSound(sound);
	}

	public void spawnCritParticles(Entity entityIn) {
		this.gm.effectRenderer.spawnCritParticles(entityIn);
	}
    
    public void onDisconnect(String reason)
    {
    	this.gm.disconnected(reason);
    }

    public void addToSendQueue(Packet p_147297_1_)
    {
        this.connection.sendPacket(p_147297_1_);
    }

    public void cleanup()
    {
        this.world = null;
    }
    
    public void handleServerConfig(SPacketServerConfig packet) {
    	NetHandler.checkThread(packet, this, this.gm);
    	for(Pair<String, Object> var : packet.getValues()) {
    		this.gm.setSyncedVar(var.first(), var.second());
    	}
    }
    
    public void handleJoinGame(SPacketJoinGame packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm);
        this.gm.dimensionName = packetIn.getDimName();
        this.gm.charEditor = packetIn.isInEditor();
        this.gm.controller = new PlayerController(this.gm, this);
        // this.gameController.gameSettings.difficulty = packetIn.getDifficulty();
        this.world = this.gm.loadWorld(packetIn.getDimension(), packetIn.getEntityType());
//        this.gameController.thePlayer.dimension = this.clientWorldController.dimension.getDimensionId();
        this.gm.player.setId(packetIn.getEntityId());
        this.gm.show(this.gm.charEditor ? GuiChar.INSTANCE : null);
//        this.currentServerMaxPlayers = packetIn.getMaxPlayers();
//        this.gameController.controller.setCheat(packetIn.getCheat());
//        this.gameController.updateViewDistance();
//        this.gameController.sendPartsToServer();
//        this.gameController.sendHeightToServer();
        // this.netManager.sendPacket(new C25PacketBrand(Version.NAME));
//        this.netManager.sendPacket(new CPacketSkin(this.gameController.getSkin()));
//        if(this.gameController.getConnected() == null)
//        	this.netManager.sendPacket(new CPacketMessage(CPacketMessage.Type.DISPLAY, 
//        			ChatFormat.replaceCodes(this.gameController.localName)));
    }

    /**
     * Spawns an instance of the objecttype indicated by the packet and sets its position and momentum
     */
    public void handleSpawnObject(SPacketSpawnObject packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        double d0 = (double)packetIn.getX() / 32.0D;
        double d1 = (double)packetIn.getY() / 32.0D;
        double d2 = (double)packetIn.getZ() / 32.0D;

        Entity // entity = null;
//        if (packetIn.getType() == 10)
//        {
//            entity = EntityMinecart.getMinecart(this.clientWorldController, d0, d1, d2, EntityMinecart.EnumMinecartType.byNetworkID(packetIn.getData()));
//        }
//        else 
//        if(packetIn.getType() == EntityRegistry.FISH_HOOK_OID)
//        {
//            Entity entity1 = this.clientWorldController.getEntityByID(packetIn.getData());
//
//            if (entity1.isPlayer())
//            {
//                entity = new EntityFishHook(this.clientWorldController, d0, d1, d2, (EntityNPC)entity1);
//            }
//
//            packetIn.setData(0);
//        }
//        else {
        entity = EntityRegistry.createEntityByID(packetIn.getType(), this.world, d0, d1, d2, packetIn.getData());
//        }
        if(entity != null && entity.dead) {
        	entity = null;
        }
        
//        else if (packetIn.getType() == 60)
//        {
//            entity = new EntityArrow(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 61)
//        {
//            entity = new EntitySnowball(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 71)
//        {
//            entity = new EntityItemFrame(this.clientWorldController, new BlockPos(MathHelper.floor_double(d0), MathHelper.floor_double(d1), MathHelper.floor_double(d2)), EnumFacing.getHorizontal(packetIn.getData()));
//            packetIn.setData(0);
//        }
//        else if (packetIn.getType() == 77)
//        {
//            entity = new EntityLeashKnot(this.clientWorldController, new BlockPos(MathHelper.floor_double(d0), MathHelper.floor_double(d1), MathHelper.floor_double(d2)));
//            packetIn.setData(0);
//        }
//        else if (packetIn.getType() == 65)
//        {
//            entity = new EntityEnderPearl(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 72)
//        {
//            entity = new EntityEnderEye(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 76)
//        {
//            entity = new EntityFireworkRocket(this.clientWorldController, d0, d1, d2, (ItemStack)null);
//        }
//        else if (packetIn.getType() == 63)
//        {
//            entity = new EntityLargeFireball(this.clientWorldController, d0, d1, d2, (double)packetIn.getSpeedX() / 8000.0D, (double)packetIn.getSpeedY() / 8000.0D, (double)packetIn.getSpeedZ() / 8000.0D);
//            packetIn.setData(0);
//        }
//        else if (packetIn.getType() == 64)
//        {
//            entity = new EntitySmallFireball(this.clientWorldController, d0, d1, d2, (double)packetIn.getSpeedX() / 8000.0D, (double)packetIn.getSpeedY() / 8000.0D, (double)packetIn.getSpeedZ() / 8000.0D);
//            packetIn.setData(0);
//        }
//        else if (packetIn.getType() == 66)
//        {
//            entity = new EntityWitherSkull(this.clientWorldController, d0, d1, d2, (double)packetIn.getSpeedX() / 8000.0D, (double)packetIn.getSpeedY() / 8000.0D, (double)packetIn.getSpeedZ() / 8000.0D);
//            packetIn.setData(0);
//        }
//        else if (packetIn.getType() == 62)
//        {
//            entity = new EntityEgg(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 73)
//        {
//            entity = new EntityPotion(this.clientWorldController, d0, d1, d2, packetIn.getData());
//            packetIn.setData(0);
//        }
//        else if (packetIn.getType() == 75)
//        {
//            entity = new EntityExpBottle(this.clientWorldController, d0, d1, d2);
//            packetIn.setData(0);
//        }
//        else if (packetIn.getType() == 1)
//        {
//            entity = new EntityBoat(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 50)
//        {
//            entity = new EntityTNTPrimed(this.clientWorldController, d0, d1, d2, (EntityLivingBase)null, packetIn.getData());
//            packetIn.setData(0);
//        }
//        else if (packetIn.getType() == 78)
//        {
//            entity = new EntityArmorStand(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 51)
//        {
//            entity = new EntityEnderCrystal(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 2)
//        {
//            entity = new EntityItem(this.clientWorldController, d0, d1, d2);
//        }
//        else if (packetIn.getType() == 70)
//        {
//            entity = new EntityFallingBlock(this.clientWorldController, d0, d1, d2, BlockRegistry.getStateById(packetIn.getData() & 65535));
//            packetIn.setData(0);
//        }
//
//        else if (packetIn.getType() == 100)
//        {
//            entity = new EntityDynamite(this.clientWorldController, d0, d1, d2, packetIn.getData());
//            packetIn.setData(0);
//        }

        if (entity != null)
        {
            entity.serverPosX = packetIn.getX();
            entity.serverPosY = packetIn.getY();
            entity.serverPosZ = packetIn.getZ();
            entity.rotPitch = (float)(packetIn.getPitch() * 360) / 256.0F;
            entity.rotYaw = (float)(packetIn.getYaw() * 360) / 256.0F;
            entity.setId(packetIn.getEntityID());
            this.gm.addEntityToWorld(packetIn.getEntityID(), entity);

            if(entity instanceof EntityProjectile projectile) {
            	projectile.setAcceleration((double)packetIn.getSpeedX() / 8000.0D, (double)packetIn.getSpeedY() / 8000.0D, (double)packetIn.getSpeedZ() / 8000.0D);
            }
            else if (entity.hasSpawnVelocity()) // packetIn.getData() > 0)
            {
//                if (packetIn.getType() == 60)
//                {
//                    Entity entity2 = this.clientWorldController.getEntityByID(packetIn.getData());
//
//                    if (entity2 instanceof EntityLivingBase && entity instanceof EntityArrow)
//                    {
//                        ((EntityArrow)entity).shootingEntity = entity2;
//                    }
//                }

                entity.setVelocity((double)packetIn.getSpeedX() / 8000.0D, (double)packetIn.getSpeedY() / 8000.0D, (double)packetIn.getSpeedZ() / 8000.0D);
            }
        }
    }

//    /**
//     * Spawns an experience orb and sets its value (amount of XP)
//     */
//    public void handleSpawnExperienceOrb(SPacketSpawnExperienceOrb packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        Entity entity = new EntityXPOrb(this.clientWorldController, (double)packetIn.getX() / 32.0D, (double)packetIn.getY() / 32.0D, (double)packetIn.getZ() / 32.0D, packetIn.getXPValue());
//        entity.serverPosX = packetIn.getX();
//        entity.serverPosY = packetIn.getY();
//        entity.serverPosZ = packetIn.getZ();
//        entity.rotYaw = 0.0F;
//        entity.rotPitch = 0.0F;
//        entity.setId(packetIn.getEntityID());
//        this.clientWorldController.addEntityToWorld(packetIn.getEntityID(), entity);
//    }

    /**
     * Handles globally visible entities. Used in vanilla for lightning bolts
     */
    public void handleSpawnGlobalEntity(SPacketSpawnGlobalEntity packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        double d0 = (double)packetIn.getEncodedX() / 32.0D;
        double d1 = (double)packetIn.getEncodedY() / 32.0D;
        double d2 = (double)packetIn.getEncodedZ() / 32.0D;
        Entity entity = null;

        if (packetIn.getType() == 1)
        {
            entity = new EntityLightning(this.world, d0, d1, d2, packetIn.getData(), 0, false, null);
        }

        if (entity != null)
        {
            entity.serverPosX = packetIn.getEncodedX();
            entity.serverPosY = packetIn.getEncodedY();
            entity.serverPosZ = packetIn.getEncodedZ();
            entity.rotYaw = 0.0F;
            entity.rotPitch = 0.0F;
            entity.setId(packetIn.getEntityId());
            this.world.effects.add(entity);
        }
    }

//    /**
//     * Handles the spawning of a painting object
//     */
//    public void handleSpawnPainting(SPacketSpawnPainting packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        EntityPainting entitypainting = new EntityPainting(this.clientWorldController, packetIn.getPosition(), packetIn.getFacing(), packetIn.getTitle());
//        this.clientWorldController.addEntityToWorld(packetIn.getEntityID(), entitypainting);
//    }

    /**
     * Sets the velocity of the specified entity to the specified value
     */
    public void handleEntityVelocity(SPacketEntityVelocity packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getEntityID());

        if (entity != null)
        {
            entity.setVelocity((double)packetIn.getMotionX() / 8000.0D, (double)packetIn.getMotionY() / 8000.0D, (double)packetIn.getMotionZ() / 8000.0D);
        }
    }

    /**
     * Invoked when the server registers new proximate objects in your watchlist or when objects in your watchlist have
     * changed -> Registers any changes locally
     */
    public void handleEntityMetadata(SPacketEntityMetadata packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getEntityId());

        if (entity != null && packetIn.func_149376_c() != null)
        {
            entity.getDataWatcher().updateWatchedObjectsFromList(packetIn.func_149376_c());

            if(entity == this.gm.player && this.gm.open instanceof GuiChar gui)
            	gui.checkReopen();
        }
    }

    /**
     * Handles the creation of a nearby player entity, sets the position and held item
     */
    public void handleSpawnPlayer(SPacketSpawnPlayer packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        double x = (double)packetIn.getX() / 32.0D;
        double y = (double)packetIn.getY() / 32.0D;
        double z = (double)packetIn.getZ() / 32.0D;
        float yaw = packetIn.getYaw();
        float pitch = packetIn.getPitch();
        EntityNPC player = (EntityNPC)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gm.world); // new EntityNPC(this.gameController.theWorld); // , /* this.getPlayerInfo( */ packetIn.getUser()); // ).getUser());
        player.setOtherPlayer();
        player.prevX = player.lastTickPosX = (double)(player.serverPosX = packetIn.getX());
        player.prevY = player.lastTickPosY = (double)(player.serverPosY = packetIn.getY());
        player.prevZ = player.lastTickPosZ = (double)(player.serverPosZ = packetIn.getZ());
        player.yawOffset = player.headYaw = yaw;
        int i = packetIn.getCurrentItemID();

        if (i == 0)
        {
            player.setHeldItem(null);
        }
        else
        {
            player.setHeldItem(new ItemStack(ItemRegistry.byId(i)));
        }

        player.setPositionAndRotation(x, y, z, yaw, pitch);
        this.gm.addEntityToWorld(packetIn.getEntityID(), player);
        List<DataWatcher.WatchableObject> list = packetIn.getData();

        if (list != null)
        {
            player.getDataWatcher().updateWatchedObjectsFromList(list);
        }

    	EntityTexManager.setTexture(packetIn.getEntityID(), packetIn.getTexture(), player.getModel());
    }

    /**
     * Updates an entity's position and rotation as specified by the packet
     */
    public void handleEntityTeleport(SPacketEntityTeleport packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getEntityId());

        if (entity != null)
        {
            entity.serverPosX = packetIn.getX();
            entity.serverPosY = packetIn.getY();
            entity.serverPosZ = packetIn.getZ();
            double d0 = (double)entity.serverPosX / 32.0D;
            double d1 = (double)entity.serverPosY / 32.0D;
            double d2 = (double)entity.serverPosZ / 32.0D;
            float f = (float)(packetIn.getYaw() * 360) / 256.0F;
            float f1 = (float)(packetIn.getPitch() * 360) / 256.0F;

            if (Math.abs(entity.posX - d0) < 0.03125D && Math.abs(entity.posY - d1) < 0.015625D && Math.abs(entity.posZ - d2) < 0.03125D)
            {
                entity.setClientPosition(entity.posX, entity.posY, entity.posZ, f, f1, true);
            }
            else
            {
                entity.setClientPosition(d0, d1, d2, f, f1, true);
            }

            entity.onGround = packetIn.getOnGround();
        }
    }

    /**
     * Updates which hotbar slot of the player is currently selected
     */
    public void handleHeldItemChange(SPacketHeldItemChange packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);

        if (packetIn.getHeldItemHotbarIndex() >= 0 && packetIn.getHeldItemHotbarIndex() < this.gm.player.getHotbarSize())
        {
        	if(this.gm.player.getSelectedIndex() != packetIn.getHeldItemHotbarIndex())
        		this.gm.controller.resetUseCooldown();
            this.gm.player.setSelectedIndex(packetIn.getHeldItemHotbarIndex());
        }
    }

    /**
     * Updates the specified entity's position by the specified relative moment and absolute rotation. Note that
     * subclassing of the packet allows for the specification of a subset of this data (e.g. only rel. position, abs.
     * rotation or both).
     */
    public void handleEntityMovement(SPacketEntity packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = packetIn.getEntity(this.world);

        if (entity != null)
        {
            entity.serverPosX += packetIn.getPosX();
            entity.serverPosY += packetIn.getPosY();
            entity.serverPosZ += packetIn.getPosZ();
            double d0 = (double)entity.serverPosX / 32.0D;
            double d1 = (double)entity.serverPosY / 32.0D;
            double d2 = (double)entity.serverPosZ / 32.0D;
            float f = packetIn.hasRotations() ? (float)(packetIn.getYaw() * 360) / 256.0F : entity.rotYaw;
            float f1 = packetIn.hasRotations() ? (float)(packetIn.getPitch() * 360) / 256.0F : entity.rotPitch;
            entity.setClientPosition(d0, d1, d2, f, f1, false);
            entity.onGround = packetIn.getOnGround();
        }
    }

    /**
     * Updates the direction in which the specified entity is looking, normally this head rotation is independent of the
     * rotation of the entity itself
     */
    public void handleEntityHeadLook(SPacketEntityHeadLook packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = packetIn.getEntity(this.world);

        if (entity != null)
        {
            float f = (float)(packetIn.getYaw() * 360) / 256.0F;
            entity.setRotationYawHead(f);
        }
    }

    /**
     * Locally eliminates the entities. Invoked by the server when the items are in fact destroyed, or the player is no
     * longer registered as required to monitor them. The latter  happens when distance between the player and item
     * increases beyond a certain treshold (typically the viewing distance)
     */
    public void handleDestroyEntities(SPacketDestroyEntities packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);

        for (int i = 0; i < packetIn.getEntityIDs().length; ++i)
        {
            this.gm.removeEntityFromWorld(packetIn.getEntityIDs()[i]);
        	EntityTexManager.setTexture(packetIn.getEntityIDs()[i], null, null);
        }
    }

    /**
     * Handles changes in player positioning and rotation such as when travelling to a new dimension, (re)spawning,
     * mounting horses etc. Seems to immediately reply to the server with the clients post-processing perspective on the
     * player positioning
     */
    public void handlePlayerPosLook(SPacketPlayerPosLook packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        EntityNPC entityplayer = this.gm.player;
        double d0 = packetIn.getX();
        double d1 = packetIn.getY();
        double d2 = packetIn.getZ();
        float f = packetIn.getYaw();
        float f1 = packetIn.getPitch();

        if (packetIn.func_179834_f().contains(SPacketPlayerPosLook.EnumFlags.X))
        {
            d0 += entityplayer.posX;
        }
        else
        {
            entityplayer.motionX = 0.0D;
        }

        if (packetIn.func_179834_f().contains(SPacketPlayerPosLook.EnumFlags.Y))
        {
            d1 += entityplayer.posY;
        }
        else
        {
            entityplayer.motionY = 0.0D;
        }

        if (packetIn.func_179834_f().contains(SPacketPlayerPosLook.EnumFlags.Z))
        {
            d2 += entityplayer.posZ;
        }
        else
        {
            entityplayer.motionZ = 0.0D;
        }

        if (packetIn.func_179834_f().contains(SPacketPlayerPosLook.EnumFlags.X_ROT))
        {
            f1 += entityplayer.rotPitch;
        }

        if (packetIn.func_179834_f().contains(SPacketPlayerPosLook.EnumFlags.Y_ROT))
        {
            f += entityplayer.rotYaw;
        }

        entityplayer.setPositionAndRotation(d0, d1, d2, f, f1);
        if(this.gm.getRenderViewEntity() == entityplayer)
        	this.connection.sendPacket(new CPacketPlayerPosLook(entityplayer.posX, entityplayer.getEntityBoundingBox().minY, entityplayer.posZ, entityplayer.rotYaw, entityplayer.rotPitch, false));

        if (!this.loaded)
        {
            this.gm.player.prevX = this.gm.player.posX;
            this.gm.player.prevY = this.gm.player.posY;
            this.gm.player.prevZ = this.gm.player.posZ;
            this.loaded = true;
            this.gm.markReload();
//            this.gameController.displayGuiScreen(null);
//            if(this.travelSound) {
//            	this.gameController.getSoundManager().playSound(new PositionedSound(SoundEvent.TELEPORT));
////            	this.clientWorldController.playSound(entityplayer.posX, entityplayer.posY + (double)entityplayer.getEyeHeight(), entityplayer.posZ, this.travelSound, 1.0F, 1.0F, false);
//            	this.travelSound = false;
//            }
        }
    }

    /**
     * Received from the servers PlayerManager if between 1 and 64 blocks in a chunk are changed. If only one block
     * requires an update, the server sends S23PacketBlockChange and if 64 or more blocks are changed, the server sends
     * S21PacketChunkData
     */
    public void handleMultiBlockChange(SPacketMultiBlockChange packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);

        for (SPacketMultiBlockChange.BlockUpdateData update : packetIn.getChangedBlocks())
        {
            this.world.setState(SPacketMultiBlockChange.getPos(packetIn.getChunkPos(), update.getRawPos()), update.getBlockState());
        }
    }

    /**
     * Updates the specified chunk with the supplied data, marks it for re-rendering and lighting recalculation
     */
    public void handleChunkData(SPacketChunkData packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);

        if (packetIn.hasBiomes())
        {
            if (packetIn.getExtractedExtend().length == 0)
            {
                this.gm.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), false);
                return;
            }

            this.gm.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), true);
        }

//        this.clientWorldController.invalidateBlockReceiveRegion(packetIn.getChunkX() << 4, 0, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, 512, (packetIn.getChunkZ() << 4) + 15);
        ChunkClient chunk = this.gm.getChunk(packetIn.getChunkX(), packetIn.getChunkZ());
        chunk.setData(packetIn.getExtractedDataBytes(), packetIn.getExtractedExtend(), packetIn.hasBiomes());
        this.gm.markBlockRangeForRenderUpdate(packetIn.getChunkX() << 4, -World.MAX_SIZE_Y, packetIn.getChunkZ() << 4, (packetIn.getChunkX() << 4) + 15, World.MAX_SIZE_Y, (packetIn.getChunkZ() << 4) + 15);
    }

    /**
     * Updates the block and metadata and generates a blockupdate (and notify the clients)
     */
    public void handleBlockChange(SPacketBlockChange packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        this.world.setState(packetIn.getBlockPosition(), packetIn.getBlockState());
    }

    /**
     * Closes the network channel
     */
    public void handleDisconnect(SPacketDisconnect packetIn)
    {
        this.connection.closeChannel(packetIn.getMessage());
    }

    public void handleCollectItem(SPacketCollectItem packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getCollectedItemEntityID());
        EntityLiving entitylivingbase = (EntityLiving)this.world.getEntityByID(packetIn.getEntityID());

        if (entitylivingbase == null)
        {
            entitylivingbase = this.gm.player;
        }

        if (entity != null)
        {
            if (entity instanceof EntityXp)
            {
                this.world.playSoundAtEntity(entity, SoundEvent.ORB, 0.2F);
            }
            else
            {
                this.world.playSoundAtEntity(entity, SoundEvent.POP, 0.2F);
            }

            this.gm.removeEntityFromWorld(packetIn.getCollectedItemEntityID());
        }
    }

    /**
     * Prints a chatmessage in the chat GUI
     */
    public void handleMessage(SPacketMessage packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm);

//        if(this.gameController.chatVisibility == EnumChatVisibility.FULL || 
//        		(this.gameController.chatVisibility == EnumChatVisibility.SYSTEM && packetIn.isSystem()))
//        {
        switch(packetIn.getType()) {
	        case CONSOLE:
	        	this.gm.logConsole(packetIn.getMessage());
	            break;
	        case CHAT:
	        	this.gm.logChat(packetIn.getMessage());
	            break;
	        case FEED:
	        	this.gm.logFeed(packetIn.getMessage());
	            break;
	        case HOTBAR:
	        	this.gm.logHotbar(packetIn.getMessage());
	            break;
        }
//        }
    }
    
//    public void handleMessage(SPacketMessage packetIn)
//    {
//    	NetHandler.checkThread(packetIn, this, this.gameController);
//        this.gameController.ingameGui.printFeed(packetIn.getMessage());
//    }
    
//    public void handleNotify(SPacketNotify packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController);
//
//        if(this.gameController.showNotifications)
//	        this.gameController.getNotifier().notify(packetIn.getStack(), packetIn.getMessage().getFormattedText(), 
//	        		packetIn.getDesciption().getFormattedText(), packetIn.getSound());
//    }

    /**
     * Renders a specified animation: Waking up a player, a living entity swinging its currently held item, being hurt
     * or receiving a critical hit by normal or magical means
     */
    public void handleAnimation(SPacketAnimation packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getEntityID());

        if (entity != null)
        {
            if (packetIn.getAnimationType() == 0)
            {
                EntityLiving entitylivingbase = (EntityLiving)entity;
                entitylivingbase.swingItem();
            }
            else if (packetIn.getAnimationType() == 1)
            {
                entity.performHurtAnimation();
            }
//            else if (packetIn.getAnimationType() == 2)
//            {
//                EntityNPC entityplayer = (EntityNPC)entity;
//                entityplayer.wakeUpPlayer();
//            }
            else if (packetIn.getAnimationType() == 4)
            {
                this.gm.effectRenderer.spawnCritParticles(entity);
            }
        }
    }

//    /**
//     * Retrieves the player identified by the packet, puts him to sleep if possible (and flags whether all players are
//     * asleep)
//     */
//    public void handleUseBed(SPacketUseBed packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        packetIn.getPlayer(this.clientWorldController).trySetSpawn(packetIn.getBedPosition());
//    }

    /**
     * Spawns the mob entity at the specified location, with the specified rotation, momentum and type. Updates the
     * entities Datawatchers with the entity metadata specified in the packet
     */
    public void handleSpawnMob(SPacketSpawnMob packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        double d0 = (double)packetIn.getX() / 32.0D;
        double d1 = (double)packetIn.getY() / 32.0D;
        double d2 = (double)packetIn.getZ() / 32.0D;
        float f = (float)(packetIn.getYaw() * 360) / 256.0F;
        float f1 = (float)(packetIn.getPitch() * 360) / 256.0F;
        EntityLiving entitylivingbase = (EntityLiving)EntityRegistry.createEntityByID(packetIn.getEntityType(), this.gm.world);
        entitylivingbase.serverPosX = packetIn.getX();
        entitylivingbase.serverPosY = packetIn.getY();
        entitylivingbase.serverPosZ = packetIn.getZ();
        entitylivingbase.yawOffset = entitylivingbase.headYaw = (float)(packetIn.getHeadPitch() * 360) / 256.0F;
        entitylivingbase.setId(packetIn.getEntityID());
        entitylivingbase.setPositionAndRotation(d0, d1, d2, f, f1);
        entitylivingbase.motionX = (double)((float)packetIn.getVelocityX() / 8000.0F);
        entitylivingbase.motionY = (double)((float)packetIn.getVelocityY() / 8000.0F);
        entitylivingbase.motionZ = (double)((float)packetIn.getVelocityZ() / 8000.0F);
        this.gm.addEntityToWorld(packetIn.getEntityID(), entitylivingbase);
        List<DataWatcher.WatchableObject> list = packetIn.getMetadata();

        if (list != null)
        {
            entitylivingbase.getDataWatcher().updateWatchedObjectsFromList(list);
        }
    }

    public void handleTimeUpdate(SPacketTimeUpdate packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        if(this.gm.world.dimension.hasOrbit())
        	this.gm.world.setOrbit(packetIn.getOrbit());
        if(this.gm.world.dimension.hasRotation())
        	this.gm.world.setRotation(packetIn.getRotation());
        this.gm.setTicked(packetIn.getServerinfo());
        Items.navigator.setLocalTime(packetIn.getLocalTime());
    }

    public void handleServerTick(SPacketServerTick packet)
    {
        NetHandler.checkThread(packet, this, this.gm);
        this.gm.setLastTick(packet.getTime());
    }

//    public void handleCompass(SPacketCompass packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        this.gameController.thePlayer.setSpawnPoint(packetIn.getSpawnPos(), true);
//    }

    public void handleEntityAttach(SPacketEntityAttach packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getEntityId());
        Entity entity1 = this.world.getEntityByID(packetIn.getVehicleEntityId());

        if (packetIn.getLeash() == 0)
        {
//            boolean flag = false;

            if (packetIn.getEntityId() == this.gm.player.getId())
            {
                entity = this.gm.player;

                if (entity1 instanceof EntityBoat boat)
                {
                    boat.setIsBoatEmpty(false);
                }

//                flag = entity.vehicle == null && entity1 != null;
            }
            else if (entity1 instanceof EntityBoat boat)
            {
                boat.setIsBoatEmpty(true);
            }

            if (entity == null)
            {
                return;
            }

            entity.mountEntity(entity1);

//            if (flag)
//            {
//                this.gameController.ingameGui.displayHotbar(TextColor.LIGHT_GRAY + String.format("Drücke %s zum Verlassen", this.gameController.keyBindSneak.getKeyDisplay()));
//            }
        }
        else if (packetIn.getLeash() == 1 && entity instanceof EntityLiving living)
        {
            if (entity1 != null)
            {
            	living.setLeashedTo(entity1, false);
            }
            else
            {
            	living.clearLeashed(false, false);
            }
        }
    }

    /**
     * Invokes the entities' handleUpdateHealth method which is implemented in LivingBase (hurt/death),
     * MinecartMobSpawner (spawn delay), FireworkRocket & MinecartTNT (explosion), IronGolem (throwing,...), Witch
     * (spawn particles), Zombie (villager transformation), Animal (breeding mode particles), Horse (breeding/smoke
     * particles), Sheep (...), Tameable (...), Villager (particles for breeding mode, angry and happy), Wolf (...)
     */
    public void handleEntityStatus(SPacketEntityStatus packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = packetIn.getEntity(this.world);

        if (entity != null)
        {
//            if (packetIn.getOpCode() == 21)
//            {
//                this.gameController.getSoundHandler().playSound(new GuardianSound((EntityGuardian)entity));
//            }
//            else
//            {
                entity.handleStatusUpdate(packetIn.getOpCode());
//            }
        }
    }

    public void handleUpdateHealth(SPacketUpdateHealth packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        this.gm.player.setPlayerSPHealth(packetIn.getHealth());
//        this.gameController.thePlayer.getFoodStats().setFoodLevel(packetIn.getFoodLevel());
//        this.gameController.thePlayer.getFoodStats().setFoodSaturationLevel(packetIn.getSaturationLevel());
    }

    public void handleSetExperience(SPacketSetExperience packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        this.gm.player.setXPStats(packetIn.getProgress(), packetIn.getTotalExperience(), packetIn.getLevel());
    }

    public void handleRespawn(SPacketRespawn packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        this.gm.charEditor = packetIn.isInEditor();
        Dimension dim = packetIn.getDimension();
        if(dim != null) {
            this.gm.dimensionName = packetIn.getDimName();
            this.loaded = false;
//            if(dim.getDimensionId() < 0 && this.gameController.thePlayer.dimension >= 0) {
//            	this.travelSound = "portal.travel";
//            }
//            Scoreboard scoreboard = this.clientWorldController.getScoreboard();
//            this.clientWorldController.setWorldScoreboard(scoreboard);
            this.world = this.gm.loadWorld(dim, packetIn.getEntityType());
//            this.gameController.thePlayer.dimension = dim.getDimensionId();
        }
//        else if(this.gameController.charEditor) {
//        	this.gameController.displayGuiScreen(GuiSkin.INSTANCE);
//        }

        this.gm.setDimensionAndSpawnPlayer(packetIn.getEntityType());
        this.gm.show(this.gm.charEditor ? GuiChar.INSTANCE : null);
//        this.gameController.controller.setCheat(packetIn.getCheat());
    }

    public void handleExplosion(SPacketExplosion packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
		if(packetIn.isLarge())
			this.gm.world.clientParticle(ParticleType.EXPLOSION_HUGE, packetIn.getX(), packetIn.getY(), packetIn.getZ());
		else
			this.gm.world.clientParticle(ParticleType.EXPLOSION_LARGE, packetIn.getX(), packetIn.getY(), packetIn.getZ(), 100);
		if(packetIn.getBlocks() != null) {
			for(BlockPos pos : packetIn.getBlocks()) {
				double d0 = (double)((float)pos.getX() + this.gm.world.rand.floatv());
				double d1 = (double)((float)pos.getY() + this.gm.world.rand.floatv());
				double d2 = (double)((float)pos.getZ() + this.gm.world.rand.floatv());
				this.gm.world.clientParticle(ParticleType.EXPLOSION_NORMAL, (d0 + packetIn.getX() * 1.0D) / 2.0D, (d1 + packetIn.getY() * 1.0D) / 2.0D, (d2 + packetIn.getZ() * 1.0D) / 2.0D);
				this.gm.world.clientParticle(ParticleType.SMOKE, d0, d1, d2);
			}
		}
    }

    public void handleOpenWindow(SPacketOpenWindow packet)
    {
        NetHandler.checkThread(packet, this, this.gm, this.world);
        EntityNPC player = this.gm.player;
        Block block = packet.getGuiId();
        int slots = packet.getSlotCount();

        if(packet.getTilePos() != null)
        {
        	TileEntity tile = this.world.getTileEntity(packet.getTilePos());
        	if(!(tile instanceof Device dev))
        		return;
        	this.gm.show(new GuiDevice(player, new InventoryBasic(slots), dev));
        }
        else if (packet.getEntityId() != -1)
        {
            Entity entity = this.world.getEntityByID(packet.getEntityId());
            if(entity == null)
            	return;
            if(entity instanceof EntityNPC)
                this.gm.show(new GuiMerchant(player, entity, player.worldObj));
            else
            	this.gm.show(new GuiEntity(player, new InventoryBasic(slots), entity));
        }
        else if (block == Blocks.warp_chest)
        {
        	this.gm.show(new GuiChest(player, new InventoryWarpChest(), block));
        }
		else if (block instanceof BlockChest)
        {
            this.gm.show(new GuiChest(player, new InventoryBasic(slots), block));
        }
        else if(block instanceof BlockWorkbench bench) {
	        this.gm.show(new GuiCrafting(player, player.worldObj, bench));
		}
        else if (block instanceof BlockAnvil)
        {
            this.gm.show(new GuiRepair(player, player.worldObj));
        }
		else if (block == Blocks.enchanting_table)
        {
            this.gm.show(new GuiEnchant(player, player.worldObj));
        }
		else {
			return;
		}
        player.openContainer.windowId = packet.getWindowId();
    }
	
	/**
     * Handles pickin up an ItemStack or dropping one in your inventory or an open container
     */
    public void handleSetSlot(SPacketSetSlot packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        EntityNPC entityplayer = this.gm.player;

        if (packetIn.getWindowId() == -1)
        {
            entityplayer.setMouseItem(packetIn.getStack());
        }
        else
        {
//            boolean flag = false;
//
//            if (this.gameController.openGui instanceof GuiCheat)
//            {
////                GuiCheat guicontainercreative = (GuiCheat)this.gameController.openGui;
//                flag = true; // guicontainercreative.getSelectedTabIndex() != CheatTab.tabInventory.getIndex();
//            }

            if (packetIn.getWindowId() == 0 && packetIn.getSlot() >= 5 + Equipment.ARMOR_SLOTS && packetIn.getSlot() < 5 + Equipment.ARMOR_SLOTS + entityplayer.getInventoryCapacity())
            {
                ItemStack itemstack = entityplayer.inventoryContainer.getSlot(packetIn.getSlot()).getStack();

//                if (packetIn.getStack() != null && (itemstack == null || itemstack.stackSize < packetIn.getStack().stackSize))
//                {
//                    packetIn.getStack().animationsToGo = 5;
//                }

                entityplayer.inventoryContainer.putStackInSlot(packetIn.getSlot(), packetIn.getStack());
            }
            else if (packetIn.getWindowId() == entityplayer.openContainer.windowId) // && (packetIn.getWindowId() != 0 || !flag))
            {
                entityplayer.openContainer.putStackInSlot(packetIn.getSlot(), packetIn.getStack());
            }
        }
    }

    /**
     * Verifies that the server and client are synchronized with respect to the inventory/container opened by the player
     * and confirms if it is the case.
     */
    public void handleConfirmTransaction(SPacketConfirmTransaction packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Container container = null;
        EntityNPC entityplayer = this.gm.player;

        if (packetIn.getWindowId() == 0)
        {
            container = entityplayer.inventoryContainer;
        }
        else if (packetIn.getWindowId() == entityplayer.openContainer.windowId)
        {
            container = entityplayer.openContainer;
        }

        if (container != null && !packetIn.isMatching())
        {
            this.addToSendQueue(new CPacketAction(CPacketAction.Action.CONFIRM_TRANSACTION, packetIn.getWindowId() | ((packetIn.getActionNumber() & 65535) << 8)));
        }
    }

    /**
     * Handles the placement of a specified ItemStack in a specified container/inventory slot
     */
    public void handleWindowItems(SPacketWindowItems packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        EntityNPC entityplayer = this.gm.player;

        if (packetIn.func_148911_c() == 0)
        {
            entityplayer.inventoryContainer.putStacksInSlots(packetIn.getItemStacks());
        }
        else if (packetIn.func_148911_c() == entityplayer.openContainer.windowId)
        {
            entityplayer.openContainer.putStacksInSlots(packetIn.getItemStacks());
        }
    }

    /**
     * Creates a sign in the specified location if it didn't exist and opens the GUI to edit its text
     */
    public void handleSignEditorOpen(SPacketSignEditorOpen packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        TileEntity tileentity = this.world.getTileEntity(packetIn.getSignPosition());

        if (!(tileentity instanceof TileEntitySign))
        {
            tileentity = new TileEntitySign();
            tileentity.setWorld(this.world);
            tileentity.setPos(packetIn.getSignPosition());
        }

        this.gm.show(new GuiSign(packetIn.getSignPosition(), ((TileEntitySign)tileentity).text));
    }
    
    public void handleForm(SPacketDisplayForm packet) {
        NetHandler.checkThread(packet, this, this.gm, this.world);
    	this.gm.show(new GuiForm(packet.getId(), packet.getTitle(), packet.getData()));
    }

    /**
     * Updates a specified sign with the specified text lines
     */
    public void handleUpdateSign(SPacketUpdateSign packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
//        boolean flag = false;

        if (this.gm.world.isBlockLoaded(packetIn.getPos()))
        {
            TileEntity tileentity = this.gm.world.getTileEntity(packetIn.getPos());

            if (tileentity instanceof TileEntitySign tileentitysign)
            {
//                if (tileentitysign.getIsEditable())
//                {
                System.arraycopy(packetIn.getLines(), 0, tileentitysign.text, 0, 4);
//                    tileentitysign.command = packetIn.getCommand();
                tileentitysign.markDirty();
//                }

//                flag = true;
            }
        }

//        if (!flag) // && this.gameController.thePlayer != null)
//        {
//            Log.warn("Konnte kein Schild bei " + packetIn.getPos().getX() + ", " + 
//            		packetIn.getPos().getY() + ", " + packetIn.getPos().getZ() + " finden");
//        }
    }

	public void handleUpdateDisplay(SPacketUpdateDisplay packet) {
		NetHandler.checkThread(packet, this, this.gm, this.world);

		if(this.gm.world.isBlockLoaded(packet.getPos())) {
			TileEntity tileentity = this.gm.world.getTileEntity(packet.getPos());

			if(tileentity instanceof TileEntityDisplay display && display.data.length == packet.getPixels().length) {
				System.arraycopy(packet.getPixels(), 0, display.data, 0, display.data.length);
				display.lastUpdated = System.currentTimeMillis();
				display.markDirty();
			}
		}
	}

	public void handleUpdateDevice(SPacketUpdateDevice packet) {
		NetHandler.checkThread(packet, this, this.gm, this.world);
		if(this.gm.world.isBlockLoaded(packet.getPos())) {
			TileEntity te = this.gm.world.getTileEntity(packet.getPos());
			if(te != null && packet.getType() == te.getBlock())
				te.readTags(packet.getTag());
		}
	}

	public void handleUpdatePipe(SPacketUpdatePipe packet) {
		NetHandler.checkThread(packet, this, this.gm, this.world);
		if(this.gm.world.isBlockLoaded(packet.getPos())) {
			TileEntity te = this.gm.world.getTileEntity(packet.getPos());
			if(te instanceof TileEntityItemPipe pipe)
				pipe.setDisplayedItem(packet.getItem());
		}
	}

    /**
     * Sets the progressbar of the opened window to the specified value
     */
    public void handleWindowProperty(SPacketWindowProperty packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        EntityNPC entityplayer = this.gm.player;

        if (entityplayer.openContainer != null && entityplayer.openContainer.windowId == packetIn.getWindowId())
        {
            entityplayer.openContainer.updateProgressBar(packetIn.getVarIndex(), packetIn.getVarValue());
        }
    }

    public void handleEntityEquipment(SPacketEntityEquipment packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getEntityID());

        if (entity instanceof EntityNPC npc)
        {
        	if(packetIn.getEquipmentSlot() == 0)
        		npc.setHeldItem(packetIn.getItemStack());
        	else
        		npc.setArmor(Equipment.ARMOR[packetIn.getEquipmentSlot() - 1], packetIn.getItemStack());
        }
    }

    /**
     * Resets the ItemStack held in hand and closes the window that is opened
     */
    public void handleCloseWindow(SPacketCloseWindow packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
//        this.gameController.thePlayer.closeScreenAndDropStack();
        this.gm.show(null);
    }

    /**
     * Updates all registered IWorldAccess instances with destroyBlockInWorldPartially
     */
    public void handleBlockBreakAnim(SPacketBlockBreakAnim packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        this.gm.renderer.setBreakProgress(packetIn.getBreakerId(), packetIn.getPosition(), packetIn.getProgress());
    }

    public void handleMapChunkBulk(SPacketMapChunkBulk packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);

        for (int i = 0; i < packetIn.getChunkCount(); ++i)
        {
            int j = packetIn.getChunkX(i);
            int k = packetIn.getChunkZ(i);
            this.gm.doPreChunk(j, k, true);
//            this.clientWorldController.invalidateBlockReceiveRegion(j << 4, 0, k << 4, (j << 4) + 15, 512, (k << 4) + 15);
            ChunkClient chunk = this.gm.getChunk(j, k);
            chunk.setData(packetIn.getChunkBytes(i), packetIn.getChunkExtend(i), true);
            this.gm.markBlockRangeForRenderUpdate(j << 4, -World.MAX_SIZE_Y, k << 4, (j << 4) + 15, World.MAX_SIZE_Y, (k << 4) + 15);
        }
    }

    public void handleChangeGameState(SPacketChangeGameState packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        switch(packetIn.getAction()) {
//	    	case SET_CHEAT:
//	            this.gameController.controller.setCheat(packetIn.getInt() == 1);
//	            break;
        	case SET_WEATHER:
        		int id = packetIn.getInt();
	            this.world.setWeather(id >= 0 && id < Weather.values().length ? Weather.values()[id] : Weather.CLEAR);
	            break;
        	case RAIN_STRENGTH:
	            this.world.setRainStrength(packetIn.getFloat(true));
	            break;
        	case DARKNESS:
	            this.world.setDarkness(packetIn.getFloat(true));
	            break;
        	case FOG_STRENGTH:
	            this.world.setFogStrength(packetIn.getFloat(true));
	            break;
        	case TEMPERATURE:
	            this.world.setTemperature(packetIn.getFloat(false));
	            break;
        }
    }

    public void handleEffect(SPacketEffect packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);

        this.playAuxSFX(packetIn.getSoundType(), packetIn.getSoundPos(), packetIn.getSoundData());
    }
    
	private void spawnParticle(ParticleType particle, double xCoord, double yCoord, double zCoord, int data) {
        this.gm.effectRenderer.spawnParticle(this.gm.getRenderViewEntity(), particle, xCoord, yCoord, zCoord, data);
    }

	private void spawnParticle(ParticleType particle, double xCoord, double yCoord, double zCoord) {
        this.gm.effectRenderer.spawnParticle(this.gm.getRenderViewEntity(), particle, xCoord, yCoord, zCoord, 0);
    }
    
    private void playSoundAtPos(BlockPos pos, SoundEvent sound, float volume)
    {
    	this.gm.getSoundManager().playSound(new PositionedSound(sound, volume, (float)pos.getX() + 0.5f, (float)pos.getY() + 0.5f, (float)pos.getZ() + 0.5f));
    }

    public void playAuxSFX(int sfxType, BlockPos blockPosIn, int data)
    {
        switch (sfxType)
        {
            case 1000:
                this.playSoundAtPos(blockPosIn, SoundEvent.CLICK, 1.0F);
                break;

            case 1001:
                this.playSoundAtPos(blockPosIn, SoundEvent.CLICK, 1.0F);
                break;

            case 1002:
                this.playSoundAtPos(blockPosIn, SoundEvent.THROW, 1.0F);
                break;

            case 1003:
                this.playSoundAtPos(blockPosIn, SoundEvent.DOOR, 1.0F);
                break;

            case 1004:
                this.playSoundAtPos(blockPosIn, SoundEvent.FIZZ, 0.5F);
                break;

            case 1005:
                this.playSoundAtPos(blockPosIn, SoundEvent.TELEPORT, 10.0F);
                break;

            case 1006:
                this.playSoundAtPos(blockPosIn, SoundEvent.DOOR, 1.0F);
                break;

            case 1007:
                this.playSoundAtPos(blockPosIn, SoundEvent.SPELL, 10.0F);
                break;

            case 1008:
                this.playSoundAtPos(blockPosIn, SoundEvent.FIREBALL, 10.0F);
                break;

            case 1009:
                this.playSoundAtPos(blockPosIn, SoundEvent.FIREBALL, 2.0F);
                break;

            case 1013:
                this.playSoundAtPos(blockPosIn, SoundEvent.TELEPORT_REV, 0.5F);
                break;

            case 1014:
                this.playSoundAtPos(blockPosIn, SoundEvent.METAL, 2.0F);
                break;

            case 1015:
                this.playSoundAtPos(blockPosIn, SoundEvent.BAT_TAKEOFF, 0.05F);
                break;

            case 1016:
                this.playSoundAtPos(blockPosIn, SoundEvent.FIREBALL, 2.0F);
                break;

            case 1017:
                this.playSoundAtPos(blockPosIn, SoundEvent.EXPLODE, 20.0f);
                break;

            case 1020:
                this.playSoundAtPos(blockPosIn, SoundEvent.ANVIL_BREAK, 1.0F);
                break;

            case 1021:
                this.playSoundAtPos(blockPosIn, SoundEvent.ANVIL_USE, 1.0F);
                break;

            case 1022:
                this.playSoundAtPos(blockPosIn, SoundEvent.ANVIL_LAND, 0.3F);
                break;

            case 1023:
                this.playSoundAtPos(blockPosIn, SoundEvent.GLASS, 1.0F);
                break;

            case 1024:
                this.playSoundAtPos(blockPosIn, SoundEvent.CLICK, 1.0F);
                break;

            case 1025:
            	MutableBlockPos pos = new MutableBlockPos(blockPosIn.getX(), blockPosIn.getY(), blockPosIn.getZ());
            	for(int z = 0; z < 1000; z++) {
            		this.spawnParticle(ParticleType.EXPLOSION_HUGE, 
        					(double)pos.getX() + this.rand.gaussian() * 128.0, (double)pos.getY() + this.rand.gaussian() * 2.0, (double)pos.getZ() + this.rand.gaussian() * 128.0);
            	}
            	for(int z = 0; z < 1000; z++) {
            		this.spawnParticle(ParticleType.EXPLOSION_NORMAL, 
            				(double)pos.getX() + this.rand.gaussian() * 128.0, (double)pos.getY() + this.rand.gaussian() * 2.0, (double)pos.getZ() + this.rand.gaussian() * 128.0, 100);
            	}
            	for(int z = 0; z < 30; z++) {
            		this.playSoundAtPos(pos.set(blockPosIn.getX() + this.rand.range(-128, 128), 
            				blockPosIn.getY() + this.rand.range(-4, 4), blockPosIn.getZ() + this.rand.range(-128, 128)), 
            				SoundEvent.EXPLODE, 30.0F);
            	}
                break;

            case 2000:
                int l = data % 3 - 1;
                int i = data / 3 % 3 - 1;
                double d15 = (double)blockPosIn.getX() + (double)l * 0.6D + 0.5D;
                double d17 = (double)blockPosIn.getY() + 0.5D;
                double d19 = (double)blockPosIn.getZ() + (double)i * 0.6D + 0.5D;

                for (int k1 = 0; k1 < 10; ++k1)
                {
                    double d20 = this.rand.doublev() * 0.2D + 0.01D;
                    double d21 = d15 + (double)l * 0.01D + (this.rand.doublev() - 0.5D) * (double)i * 0.5D;
                    double d4 = d17 + (this.rand.doublev() - 0.5D) * 0.5D;
                    double d6 = d19 + (double)i * 0.01D + (this.rand.doublev() - 0.5D) * (double)l * 0.5D;
                    this.spawnParticle(ParticleType.SMOKE, d21, d4, d6);
                }

                return;

            case 2001:
                State state = BlockRegistry.byId(data);

                if (state != null && state.getBlock() != Blocks.air)
                {
                    this.gm.getSoundManager().playSound(new PositionedSound(state.getBlock().getSound().getBreakSound(), 1.0F, /* block.sound.getFrequency() * 0.8F, */ (float)blockPosIn.getX() + 0.5F, (float)blockPosIn.getY() + 0.5F, (float)blockPosIn.getZ() + 0.5F));
                }
                if(state != null)
                	this.gm.effectRenderer.destroyBlock(blockPosIn, state);
                break;

            case 2002:
                double d13 = (double)blockPosIn.getX();
                double d14 = (double)blockPosIn.getY();
                double d16 = (double)blockPosIn.getZ();

                for (int i1 = 0; i1 < 8; ++i1)
                {
					this.spawnParticle(ParticleType.ITEM_CRACK, d13, d14, d16, ItemRegistry.getId(Items.water_bottle));
                }

                for (int l1 = 0; l1 < 100; ++l1)
                {
                    this.spawnParticle(ParticleType.POTION, d13, d14, d16, data);
                }

                this.playSoundAtPos(blockPosIn, SoundEvent.GLASS, 1.0F);
                break;

            case 2005:
                ItemGrindedBones.spawnParticles(this.gm.world, blockPosIn, data);
                break;
                
            case 2016:
            	TileEntity te = this.gm.world.getTileEntity(blockPosIn);
            	if(te instanceof TileEntityChest chest) {
            		chest.setUsing(data);
            		this.gm.world.markBlockForUpdate(blockPosIn);
            	}
        }
    }

//    /**
//     * Updates the players statistics or achievements
//     */
//    public void handleStatistics(S37PacketStatistics packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        boolean flag = false;
//
//        for (Entry<StatBase, Integer> entry : packetIn.getStats().entrySet())
//        {
//            StatBase statbase = (StatBase)entry.getKey();
//            int i = ((Integer)entry.getValue()).intValue();
//
////            if (statbase.isAchievement() && i > 0)
////            {
////                if (this.field_147308_k && this.gameController.thePlayer.getStatFileWriter().readStat(statbase) == 0)
////                {
////                    Achievement achievement = (Achievement)statbase;
////                    this.gameController.getNotifier().displayAchievement(achievement);
////
//////                    if (statbase == AchievementList.openInventory)
//////                    {
//////                        this.gameController.showInventoryAchievementHint = false;
//////                        this.gameController.saveOptions();
//////                    }
////                }
////
////                flag = true;
////            }
//
//            this.gameController.stats.put(statbase, i);
//        }
//
////        if (!this.field_147308_k && !flag && this.gameController.showInventoryAchievementHint)
////        {
////            this.gameController.getNotifier().displayUnformattedAchievement(AchievementList.openInventory);
////        }
//
////        this.field_147308_k = true;
//
////        if (this.gameController.openGui instanceof GuiAchievements)
////        {
////            ((GuiAchievements)this.gameController.openGui).doneLoading();
////        }
////        else
//        if (this.gameController.openGui instanceof GuiStats)
//        {
//            ((GuiStats)this.gameController.openGui).doneLoading();
//        }
//    }

    public void handleEntityEffect(SPacketEntityEffect packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getEntityId());

        if (entity instanceof EntityLiving living)
        {
            StatusEffect potioneffect = new StatusEffect(packetIn.getEffectId(), packetIn.getDuration(), packetIn.getAmplifier())
            	.setRemaining(packetIn.getRemaining());
            living.addEffect(potioneffect);
        }
    }

//    public void handleCombatEvent(S42PacketCombatEvent packetIn)
//    {
//        PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.gameController);
//        
//    }

//    public void handleServerDifficulty(S3EPacketServerDifficulty packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
////        this.gameController.theWorld.setHardcore(packetIn.isHardcore());
////        this.gameController.theWorld.getWorldInfo().setLocked(packetIn.isDifficultyLocked());
//    }

    public void handleCamera(SPacketCamera packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        EntityCamera camera = packetIn.getEntity(this.world);
        this.gm.setRenderViewEntity(camera == null ? this.gm.player : camera);
    }

    
//    public void handleTitle(S42PacketTitle packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController);
//        this.gameController.ingameGui.displayTitle(packetIn.getTitle(), packetIn.getSubtitle());
//    }

//    public void handleSetCompressionLevel(S46PacketSetCompressionLevel packetIn)
//    {
//        if (!this.netManager.isLocalChannel())
//        {
//            this.netManager.setCompressionTreshold(packetIn.getThreshold());
//        }
//    }

//    public void handlePlayerListHeaderFooter(S47PacketPlayerListHeaderFooter packetIn)
//    {
//    }

//    public void handleDisplay(SPacketDisplay packetIn)
//    {
////    	switch(packetIn.getType()) {
////	    	case DISPLAY:
//    	this.gameController.nickname = packetIn.getName() == null ? "" : (packetIn.getName().length() > 48 ? packetIn.getName().substring(0, 48) : packetIn.getName());
////    	this.gameController.nickChanged = true;
////	        	break;
////	    	case HEADER:
////	            this.gameController.ingameGui.setHeader(packetIn.getList() == null ? null : 
////	            	packetIn.getList().replace("${user}", this.gameController.getUser()));
////	    		break;
////	    	case FOOTER:
////	            this.gameController.ingameGui.setFooter(packetIn.getList() == null ? null : 
////	            	packetIn.getList().replace("${user}", this.gameController.getUser()));
////	    		break;
////	    	case SIDEBAR:
////	        	this.gameController.ingameGui.displaySidebar(packetIn.getList());
////	    		break;
////    	}
//    }

    public void handleRemoveEntityEffect(SPacketRemoveEntityEffect packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = this.world.getEntityByID(packetIn.getEntityId());

        if (entity instanceof EntityLiving living)
        {
            living.removeEffectClient(packetIn.getEffectId());
        }
    }

    
    public void handlePlayerListItem(SPacketPlayerListItem packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm);

        for(Entry<String, Integer> data : packetIn.getEntries()) {
            if(data.getValue() < 0)
                this.gm.playerList.remove(data.getKey());
            else
                this.gm.playerList.put(data.getKey(), data.getValue());
        }
//        String[] list = new String[this.playerList.size()];
//        int[] data = new int[this.playerList.size()];
//        int pos = 0;
//        for(Entry<String, Integer> entry : this.playerList.entrySet()) {
//        	list[pos] = entry.getKey();
//        	data[pos++] = entry.getValue();
//        }
//        this.gameController.infolist(list, data);
    }

    public void handleCharacterList(SPacketCharacterList packet)
    {
    	NetHandler.checkThread(packet, this, this.gm);

        for(Entry<Integer, PlayerCharacter> data : packet.getEntries()) {
            if(data.getValue() == null)
                this.gm.characterList.remove(data.getKey().intValue());
            else if(data.getKey() < this.gm.characterList.size())
            	this.gm.characterList.set(data.getKey(), data.getValue());
            else
                this.gm.characterList.add(data.getKey(), data.getValue());
        }
        this.gm.selectedCharacter = packet.getSelected();
        if(this.gm.charEditor && this.gm.selectedCharacter >= 0) {
        	this.gm.charEditor = false;
        	this.gm.show(null);
        }
        else if(this.gm.open instanceof GuiCharacters) {
        	this.gm.show(this.gm.open);
        }
        else if(this.gm.open instanceof GuiChar guichar) {
        	guichar.setCharsAvailable();
        }
    }

    public void handleKeepAlive(SPacketKeepAlive packetIn)
    {
        this.addToSendQueue(new CPacketKeepAlive(packetIn.getValue()));
    }

    public void handlePlayerAbilities(SPacketPlayerAbilities packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        EntityNPC entityplayer = this.gm.player;
        entityplayer.flying = packetIn.isFlying();
        entityplayer.noclip = packetIn.isNoclip();
//        entityplayer.speed = packetIn.getSpeed();
//        entityplayer.capabilities.setWalkSpeed(packetIn.getWalkSpeed());
    }

    /**
     * Displays the available command-completion options the server knows of
     */
    public void handleTabComplete(SPacketTabComplete packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        String[] astring = packetIn.func_149630_c();
//        this.gameController.complete(astring);
        if (this.gm.open instanceof GuiConsole guichat)
        {
            guichat.onAutocompleteResponse(astring);
        }
    }

    public void handleSoundEffect(SPacketSoundEffect packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        if(packetIn.getSound() == null) {
        	this.gm.getSoundManager().stopSounds();
        	return;
        }
//        else if(packetIn.getSoundName().startsWith("music#")) {
//        	return;
//        }
        this.gm.getSoundManager().playSound(new PositionedSound(packetIn.getSound(), packetIn.getVolume(), (float)packetIn.getX(), (float)packetIn.getY(), (float)packetIn.getZ()));
    }

//    public void handleDisplay(S48PacketDisplay packetIn)
//    {
////        if(this.gameController.getConnected() == null)
////        {
////            File file1 = new File("saves");
////            File file2 = new File(file1, "resources.zip");
////
////            if (file2.isFile())
////            {
////                Futures.addCallback(this.gameController.getResourcePackRepository().setResourcePackInstance(file2), new FutureCallback<Object>()
////                {
////                    public void onSuccess(Object p_onSuccess_1_)
////                    {
////                        
////                    }
////                    public void onFailure(Throwable p_onFailure_1_)
////                    {
////                        
////                    }
////                });
////            }
////        }
//    }

    public void handleEntityTags(SPacketUpdateEntityTags packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        Entity entity = packetIn.getEntity(this.world);

        if (entity != null)
        {
            entity.clientUpdateEntityTags(packetIn.getTagCompound());
        }
    }
    
//    public void handleDisplayList(S3BPacketDisplayList packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        
//    }

//    /**
//     * Either updates the score with a specified value or removes the score for an objective
//     */
//    public void handleUpdateScore(S3CPacketUpdateScore packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        Scoreboard scoreboard = this.clientWorldController.getScoreboard();
//        ScoreObjective scoreobjective = scoreboard.getObjective(packetIn.getObjectiveName());
//
//        if (packetIn.getScoreAction() == S3CPacketUpdateScore.Action.CHANGE)
//        {
//            Score score = scoreboard.getValueFromObjective(packetIn.getPlayerName(), scoreobjective);
//            score.setScorePoints(packetIn.getScoreValue());
//        }
//        else if (packetIn.getScoreAction() == S3CPacketUpdateScore.Action.REMOVE)
//        {
//            if (packetIn.getObjectiveName() == null || packetIn.getObjectiveName().isEmpty())
//            {
//                scoreboard.removeObjectiveFromEntity(packetIn.getPlayerName(), (ScoreObjective)null);
//            }
//            else if (scoreobjective != null)
//            {
//                scoreboard.removeObjectiveFromEntity(packetIn.getPlayerName(), scoreobjective);
//            }
//        }
//    }
//
//    /**
//     * Removes or sets the ScoreObjective to be displayed at a particular scoreboard position (list, sidebar, below
//     * name)
//     */
//    public void handleDisplayScoreboard(S3DPacketDisplayScoreboard packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        Scoreboard scoreboard = this.clientWorldController.getScoreboard();
//
//        if (packetIn.func_149370_d().length() == 0)
//        {
//            scoreboard.setObjectiveInDisplaySlot(packetIn.func_149371_c(), (ScoreObjective)null);
//        }
//        else
//        {
//            ScoreObjective scoreobjective = scoreboard.getObjective(packetIn.func_149370_d());
//            scoreboard.setObjectiveInDisplaySlot(packetIn.func_149371_c(), scoreobjective);
//        }
//    }

//    /**
//     * Updates a team managed by the scoreboard: Create/Remove the team registration, Register/Remove the player-team-
//     * memberships, Set team displayname/prefix/suffix and/or whether friendly fire is enabled
//     */
//    public void handleTeams(S3EPacketTeams packetIn)
//    {
//        NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//        Scoreboard scoreboard = this.clientWorldController.getScoreboard();
//        Team scoreplayerteam;
//
//        if (packetIn.getAction() == 0)
//        {
//            scoreplayerteam = scoreboard.createTeam(packetIn.getName());
//        }
//        else
//        {
//            scoreplayerteam = scoreboard.getTeam(packetIn.getName());
//        }
//
////        if (packetIn.getAction() == 0 || packetIn.getAction() == 2)
////        {
////            scoreplayerteam.setTeamName(packetIn.getDisplayName());
////            scoreplayerteam.setNamePrefix(packetIn.getPrefix());
////            scoreplayerteam.setNameSuffix(packetIn.getSuffix());
////            scoreplayerteam.setChatFormat(ChatFormat.getByIndex(packetIn.getColor()));
////            scoreplayerteam.func_98298_a(packetIn.getFriendlyFlags());
////            Team.EnumVisible team$enumvisible = Team.EnumVisible.func_178824_a(packetIn.getNameTagVisibility());
////
////            if (team$enumvisible != null)
////            {
////                scoreplayerteam.setNameTagVisibility(team$enumvisible);
////            }
////        }
//
//        if (packetIn.getAction() == 0 || packetIn.getAction() == 3)
//        {
//            for (String s : packetIn.getPlayers())
//            {
//                scoreboard.addPlayerToTeam(s, packetIn.getName());
//            }
//        }
//
//        if (packetIn.getAction() == 4)
//        {
//            for (String s1 : packetIn.getPlayers())
//            {
//                scoreboard.removePlayerFromTeam(s1, scoreplayerteam);
//            }
//        }
//
//        if (packetIn.getAction() == 1)
//        {
//            scoreboard.removeTeam(scoreplayerteam);
//        }
//    }

    /**
     * Spawns a specified number of particles at the specified location with a randomized displacement according to
     * specified bounds
     */
    public void handleParticles(SPacketParticles packetIn)
    {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);

        try
        {
			this.world.clientParticle(packetIn.getParticleType(), packetIn.getXCoordinate(), packetIn.getYCoordinate(), packetIn.getZCoordinate(), packetIn.getParticleArg());
        }
        catch (Throwable var17)
        {
            Log.RENDER.warn("Konnte Partikel-Effekt " + packetIn.getParticleType() + " nicht erzeugen");
        }
    }

    public void handleSkin(SPacketSkin packetIn) {
        NetHandler.checkThread(packetIn, this, this.gm, this.world);
        
        Entity entity = packetIn.getEntity(this.world);
        if(entity != null && entity.isPlayer()) // {
        	EntityTexManager.setTexture(entity.getId(), packetIn.getTexture(), ((EntityNPC)entity).getModel());
//        	if(entity == this.gameController.thePlayer)
//        		this.gameController.confirmSkin(true);
//        }
    }
    
//    public void handleCapes(SPacketCapes packetIn) {
//        NetHandler.checkThread(packetIn, this, this.gameController);
//    	EntityTexManager.setCapeTextures(packetIn.getCapes());
//    }
    
//    public void handleBook(SPacketBook packetIn) {
//    	 NetHandler.checkThread(packetIn, this, this.gameController, this.clientWorldController);
//
//         ItemStack itemstack = this.gameController.thePlayer.getCurrentEquippedItem();
//
//         if (itemstack != null && itemstack.getItem() == Items.writable_book)
//         {
//             this.gameController.displayGuiScreen(new GuiBook(itemstack));
//         }
//    }
    
    public void handleTrades(SPacketTrades packetIn) {
    	 NetHandler.checkThread(packetIn, this, this.gm, this.world);

         try
         {
             int i = packetIn.getWindowId();
             Gui gui = this.gm.open;

             if (gui != null && gui instanceof GuiMerchant merchant && i == this.gm.player.openContainer.windowId)
             {
//                 NpcMerchant imerchant = ((GuiMerchant)guiscreen).getMerchant();
                 MerchantRecipeList merchantrecipelist = packetIn.getTrades();
                 merchant.setRecipes(merchantrecipelist);
             }
         }
         catch (Exception exception)
         {
             Log.TICK.error((Throwable)exception, (String)"Konnte Handel nicht laden");
         }
    }
    
    public void handleDimName(SPacketDimensionName packet) {
   	 	NetHandler.checkThread(packet, this, this.gm, this.world);
   	 	this.world.dimension.setDisplay(packet.getCustomName());
   	 	this.world.dimension.setBaseNames(packet.getFullName());
   	 	Dimension dim = DimensionMapping.getDimension(this.gm.dimensionName);
   	 	if(dim != null) {
   	 		dim.setDisplay(packet.getCustomName());
   	 		dim.setBaseNames(packet.getFullName());
   	 	}
    }
    
    public void handleCelestials(SPacketCelestials packet) {
   	 	NetHandler.checkThread(packet, this, this.gm, this.world);
   	 	this.gm.setExterminated(packet.getExterminated());
   	 	if(this.world.dimension.getType() == DimType.PLANET || this.world.dimension.getType() == DimType.MOON) {
	   	 	this.world.dimension.setSunColor(packet.getSunColor());
	   	 	this.world.dimension.setMoonColors(packet.getMoonColors());
   	 	}
    }

    public void handleDimensions(SPacketDimensions packet)
    {
    	NetHandler.checkThread(packet, this, this.gm);
        for(DimData data : packet.getDimensions()) {
            if(data.name() == null) {
                DimensionMapping.remove(data.id());
            }
            else {
            	Dimension dim = data.type() == null ? Space.INSTANCE : Dimension.create(data.type());
            	dim.setDisplay(data.display());
            	dim.setBaseNames(data.full());
                DimensionMapping.put(data.name(), data.id(), dim);
            }
        }
    }
}
