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