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