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