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