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