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