    001    package net.minecraft.src;
    002
    003    import java.io.ByteArrayInputStream;
    004    import java.io.DataInputStream;
    005    import java.io.IOException;
    006    import java.util.ArrayList;
    007    import java.util.Iterator;
    008    import java.util.Random;
    009    import java.util.logging.Logger;
    010
    011    import cpw.mods.fml.common.network.FMLNetworkHandler;
    012    import net.minecraft.server.MinecraftServer;
    013    import net.minecraftforge.event.Event;
    014    import net.minecraftforge.event.ForgeEventFactory;
    015    import net.minecraftforge.event.entity.player.PlayerInteractEvent;
    016    import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action;
    017
    018    public class NetServerHandler extends NetHandler
    019    {
    020        /** The logging system. */
    021        public static Logger logger = Logger.getLogger("Minecraft");
    022
    023        /** The underlying network manager for this server handler. */
    024        public NetworkManager netManager;
    025
    026        /** This is set to true whenever a player disconnects from the server. */
    027        public boolean connectionClosed = false;
    028
    029        /** Reference to the MinecraftServer object. */
    030        private MinecraftServer mcServer;
    031
    032        /** Reference to the EntityPlayerMP object. */
    033        private EntityPlayerMP playerEntity;
    034
    035        /** incremented each tick */
    036        private int currentTicks;
    037
    038        /**
    039         * player is kicked if they float for over 80 ticks without flying enabled
    040         */
    041        public int ticksForFloatKick;
    042        private boolean field_72584_h;
    043        private int keepAliveRandomID;
    044        private long keepAliveTimeSent;
    045        private static Random randomGenerator = new Random();
    046        private long ticksOfLastKeepAlive;
    047        private int chatSpamThresholdCount = 0;
    048        private int creativeItemCreationSpamThresholdTally = 0;
    049
    050        /** The last known x position for this connection. */
    051        private double lastPosX;
    052
    053        /** The last known y position for this connection. */
    054        private double lastPosY;
    055
    056        /** The last known z position for this connection. */
    057        private double lastPosZ;
    058
    059        /** is true when the player has moved since his last movement packet */
    060        private boolean hasMoved = true;
    061        private IntHashMap field_72586_s = new IntHashMap();
    062
    063        public NetServerHandler(MinecraftServer par1MinecraftServer, NetworkManager par2NetworkManager, EntityPlayerMP par3EntityPlayerMP)
    064        {
    065            this.mcServer = par1MinecraftServer;
    066            this.netManager = par2NetworkManager;
    067            par2NetworkManager.setNetHandler(this);
    068            this.playerEntity = par3EntityPlayerMP;
    069            par3EntityPlayerMP.playerNetServerHandler = this;
    070        }
    071
    072        /**
    073         * run once each game tick
    074         */
    075        public void networkTick()
    076        {
    077            this.field_72584_h = false;
    078            ++this.currentTicks;
    079            this.mcServer.theProfiler.startSection("packetflow");
    080            this.netManager.processReadPackets();
    081            this.mcServer.theProfiler.endStartSection("keepAlive");
    082
    083            if ((long)this.currentTicks - this.ticksOfLastKeepAlive > 20L)
    084            {
    085                this.ticksOfLastKeepAlive = (long)this.currentTicks;
    086                this.keepAliveTimeSent = System.nanoTime() / 1000000L;
    087                this.keepAliveRandomID = randomGenerator.nextInt();
    088                this.sendPacketToPlayer(new Packet0KeepAlive(this.keepAliveRandomID));
    089            }
    090
    091            if (this.chatSpamThresholdCount > 0)
    092            {
    093                --this.chatSpamThresholdCount;
    094            }
    095
    096            if (this.creativeItemCreationSpamThresholdTally > 0)
    097            {
    098                --this.creativeItemCreationSpamThresholdTally;
    099            }
    100
    101            this.mcServer.theProfiler.endStartSection("playerTick");
    102
    103            if (!this.field_72584_h && !this.playerEntity.playerConqueredTheEnd)
    104            {
    105                this.playerEntity.onUpdateEntity();
    106
    107                if (this.playerEntity.ridingEntity == null)
    108                {
    109                    this.playerEntity.setLocationAndAngles(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch);
    110                }
    111            }
    112
    113            this.mcServer.theProfiler.endSection();
    114        }
    115
    116        public void kickPlayerFromServer(String par1Str)
    117        {
    118            if (!this.connectionClosed)
    119            {
    120                this.playerEntity.mountEntityAndWakeUp();
    121                this.sendPacketToPlayer(new Packet255KickDisconnect(par1Str));
    122                this.netManager.serverShutdown();
    123                this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat("\u00a7e" + this.playerEntity.username + " left the game."));
    124                this.mcServer.getConfigurationManager().playerLoggedOut(this.playerEntity);
    125                this.connectionClosed = true;
    126            }
    127        }
    128
    129        public void handleFlying(Packet10Flying par1Packet10Flying)
    130        {
    131            WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension);
    132            this.field_72584_h = true;
    133
    134            if (!this.playerEntity.playerConqueredTheEnd)
    135            {
    136                double var3;
    137
    138                if (!this.hasMoved)
    139                {
    140                    var3 = par1Packet10Flying.yPosition - this.lastPosY;
    141
    142                    if (par1Packet10Flying.xPosition == this.lastPosX && var3 * var3 < 0.01D && par1Packet10Flying.zPosition == this.lastPosZ)
    143                    {
    144                        this.hasMoved = true;
    145                    }
    146                }
    147
    148                if (this.hasMoved)
    149                {
    150                    double var5;
    151                    double var7;
    152                    double var9;
    153                    double var13;
    154
    155                    if (this.playerEntity.ridingEntity != null)
    156                    {
    157                        float var34 = this.playerEntity.rotationYaw;
    158                        float var4 = this.playerEntity.rotationPitch;
    159                        this.playerEntity.ridingEntity.updateRiderPosition();
    160                        var5 = this.playerEntity.posX;
    161                        var7 = this.playerEntity.posY;
    162                        var9 = this.playerEntity.posZ;
    163                        double var35 = 0.0D;
    164                        var13 = 0.0D;
    165
    166                        if (par1Packet10Flying.rotating)
    167                        {
    168                            var34 = par1Packet10Flying.yaw;
    169                            var4 = par1Packet10Flying.pitch;
    170                        }
    171
    172                        if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D && par1Packet10Flying.stance == -999.0D)
    173                        {
    174                            if (Math.abs(par1Packet10Flying.xPosition) > 1.0D || Math.abs(par1Packet10Flying.zPosition) > 1.0D)
    175                            {
    176                                System.err.println(this.playerEntity.username + " was caught trying to crash the server with an invalid position.");
    177                                this.kickPlayerFromServer("Nope!");
    178                                return;
    179                            }
    180
    181                            var35 = par1Packet10Flying.xPosition;
    182                            var13 = par1Packet10Flying.zPosition;
    183                        }
    184
    185                        this.playerEntity.onGround = par1Packet10Flying.onGround;
    186                        this.playerEntity.onUpdateEntity();
    187                        this.playerEntity.moveEntity(var35, 0.0D, var13);
    188                        this.playerEntity.setPositionAndRotation(var5, var7, var9, var34, var4);
    189                        this.playerEntity.motionX = var35;
    190                        this.playerEntity.motionZ = var13;
    191
    192                        if (this.playerEntity.ridingEntity != null)
    193                        {
    194                            var2.uncheckedUpdateEntity(this.playerEntity.ridingEntity, true);
    195                        }
    196
    197                        if (this.playerEntity.ridingEntity != null)
    198                        {
    199                            this.playerEntity.ridingEntity.updateRiderPosition();
    200                        }
    201
    202                        if (!this.hasMoved) //Fixes teleportation kick while riding entities
    203                        {
    204                            return;
    205                        }
    206
    207                        this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity);
    208                        this.lastPosX = this.playerEntity.posX;
    209                        this.lastPosY = this.playerEntity.posY;
    210                        this.lastPosZ = this.playerEntity.posZ;
    211                        var2.updateEntity(this.playerEntity);
    212                        return;
    213                    }
    214
    215                    if (this.playerEntity.isPlayerSleeping())
    216                    {
    217                        this.playerEntity.onUpdateEntity();
    218                        this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch);
    219                        var2.updateEntity(this.playerEntity);
    220                        return;
    221                    }
    222
    223                    var3 = this.playerEntity.posY;
    224                    this.lastPosX = this.playerEntity.posX;
    225                    this.lastPosY = this.playerEntity.posY;
    226                    this.lastPosZ = this.playerEntity.posZ;
    227                    var5 = this.playerEntity.posX;
    228                    var7 = this.playerEntity.posY;
    229                    var9 = this.playerEntity.posZ;
    230                    float var11 = this.playerEntity.rotationYaw;
    231                    float var12 = this.playerEntity.rotationPitch;
    232
    233                    if (par1Packet10Flying.moving && par1Packet10Flying.yPosition == -999.0D && par1Packet10Flying.stance == -999.0D)
    234                    {
    235                        par1Packet10Flying.moving = false;
    236                    }
    237
    238                    if (par1Packet10Flying.moving)
    239                    {
    240                        var5 = par1Packet10Flying.xPosition;
    241                        var7 = par1Packet10Flying.yPosition;
    242                        var9 = par1Packet10Flying.zPosition;
    243                        var13 = par1Packet10Flying.stance - par1Packet10Flying.yPosition;
    244
    245                        if (!this.playerEntity.isPlayerSleeping() && (var13 > 1.65D || var13 < 0.1D))
    246                        {
    247                            this.kickPlayerFromServer("Illegal stance");
    248                            logger.warning(this.playerEntity.username + " had an illegal stance: " + var13);
    249                            return;
    250                        }
    251
    252                        if (Math.abs(par1Packet10Flying.xPosition) > 3.2E7D || Math.abs(par1Packet10Flying.zPosition) > 3.2E7D)
    253                        {
    254                            this.kickPlayerFromServer("Illegal position");
    255                            return;
    256                        }
    257                    }
    258
    259                    if (par1Packet10Flying.rotating)
    260                    {
    261                        var11 = par1Packet10Flying.yaw;
    262                        var12 = par1Packet10Flying.pitch;
    263                    }
    264
    265                    this.playerEntity.onUpdateEntity();
    266                    this.playerEntity.ySize = 0.0F;
    267                    this.playerEntity.setPositionAndRotation(this.lastPosX, this.lastPosY, this.lastPosZ, var11, var12);
    268
    269                    if (!this.hasMoved)
    270                    {
    271                        return;
    272                    }
    273
    274                    var13 = var5 - this.playerEntity.posX;
    275                    double var15 = var7 - this.playerEntity.posY;
    276                    double var17 = var9 - this.playerEntity.posZ;
    277                    double var19 = Math.min(Math.abs(var13), Math.abs(this.playerEntity.motionX));
    278                    double var21 = Math.min(Math.abs(var15), Math.abs(this.playerEntity.motionY));
    279                    double var23 = Math.min(Math.abs(var17), Math.abs(this.playerEntity.motionZ));
    280                    double var25 = var19 * var19 + var21 * var21 + var23 * var23;
    281
    282                    if (var25 > 100.0D && (!this.mcServer.isSinglePlayer() || !this.mcServer.getServerOwner().equals(this.playerEntity.username)))
    283                    {
    284                        logger.warning(this.playerEntity.username + " moved too quickly! " + var13 + "," + var15 + "," + var17 + " (" + var19 + ", " + var21 + ", " + var23 + ")");
    285                        this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch);
    286                        return;
    287                    }
    288
    289                    float var27 = 0.0625F;
    290                    boolean var28 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract((double)var27, (double)var27, (double)var27)).isEmpty();
    291
    292                    if (this.playerEntity.onGround && !par1Packet10Flying.onGround && var15 > 0.0D)
    293                    {
    294                        this.playerEntity.addExhaustion(0.2F);
    295                    }
    296
    297                    if (!this.hasMoved) //Fixes "Moved Too Fast" kick when being teleported while moving
    298                    {
    299                        return;
    300                    }
    301
    302                    this.playerEntity.moveEntity(var13, var15, var17);
    303                    this.playerEntity.onGround = par1Packet10Flying.onGround;
    304                    this.playerEntity.addMovementStat(var13, var15, var17);
    305                    double var29 = var15;
    306                    var13 = var5 - this.playerEntity.posX;
    307                    var15 = var7 - this.playerEntity.posY;
    308
    309                    if (var15 > -0.5D || var15 < 0.5D)
    310                    {
    311                        var15 = 0.0D;
    312                    }
    313
    314                    var17 = var9 - this.playerEntity.posZ;
    315                    var25 = var13 * var13 + var15 * var15 + var17 * var17;
    316                    boolean var31 = false;
    317
    318                    if (var25 > 0.0625D && !this.playerEntity.isPlayerSleeping() && !this.playerEntity.theItemInWorldManager.isCreative())
    319                    {
    320                        var31 = true;
    321                        logger.warning(this.playerEntity.username + " moved wrongly!");
    322                    }
    323
    324                    if (!this.hasMoved) //Fixes "Moved Too Fast" kick when being teleported while moving
    325                    {
    326                        return;
    327                    }
    328
    329                    this.playerEntity.setPositionAndRotation(var5, var7, var9, var11, var12);
    330                    boolean var32 = var2.getCollidingBoundingBoxes(this.playerEntity, this.playerEntity.boundingBox.copy().contract((double)var27, (double)var27, (double)var27)).isEmpty();
    331
    332                    if (var28 && (var31 || !var32) && !this.playerEntity.isPlayerSleeping() && !this.playerEntity.noClip)
    333                    {
    334                        this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, var11, var12);
    335                        return;
    336                    }
    337
    338                    AxisAlignedBB var33 = this.playerEntity.boundingBox.copy().expand((double)var27, (double)var27, (double)var27).addCoord(0.0D, -0.55D, 0.0D);
    339
    340                    if (!this.mcServer.isFlightAllowed() && !this.playerEntity.theItemInWorldManager.isCreative() && !var2.isAABBNonEmpty(var33)  && !this.playerEntity.capabilities.allowFlying)
    341                    {
    342                        if (var29 >= -0.03125D)
    343                        {
    344                            ++this.ticksForFloatKick;
    345
    346                            if (this.ticksForFloatKick > 80)
    347                            {
    348                                logger.warning(this.playerEntity.username + " was kicked for floating too long!");
    349                                this.kickPlayerFromServer("Flying is not enabled on this server");
    350                                return;
    351                            }
    352                        }
    353                    }
    354                    else
    355                    {
    356                        this.ticksForFloatKick = 0;
    357                    }
    358
    359                    if (!this.hasMoved) //Fixes "Moved Too Fast" kick when being teleported while moving
    360                    {
    361                        return;
    362                    }
    363
    364                    this.playerEntity.onGround = par1Packet10Flying.onGround;
    365                    this.mcServer.getConfigurationManager().serverUpdateMountedMovingPlayer(this.playerEntity);
    366                    this.playerEntity.updateFlyingState(this.playerEntity.posY - var3, par1Packet10Flying.onGround);
    367                }
    368            }
    369        }
    370
    371        /**
    372         * Moves the player to the specified destination and rotation
    373         */
    374        public void setPlayerLocation(double par1, double par3, double par5, float par7, float par8)
    375        {
    376            this.hasMoved = false;
    377            this.lastPosX = par1;
    378            this.lastPosY = par3;
    379            this.lastPosZ = par5;
    380            this.playerEntity.setPositionAndRotation(par1, par3, par5, par7, par8);
    381            this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet13PlayerLookMove(par1, par3 + 1.6200000047683716D, par3, par5, par7, par8, false));
    382        }
    383
    384        public void handleBlockDig(Packet14BlockDig par1Packet14BlockDig)
    385        {
    386            WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension);
    387
    388            if (par1Packet14BlockDig.status == 4)
    389            {
    390                this.playerEntity.dropOneItem();
    391            }
    392            else if (par1Packet14BlockDig.status == 5)
    393            {
    394                this.playerEntity.stopUsingItem();
    395            }
    396            else
    397            {
    398                boolean var3 = var2.actionsAllowed = var2.provider.dimensionId != 0 || this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username) || this.mcServer.isSinglePlayer();
    399                boolean var4 = false;
    400
    401                if (par1Packet14BlockDig.status == 0)
    402                {
    403                    var4 = true;
    404                }
    405
    406                if (par1Packet14BlockDig.status == 2)
    407                {
    408                    var4 = true;
    409                }
    410
    411                int var5 = par1Packet14BlockDig.xPosition;
    412                int var6 = par1Packet14BlockDig.yPosition;
    413                int var7 = par1Packet14BlockDig.zPosition;
    414
    415                if (var4)
    416                {
    417                    double var8 = this.playerEntity.posX - ((double)var5 + 0.5D);
    418                    double var10 = this.playerEntity.posY - ((double)var6 + 0.5D) + 1.5D;
    419                    double var12 = this.playerEntity.posZ - ((double)var7 + 0.5D);
    420                    double var14 = var8 * var8 + var10 * var10 + var12 * var12;
    421
    422                    double dist = playerEntity.theItemInWorldManager.getBlockReachDistance() + 1;
    423                    dist *= dist;
    424
    425                    if (var14 > dist)
    426                    {
    427                        return;
    428                    }
    429
    430                    if (var6 >= this.mcServer.getBuildLimit())
    431                    {
    432                        return;
    433                    }
    434                }
    435
    436                ChunkCoordinates var19 = var2.getSpawnPoint();
    437                int var9 = MathHelper.abs_int(var5 - var19.posX);
    438                int var20 = MathHelper.abs_int(var7 - var19.posZ);
    439
    440                if (var9 > var20)
    441                {
    442                    var20 = var9;
    443                }
    444
    445                if (par1Packet14BlockDig.status == 0)
    446                {
    447                    if (var20 <= mcServer.spawnProtectionSize && !var3)
    448                    {
    449                        ForgeEventFactory.onPlayerInteract(playerEntity, Action.LEFT_CLICK_BLOCK, var5, var6, var7, 0);
    450                        this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2));
    451                    }
    452                    else
    453                    {
    454                        this.playerEntity.theItemInWorldManager.onBlockClicked(var5, var6, var7, par1Packet14BlockDig.face);
    455                    }
    456                }
    457                else if (par1Packet14BlockDig.status == 2)
    458                {
    459                    this.playerEntity.theItemInWorldManager.uncheckedTryHarvestBlock(var5, var6, var7);
    460
    461                    if (var2.getBlockId(var5, var6, var7) != 0)
    462                    {
    463                        this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2));
    464                    }
    465                }
    466                else if (par1Packet14BlockDig.status == 1)
    467                {
    468                    this.playerEntity.theItemInWorldManager.destroyBlockInWorldPartially(var5, var6, var7);
    469
    470                    if (var2.getBlockId(var5, var6, var7) != 0)
    471                    {
    472                        this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2));
    473                    }
    474                }
    475                else if (par1Packet14BlockDig.status == 3)
    476                {
    477                    double var11 = this.playerEntity.posX - ((double)var5 + 0.5D);
    478                    double var13 = this.playerEntity.posY - ((double)var6 + 0.5D);
    479                    double var15 = this.playerEntity.posZ - ((double)var7 + 0.5D);
    480                    double var17 = var11 * var11 + var13 * var13 + var15 * var15;
    481
    482                    if (var17 < 256.0D)
    483                    {
    484                        this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2));
    485                    }
    486                }
    487
    488                var2.actionsAllowed = false;
    489            }
    490        }
    491
    492        public void handlePlace(Packet15Place par1Packet15Place)
    493        {
    494            WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension);
    495            ItemStack var3 = this.playerEntity.inventory.getCurrentItem();
    496            boolean var4 = false;
    497            int var5 = par1Packet15Place.getXPosition();
    498            int var6 = par1Packet15Place.getYPosition();
    499            int var7 = par1Packet15Place.getZPosition();
    500            int var8 = par1Packet15Place.getDirection();
    501            boolean var9 = var2.actionsAllowed = var2.provider.dimensionId != 0 || this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username) || this.mcServer.isSinglePlayer();
    502
    503            if (par1Packet15Place.getDirection() == 255)
    504            {
    505                if (var3 == null)
    506                {
    507                    return;
    508                }
    509
    510                PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(playerEntity, PlayerInteractEvent.Action.RIGHT_CLICK_AIR, 0, 0, 0, -1);
    511                if (event.useItem != Event.Result.DENY)
    512                {
    513                    this.playerEntity.theItemInWorldManager.tryUseItem(this.playerEntity, var2, var3);
    514                }
    515            }
    516            else if (par1Packet15Place.getYPosition() >= this.mcServer.getBuildLimit() - 1 && (par1Packet15Place.getDirection() == 1 || par1Packet15Place.getYPosition() >= this.mcServer.getBuildLimit()))
    517            {
    518                this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet3Chat("\u00a77Height limit for building is " + this.mcServer.getBuildLimit()));
    519                var4 = true;
    520            }
    521            else
    522            {
    523                ChunkCoordinates var10 = var2.getSpawnPoint();
    524                int var11 = MathHelper.abs_int(var5 - var10.posX);
    525                int var12 = MathHelper.abs_int(var7 - var10.posZ);
    526
    527                if (var11 > var12)
    528                {
    529                    var12 = var11;
    530                }
    531
    532                double dist = playerEntity.theItemInWorldManager.getBlockReachDistance() + 1;
    533                dist *= dist;
    534                if (this.hasMoved && this.playerEntity.getDistanceSq((double)var5 + 0.5D, (double)var6 + 0.5D, (double)var7 + 0.5D) < dist && (var12 > mcServer.spawnProtectionSize || var9))
    535                {
    536                    this.playerEntity.theItemInWorldManager.activateBlockOrUseItem(this.playerEntity, var2, var3, var5, var6, var7, var8, par1Packet15Place.getXOffset(), par1Packet15Place.getYOffset(), par1Packet15Place.getZOffset());
    537                }
    538
    539                var4 = true;
    540            }
    541
    542            if (var4)
    543            {
    544                this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2));
    545
    546                if (var8 == 0)
    547                {
    548                    --var6;
    549                }
    550
    551                if (var8 == 1)
    552                {
    553                    ++var6;
    554                }
    555
    556                if (var8 == 2)
    557                {
    558                    --var7;
    559                }
    560
    561                if (var8 == 3)
    562                {
    563                    ++var7;
    564                }
    565
    566                if (var8 == 4)
    567                {
    568                    --var5;
    569                }
    570
    571                if (var8 == 5)
    572                {
    573                    ++var5;
    574                }
    575
    576                this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet53BlockChange(var5, var6, var7, var2));
    577            }
    578
    579            var3 = this.playerEntity.inventory.getCurrentItem();
    580
    581            if (var3 != null && var3.stackSize == 0)
    582            {
    583                this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = null;
    584                var3 = null;
    585            }
    586
    587            if (var3 == null || var3.getMaxItemUseDuration() == 0)
    588            {
    589                this.playerEntity.playerInventoryBeingManipulated = true;
    590                this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = ItemStack.copyItemStack(this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem]);
    591                Slot var13 = this.playerEntity.craftingInventory.getSlotFromInventory(this.playerEntity.inventory, this.playerEntity.inventory.currentItem);
    592                this.playerEntity.craftingInventory.updateCraftingResults();
    593                this.playerEntity.playerInventoryBeingManipulated = false;
    594
    595                if (!ItemStack.areItemStacksEqual(this.playerEntity.inventory.getCurrentItem(), par1Packet15Place.getItemStack()))
    596                {
    597                    this.sendPacketToPlayer(new Packet103SetSlot(this.playerEntity.craftingInventory.windowId, var13.slotNumber, this.playerEntity.inventory.getCurrentItem()));
    598                }
    599            }
    600
    601            var2.actionsAllowed = false;
    602        }
    603
    604        public void handleErrorMessage(String par1Str, Object[] par2ArrayOfObj)
    605        {
    606            logger.info(this.playerEntity.username + " lost connection: " + par1Str);
    607            this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat("\u00a7e" + this.playerEntity.username + " left the game."));
    608            this.mcServer.getConfigurationManager().playerLoggedOut(this.playerEntity);
    609            this.connectionClosed = true;
    610
    611            if (this.mcServer.isSinglePlayer() && this.playerEntity.username.equals(this.mcServer.getServerOwner()))
    612            {
    613                logger.info("Stopping singleplayer server as player logged out");
    614                this.mcServer.initiateShutdown();
    615            }
    616        }
    617
    618        /**
    619         * Default handler called for packets that don't have their own handlers in NetClientHandler; currentlly does
    620         * nothing.
    621         */
    622        public void unexpectedPacket(Packet par1Packet)
    623        {
    624            logger.warning(this.getClass() + " wasn\'t prepared to deal with a " + par1Packet.getClass());
    625            this.kickPlayerFromServer("Protocol error, unexpected packet");
    626        }
    627
    628        /**
    629         * addToSendQueue. if it is a chat packet, check before sending it
    630         */
    631        public void sendPacketToPlayer(Packet par1Packet)
    632        {
    633            if (par1Packet instanceof Packet3Chat)
    634            {
    635                Packet3Chat var2 = (Packet3Chat)par1Packet;
    636                int var3 = this.playerEntity.getChatVisibility();
    637
    638                if (var3 == 2)
    639                {
    640                    return;
    641                }
    642
    643                if (var3 == 1 && !var2.func_73475_d())
    644                {
    645                    return;
    646                }
    647            }
    648
    649            this.netManager.addToSendQueue(par1Packet);
    650        }
    651
    652        public void handleBlockItemSwitch(Packet16BlockItemSwitch par1Packet16BlockItemSwitch)
    653        {
    654            if (par1Packet16BlockItemSwitch.id >= 0 && par1Packet16BlockItemSwitch.id < InventoryPlayer.func_70451_h())
    655            {
    656                this.playerEntity.inventory.currentItem = par1Packet16BlockItemSwitch.id;
    657            }
    658            else
    659            {
    660                logger.warning(this.playerEntity.username + " tried to set an invalid carried item");
    661            }
    662        }
    663
    664        public void handleChat(Packet3Chat par1Packet3Chat)
    665        {
    666            par1Packet3Chat = FMLNetworkHandler.handleChatMessage(this, par1Packet3Chat);
    667            if (this.playerEntity.getChatVisibility() == 2)
    668            {
    669                this.sendPacketToPlayer(new Packet3Chat("Cannot send chat message."));
    670            }
    671            else
    672            {
    673                String var2 = par1Packet3Chat.message;
    674
    675                if (var2.length() > 100)
    676                {
    677                    this.kickPlayerFromServer("Chat message too long");
    678                }
    679                else
    680                {
    681                    var2 = var2.trim();
    682
    683                    for (int var3 = 0; var3 < var2.length(); ++var3)
    684                    {
    685                        if (!ChatAllowedCharacters.isAllowedCharacter(var2.charAt(var3)))
    686                        {
    687                            this.kickPlayerFromServer("Illegal characters in chat");
    688                            return;
    689                        }
    690                    }
    691
    692                    if (var2.startsWith("/"))
    693                    {
    694                        this.handleSlashCommand(var2);
    695                    }
    696                    else
    697                    {
    698                        if (this.playerEntity.getChatVisibility() == 1)
    699                        {
    700                            this.sendPacketToPlayer(new Packet3Chat("Cannot send chat message."));
    701                            return;
    702                        }
    703
    704                        var2 = "<" + this.playerEntity.username + "> " + var2;
    705                        logger.info(var2);
    706                        this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat(var2, false));
    707                    }
    708
    709                    this.chatSpamThresholdCount += 20;
    710
    711                    if (this.chatSpamThresholdCount > 200 && !this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username))
    712                    {
    713                        this.kickPlayerFromServer("disconnect.spam");
    714                    }
    715                }
    716            }
    717        }
    718
    719        /**
    720         * Processes a / command
    721         */
    722        private void handleSlashCommand(String par1Str)
    723        {
    724            this.mcServer.getCommandManager().executeCommand(this.playerEntity, par1Str);
    725        }
    726
    727        public void handleAnimation(Packet18Animation par1Packet18Animation)
    728        {
    729            if (par1Packet18Animation.animate == 1)
    730            {
    731                this.playerEntity.swingItem();
    732            }
    733        }
    734
    735        /**
    736         * runs registerPacket on the given Packet19EntityAction
    737         */
    738        public void handleEntityAction(Packet19EntityAction par1Packet19EntityAction)
    739        {
    740            if (par1Packet19EntityAction.state == 1)
    741            {
    742                this.playerEntity.setSneaking(true);
    743            }
    744            else if (par1Packet19EntityAction.state == 2)
    745            {
    746                this.playerEntity.setSneaking(false);
    747            }
    748            else if (par1Packet19EntityAction.state == 4)
    749            {
    750                this.playerEntity.setSprinting(true);
    751            }
    752            else if (par1Packet19EntityAction.state == 5)
    753            {
    754                this.playerEntity.setSprinting(false);
    755            }
    756            else if (par1Packet19EntityAction.state == 3)
    757            {
    758                this.playerEntity.wakeUpPlayer(false, true, true);
    759                this.hasMoved = false;
    760            }
    761        }
    762
    763        public void handleKickDisconnect(Packet255KickDisconnect par1Packet255KickDisconnect)
    764        {
    765            this.netManager.networkShutdown("disconnect.quitting", new Object[0]);
    766        }
    767
    768        /**
    769         * returns 0 for memoryMapped connections
    770         */
    771        public int packetSize()
    772        {
    773            return this.netManager.packetSize();
    774        }
    775
    776        public void handleUseEntity(Packet7UseEntity par1Packet7UseEntity)
    777        {
    778            WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension);
    779            Entity var3 = var2.getEntityByID(par1Packet7UseEntity.targetEntity);
    780
    781            if (var3 != null)
    782            {
    783                boolean var4 = this.playerEntity.canEntityBeSeen(var3);
    784                double var5 = 36.0D;
    785
    786                if (!var4)
    787                {
    788                    var5 = 9.0D;
    789                }
    790
    791                if (this.playerEntity.getDistanceSqToEntity(var3) < var5)
    792                {
    793                    if (par1Packet7UseEntity.isLeftClick == 0)
    794                    {
    795                        this.playerEntity.interactWith(var3);
    796                    }
    797                    else if (par1Packet7UseEntity.isLeftClick == 1)
    798                    {
    799                        this.playerEntity.attackTargetEntityWithCurrentItem(var3);
    800                    }
    801                }
    802            }
    803        }
    804
    805        public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand)
    806        {
    807            if (par1Packet205ClientCommand.forceRespawn == 1)
    808            {
    809                if (this.playerEntity.playerConqueredTheEnd)
    810                {
    811                    this.playerEntity = this.mcServer.getConfigurationManager().respawnPlayer(this.playerEntity, 0, true);
    812                }
    813                else if (this.playerEntity.getServerForPlayer().getWorldInfo().isHardcoreModeEnabled())
    814                {
    815                    if (this.mcServer.isSinglePlayer() && this.playerEntity.username.equals(this.mcServer.getServerOwner()))
    816                    {
    817                        this.playerEntity.playerNetServerHandler.kickPlayerFromServer("You have died. Game over, man, it\'s game over!");
    818                        this.mcServer.deleteWorldAndStopServer();
    819                    }
    820                    else
    821                    {
    822                        BanEntry var2 = new BanEntry(this.playerEntity.username);
    823                        var2.setBanReason("Death in Hardcore");
    824                        this.mcServer.getConfigurationManager().getBannedPlayers().put(var2);
    825                        this.playerEntity.playerNetServerHandler.kickPlayerFromServer("You have died. Game over, man, it\'s game over!");
    826                    }
    827                }
    828                else
    829                {
    830                    if (this.playerEntity.getHealth() > 0)
    831                    {
    832                        return;
    833                    }
    834
    835                    this.playerEntity = this.mcServer.getConfigurationManager().respawnPlayer(this.playerEntity, playerEntity.dimension, false);
    836                }
    837            }
    838        }
    839
    840        /**
    841         * packet.processPacket is only called if this returns true
    842         */
    843        public boolean canProcessPackets()
    844        {
    845            return true;
    846        }
    847
    848        /**
    849         * respawns the player
    850         */
    851        public void handleRespawn(Packet9Respawn par1Packet9Respawn) {}
    852
    853        public void handleCloseWindow(Packet101CloseWindow par1Packet101CloseWindow)
    854        {
    855            this.playerEntity.closeInventory();
    856        }
    857
    858        public void handleWindowClick(Packet102WindowClick par1Packet102WindowClick)
    859        {
    860            if (this.playerEntity.craftingInventory.windowId == par1Packet102WindowClick.window_Id && this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity))
    861            {
    862                ItemStack var2 = this.playerEntity.craftingInventory.slotClick(par1Packet102WindowClick.inventorySlot, par1Packet102WindowClick.mouseClick, par1Packet102WindowClick.holdingShift, this.playerEntity);
    863
    864                if (ItemStack.areItemStacksEqual(par1Packet102WindowClick.itemStack, var2))
    865                {
    866                    this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet106Transaction(par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, true));
    867                    this.playerEntity.playerInventoryBeingManipulated = true;
    868                    this.playerEntity.craftingInventory.updateCraftingResults();
    869                    this.playerEntity.sendInventoryToPlayer();
    870                    this.playerEntity.playerInventoryBeingManipulated = false;
    871                }
    872                else
    873                {
    874                    this.field_72586_s.addKey(this.playerEntity.craftingInventory.windowId, Short.valueOf(par1Packet102WindowClick.action));
    875                    this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet106Transaction(par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, false));
    876                    this.playerEntity.craftingInventory.setPlayerIsPresent(this.playerEntity, false);
    877                    ArrayList var3 = new ArrayList();
    878
    879                    for (int var4 = 0; var4 < this.playerEntity.craftingInventory.inventorySlots.size(); ++var4)
    880                    {
    881                        var3.add(((Slot)this.playerEntity.craftingInventory.inventorySlots.get(var4)).getStack());
    882                    }
    883
    884                    this.playerEntity.sendContainerAndContentsToPlayer(this.playerEntity.craftingInventory, var3);
    885                }
    886            }
    887        }
    888
    889        public void handleEnchantItem(Packet108EnchantItem par1Packet108EnchantItem)
    890        {
    891            if (this.playerEntity.craftingInventory.windowId == par1Packet108EnchantItem.windowId && this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity))
    892            {
    893                this.playerEntity.craftingInventory.enchantItem(this.playerEntity, par1Packet108EnchantItem.enchantment);
    894                this.playerEntity.craftingInventory.updateCraftingResults();
    895            }
    896        }
    897
    898        /**
    899         * Handle a creative slot packet.
    900         */
    901        public void handleCreativeSetSlot(Packet107CreativeSetSlot par1Packet107CreativeSetSlot)
    902        {
    903            if (this.playerEntity.theItemInWorldManager.isCreative())
    904            {
    905                boolean var2 = par1Packet107CreativeSetSlot.slot < 0;
    906                ItemStack var3 = par1Packet107CreativeSetSlot.itemStack;
    907                boolean var4 = par1Packet107CreativeSetSlot.slot >= 1 && par1Packet107CreativeSetSlot.slot < 36 + InventoryPlayer.func_70451_h();
    908                boolean var5 = var3 == null || var3.itemID < Item.itemsList.length && var3.itemID >= 0 && Item.itemsList[var3.itemID] != null;
    909                boolean var6 = var3 == null || var3.getItemDamage() >= 0 && var3.getItemDamage() >= 0 && var3.stackSize <= 64 && var3.stackSize > 0;
    910
    911                if (var4 && var5 && var6)
    912                {
    913                    if (var3 == null)
    914                    {
    915                        this.playerEntity.inventorySlots.putStackInSlot(par1Packet107CreativeSetSlot.slot, (ItemStack)null);
    916                    }
    917                    else
    918                    {
    919                        this.playerEntity.inventorySlots.putStackInSlot(par1Packet107CreativeSetSlot.slot, var3);
    920                    }
    921
    922                    this.playerEntity.inventorySlots.setPlayerIsPresent(this.playerEntity, true);
    923                }
    924                else if (var2 && var5 && var6 && this.creativeItemCreationSpamThresholdTally < 200)
    925                {
    926                    this.creativeItemCreationSpamThresholdTally += 20;
    927                    EntityItem var7 = this.playerEntity.dropPlayerItem(var3);
    928
    929                    if (var7 != null)
    930                    {
    931                        var7.func_70288_d();
    932                    }
    933                }
    934            }
    935        }
    936
    937        public void handleTransaction(Packet106Transaction par1Packet106Transaction)
    938        {
    939            Short var2 = (Short)this.field_72586_s.lookup(this.playerEntity.craftingInventory.windowId);
    940
    941            if (var2 != null && par1Packet106Transaction.shortWindowId == var2.shortValue() && this.playerEntity.craftingInventory.windowId == par1Packet106Transaction.windowId && !this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity))
    942            {
    943                this.playerEntity.craftingInventory.setPlayerIsPresent(this.playerEntity, true);
    944            }
    945        }
    946
    947        /**
    948         * Updates Client side signs
    949         */
    950        public void handleUpdateSign(Packet130UpdateSign par1Packet130UpdateSign)
    951        {
    952            WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension);
    953
    954            if (var2.blockExists(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition))
    955            {
    956                TileEntity var3 = var2.getBlockTileEntity(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition);
    957
    958                if (var3 instanceof TileEntitySign)
    959                {
    960                    TileEntitySign var4 = (TileEntitySign)var3;
    961
    962                    if (!var4.isEditable())
    963                    {
    964                        this.mcServer.logWarning("Player " + this.playerEntity.username + " just tried to change non-editable sign");
    965                        return;
    966                    }
    967                }
    968
    969                int var6;
    970                int var8;
    971
    972                for (var8 = 0; var8 < 4; ++var8)
    973                {
    974                    boolean var5 = true;
    975
    976                    if (par1Packet130UpdateSign.signLines[var8].length() > 15)
    977                    {
    978                        var5 = false;
    979                    }
    980                    else
    981                    {
    982                        for (var6 = 0; var6 < par1Packet130UpdateSign.signLines[var8].length(); ++var6)
    983                        {
    984                            if (ChatAllowedCharacters.allowedCharacters.indexOf(par1Packet130UpdateSign.signLines[var8].charAt(var6)) < 0)
    985                            {
    986                                var5 = false;
    987                            }
    988                        }
    989                    }
    990
    991                    if (!var5)
    992                    {
    993                        par1Packet130UpdateSign.signLines[var8] = "!?";
    994                    }
    995                }
    996
    997                if (var3 instanceof TileEntitySign)
    998                {
    999                    var8 = par1Packet130UpdateSign.xPosition;
    1000                    int var9 = par1Packet130UpdateSign.yPosition;
    1001                    var6 = par1Packet130UpdateSign.zPosition;
    1002                    TileEntitySign var7 = (TileEntitySign)var3;
    1003                    System.arraycopy(par1Packet130UpdateSign.signLines, 0, var7.signText, 0, 4);
    1004                    var7.onInventoryChanged();
    1005                    var2.markBlockNeedsUpdate(var8, var9, var6);
    1006                }
    1007            }
    1008        }
    1009
    1010        /**
    1011         * Handle a keep alive packet.
    1012         */
    1013        public void handleKeepAlive(Packet0KeepAlive par1Packet0KeepAlive)
    1014        {
    1015            if (par1Packet0KeepAlive.randomId == this.keepAliveRandomID)
    1016            {
    1017                int var2 = (int)(System.nanoTime() / 1000000L - this.keepAliveTimeSent);
    1018                this.playerEntity.ping = (this.playerEntity.ping * 3 + var2) / 4;
    1019            }
    1020        }
    1021
    1022        /**
    1023         * determine if it is a server handler
    1024         */
    1025        public boolean isServerHandler()
    1026        {
    1027            return true;
    1028        }
    1029
    1030        /**
    1031         * Handle a player abilities packet.
    1032         */
    1033        public void handlePlayerAbilities(Packet202PlayerAbilities par1Packet202PlayerAbilities)
    1034        {
    1035            this.playerEntity.capabilities.isFlying = par1Packet202PlayerAbilities.getFlying() && this.playerEntity.capabilities.allowFlying;
    1036        }
    1037
    1038        public void handleAutoComplete(Packet203AutoComplete par1Packet203AutoComplete)
    1039        {
    1040            StringBuilder var2 = new StringBuilder();
    1041            String var4;
    1042
    1043            for (Iterator var3 = this.mcServer.getPossibleCompletions(this.playerEntity, par1Packet203AutoComplete.getText()).iterator(); var3.hasNext(); var2.append(var4))
    1044            {
    1045                var4 = (String)var3.next();
    1046
    1047                if (var2.length() > 0)
    1048                {
    1049                    var2.append("\u0000");
    1050                }
    1051            }
    1052
    1053            this.playerEntity.playerNetServerHandler.sendPacketToPlayer(new Packet203AutoComplete(var2.toString()));
    1054        }
    1055
    1056        public void handleClientInfo(Packet204ClientInfo par1Packet204ClientInfo)
    1057        {
    1058            this.playerEntity.updateClientInfo(par1Packet204ClientInfo);
    1059        }
    1060
    1061        public void handleCustomPayload(Packet250CustomPayload par1Packet250CustomPayload)
    1062        {
    1063            FMLNetworkHandler.handlePacket250Packet(par1Packet250CustomPayload, netManager, this);
    1064        }
    1065
    1066        public void handleVanilla250Packet(Packet250CustomPayload par1Packet250CustomPayload)
    1067        {
    1068            DataInputStream var2;
    1069            ItemStack var3;
    1070            ItemStack var4;
    1071
    1072            if ("MC|BEdit".equals(par1Packet250CustomPayload.channel))
    1073            {
    1074                try
    1075                {
    1076                    var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data));
    1077                    var3 = Packet.readItemStack(var2);
    1078
    1079                    if (!ItemWritableBook.validBookTagPages(var3.getTagCompound()))
    1080                    {
    1081                        throw new IOException("Invalid book tag!");
    1082                    }
    1083
    1084                    var4 = this.playerEntity.inventory.getCurrentItem();
    1085
    1086                    if (var3 != null && var3.itemID == Item.writableBook.shiftedIndex && var3.itemID == var4.itemID)
    1087                    {
    1088                        var4.setTagCompound(var3.getTagCompound());
    1089                    }
    1090                }
    1091                catch (Exception var7)
    1092                {
    1093                    var7.printStackTrace();
    1094                }
    1095            }
    1096            else if ("MC|BSign".equals(par1Packet250CustomPayload.channel))
    1097            {
    1098                try
    1099                {
    1100                    var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data));
    1101                    var3 = Packet.readItemStack(var2);
    1102
    1103                    if (!ItemEditableBook.validBookTagContents(var3.getTagCompound()))
    1104                    {
    1105                        throw new IOException("Invalid book tag!");
    1106                    }
    1107
    1108                    var4 = this.playerEntity.inventory.getCurrentItem();
    1109
    1110                    if (var3 != null && var3.itemID == Item.writtenBook.shiftedIndex && var4.itemID == Item.writableBook.shiftedIndex)
    1111                    {
    1112                        var4.setTagCompound(var3.getTagCompound());
    1113                        var4.itemID = Item.writtenBook.shiftedIndex;
    1114                    }
    1115                }
    1116                catch (Exception var6)
    1117                {
    1118                    var6.printStackTrace();
    1119                }
    1120            }
    1121            else if ("MC|TrSel".equals(par1Packet250CustomPayload.channel))
    1122            {
    1123                try
    1124                {
    1125                    var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data));
    1126                    int var8 = var2.readInt();
    1127                    Container var9 = this.playerEntity.craftingInventory;
    1128
    1129                    if (var9 instanceof ContainerMerchant)
    1130                    {
    1131                        ((ContainerMerchant)var9).setCurrentRecipeIndex(var8);
    1132                    }
    1133                }
    1134                catch (Exception var5)
    1135                {
    1136                    var5.printStackTrace();
    1137                }
    1138            }
    1139        }
    1140
    1141        @Override
    1142
    1143        /**
    1144         * Contains logic for handling packets containing arbitrary unique item data. Currently this is only for maps.
    1145         */
    1146        public void handleMapData(Packet131MapData par1Packet131MapData)
    1147        {
    1148            FMLNetworkHandler.handlePacket131Packet(this, par1Packet131MapData);
    1149        }
    1150
    1151        // modloader compat -- yuk!
    1152        @Override
    1153        public EntityPlayerMP getPlayer()
    1154        {
    1155            return playerEntity;
    1156        }
    1157    }