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