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            par1Packet3Chat = FMLNetworkHandler.handleChatMessage(this, par1Packet3Chat);
627            if (this.playerEntity.getChatVisibility() == 2)
628            {
629                this.sendPacketToPlayer(new Packet3Chat("Cannot send chat message."));
630            }
631            else
632            {
633                String var2 = par1Packet3Chat.message;
634    
635                if (var2.length() > 100)
636                {
637                    this.kickPlayerFromServer("Chat message too long");
638                }
639                else
640                {
641                    var2 = var2.trim();
642    
643                    for (int var3 = 0; var3 < var2.length(); ++var3)
644                    {
645                        if (!ChatAllowedCharacters.isAllowedCharacter(var2.charAt(var3)))
646                        {
647                            this.kickPlayerFromServer("Illegal characters in chat");
648                            return;
649                        }
650                    }
651    
652                    if (var2.startsWith("/"))
653                    {
654                        this.handleSlashCommand(var2);
655                    }
656                    else
657                    {
658                        if (this.playerEntity.getChatVisibility() == 1)
659                        {
660                            this.sendPacketToPlayer(new Packet3Chat("Cannot send chat message."));
661                            return;
662                        }
663    
664                        var2 = "<" + this.playerEntity.username + "> " + var2;
665                        logger.info(var2);
666                        this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new Packet3Chat(var2, false));
667                    }
668    
669                    this.chatSpamThresholdCount += 20;
670    
671                    if (this.chatSpamThresholdCount > 200 && !this.mcServer.getConfigurationManager().areCommandsAllowed(this.playerEntity.username))
672                    {
673                        this.kickPlayerFromServer("disconnect.spam");
674                    }
675                }
676            }
677        }
678    
679        /**
680         * Processes a / command
681         */
682        private void handleSlashCommand(String par1Str)
683        {
684            this.mcServer.getCommandManager().executeCommand(this.playerEntity, par1Str);
685        }
686    
687        public void handleAnimation(Packet18Animation par1Packet18Animation)
688        {
689            if (par1Packet18Animation.animate == 1)
690            {
691                this.playerEntity.swingItem();
692            }
693        }
694    
695        /**
696         * runs registerPacket on the given Packet19EntityAction
697         */
698        public void handleEntityAction(Packet19EntityAction par1Packet19EntityAction)
699        {
700            if (par1Packet19EntityAction.state == 1)
701            {
702                this.playerEntity.setSneaking(true);
703            }
704            else if (par1Packet19EntityAction.state == 2)
705            {
706                this.playerEntity.setSneaking(false);
707            }
708            else if (par1Packet19EntityAction.state == 4)
709            {
710                this.playerEntity.setSprinting(true);
711            }
712            else if (par1Packet19EntityAction.state == 5)
713            {
714                this.playerEntity.setSprinting(false);
715            }
716            else if (par1Packet19EntityAction.state == 3)
717            {
718                this.playerEntity.wakeUpPlayer(false, true, true);
719                this.hasMoved = false;
720            }
721        }
722    
723        public void handleKickDisconnect(Packet255KickDisconnect par1Packet255KickDisconnect)
724        {
725            this.theNetworkManager.networkShutdown("disconnect.quitting", new Object[0]);
726        }
727    
728        /**
729         * returns 0 for memoryMapped connections
730         */
731        public int packetSize()
732        {
733            return this.theNetworkManager.packetSize();
734        }
735    
736        public void handleUseEntity(Packet7UseEntity par1Packet7UseEntity)
737        {
738            WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension);
739            Entity var3 = var2.getEntityByID(par1Packet7UseEntity.targetEntity);
740    
741            if (var3 != null)
742            {
743                boolean var4 = this.playerEntity.canEntityBeSeen(var3);
744                double var5 = 36.0D;
745    
746                if (!var4)
747                {
748                    var5 = 9.0D;
749                }
750    
751                if (this.playerEntity.getDistanceSqToEntity(var3) < var5)
752                {
753                    if (par1Packet7UseEntity.isLeftClick == 0)
754                    {
755                        this.playerEntity.interactWith(var3);
756                    }
757                    else if (par1Packet7UseEntity.isLeftClick == 1)
758                    {
759                        this.playerEntity.attackTargetEntityWithCurrentItem(var3);
760                    }
761                }
762            }
763        }
764    
765        public void handleClientCommand(Packet205ClientCommand par1Packet205ClientCommand)
766        {
767            if (par1Packet205ClientCommand.forceRespawn == 1)
768            {
769                if (this.playerEntity.playerHasConqueredTheEnd)
770                {
771                    this.playerEntity = this.mcServer.getConfigurationManager().respawnPlayer(this.playerEntity, 0, true);
772                }
773                else if (this.playerEntity.getServerForPlayer().getWorldInfo().isHardcoreModeEnabled())
774                {
775                    if (this.mcServer.isSinglePlayer() && this.playerEntity.username.equals(this.mcServer.getServerOwner()))
776                    {
777                        this.playerEntity.serverForThisPlayer.kickPlayerFromServer("You have died. Game over, man, it\'s game over!");
778                        this.mcServer.deleteWorldAndStopServer();
779                    }
780                    else
781                    {
782                        BanEntry var2 = new BanEntry(this.playerEntity.username);
783                        var2.setBanReason("Death in Hardcore");
784                        this.mcServer.getConfigurationManager().getBannedPlayers().put(var2);
785                        this.playerEntity.serverForThisPlayer.kickPlayerFromServer("You have died. Game over, man, it\'s game over!");
786                    }
787                }
788                else
789                {
790                    if (this.playerEntity.getHealth() > 0)
791                    {
792                        return;
793                    }
794    
795                    this.playerEntity = this.mcServer.getConfigurationManager().respawnPlayer(this.playerEntity, 0, false);
796                }
797            }
798        }
799    
800        /**
801         * packet.processPacket is only called if this returns true
802         */
803        public boolean canProcessPackets()
804        {
805            return true;
806        }
807    
808        /**
809         * respawns the player
810         */
811        public void handleRespawn(Packet9Respawn par1Packet9Respawn) {}
812    
813        public void handleCloseWindow(Packet101CloseWindow par1Packet101CloseWindow)
814        {
815            this.playerEntity.closeInventory();
816        }
817    
818        public void handleWindowClick(Packet102WindowClick par1Packet102WindowClick)
819        {
820            if (this.playerEntity.craftingInventory.windowId == par1Packet102WindowClick.window_Id && this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity))
821            {
822                ItemStack var2 = this.playerEntity.craftingInventory.slotClick(par1Packet102WindowClick.inventorySlot, par1Packet102WindowClick.mouseClick, par1Packet102WindowClick.holdingShift, this.playerEntity);
823    
824                if (ItemStack.areItemStacksEqual(par1Packet102WindowClick.itemStack, var2))
825                {
826                    this.playerEntity.serverForThisPlayer.sendPacketToPlayer(new Packet106Transaction(par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, true));
827                    this.playerEntity.playerInventoryBeingManipulated = true;
828                    this.playerEntity.craftingInventory.updateCraftingResults();
829                    this.playerEntity.sendInventoryToPlayer();
830                    this.playerEntity.playerInventoryBeingManipulated = false;
831                }
832                else
833                {
834                    this.field_72586_s.addKey(this.playerEntity.craftingInventory.windowId, Short.valueOf(par1Packet102WindowClick.action));
835                    this.playerEntity.serverForThisPlayer.sendPacketToPlayer(new Packet106Transaction(par1Packet102WindowClick.window_Id, par1Packet102WindowClick.action, false));
836                    this.playerEntity.craftingInventory.setPlayerIsPresent(this.playerEntity, false);
837                    ArrayList var3 = new ArrayList();
838    
839                    for (int var4 = 0; var4 < this.playerEntity.craftingInventory.inventorySlots.size(); ++var4)
840                    {
841                        var3.add(((Slot)this.playerEntity.craftingInventory.inventorySlots.get(var4)).getStack());
842                    }
843    
844                    this.playerEntity.sendContainerAndContentsToPlayer(this.playerEntity.craftingInventory, var3);
845                }
846            }
847        }
848    
849        public void handleEnchantItem(Packet108EnchantItem par1Packet108EnchantItem)
850        {
851            if (this.playerEntity.craftingInventory.windowId == par1Packet108EnchantItem.windowId && this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity))
852            {
853                this.playerEntity.craftingInventory.enchantItem(this.playerEntity, par1Packet108EnchantItem.enchantment);
854                this.playerEntity.craftingInventory.updateCraftingResults();
855            }
856        }
857    
858        /**
859         * Handle a creative slot packet.
860         */
861        public void handleCreativeSetSlot(Packet107CreativeSetSlot par1Packet107CreativeSetSlot)
862        {
863            if (this.playerEntity.theItemInWorldManager.isCreative())
864            {
865                boolean var2 = par1Packet107CreativeSetSlot.slot < 0;
866                ItemStack var3 = par1Packet107CreativeSetSlot.itemStack;
867                boolean var4 = par1Packet107CreativeSetSlot.slot >= 1 && par1Packet107CreativeSetSlot.slot < 36 + InventoryPlayer.func_70451_h();
868                boolean var5 = var3 == null || var3.itemID < Item.itemsList.length && var3.itemID >= 0 && Item.itemsList[var3.itemID] != null;
869                boolean var6 = var3 == null || var3.getItemDamage() >= 0 && var3.getItemDamage() >= 0 && var3.stackSize <= 64 && var3.stackSize > 0;
870    
871                if (var4 && var5 && var6)
872                {
873                    if (var3 == null)
874                    {
875                        this.playerEntity.inventorySlots.putStackInSlot(par1Packet107CreativeSetSlot.slot, (ItemStack)null);
876                    }
877                    else
878                    {
879                        this.playerEntity.inventorySlots.putStackInSlot(par1Packet107CreativeSetSlot.slot, var3);
880                    }
881    
882                    this.playerEntity.inventorySlots.setPlayerIsPresent(this.playerEntity, true);
883                }
884                else if (var2 && var5 && var6 && this.creativeItemCreationSpamThresholdTally < 200)
885                {
886                    this.creativeItemCreationSpamThresholdTally += 20;
887                    EntityItem var7 = this.playerEntity.dropPlayerItem(var3);
888    
889                    if (var7 != null)
890                    {
891                        var7.func_70288_d();
892                    }
893                }
894            }
895        }
896    
897        public void handleTransaction(Packet106Transaction par1Packet106Transaction)
898        {
899            Short var2 = (Short)this.field_72586_s.lookup(this.playerEntity.craftingInventory.windowId);
900    
901            if (var2 != null && par1Packet106Transaction.shortWindowId == var2.shortValue() && this.playerEntity.craftingInventory.windowId == par1Packet106Transaction.windowId && !this.playerEntity.craftingInventory.isPlayerNotUsingContainer(this.playerEntity))
902            {
903                this.playerEntity.craftingInventory.setPlayerIsPresent(this.playerEntity, true);
904            }
905        }
906    
907        /**
908         * Updates Client side signs
909         */
910        public void handleUpdateSign(Packet130UpdateSign par1Packet130UpdateSign)
911        {
912            WorldServer var2 = this.mcServer.worldServerForDimension(this.playerEntity.dimension);
913    
914            if (var2.blockExists(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition))
915            {
916                TileEntity var3 = var2.getBlockTileEntity(par1Packet130UpdateSign.xPosition, par1Packet130UpdateSign.yPosition, par1Packet130UpdateSign.zPosition);
917    
918                if (var3 instanceof TileEntitySign)
919                {
920                    TileEntitySign var4 = (TileEntitySign)var3;
921    
922                    if (!var4.isEditable())
923                    {
924                        this.mcServer.logWarningMessage("Player " + this.playerEntity.username + " just tried to change non-editable sign");
925                        return;
926                    }
927                }
928    
929                int var6;
930                int var8;
931    
932                for (var8 = 0; var8 < 4; ++var8)
933                {
934                    boolean var5 = true;
935    
936                    if (par1Packet130UpdateSign.signLines[var8].length() > 15)
937                    {
938                        var5 = false;
939                    }
940                    else
941                    {
942                        for (var6 = 0; var6 < par1Packet130UpdateSign.signLines[var8].length(); ++var6)
943                        {
944                            if (ChatAllowedCharacters.allowedCharacters.indexOf(par1Packet130UpdateSign.signLines[var8].charAt(var6)) < 0)
945                            {
946                                var5 = false;
947                            }
948                        }
949                    }
950    
951                    if (!var5)
952                    {
953                        par1Packet130UpdateSign.signLines[var8] = "!?";
954                    }
955                }
956    
957                if (var3 instanceof TileEntitySign)
958                {
959                    var8 = par1Packet130UpdateSign.xPosition;
960                    int var9 = par1Packet130UpdateSign.yPosition;
961                    var6 = par1Packet130UpdateSign.zPosition;
962                    TileEntitySign var7 = (TileEntitySign)var3;
963                    System.arraycopy(par1Packet130UpdateSign.signLines, 0, var7.signText, 0, 4);
964                    var7.onInventoryChanged();
965                    var2.markBlockNeedsUpdate(var8, var9, var6);
966                }
967            }
968        }
969    
970        /**
971         * Handle a keep alive packet.
972         */
973        public void handleKeepAlive(Packet0KeepAlive par1Packet0KeepAlive)
974        {
975            if (par1Packet0KeepAlive.randomId == this.keepAliveRandomID)
976            {
977                int var2 = (int)(System.nanoTime() / 1000000L - this.keepAliveTimeSent);
978                this.playerEntity.ping = (this.playerEntity.ping * 3 + var2) / 4;
979            }
980        }
981    
982        /**
983         * determine if it is a server handler
984         */
985        public boolean isServerHandler()
986        {
987            return true;
988        }
989    
990        /**
991         * Handle a player abilities packet.
992         */
993        public void handlePlayerAbilities(Packet202PlayerAbilities par1Packet202PlayerAbilities)
994        {
995            this.playerEntity.capabilities.isFlying = par1Packet202PlayerAbilities.getIsFlying() && this.playerEntity.capabilities.allowFlying;
996        }
997    
998        public void handleAutoComplete(Packet203AutoComplete par1Packet203AutoComplete)
999        {
1000            StringBuilder var2 = new StringBuilder();
1001            String var4;
1002    
1003            for (Iterator var3 = this.mcServer.getPossibleCompletions(this.playerEntity, par1Packet203AutoComplete.func_73473_d()).iterator(); var3.hasNext(); var2.append(var4))
1004            {
1005                var4 = (String)var3.next();
1006    
1007                if (var2.length() > 0)
1008                {
1009                    var2.append("\u0000");
1010                }
1011            }
1012    
1013            this.playerEntity.serverForThisPlayer.sendPacketToPlayer(new Packet203AutoComplete(var2.toString()));
1014        }
1015    
1016        public void handleClientInfo(Packet204ClientInfo par1Packet204ClientInfo)
1017        {
1018            this.playerEntity.updateClientInfo(par1Packet204ClientInfo);
1019        }
1020    
1021        public void handleCustomPayload(Packet250CustomPayload par1Packet250CustomPayload)
1022        {
1023            FMLNetworkHandler.handlePacket250Packet(par1Packet250CustomPayload, theNetworkManager, this);
1024        }
1025    
1026        public void handleVanilla250Packet(Packet250CustomPayload par1Packet250CustomPayload)
1027        {
1028            DataInputStream var2;
1029            ItemStack var3;
1030            ItemStack var4;
1031    
1032            if ("MC|BEdit".equals(par1Packet250CustomPayload.channel))
1033            {
1034                try
1035                {
1036                    var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data));
1037                    var3 = Packet.readItemStack(var2);
1038    
1039                    if (!ItemWritableBook.validBookTagPages(var3.getTagCompound()))
1040                    {
1041                        throw new IOException("Invalid book tag!");
1042                    }
1043    
1044                    var4 = this.playerEntity.inventory.getCurrentItem();
1045    
1046                    if (var3 != null && var3.itemID == Item.writableBook.shiftedIndex && var3.itemID == var4.itemID)
1047                    {
1048                        var4.setTagCompound(var3.getTagCompound());
1049                    }
1050                }
1051                catch (Exception var7)
1052                {
1053                    var7.printStackTrace();
1054                }
1055            }
1056            else if ("MC|BSign".equals(par1Packet250CustomPayload.channel))
1057            {
1058                try
1059                {
1060                    var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data));
1061                    var3 = Packet.readItemStack(var2);
1062    
1063                    if (!ItemEditableBook.validBookTagContents(var3.getTagCompound()))
1064                    {
1065                        throw new IOException("Invalid book tag!");
1066                    }
1067    
1068                    var4 = this.playerEntity.inventory.getCurrentItem();
1069    
1070                    if (var3 != null && var3.itemID == Item.writtenBook.shiftedIndex && var4.itemID == Item.writableBook.shiftedIndex)
1071                    {
1072                        var4.setTagCompound(var3.getTagCompound());
1073                        var4.itemID = Item.writtenBook.shiftedIndex;
1074                    }
1075                }
1076                catch (Exception var6)
1077                {
1078                    var6.printStackTrace();
1079                }
1080            }
1081            else if ("MC|TrSel".equals(par1Packet250CustomPayload.channel))
1082            {
1083                try
1084                {
1085                    var2 = new DataInputStream(new ByteArrayInputStream(par1Packet250CustomPayload.data));
1086                    int var8 = var2.readInt();
1087                    Container var9 = this.playerEntity.craftingInventory;
1088    
1089                    if (var9 instanceof ContainerMerchant)
1090                    {
1091                        ((ContainerMerchant)var9).setCurrentRecipeIndex(var8);
1092                    }
1093                }
1094                catch (Exception var5)
1095                {
1096                    var5.printStackTrace();
1097                }
1098            }
1099        }
1100    
1101        @Override
1102    
1103        /**
1104         * Contains logic for handling packets containing arbitrary unique item data. Currently this is only for maps.
1105         */
1106        public void handleMapData(Packet131MapData par1Packet131MapData)
1107        {
1108            FMLNetworkHandler.handlePacket131Packet(this, par1Packet131MapData);
1109        }
1110    
1111        // modloader compat -- yuk!
1112        @Override
1113        public EntityPlayerMP getPlayer()
1114        {
1115            return playerEntity;
1116        }
1117    }