Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
at develop 1561 lines 67 kB view raw
1package net.minecraft.server; 2 3import com.legacyminecraft.poseidon.Poseidon; 4import com.legacyminecraft.poseidon.event.PlayerSendPacketEvent; 5import com.projectposeidon.ConnectionType; 6import com.legacyminecraft.poseidon.PoseidonConfig; 7 8import java.util.ArrayList; 9import java.util.HashMap; 10import java.util.Map; 11import java.util.logging.Logger; 12 13import me.devcody.uberbukkit.patch.Patches; 14import org.bukkit.Bukkit; 15import org.bukkit.ChatColor; 16import org.bukkit.Location; 17import org.bukkit.command.CommandException; 18import org.bukkit.craftbukkit.ChunkCompressionThread; 19import org.bukkit.craftbukkit.CraftServer; 20import org.bukkit.craftbukkit.TextWrapper; 21import org.bukkit.craftbukkit.block.CraftBlock; 22import org.bukkit.craftbukkit.entity.CraftPlayer; 23import org.bukkit.craftbukkit.event.CraftEventFactory; 24import org.bukkit.craftbukkit.inventory.CraftItemStack; 25import org.bukkit.entity.Player; 26import org.bukkit.entity.StorageMinecart; 27import org.bukkit.event.Event; 28import org.bukkit.event.block.Action; 29import org.bukkit.event.block.BlockDamageEvent; 30import org.bukkit.event.block.BlockRedstoneEvent; 31import org.bukkit.event.block.SignChangeEvent; 32import org.bukkit.event.packet.*; 33import org.bukkit.event.player.*; 34 35import uk.betacraft.uberbukkit.UberbukkitConfig; 36import uk.betacraft.uberbukkit.packet.Packet62Sound; 37import uk.betacraft.uberbukkit.packet.Packet63Digging; 38import uk.betacraft.uberbukkit.protocol.Protocol; 39 40public class NetServerHandler extends NetHandler implements ICommandListener { 41 42 private static boolean isStaffExemptFromFlyKick = UberbukkitConfig.getInstance().getBoolean("settings.exempt-staff-from-flight-kick", false); 43 public static Logger a = Logger.getLogger("Minecraft"); 44 public NetworkManager networkManager; 45 public boolean disconnected = false; 46 private MinecraftServer minecraftServer; 47 public EntityPlayer player; // CraftBukkit - private -> public 48 private int f; 49 private int g; 50 private int h; 51 private boolean i; 52 private double x; 53 private double y; 54 private double z; 55 private boolean checkMovement = true; 56 private Map n = new HashMap(); 57 private boolean usingReleaseToBeta = false; //Project Poseidon - Create Variable 58 private ConnectionType connectionType = ConnectionType.NORMAL; //Project Poseidon - Create Variable 59 private int rawConnectionType = 0; //Project Poseidon - Create Variable 60 private boolean receivedKeepAlive = false; 61 private boolean firePacketEvents; 62 63 private final String msgPlayerLeave; 64 65 public boolean isReceivedKeepAlive() { 66 return receivedKeepAlive; 67 } 68 69 public void setReceivedKeepAlive(boolean receivedKeepAlive) { 70 this.receivedKeepAlive = receivedKeepAlive; 71 } 72 73 public NetServerHandler(MinecraftServer minecraftserver, NetworkManager networkmanager, EntityPlayer entityplayer) { 74 this.minecraftServer = minecraftserver; 75 this.networkManager = networkmanager; 76 networkmanager.a((NetHandler) this); 77 this.player = entityplayer; 78 entityplayer.netServerHandler = this; 79 80 // CraftBukkit start 81 this.server = minecraftserver.server; 82 this.firePacketEvents = PoseidonConfig.getInstance().getBoolean("settings.packet-events.enabled", false); //Poseidon 83 this.msgPlayerLeave = PoseidonConfig.getInstance().getConfigString("message.player.leave"); 84 } 85 86 //Project Poseidon - Start 87 public boolean isUsingReleaseToBeta() { 88 return usingReleaseToBeta; 89 } 90 91 public void setUsingReleaseToBeta(boolean usingReleaseToBeta) { 92 this.usingReleaseToBeta = usingReleaseToBeta; 93 } 94 95 public ConnectionType getConnectionType() { 96 return this.connectionType; 97 } 98 99 public void setConnectionType(ConnectionType connectionType) { 100 this.connectionType = connectionType; 101 } 102 103 public void setRawConnectionType(int rawConnectionType) { 104 this.rawConnectionType = rawConnectionType; 105 } 106 107 public int getRawConnectionType() { 108 return this.rawConnectionType; 109 } 110 111 //Project Poseidon - End 112 113 private final CraftServer server; 114 private int lastTick = MinecraftServer.currentTick; 115 private int lastDropTick = MinecraftServer.currentTick; 116 private int dropCount = 0; 117 private static final int PLACE_DISTANCE_SQUARED = 6 * 6; 118 119 // Get position of last block hit for BlockDamageLevel.STOPPED 120 private double lastPosX = Double.MAX_VALUE; 121 private double lastPosY = Double.MAX_VALUE; 122 private double lastPosZ = Double.MAX_VALUE; 123 private float lastPitch = Float.MAX_VALUE; 124 private float lastYaw = Float.MAX_VALUE; 125 private boolean justTeleported = false; 126 127 // For the packet15 hack :( 128 Long lastPacket; 129 130 // Store the last block right clicked and what type it was 131 private int lastMaterial; 132 133 public CraftPlayer getPlayer() { 134 return (this.player == null) ? null : (CraftPlayer) this.player.getBukkitEntity(); 135 } 136 // CraftBukkit end 137 138 // uberbukkit 139 public Integer lastDigX = null; 140 public Integer lastDigY = null; 141 public Integer lastDigZ = null; 142 public Integer lastDigFace = null; 143 144 145 public void a() { 146 this.i = false; 147 this.networkManager.b(); 148 149 if (this.f - this.g > 20) { 150 this.sendPacket(new Packet0KeepAlive()); 151 } 152 153 // uberbukkit - play breaking sound & animation for others 154 if (this.mineExpire >= System.currentTimeMillis()) { 155 if (this.lastMine + 200L < System.currentTimeMillis()) { 156 return; 157 } 158 159 if (this.networkManager.pvn < 9) return; 160 161 delaySound++; 162 if (delaySound % 4 != 0) return; 163 164 // prevent overflow (lol) 165 delaySound = 0; 166 167 int id = this.player.world.getTypeId(lastDigX, lastDigY, lastDigZ); 168 if (id == 0) return; 169 170 Block block = Block.byId[id]; 171 172 float vol1 = (block.stepSound.getVolume1() + 1.0F) / 8.0F; 173 this.minecraftServer.serverConfigurationManager.sendPacketNearbyToScale(this.player, (double) lastDigX + 0.5D, (double) lastDigY + 0.5D, (double) lastDigZ + 0.5D, vol1, ((WorldServer) this.player.world).dimension, new Packet62Sound(block.stepSound.getName(), (double) lastDigX + 0.5D, (double) lastDigY + 0.5D, (double) lastDigZ + 0.5D, vol1, block.stepSound.getVolume2() * 0.5F)); 174 175 if (lastDigFace != null) { 176 float progress = block.getDamage(this.player) * (float) (this.player.itemInWorldManager.getCurrentMagic() + 1); 177 if (progress > 1.0F) { 178 progress = 1.0F; 179 } 180 181 this.minecraftServer.serverConfigurationManager.sendPacketNearby(player, lastDigX, lastDigY, lastDigZ, 64D, player.dimension, new Packet63Digging(lastDigX, lastDigY, lastDigZ, lastDigFace, progress)); 182 } 183 } 184 } 185 186 public void disconnect(String s) { 187 if (disconnected) return; // Poseidon: Kick/Disconnect spam fix 188 189 // CraftBukkit start 190 String leaveMessage = this.msgPlayerLeave.replace("%player%", this.player.name); 191 192 PlayerKickEvent event = new PlayerKickEvent(this.server.getPlayer(this.player), s, leaveMessage); 193 this.server.getPluginManager().callEvent(event); 194 195 if (event.isCancelled()) { 196 // Do not kick the player 197 return; 198 } 199 // Send the possibly modified leave message 200 s = event.getReason(); 201 // CraftBukkit end 202 203 this.player.B(); 204 this.sendPacket(new Packet255KickDisconnect(s)); 205 this.networkManager.d(); 206 207 // CraftBukkit start 208 leaveMessage = event.getLeaveMessage(); 209 if (leaveMessage != null) { 210 this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(leaveMessage)); 211 } 212 // CraftBukkit end 213 214 this.minecraftServer.serverConfigurationManager.disconnect(this.player); 215 this.disconnected = true; 216 } 217 218 // uberbukkit 219 public void a(Packet5EntityEquipment packet5) { 220 if (this.networkManager.pvn > 6) return; 221 222 this.player.packet5.process(packet5); 223 } 224 225 public void a(Packet27 packet27) { 226 // poseidon 227 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet27); 228 server.getPluginManager().callEvent(event); 229 if (event.isCancelled()) return; 230 231 this.player.a(packet27.c(), packet27.e(), packet27.g(), packet27.h(), packet27.d(), packet27.f()); 232 } 233 234 public void a(Packet10Flying packet10flying) { 235 // poseidon 236 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet10flying); 237 server.getPluginManager().callEvent(pevent); 238 if (pevent.isCancelled()) return; 239 240 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); 241 242 this.i = true; 243 double d0; 244 245 if (!this.checkMovement) { 246 d0 = packet10flying.y - this.y; 247 if (packet10flying.x == this.x && d0 * d0 < 0.01D && packet10flying.z == this.z) { 248 this.checkMovement = true; 249 } 250 } 251 252 // CraftBukkit start 253 Player player = this.getPlayer(); 254 Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. 255 Location to = player.getLocation().clone(); // Start off the To location as the Players current location. 256 257 // If the packet contains movement information then we update the To location with the correct XYZ. 258 if (packet10flying.h && !(packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D)) { 259 to.setX(packet10flying.x); 260 to.setY(packet10flying.y); 261 to.setZ(packet10flying.z); 262 } 263 264 // If the packet contains look information then we update the To location with the correct Yaw & Pitch. 265 if (packet10flying.hasLook && Patches.HEAD_ROTATION.check(this.player, packet10flying.yaw, packet10flying.pitch)) { 266 to.setYaw(packet10flying.yaw); 267 to.setPitch(packet10flying.pitch); 268 } 269 270 // Prevent 40 event-calls for less than a single pixel of movement >.> 271 double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2); 272 float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch()); 273 274 if ((delta > 1f / 256 || deltaAngle > 10f) && (this.checkMovement && !this.player.dead)) { 275 this.player.isInWorkbench = false; // uberbukkit - cancel workbench status when player moves 276 this.lastPosX = to.getX(); 277 this.lastPosY = to.getY(); 278 this.lastPosZ = to.getZ(); 279 this.lastYaw = to.getYaw(); 280 this.lastPitch = to.getPitch(); 281 282 // Skip the first time we do this 283 if (from.getX() != Double.MAX_VALUE) { 284 PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); 285 this.server.getPluginManager().callEvent(event); 286 287 // If the event is cancelled we move the player back to their old location. 288 if (event.isCancelled()) { 289 this.player.netServerHandler.sendPacket(new Packet13PlayerLookMove(from.getX(), from.getY() + 1.6200000047683716D, from.getY(), from.getZ(), from.getYaw(), from.getPitch(), false)); 290 return; 291 } 292 293 /* If a Plugin has changed the To destination then we teleport the Player 294 there to avoid any 'Moved wrongly' or 'Moved too quickly' errors. 295 We only do this if the Event was not cancelled. */ 296 if (!to.equals(event.getTo())) { 297 this.player.getBukkitEntity().teleport(event.getTo()); 298 return; 299 } 300 301 /* Check to see if the Players Location has somehow changed during the call of the event. 302 This can happen due to a plugin teleporting the player instead of using .setTo() */ 303 if (!from.equals(this.getPlayer().getLocation()) && this.justTeleported) { 304 this.justTeleported = false; 305 return; 306 } 307 } 308 } 309 310 if (Double.isNaN(packet10flying.x) || Double.isNaN(packet10flying.y) || Double.isNaN(packet10flying.z) || Double.isNaN(packet10flying.stance) && player.isOnline() && !disconnected) { 311 player.teleport(player.getWorld().getSpawnLocation()); 312 System.err.println(player.getName() + " was caught trying to crash the server with an invalid position."); 313 player.kickPlayer("Nope!"); 314 return; 315 } 316 317 if (this.checkMovement && !this.player.dead) { 318 // CraftBukkit end 319 double d1; 320 double d2; 321 double d3; 322 double d4; 323 324 if (this.player.vehicle != null) { 325 float f = this.player.yaw; 326 float f1 = this.player.pitch; 327 328 this.player.vehicle.f(); 329 d1 = this.player.locX; 330 d2 = this.player.locY; 331 d3 = this.player.locZ; 332 double d5 = 0.0D; 333 334 d4 = 0.0D; 335 if (packet10flying.hasLook) { 336 f = packet10flying.yaw; 337 f1 = packet10flying.pitch; 338 } 339 340 if (packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D) { 341 d5 = packet10flying.x; 342 d4 = packet10flying.z; 343 344 // Project Poseidon - Start 345 // Boat crash fix ported from UberBukkit 346 347 double d8 = d5 * d5 + d4 * d4; 348 if (d8 > 100.0D) { 349 a.warning("[Poseidon]" + this.player.name + " tried crashing server on entity " + this.player.vehicle.toString() + ". They have been kicked."); 350 player.kickPlayer("Boat crash attempt detected!"); 351 return; 352 } 353 354 // Project Poseidon - End 355 356 } 357 358 this.player.onGround = packet10flying.g; 359 this.player.a(true); 360 this.player.move(d5, 0.0D, d4); 361 this.player.setLocation(d1, d2, d3, f, f1); 362 this.player.motX = d5; 363 this.player.motZ = d4; 364 if (this.player.vehicle != null) { 365 worldserver.vehicleEnteredWorld(this.player.vehicle, true); 366 } 367 368 if (this.player.vehicle != null) { 369 this.player.vehicle.f(); 370 this.player.vehicle.airBorne = true; 371 } 372 373 this.minecraftServer.serverConfigurationManager.d(this.player); 374 this.x = this.player.locX; 375 this.y = this.player.locY; 376 this.z = this.player.locZ; 377 worldserver.playerJoinedWorld(this.player); 378 return; 379 } 380 381 if (this.player.isSleeping()) { 382 this.player.a(true); 383 this.player.setLocation(this.x, this.y, this.z, this.player.yaw, this.player.pitch); 384 worldserver.playerJoinedWorld(this.player); 385 return; 386 } 387 388 d0 = this.player.locY; 389 this.x = this.player.locX; 390 this.y = this.player.locY; 391 this.z = this.player.locZ; 392 d1 = this.player.locX; 393 d2 = this.player.locY; 394 d3 = this.player.locZ; 395 float f2 = this.player.yaw; 396 float f3 = this.player.pitch; 397 398 if (packet10flying.h && packet10flying.y == -999.0D && packet10flying.stance == -999.0D) { 399 packet10flying.h = false; 400 } 401 402 if (packet10flying.h) { 403 d1 = packet10flying.x; 404 d2 = packet10flying.y; 405 d3 = packet10flying.z; 406 d4 = packet10flying.stance - packet10flying.y; 407 if (!this.player.isSleeping() && (d4 > 1.65D || d4 < 0.1D)) { 408 this.disconnect("Illegal stance"); 409 a.warning(this.player.name + " had an illegal stance: " + d4); 410 return; 411 } 412 413 if (Math.abs(packet10flying.x) > 3.2E7D || Math.abs(packet10flying.z) > 3.2E7D) { 414 this.disconnect("Illegal position"); 415 return; 416 } 417 } 418 419 if (packet10flying.hasLook) { 420 f2 = packet10flying.yaw; 421 f3 = packet10flying.pitch; 422 } 423 424 this.player.a(true); 425 this.player.br = 0.0F; 426 this.player.setLocation(this.x, this.y, this.z, f2, f3); 427 if (!this.checkMovement) { 428 return; 429 } 430 431 d4 = d1 - this.player.locX; 432 double d6 = d2 - this.player.locY; 433 double d7 = d3 - this.player.locZ; 434 double d14 = this.player.motX * this.player.motX + this.player.motY * this.player.motY + this.player.motZ * this.player.motZ; 435 double d8 = d4 * d4 + d6 * d6 + d7 * d7; 436 437 if ((boolean) PoseidonConfig.getInstance().getConfigOption("world.settings.speed-hack-check.enabled", true)) { 438 if (d8 - d14 > (double) PoseidonConfig.getInstance().getConfigOption("world.settings.speed-hack-check.distance", 100.0D) && this.checkMovement) { // CraftBukkit - Added this.checkMovement condition to solve this check being triggered by teleports 439 a.warning(this.player.name + " moved too quickly! " + d4 + "," + d6 + "," + d7 + " (" + d4 + ", " + d6 + ", " + d7 + ")"); 440 if ((boolean) PoseidonConfig.getInstance().getConfigOption("world.settings.speed-hack-check.teleport", true)) { 441 this.a(this.x, this.y, this.z, this.player.yaw, this.player.pitch); 442 } else { 443 this.disconnect("You moved too quickly :( (Hacking?)"); 444 } 445 return; 446 } 447 } 448 449 float f4 = 0.0625F; 450 boolean flag = worldserver.getEntities(this.player, this.player.boundingBox.clone().shrink((double) f4, (double) f4, (double) f4)).size() == 0; 451 452 this.player.move(d4, d6, d7); 453 d4 = d1 - this.player.locX; 454 d6 = d2 - this.player.locY; 455 if (d6 > -0.5D || d6 < 0.5D) { 456 d6 = 0.0D; 457 } 458 459 d7 = d3 - this.player.locZ; 460 d8 = d4 * d4 + d6 * d6 + d7 * d7; 461 boolean flag1 = false; 462 463 if (d8 > 0.0625D && !this.player.isSleeping()) { 464 flag1 = true; 465 a.warning(this.player.name + " moved wrongly!"); 466 System.out.println("Got position " + d1 + ", " + d2 + ", " + d3); 467 System.out.println("Expected " + this.player.locX + ", " + this.player.locY + ", " + this.player.locZ); 468 } 469 470 this.player.setLocation(d1, d2, d3, f2, f3); 471 boolean flag2 = worldserver.getEntities(this.player, this.player.boundingBox.clone().shrink((double) f4, (double) f4, (double) f4)).size() == 0; 472 473 if (flag && (flag1 || !flag2) && !this.player.isSleeping()) { 474 this.a(this.x, this.y, this.z, f2, f3); 475 return; 476 } 477 478 AxisAlignedBB axisalignedbb = this.player.boundingBox.clone().b((double) f4, (double) f4, (double) f4).a(0.0D, -0.55D, 0.0D); 479 480 // uberbukkit 481 boolean bool = false; 482 if (isStaffExemptFromFlyKick) { 483 Player bukkitPlayer = (Player) this.player.getBukkitEntity(); 484 bool = bukkitPlayer.isOp() || bukkitPlayer.hasPermission("uberbukkit.fly"); 485 } 486 487 if (!this.minecraftServer.allowFlight && !worldserver.b(axisalignedbb) && !bool) { 488 if (d6 >= -0.03125D) { 489 ++this.h; 490 if (this.h > 80) { 491 a.warning(this.player.name + " was kicked for floating too long!"); 492 this.disconnect("Flying is not enabled on this server"); 493 return; 494 } 495 } 496 } else { 497 this.h = 0; 498 } 499 500 this.player.onGround = packet10flying.g; 501 this.minecraftServer.serverConfigurationManager.d(this.player); 502 this.player.b(this.player.locY - d0, packet10flying.g); 503 } 504 } 505 506 public void a(double d0, double d1, double d2, float f, float f1) { 507 // CraftBukkit start - Delegate to teleport(Location) 508 Player player = this.getPlayer(); 509 Location from = player.getLocation(); 510 Location to = new Location(this.getPlayer().getWorld(), d0, d1, d2, f, f1); 511 PlayerTeleportEvent event = new PlayerTeleportEvent(player, from, to); 512 this.server.getPluginManager().callEvent(event); 513 514 from = event.getFrom(); 515 to = event.isCancelled() ? from : event.getTo(); 516 517 this.teleport(to); 518 } 519 520 public void teleport(Location dest) { 521 double d0, d1, d2; 522 float f, f1; 523 524 d0 = dest.getX(); 525 d1 = dest.getY(); 526 d2 = dest.getZ(); 527 f = dest.getYaw(); 528 f1 = dest.getPitch(); 529 530 // TODO: make sure this is the best way to address this. 531 if (Float.isNaN(f)) { 532 f = 0; 533 } 534 535 if (Float.isNaN(f1)) { 536 f1 = 0; 537 } 538 539 this.lastPosX = d0; 540 this.lastPosY = d1; 541 this.lastPosZ = d2; 542 this.lastYaw = f; 543 this.lastPitch = f1; 544 this.justTeleported = true; 545 // CraftBukkit end 546 547 this.checkMovement = false; 548 this.x = d0; 549 this.y = d1; 550 this.z = d2; 551 this.player.setLocation(d0, d1, d2, f, f1); 552 this.player.netServerHandler.sendPacket(new Packet13PlayerLookMove(d0, d1 + 1.6200000047683716D, d1, d2, f, f1, false)); 553 } 554 555 // uberbukkit 556 public void a(Packet21PickupSpawn packet21) { 557 // copy from craftbukkit 558 if (this.lastDropTick != MinecraftServer.currentTick) { 559 this.dropCount = 0; 560 this.lastDropTick = MinecraftServer.currentTick; 561 } else { 562 // Else we increment the drop count and check the amount. 563 this.dropCount++; 564 if (this.dropCount >= 20) { 565 a.warning(this.player.name + " dropped their items too quickly!"); 566 this.disconnect("You dropped your items too quickly (Hacking?)"); 567 } 568 } 569 // drop itemstack 570 ItemStack hand = this.player.inventory.items[this.player.inventory.itemInHandIndex]; 571 ItemStack todrop = null; 572 573 if (hand != null && hand.id == packet21.h && hand.count >= packet21.i && packet21.i == 1) { 574 todrop = hand.cloneItemStack(); 575 todrop.count = packet21.i; 576 hand.count -= packet21.i; 577 } else { 578 ArrayList<ItemStack> list = this.player.packet5.queue.getQueue(); 579 for (ItemStack stack : list) { 580 if (stack.id == packet21.h && stack.count >= packet21.i) { 581 todrop = stack.cloneItemStack(); 582 todrop.count = packet21.i; 583 this.player.packet5.queue.removeStackFromQueue(todrop); 584 break; 585 } 586 } 587 } 588 this.player.a(todrop, false); 589 //this.player.F(); 590 } 591 592 public long mineExpire = 0; 593 public long lastMine = 0; 594 public int delaySound = 0; 595 596 public void a(Packet14BlockDig packet14blockdig) { 597 // poseidon 598 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet14blockdig); 599 server.getPluginManager().callEvent(event); 600 if (event.isCancelled()) return; 601 602 if (this.player.dead) return; // CraftBukkit 603 604 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); 605 606 if (packet14blockdig.e == 4) { 607 // CraftBukkit start 608 // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick. 609 if (this.lastDropTick != MinecraftServer.currentTick) { 610 this.dropCount = 0; 611 this.lastDropTick = MinecraftServer.currentTick; 612 } else { 613 // Else we increment the drop count and check the amount. 614 this.dropCount++; 615 if (this.dropCount >= 20) { 616 a.warning(this.player.name + " dropped their items too quickly!"); 617 this.disconnect("You dropped your items too quickly (Hacking?)"); 618 } 619 } 620 // CraftBukkit end 621 this.player.F(); 622 } else { 623 boolean flag = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit 624 boolean flag1 = false; 625 626 // uberbukkit 627 628 // Pre-b1.3 block handling 629 // e == 2 is stop digging (holds no block coordinate data) 630 // e == 3 is expected block break from client 631 // e == 1 is digging 632 // e == 0 is start digging, or digging every 5 packets (notch is weird) 633 634 // Post-b1.2_01 block handling 635 // e == 2 is stop digging 636 // e == 0 is start digging 637 Integer i = packet14blockdig.a; 638 Integer j = packet14blockdig.b; 639 Integer k = packet14blockdig.c; 640 641 if (packet14blockdig.e == 0) { 642 flag1 = true; 643 } 644 645 if (packet14blockdig.e == 1 && this.networkManager.pvn <= 8) { 646 flag1 = true; 647 } 648 649 if (packet14blockdig.e == 2 && this.networkManager.pvn >= 9) { 650 flag1 = true; 651 } 652 653 if (flag1) { 654 double d0 = this.player.locX - ((double) i + 0.5D); 655 double d1 = this.player.locY - ((double) j + 0.5D); 656 double d2 = this.player.locZ - ((double) k + 0.5D); 657 double d3 = d0 * d0 + d1 * d1 + d2 * d2; 658 659 if (d3 > 36.0D) { 660 return; 661 } 662 } 663 664 ChunkCoordinates chunkcoordinates = worldserver.getSpawn(); 665 int l = (int) MathHelper.abs((float) (i - chunkcoordinates.x)); 666 int i1 = (int) MathHelper.abs((float) (k - chunkcoordinates.z)); 667 668 if (l > i1) { 669 i1 = l; 670 } 671 672 if (this.networkManager.pvn <= 8) { 673 // CraftBukkit start 674 CraftPlayer player = getPlayer(); 675 CraftBlock block = (CraftBlock) player.getWorld().getBlockAt(i, j, k); 676 int blockId = block.getTypeId(); 677 float damage = 0; 678 if (Block.byId[blockId] != null) { 679 damage = Block.byId[blockId].getDamage(player.getHandle()); //Get amount of damage going to block 680 } 681 // CraftBukkit end 682 683 if (packet14blockdig.e == 0) { 684 // CraftBukkit start 685 if (i1 > this.server.getSpawnRadius() || flag) { 686 if (blockId > 0) { 687 BlockDamageEvent breakEvent; 688 // If the amount of damage that the player is going to do to the block 689 // is >= 1, then the block is going to break (eg, flowers, torches) 690 if (damage >= 1.0F) { 691 // if we are destroying either a redstone wire with a current greater than 0 or 692 // a redstone torch that is on, then we should notify plugins that this block has 693 // returned to a current value of 0 (since it will once the redstone is destroyed) 694 if ((blockId == Block.REDSTONE_WIRE.id && block.getData() > 0) || blockId == Block.REDSTONE_TORCH_ON.id) { 695 server.getPluginManager().callEvent(new BlockRedstoneEvent(block, (blockId == Block.REDSTONE_WIRE.id ? block.getData() : 15), 0)); 696 } 697 breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), true); 698 } else { 699 breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), false); 700 } 701 server.getPluginManager().callEvent(breakEvent); 702 if (!breakEvent.isCancelled()) { 703 this.player.itemInWorldManager.oldClick(i, j, k, packet14blockdig.face); 704 705 this.lastDigFace = packet14blockdig.face; // uberbukkit - handle digging 706 } 707 } 708 } 709 // CraftBukkit end 710 } else if (packet14blockdig.e == 2) { 711 // CraftBukkit start - Get last block that the player hit 712 // Otherwise the block is a Bedrock @(0,0,0) 713 block = (CraftBlock) player.getWorld().getBlockAt(lastDigX, lastDigY, lastDigZ); 714 BlockDamageEvent breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), damage >= 1.0F); 715 server.getPluginManager().callEvent(breakEvent); 716 if (!breakEvent.isCancelled()) { 717 this.player.itemInWorldManager.oldHaltBreak(); 718 } 719 // CraftBukkit end 720 } else if (packet14blockdig.e == 1) { 721 // CraftBukkit start 722 if (i1 > this.server.getSpawnRadius() || flag) { 723 BlockDamageEvent breakEvent; 724 // If the amount of damage going to the block plus the current amount 725 // of damage is greater than 1, the block is going to break. 726 if (this.player.itemInWorldManager.damageDealt + damage >= 1.0F) { 727 // if we are destroying either a redstone wire with a current greater than 0 or 728 // a redstone torch that is on, then we should notify plugins that this block has 729 // returned to a current value of 0 (since it will once the redstone is destroyed) 730 if ((blockId == Block.REDSTONE_WIRE.id && block.getData() > 0) || blockId == Block.REDSTONE_TORCH_ON.id) { 731 server.getPluginManager().callEvent(new BlockRedstoneEvent(block, (blockId == Block.REDSTONE_WIRE.id ? block.getData() : 15), 0)); 732 } 733 breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), damage >= 1.0F); 734 } else { 735 breakEvent = new BlockDamageEvent(player, block, player.getItemInHand(), damage >= 1.0F); 736 } 737 server.getPluginManager().callEvent(breakEvent); 738 if (!breakEvent.isCancelled()) { 739 this.player.itemInWorldManager.oldDig(i, j, k, packet14blockdig.face); 740 741 this.lastDigFace = packet14blockdig.face; // uberbukkit - handle digging 742 } else { 743 this.player.itemInWorldManager.damageDealt = 0; // Reset the amount of damage if stopping break. 744 } 745 } 746 // CraftBukkit end 747 } else if (packet14blockdig.e == 3) { 748 double d5 = this.player.locX - ((double) i + 0.5D); 749 double d6 = this.player.locY - ((double) j + 0.5D); 750 double d7 = this.player.locZ - ((double) k + 0.5D); 751 double d8 = d5 * d5 + d6 * d6 + d7 * d7; 752 753 if (d8 < 256.0D) { 754 this.player.netServerHandler.sendPacket((Packet) (new Packet53BlockChange(i, j, k, this.player.world))); // Craftbukkit 755 } 756 } 757 } else { 758 if (packet14blockdig.e == 0) { 759 // CraftBukkit 760 if (i1 < this.server.getSpawnRadius() && !flag) { 761 this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver)); 762 } else { 763 // CraftBukkit - add face argument 764 this.player.itemInWorldManager.dig(i, j, k, packet14blockdig.face); 765 766 // uberbukkit - handle digging 767 this.mineExpire = this.player.itemInWorldManager.getExpectedDigEnd(); 768 this.lastDigFace = packet14blockdig.face; 769 } 770 } else if (packet14blockdig.e == 2) { 771 // uberbukkit - swapped i,j,k for lastDigX,lastDigY,lastDigZ 772 this.player.itemInWorldManager.a(lastDigX, lastDigY, lastDigZ); 773 774 // uberbukkit - handle digging 775 this.mineExpire = 0; 776 this.lastMine = 0; 777 778 if (worldserver.getTypeId(lastDigX, lastDigY, lastDigZ) != 0) { 779 this.player.netServerHandler.sendPacket(new Packet53BlockChange(lastDigX, lastDigY, lastDigZ, worldserver)); 780 } 781 } else if (packet14blockdig.e == 3) { 782 double d4 = this.player.locX - ((double) i + 0.5D); 783 double d5 = this.player.locY - ((double) j + 0.5D); 784 double d6 = this.player.locZ - ((double) k + 0.5D); 785 double d7 = d4 * d4 + d5 * d5 + d6 * d6; 786 787 if (d7 < 256.0D) { 788 this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver)); 789 } 790 } 791 } 792 793 // uberbukkit - reset last positions when stops digging 794 lastDigX = i; 795 lastDigY = j; 796 lastDigZ = k; 797 798 worldserver.weirdIsOpCache = false; 799 } 800 } 801 802 public void a(Packet15Place packet15place) { 803// System.out.println("Packet15 received"); 804// System.out.println("a: " + packet15place.a); 805// System.out.println("b: " + packet15place.b); 806// System.out.println("c: " + packet15place.c); 807// System.out.println("face: " + packet15place.face); 808// System.out.println("data: " + packet15place.data); 809 // poseidon 810 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet15place); 811 server.getPluginManager().callEvent(pevent); 812 if (pevent.isCancelled()) return; 813 814 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); 815 816 // CraftBukkit start 817 if (this.player.dead) return; 818 819 // uberbukkit: noptch what the fuck have you done 820 if (this.networkManager.pvn == 7) { 821 if (packet15place.itemstack != null && packet15place.a != -1 && packet15place.b != 255 && packet15place.c != -1 && (packet15place.itemstack.id == Item.BUCKET.id || packet15place.itemstack.id == Item.WATER_BUCKET.id || packet15place.itemstack.id == Item.LAVA_BUCKET.id || packet15place.itemstack.id == Item.MILK_BUCKET.id)) { 822 return; 823 } 824 } 825 826 // This is a horrible hack needed because the client sends 2 packets on 'right mouse click' 827 // aimed at a block. We shouldn't need to get the second packet if the data is handled 828 // but we cannot know what the client will do, so we might still get it 829 // 830 // If the time between packets is small enough, and the 'signature' similar, we discard the 831 // second one. This sadly has to remain until Mojang makes their packets saner. :( 832 // -- Grum 833 834 if (packet15place.face == 255) { 835 if (packet15place.itemstack != null && packet15place.itemstack.id == this.lastMaterial && this.lastPacket != null && packet15place.timestamp - this.lastPacket < 100) { 836 this.lastPacket = null; 837 return; 838 } 839 } else { 840 this.lastMaterial = packet15place.itemstack == null ? -1 : packet15place.itemstack.id; 841 this.lastPacket = packet15place.timestamp; 842 } 843 844 // CraftBukkit - if rightclick decremented the item, always send the update packet. 845 // this is not here for CraftBukkit's own functionality; rather it is to fix 846 // a notch bug where the item doesn't update correctly. 847 boolean always = false; 848 849 // CraftBukkit end 850 851 ItemStack itemstack = this.player.inventory.getItemInHand(); 852 boolean flag = worldserver.weirdIsOpCache = worldserver.dimension != 0 || this.minecraftServer.serverConfigurationManager.isOp(this.player.name); // CraftBukkit 853 854 if (packet15place.face == 255) { 855 if (itemstack == null) { 856 return; 857 } 858 859 // CraftBukkit start 860 int itemstackAmount = itemstack.count; 861 PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack); 862 if (event.useItemInHand() != Event.Result.DENY) { 863 this.player.itemInWorldManager.useItem(this.player, this.player.world, itemstack); 864 } 865 866 // CraftBukkit - notch decrements the counter by 1 in the above method with food, 867 // snowballs and so forth, but he does it in a place that doesn't cause the 868 // inventory update packet to get sent 869 always = (itemstack.count != itemstackAmount); 870 // CraftBukkit end 871 } else { 872 int i = packet15place.a; 873 int j = packet15place.b; 874 int k = packet15place.c; 875 int l = packet15place.face; 876 ChunkCoordinates chunkcoordinates = worldserver.getSpawn(); 877 int i1 = (int) MathHelper.abs((float) (i - chunkcoordinates.x)); 878 int j1 = (int) MathHelper.abs((float) (k - chunkcoordinates.z)); 879 880 if (i1 > j1) { 881 j1 = i1; 882 } 883 884 // CraftBukkit start - Check if we can actually do something over this large a distance 885 Location eyeLoc = this.getPlayer().getEyeLocation(); 886 if (Math.pow(eyeLoc.getX() - i, 2) + Math.pow(eyeLoc.getY() - j, 2) + Math.pow(eyeLoc.getZ() - k, 2) > PLACE_DISTANCE_SQUARED) { 887 return; 888 } 889 flag = true; // spawn protection moved to ItemBlock!!! 890 // CraftBukkit end 891 892 if (j1 > 16 || flag) { 893 this.player.itemInWorldManager.interact(this.player, worldserver, itemstack, i, j, k, l); 894 } 895 896 this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver)); 897 if (l == 0) { 898 --j; 899 } 900 901 if (l == 1) { 902 ++j; 903 } 904 905 if (l == 2) { 906 --k; 907 } 908 909 if (l == 3) { 910 ++k; 911 } 912 913 if (l == 4) { 914 --i; 915 } 916 917 if (l == 5) { 918 ++i; 919 } 920 921 this.player.netServerHandler.sendPacket(new Packet53BlockChange(i, j, k, worldserver)); 922 } 923 924 itemstack = this.player.inventory.getItemInHand(); 925 if (itemstack != null && itemstack.count == 0) { 926 this.player.inventory.items[this.player.inventory.itemInHandIndex] = null; 927 } 928 929 this.player.h = true; 930 this.player.inventory.items[this.player.inventory.itemInHandIndex] = ItemStack.b(this.player.inventory.items[this.player.inventory.itemInHandIndex]); 931 Slot slot = this.player.activeContainer.a(this.player.inventory, this.player.inventory.itemInHandIndex); 932 933 this.player.activeContainer.a(); 934 this.player.h = false; 935 // CraftBukkit 936 if (!ItemStack.equals(this.player.inventory.getItemInHand(), packet15place.itemstack) || always) { 937 if (this.networkManager.pvn <= 6) { 938 this.refreshInventory(); 939 } else { 940 this.sendPacket(new Packet103SetSlot(this.player.activeContainer.windowId, slot.a, this.player.inventory.getItemInHand())); 941 } 942 } 943 944 worldserver.weirdIsOpCache = false; 945 } 946 947 // uberbukkit 948 public void refreshInventory() { 949 this.sendPacket(new Packet5EntityEquipment(-1, this.player.inventory.items)); 950 this.sendPacket(new Packet5EntityEquipment(-2, this.player.inventory.craft)); 951 this.sendPacket(new Packet5EntityEquipment(-3, this.player.inventory.armor)); 952 } 953 954 public void a(String s, Object[] aobject) { 955 if (this.disconnected) return; // CraftBukkit - rarely it would send a disconnect line twice 956 957 958 if (!(boolean) PoseidonConfig.getInstance().getConfigOption("settings.remove-join-leave-debug", true) || !s.equals("disconnect.quitting")) { 959 a.info(this.player.name + " lost connection: " + s); 960 } 961 962 a.info(this.player.name + " has left the game."); 963 // CraftBukkit start - we need to handle custom quit messages 964 String quitMessage = this.minecraftServer.serverConfigurationManager.disconnect(this.player); 965 if (quitMessage != null) { 966 this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(quitMessage)); 967 } 968 // CraftBukkit end 969 this.disconnected = true; 970 } 971 972 public void a(Packet packet) { 973 a.warning(this.getClass() + " wasn\'t prepared to deal with a " + packet.getClass()); 974 this.disconnect("Protocol error, unexpected packet"); 975 } 976 977 public void sendPacket(Packet packet) { 978 //Poseidon Start - Send Packet Event 979 if (packet == null) // Why do anything if there's no packet? (fixes Internal server error) 980 return; 981 982 if (firePacketEvents) { 983 PlayerSendPacketEvent event = new PlayerSendPacketEvent(this.player.name, packet); 984 Bukkit.getPluginManager().callEvent(event); 985 if (event.isCancelled()) { 986 return; 987 } 988 packet = event.getPacket(); //In case a plugin replaces the entire packet 989 } 990 //Poseidon End 991 992 // UberBukkit 993 PacketSentEvent packetSentEvent = new PacketSentEvent(getPlayer(), packet); 994 Bukkit.getPluginManager().callEvent(packetSentEvent); 995 if (packetSentEvent.isCancelled()) { 996 return; 997 } 998 packet = packetSentEvent.getPacket(); 999 1000 Protocol protocol = this.player.protocol; 1001 if (!protocol.canReceivePacket(packet.b())) { 1002 this.g = this.f; 1003 return; 1004 } 1005 1006 // uberbukkit - try to disallow for incompatible blocks and packets 1007 if (packet instanceof Packet5EntityEquipment) { 1008 Packet5EntityEquipment packet5 = (Packet5EntityEquipment) packet; 1009 1010 // don't send entity equipment data to pre-b1.0 clients 1011 // (they use packet 5 for inventory data) 1012 if (packet5.items == null && this.networkManager.pvn < 7) { 1013 this.g = this.f; 1014 return; 1015 } 1016 1017 if (packet5.c > 0 && !protocol.canReceiveBlockItem(packet5.c)) { 1018 this.networkManager.queue(new Packet5EntityEquipment(packet5.a, packet5.b, null)); 1019 packet = null; 1020 } 1021 } else if (packet instanceof Packet53BlockChange) { 1022 Packet53BlockChange packet53 = (Packet53BlockChange) packet; 1023 if (!protocol.canReceiveBlockItem(packet53.material)) { 1024 this.networkManager.queue(new Packet53BlockChange(packet53.a, packet53.b, packet53.c, 1, packet53.data)); 1025 packet = null; 1026 } 1027 } else if (packet instanceof Packet18ArmAnimation) { 1028 Packet18ArmAnimation packet18 = (Packet18ArmAnimation) packet; 1029 1030 // skip riding/burning/sneaking packets for a1.1.2_01 1031 if (this.networkManager.pvn <= 2 && packet18.b >= 100) { 1032 this.g = this.f; 1033 return; 1034 } 1035 } 1036 1037 // CraftBukkit start 1038 else if (packet instanceof Packet6SpawnPosition) { 1039 Packet6SpawnPosition packet6 = (Packet6SpawnPosition) packet; 1040 this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.x, packet6.y, packet6.z); 1041 } else if (packet instanceof Packet3Chat) { 1042 String message = ((Packet3Chat) packet).message; 1043 // uberbukkit 1044 String[] wrapped = null; 1045 if (this.networkManager.pvn >= 9) { // TODO check compatibility 1046 wrapped = TextWrapper.wrapText(message); 1047 } else { 1048 wrapped = TextWrapper.wrapTextLegacy(message); 1049 } 1050 1051 for (final String line : wrapped) { 1052 this.networkManager.queue(new Packet3Chat(line)); 1053 } 1054 packet = null; 1055 } else if (packet.k == true) { 1056 // Reroute all low-priority packets through to compression thread. 1057 ChunkCompressionThread.sendPacket(this.player, packet); 1058 packet = null; 1059 } 1060 if (packet != null) this.networkManager.queue(packet); 1061 // CraftBukkit end 1062 1063 this.g = this.f; 1064 } 1065 1066 public void a(Packet16BlockItemSwitch packet16blockitemswitch) { 1067 // poseidon 1068 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet16blockitemswitch); 1069 server.getPluginManager().callEvent(pevent); 1070 if (pevent.isCancelled()) return; 1071 1072 if (this.player.dead) return; // CraftBukkit 1073 1074 if (this.networkManager.pvn >= 7) { 1075 if (packet16blockitemswitch.itemInHandIndex >= 0 && packet16blockitemswitch.itemInHandIndex <= InventoryPlayer.e()) { 1076 // CraftBukkit start 1077 PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayer(), this.player.inventory.itemInHandIndex, packet16blockitemswitch.itemInHandIndex); 1078 this.server.getPluginManager().callEvent(event); 1079 // CraftBukkit end 1080 1081 this.player.inventory.itemInHandIndex = packet16blockitemswitch.itemInHandIndex; 1082 } else { 1083 a.warning(this.player.name + " tried to set an invalid carried item"); 1084 this.disconnect("Invalid hotbar selection (Hacking?)"); 1085 } 1086 } else { 1087 1088 for (int i = 0; i < 9; i++) { 1089 ItemStack stack = this.player.inventory.items[i]; 1090 1091 if ((stack != null && stack.id == packet16blockitemswitch.itemId) || (stack == null && packet16blockitemswitch.itemId == 0)) { 1092 this.player.inventory.itemInHandIndex = i; 1093 } 1094 } 1095 } 1096 } 1097 1098 public void a(Packet3Chat packet3chat) { 1099 // poseidon 1100 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet3chat); 1101 server.getPluginManager().callEvent(event); 1102 if (event.isCancelled()) return; 1103 1104 String s = packet3chat.message; 1105 1106 if (s.length() > 100) { 1107 this.disconnect("Chat message too long"); 1108 } else { 1109 s = s.trim(); 1110 1111 for (int i = 0; i < s.length(); ++i) { 1112 if (FontAllowedCharacters.allowedCharacters.indexOf(s.charAt(i)) < 0) { 1113 this.disconnect("Illegal characters in chat"); 1114 return; 1115 } 1116 } 1117 1118 // CraftBukkit start 1119 this.chat(s); 1120 } 1121 } 1122 1123 public boolean chat(String s) { 1124 if (!this.player.dead) { 1125 // UberBukkit - Start 1126 // Forcefully closes a container when a player sends a chat message 1127 if (player.activeContainer != player.defaultContainer) { 1128 player.y(); 1129 } 1130 // UberBukkit - End 1131 1132 if (s.startsWith("/")) { 1133 this.handleCommand(s); 1134 return true; 1135 } else { 1136 Player player = this.getPlayer(); 1137 PlayerChatEvent event = new PlayerChatEvent(player, s); 1138 this.server.getPluginManager().callEvent(event); 1139 1140 if (event.isCancelled()) { 1141 return true; 1142 } 1143 1144 s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage()); 1145 minecraftServer.console.sendMessage(s); 1146 for (Player recipient : event.getRecipients()) { 1147 recipient.sendMessage(s); 1148 } 1149 } 1150 } 1151 1152 return false; 1153 // CraftBukkit end 1154 } 1155 1156 private void handleCommand(String s) { 1157 // CraftBukkit start 1158 CraftPlayer player = this.getPlayer(); 1159 1160 PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, s); 1161 this.server.getPluginManager().callEvent(event); 1162 1163 if (event.isCancelled()) { 1164 return; 1165 } 1166 1167 s = event.getMessage(); //Poseidon: Override command with new command string. 1168 1169 try { 1170 if (this.server.dispatchCommand(player, s.substring(1))) { 1171 //Project Poseidon Start 1172 //Hide commands from being logged in console 1173 String cmdName = s.split(" ")[0].replaceAll("/", ""); 1174 1175 if (Poseidon.getServer().isCommandHidden(cmdName)) { 1176 a.info(player.getName() + " issued server command: COMMAND REDACTED"); 1177 } else { 1178 a.info(player.getName() + " issued server command: " + s); 1179 } 1180 1181 //Project Poseidon End 1182 return; 1183 } 1184 } catch (CommandException ex) { 1185 player.sendMessage(ChatColor.RED + "An internal error occurred while attempting to perform this command"); 1186 Logger.getLogger(NetServerHandler.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 1187 return; 1188 } 1189 // CraftBukkit end 1190 1191 /* CraftBukkit start - No longer neaded av we have already handled it server.dispatchCommand above. 1192 if (s.toLowerCase().startsWith("/me ")) { 1193 s = "* " + this.player.name + " " + s.substring(s.indexOf(" ")).trim(); 1194 a.info(s); 1195 this.minecraftServer.serverConfigurationManager.sendAll(new Packet3Chat(s)); 1196 } else if (s.toLowerCase().startsWith("/kill")) { 1197 this.player.damageEntity(this.player, 1000); // CraftBukkit - replace null entity with player entity; TODO: decide if we want damage with a null source to fire an event. 1198 } else if (s.toLowerCase().startsWith("/tell ")) { 1199 String[] astring = s.split(" "); 1200 1201 if (astring.length >= 3) { 1202 s = s.substring(s.indexOf(" ")).trim(); 1203 s = s.substring(s.indexOf(" ")).trim(); 1204 s = "\u00A77" + this.player.name + " whispers " + s; 1205 a.info(s + " to " + astring[1]); 1206 if (!this.minecraftServer.serverConfigurationManager.a(astring[1], (Packet) (new Packet3Chat(s)))) { 1207 this.sendPacket(new Packet3Chat("\u00A7cThere\'s no player by that name online.")); 1208 } 1209 } 1210 } else { 1211 String s1; 1212 1213 if (this.minecraftServer.serverConfigurationManager.isOp(this.player.name)) { 1214 s1 = s.substring(1); 1215 a.info(this.player.name + " issued server command: " + s1); 1216 this.minecraftServer.issueCommand(s1, this); 1217 } else { 1218 s1 = s.substring(1); 1219 a.info(this.player.name + " tried command: " + s1); 1220 } 1221 } 1222 // CraftBukkit end */ 1223 } 1224 1225 public void a(Packet18ArmAnimation packet18armanimation) { 1226 // poseidon 1227 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet18armanimation); 1228 server.getPluginManager().callEvent(pevent); 1229 if (pevent.isCancelled()) return; 1230 1231 // CraftBukkit start 1232 if (this.player.dead) return; 1233 1234 if (packet18armanimation.b == 104 || packet18armanimation.b == 105) { 1235 PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getPlayer(), packet18armanimation.b == 104); 1236 this.server.getPluginManager().callEvent(event); 1237 1238 if (event.isCancelled()) { 1239 return; 1240 } 1241 } 1242 // CraftBukkit end 1243 1244 if (packet18armanimation.b == 1) { 1245 // CraftBukkit start - raytrace to look for 'rogue armswings' 1246 float f = 1.0F; 1247 float f1 = this.player.lastPitch + (this.player.pitch - this.player.lastPitch) * f; 1248 float f2 = this.player.lastYaw + (this.player.yaw - this.player.lastYaw) * f; 1249 double d0 = this.player.lastX + (this.player.locX - this.player.lastX) * (double) f; 1250 double d1 = this.player.lastY + (this.player.locY - this.player.lastY) * (double) f + 1.62D - (double) this.player.height; 1251 double d2 = this.player.lastZ + (this.player.locZ - this.player.lastZ) * (double) f; 1252 Vec3D vec3d = Vec3D.create(d0, d1, d2); 1253 1254 float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); 1255 float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); 1256 float f5 = -MathHelper.cos(-f1 * 0.017453292F); 1257 float f6 = MathHelper.sin(-f1 * 0.017453292F); 1258 float f7 = f4 * f5; 1259 float f8 = f3 * f5; 1260 double d3 = 5.0D; 1261 Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); 1262 MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, true); 1263 1264 if (movingobjectposition == null || movingobjectposition.type != EnumMovingObjectType.TILE) { 1265 CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.inventory.getItemInHand()); 1266 } 1267 1268 // Arm swing animation 1269 PlayerAnimationEvent event = new PlayerAnimationEvent(this.getPlayer()); 1270 this.server.getPluginManager().callEvent(event); 1271 1272 if (event.isCancelled()) return; 1273 // CraftBukkit end 1274 1275 this.player.w(); 1276 1277 // uberbukkit - handle digging 1278 if (this.mineExpire >= System.currentTimeMillis() && this.networkManager.pvn >= 9) { 1279 lastMine = System.currentTimeMillis(); 1280 } 1281 } else if (packet18armanimation.b == 104) { 1282 this.player.setSneak(true); 1283 } else if (packet18armanimation.b == 105) { 1284 this.player.setSneak(false); 1285 } 1286 } 1287 1288 public void a(Packet19EntityAction packet19entityaction) { 1289 // poseidon 1290 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet19entityaction); 1291 server.getPluginManager().callEvent(pevent); 1292 if (pevent.isCancelled()) return; 1293 1294 // CraftBukkit start 1295 if (this.player.dead) return; 1296 1297 if (packet19entityaction.animation == 1 || packet19entityaction.animation == 2) { 1298 PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getPlayer(), packet19entityaction.animation == 1); 1299 this.server.getPluginManager().callEvent(event); 1300 1301 if (event.isCancelled()) { 1302 return; 1303 } 1304 } 1305 // CraftBukkit end 1306 1307 if (packet19entityaction.animation == 1) { 1308 this.player.setSneak(true); 1309 } else if (packet19entityaction.animation == 2) { 1310 this.player.setSneak(false); 1311 } else if (packet19entityaction.animation == 3) { 1312 this.player.a(false, true, true); 1313 this.checkMovement = false; 1314 } 1315 } 1316 1317 public void a(Packet0KeepAlive packet0KeepAlive) { 1318 this.receivedKeepAlive = true; 1319 } 1320 1321 public void a(Packet255KickDisconnect packet255kickdisconnect) { 1322 // poseidon 1323 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet255kickdisconnect); 1324 server.getPluginManager().callEvent(event); 1325 if (event.isCancelled()) return; 1326 1327 // uberbukkit - drop item queue on disconnect 1328 if (this.networkManager.pvn <= 6) { 1329 ArrayList<ItemStack> queue = this.player.packet5.queue.dropAllQueue(); 1330 Player bukkitEntity = (Player) this.player.getBukkitEntity(); 1331 for (ItemStack item : queue) { 1332 System.out.println("Drop queue id: " + item.id + ", dmg: " + item.damage + ", cnt: " + item.count); 1333 HashMap<Integer, org.bukkit.inventory.ItemStack> map = bukkitEntity.getInventory().addItem(new CraftItemStack(item)); 1334 // drop what couldn't fit in the inventory 1335 for (org.bukkit.inventory.ItemStack stack : map.values()) { 1336 bukkitEntity.getWorld().dropItemNaturally(bukkitEntity.getLocation(), stack); 1337 } 1338 } 1339 } 1340 this.networkManager.a("disconnect.quitting", new Object[0]); 1341 } 1342 1343 public int b() { 1344 return this.networkManager.e(); 1345 } 1346 1347 public void sendMessage(String s) { 1348 this.sendPacket(new Packet3Chat("\u00A77" + s)); 1349 } 1350 1351 public String getName() { 1352 return this.player.name; 1353 } 1354 1355 public void a(Packet7UseEntity packet7useentity) { 1356 // poseidon 1357 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet7useentity); 1358 server.getPluginManager().callEvent(pevent); 1359 if (pevent.isCancelled()) return; 1360 1361 if (this.player.dead) return; // CraftBukkit 1362 1363 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); 1364 Entity entity = worldserver.getEntity(packet7useentity.target); 1365 ItemStack itemInHand = this.player.inventory.getItemInHand(); 1366 1367 if (entity != null) { 1368 1369 // uberbukkit start 1370 // backported from release 1.2, fixes mobs being unpunchable from certain positions 1371 boolean flag = this.player.e(entity); 1372 double maxRange = 36.0D; 1373 1374 if (!flag) maxRange = 9.0D; 1375 1376 if (this.player.g(entity) >= maxRange) return; 1377 1378 // uberbukkit end 1379 1380 if (packet7useentity.c == 0) { 1381 Player player = (Player) this.getPlayer(); 1382 org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); 1383 // CraftBukkit start 1384 //Project Poseidon Start - Fixes a Minecart dupe glitch 1385 if (player.isInsideVehicle() && bukkitEntity instanceof StorageMinecart) { 1386 return; 1387 } 1388 //Project Poseidon End 1389 PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, bukkitEntity); 1390 this.server.getPluginManager().callEvent(event); 1391 1392 if (event.isCancelled()) { 1393 return; 1394 } 1395 // CraftBukkit end 1396 this.player.c(entity); 1397 // CraftBukkit start - update the client if the item is an infinite one 1398 if (itemInHand != null && itemInHand.count <= -1) { 1399 this.player.updateInventory(this.player.activeContainer); 1400 } 1401 // CraftBukkit end 1402 } else if (packet7useentity.c == 1) { 1403 this.player.d(entity); 1404 // CraftBukkit start - update the client if the item is an infinite one 1405 if (itemInHand != null && itemInHand.count <= -1) { 1406 this.player.updateInventory(this.player.activeContainer); 1407 } 1408 // CraftBukkit end 1409 } 1410 } 1411 } 1412 1413 public void a(Packet9Respawn packet9respawn) { 1414 // poseidon 1415 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet9respawn); 1416 server.getPluginManager().callEvent(event); 1417 if (event.isCancelled()) return; 1418 1419 if (this.player.health <= 0) { 1420 this.player = this.minecraftServer.serverConfigurationManager.moveToWorld(this.player, 0); 1421 1422 this.getPlayer().setHandle(this.player); // CraftBukkit 1423 } 1424 } 1425 1426 public void a(Packet101CloseWindow packet101closewindow) { 1427 if (this.player.dead) return; // CraftBukkit 1428 1429 this.player.A(); 1430 } 1431 1432 public void a(Packet102WindowClick packet102windowclick) { 1433 // poseidon 1434 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet102windowclick); 1435 server.getPluginManager().callEvent(event); 1436 if (event.isCancelled()) return; 1437 1438 if (this.player.dead) return; // CraftBukkit 1439 1440 if (this.player.activeContainer.windowId == packet102windowclick.a && this.player.activeContainer.c(this.player)) { 1441 if (this.player.activeContainer.isPositioned() && !Patches.CONTAINER_DISTANCE.check(this.player, this.player.activeContainer.getPosition())) { 1442 return; 1443 } 1444 1445 ItemStack itemstack = this.player.activeContainer.a(packet102windowclick.b, packet102windowclick.c, packet102windowclick.f, this.player); 1446 1447 if (ItemStack.equals(packet102windowclick.e, itemstack)) { 1448 this.player.netServerHandler.sendPacket(new Packet106Transaction(packet102windowclick.a, packet102windowclick.d, true)); 1449 this.player.h = true; 1450 this.player.activeContainer.a(); 1451 this.player.z(); 1452 this.player.h = false; 1453 } else { 1454 this.n.put(this.player.activeContainer.windowId, packet102windowclick.d); 1455 this.player.netServerHandler.sendPacket(new Packet106Transaction(packet102windowclick.a, packet102windowclick.d, false)); 1456 this.player.activeContainer.a(this.player, false); 1457 ArrayList arraylist = new ArrayList(); 1458 1459 for (int i = 0; i < this.player.activeContainer.e.size(); ++i) { 1460 arraylist.add(((Slot) this.player.activeContainer.e.get(i)).getItem()); 1461 } 1462 1463 this.player.a(this.player.activeContainer, arraylist); 1464 } 1465 } 1466 } 1467 1468 public void a(Packet106Transaction packet106transaction) { 1469 // poseidon 1470 PacketReceivedEvent event = new PacketReceivedEvent(server.getPlayer(player), packet106transaction); 1471 server.getPluginManager().callEvent(event); 1472 if (event.isCancelled()) return; 1473 1474 if (this.player.dead) return; // CraftBukkit 1475 1476 Short oshort = (Short) this.n.get(this.player.activeContainer.windowId); 1477 1478 if (oshort != null && packet106transaction.b == oshort && this.player.activeContainer.windowId == packet106transaction.a && !this.player.activeContainer.c(this.player)) { 1479 if (this.player.activeContainer.isPositioned() && !Patches.CONTAINER_DISTANCE.check(this.player, this.player.activeContainer.getPosition())) { 1480 return; 1481 } 1482 1483 this.player.activeContainer.a(this.player, true); 1484 } 1485 } 1486 1487 public void a(Packet130UpdateSign packet130updatesign) { 1488 // poseidon 1489 PacketReceivedEvent pevent = new PacketReceivedEvent(server.getPlayer(player), packet130updatesign); 1490 server.getPluginManager().callEvent(pevent); 1491 if (pevent.isCancelled()) return; 1492 1493 if (this.player.dead) return; // CraftBukkit 1494 1495 WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); 1496 1497 if (worldserver.isLoaded(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z)) { 1498 TileEntity tileentity = worldserver.getTileEntity(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z); 1499 1500 if (tileentity instanceof TileEntitySign) { 1501 TileEntitySign tileentitysign = (TileEntitySign) tileentity; 1502 1503 if (!tileentitysign.a()) { 1504 this.minecraftServer.c("Player " + this.player.name + " just tried to change non-editable sign"); 1505 // CraftBukkit 1506 this.sendPacket(new Packet130UpdateSign(packet130updatesign.x, packet130updatesign.y, packet130updatesign.z, tileentitysign.lines)); 1507 return; 1508 } 1509 } 1510 1511 int i; 1512 int j; 1513 1514 for (j = 0; j < 4; ++j) { 1515 boolean flag = true; 1516 1517 if (packet130updatesign.lines[j].length() > 15) { 1518 flag = false; 1519 } else { 1520 for (i = 0; i < packet130updatesign.lines[j].length(); ++i) { 1521 if (FontAllowedCharacters.allowedCharacters.indexOf(packet130updatesign.lines[j].charAt(i)) < 0) { 1522 flag = false; 1523 } 1524 } 1525 } 1526 1527 if (!flag) { 1528 packet130updatesign.lines[j] = "!?"; 1529 } 1530 } 1531 1532 if (tileentity instanceof TileEntitySign) { 1533 j = packet130updatesign.x; 1534 int k = packet130updatesign.y; 1535 1536 i = packet130updatesign.z; 1537 TileEntitySign tileentitysign1 = (TileEntitySign) tileentity; 1538 1539 // CraftBukkit start 1540 Player player = this.server.getPlayer(this.player); 1541 SignChangeEvent event = new SignChangeEvent((CraftBlock) player.getWorld().getBlockAt(j, k, i), this.server.getPlayer(this.player), packet130updatesign.lines); 1542 this.server.getPluginManager().callEvent(event); 1543 1544 if (!event.isCancelled()) { 1545 for (int l = 0; l < 4; ++l) { 1546 tileentitysign1.lines[l] = event.getLine(l); 1547 } 1548 tileentitysign1.a(false); 1549 } 1550 // CraftBukkit end 1551 1552 tileentitysign1.update(); 1553 worldserver.notify(j, k, i); 1554 } 1555 } 1556 } 1557 1558 public boolean c() { 1559 return true; 1560 } 1561}