Commits
md_5 authored 02f4218da51
118 118 | |
119 119 | if (this.j > 0) { |
120 120 | --this.j; |
121 121 | } |
122 122 | |
123 123 | if (this.player.I() > 0L && this.minecraftServer.getIdleTimeout() > 0 && MinecraftServer.av() - this.player.I() > (long) (this.minecraftServer.getIdleTimeout() * 1000 * 60)) { |
124 124 | + this.player.resetIdleTimer(); // CraftBukkit - SPIGOT-854 |
125 125 | this.disconnect("You have been idle for too long!"); |
126 126 | } |
127 127 | |
128 - | |
128 + | |
129 129 | } |
130 130 | |
131 131 | public void disconnect(String s) { |
132 132 | + // CraftBukkit start - fire PlayerKickEvent |
133 + | + if (this.processedDisconnect) { |
134 + | + return; |
135 + | + } |
133 136 | + String leaveMessage = EnumChatFormat.YELLOW + this.player.getName() + " left the game."; |
134 137 | + |
135 138 | + PlayerKickEvent event = new PlayerKickEvent(this.server.getPlayer(this.player), s, leaveMessage); |
136 139 | + |
137 140 | + if (this.server.getServer().isRunning()) { |
138 141 | + this.server.getPluginManager().callEvent(event); |
139 142 | + } |
140 143 | + |
141 144 | + if (event.isCancelled()) { |
142 145 | + // Do not kick the player |
159 162 | + // CraftBukkit - Don't wait |
160 163 | + this.minecraftServer.postToMainThread(new Runnable() { |
161 164 | public void run() { |
162 165 | PlayerConnection.this.networkManager.handleDisconnection(); |
163 166 | } |
164 167 | - })); |
165 168 | + }); |
166 169 | } |
167 170 | |
168 171 | public void a(PacketPlayInSteerVehicle packetplayinsteervehicle) { |
169 - | |
172 + | |
170 173 | double d9 = entity.motX * entity.motX + entity.motY * entity.motY + entity.motZ * entity.motZ; |
171 174 | double d10 = d6 * d6 + d7 * d7 + d8 * d8; |
172 175 | |
173 176 | - if (d10 - d9 > 100.0D && (!this.minecraftServer.R() || !this.minecraftServer.Q().equals(entity.getName()))) { |
174 177 | + |
175 178 | + // CraftBukkit start - handle custom speeds and skipped ticks |
176 179 | + this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick; |
177 180 | + this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1); |
178 181 | + this.lastTick = (int) (System.currentTimeMillis() / 50); |
179 182 | + |
195 198 | + } else { |
196 199 | + speed = player.abilities.walkSpeed * 10f; |
197 200 | + } |
198 201 | + speed *= 2f; // TODO: Get the speed of the vehicle instead of the player |
199 202 | + |
200 203 | + if (d10 - d9 > Math.max(100, Math.pow((double) (10.0F * (float) i * speed), 2)) && (!this.minecraftServer.R() || !this.minecraftServer.Q().equals(entity.getName()))) { |
201 204 | + // CraftBukkit end |
202 205 | PlayerConnection.LOGGER.warn("{} (vehicle of {}) moved too quickly! {},{},{}", new Object[] { entity.getName(), this.player.getName(), Double.valueOf(d6), Double.valueOf(d7), Double.valueOf(d8)}); |
203 206 | this.networkManager.sendPacket(new PacketPlayOutVehicleMove(entity)); |
204 207 | return; |
205 - | |
208 + | |
206 209 | return; |
207 210 | } |
208 211 | |
209 212 | + // CraftBukkit start - fire PlayerMoveEvent |
210 213 | + Player player = this.getPlayer(); |
211 214 | + Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. |
212 215 | + Location to = player.getLocation().clone(); // Start off the To location as the Players current location. |
213 216 | + |
214 217 | + // If the packet contains movement information then we update the To location with the correct XYZ. |
215 218 | + to.setX(packetplayinvehiclemove.getX()); |
258 261 | + this.justTeleported = false; |
259 262 | + return; |
260 263 | + } |
261 264 | + } |
262 265 | + } |
263 266 | + // CraftBukkit end |
264 267 | + |
265 268 | this.minecraftServer.getPlayerList().d(this.player); |
266 269 | this.player.checkMovement(this.player.locX - d0, this.player.locY - d1, this.player.locZ - d2); |
267 270 | this.D = d11 >= -0.03125D && !this.minecraftServer.getAllowFlight() && !worldserver.d(entity.getBoundingBox().g(0.0625D).a(0.0D, -0.55D, 0.0D)); |
268 - | |
271 + | |
269 272 | } else { |
270 273 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
271 274 | |
272 275 | - if (!this.player.viewingCredits) { |
273 276 | + if (!this.player.viewingCredits && !this.player.dead) { // CraftBukkit - Added ' && !this.player.dead' |
274 277 | if (this.e == 0) { |
275 278 | this.d(); |
276 279 | } |
277 - | |
280 + | |
278 281 | this.A = this.e; |
279 282 | this.a(this.teleportPos.x, this.teleportPos.y, this.teleportPos.z, this.player.yaw, this.player.pitch); |
280 283 | } |
281 284 | - |
282 285 | + this.allowedPlayerTicks = 20; // CraftBukkit |
283 286 | } else { |
284 287 | this.A = this.e; |
285 288 | if (this.player.isPassenger()) { |
286 289 | this.player.setLocation(this.player.locX, this.player.locY, this.player.locZ, packetplayinflying.a(this.player.yaw), packetplayinflying.b(this.player.pitch)); |
287 290 | this.minecraftServer.getPlayerList().d(this.player); |
290 293 | + // CraftBukkit - Make sure the move is valid but then reset it for plugins to modify |
291 294 | + double prevX = player.locX; |
292 295 | + double prevY = player.locY; |
293 296 | + double prevZ = player.locZ; |
294 297 | + float prevYaw = player.yaw; |
295 298 | + float prevPitch = player.pitch; |
296 299 | + // CraftBukkit end |
297 300 | double d0 = this.player.locX; |
298 301 | double d1 = this.player.locY; |
299 302 | double d2 = this.player.locZ; |
300 - | |
303 + | |
301 304 | ++this.F; |
302 305 | int i = this.F - this.G; |
303 306 | |
304 307 | - if (i > 5) { |
305 308 | - PlayerConnection.LOGGER.debug("{} is sending move packets too frequently ({} packets since last tick)", new Object[] { this.player.getName(), Integer.valueOf(i)}); |
306 309 | + // CraftBukkit start - handle custom speeds and skipped ticks |
307 310 | + this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick; |
308 311 | + this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1); |
309 312 | + this.lastTick = (int) (System.currentTimeMillis() / 50); |
310 313 | + |
327 330 | + |
328 331 | if (!this.player.K() && (!this.player.x().getGameRules().getBoolean("disableElytraMovementCheck") || !this.player.cG())) { |
329 332 | float f2 = this.player.cG() ? 300.0F : 100.0F; |
330 333 | |
331 334 | - if (d11 - d10 > (double) (f2 * (float) i) && (!this.minecraftServer.R() || !this.minecraftServer.Q().equals(this.player.getName()))) { |
332 335 | + if (d11 - d10 > Math.max(100, Math.pow((double) (10.0F * (float) i * speed), 2)) && (!this.minecraftServer.R() || !this.minecraftServer.Q().equals(this.player.getName()))) { |
333 336 | + // CraftBukkit end |
334 337 | PlayerConnection.LOGGER.warn("{} moved too quickly! {},{},{}", new Object[] { this.player.getName(), Double.valueOf(d7), Double.valueOf(d8), Double.valueOf(d9)}); |
335 338 | this.a(this.player.locX, this.player.locY, this.player.locZ, this.player.yaw, this.player.pitch); |
336 339 | return; |
337 - | |
340 + | |
338 341 | } |
339 342 | } |
340 343 | |
341 344 | + // CraftBukkit start - fire PlayerMoveEvent |
342 345 | + // Rest to old location first |
343 346 | + this.player.setLocation(prevX, prevY, prevZ, prevYaw, prevPitch); |
344 347 | + |
345 348 | + Player player = this.getPlayer(); |
346 349 | + Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. |
347 350 | + Location to = player.getLocation().clone(); // Start off the To location as the Players current location. |
397 400 | + return; |
398 401 | + } |
399 402 | + } |
400 403 | + } |
401 404 | + this.player.setLocation(d4, d5, d6, f, f1); // Copied from above |
402 405 | + // CraftBukkit end |
403 406 | + |
404 407 | this.B = d12 >= -0.03125D; |
405 408 | this.B &= !this.minecraftServer.getAllowFlight() && !this.player.abilities.canFly; |
406 409 | this.B &= !this.player.hasEffect(MobEffects.LEVITATION) && !this.player.cG() && !worldserver.d(this.player.getBoundingBox().g(0.0625D).a(0.0D, -0.55D, 0.0D)); |
407 - | |
410 + | |
408 411 | } |
409 412 | |
410 413 | public void a(double d0, double d1, double d2, float f, float f1) { |
411 414 | - this.a(d0, d1, d2, f, f1, Collections.emptySet()); |
412 415 | + this.a(d0, d1, d2, f, f1, Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet()); |
413 416 | } |
414 417 | |
415 418 | public void a(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set) { |
416 419 | - double d3 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X) ? this.player.locX : 0.0D; |
417 420 | - double d4 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y) ? this.player.locY : 0.0D; |
451 454 | + to = event.isCancelled() ? event.getFrom() : event.getTo(); |
452 455 | + d0 = to.getX(); |
453 456 | + d1 = to.getY(); |
454 457 | + d2 = to.getZ(); |
455 458 | + f = to.getYaw(); |
456 459 | + f1 = to.getPitch(); |
457 460 | + } |
458 461 | + |
459 462 | + this.internalTeleport(d0, d1, d2, f, f1, set); |
460 463 | + } |
461 - | |
462 - | - this.teleportPos = new Vec3D(d0 + d3, d1 + d4, d2 + d5); |
464 + | + |
463 465 | + public void teleport(Location dest) { |
464 466 | + internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.emptySet()); |
465 467 | + } |
466 468 | + |
467 469 | + private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set set) { |
468 470 | + if (Float.isNaN(f)) { |
469 471 | + f = 0; |
470 472 | + } |
471 473 | + |
472 474 | + if (Float.isNaN(f1)) { |
473 475 | + f1 = 0; |
474 476 | + } |
475 477 | + this.justTeleported = true; |
476 478 | + this.teleportPos = new Vec3D(d0, d1, d2); |
477 479 | + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X)) { |
478 480 | + this.teleportPos = this.teleportPos.add(this.player.locX, 0.0D, 0.0D); |
479 481 | + } |
480 482 | + |
481 483 | + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y)) { |
482 484 | + this.teleportPos = this.teleportPos.add(0.0D, this.player.locY, 0.0D); |
483 485 | + } |
484 - | + |
486 + | |
487 + | - this.teleportPos = new Vec3D(d0 + d3, d1 + d4, d2 + d5); |
485 488 | + if (set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z)) { |
486 489 | + this.teleportPos = this.teleportPos.add(0.0D, 0.0D, this.player.locZ); |
487 490 | + } |
488 491 | + // CraftBukkit end |
489 492 | float f2 = f; |
490 493 | float f3 = f1; |
491 494 | |
492 - | |
495 + | |
493 496 | f3 = f1 + this.player.pitch; |
494 497 | } |
495 498 | |
496 499 | + // CraftBukkit start - update last location |
497 500 | + this.lastPosX = this.teleportPos.x; |
498 501 | + this.lastPosY = this.teleportPos.y; |
499 502 | + this.lastPosZ = this.teleportPos.z; |
500 503 | + this.lastYaw = f2; |
501 504 | + this.lastPitch = f3; |
502 505 | + // CraftBukkit end |
503 506 | + |
504 507 | if (++this.teleportAwait == Integer.MAX_VALUE) { |
505 508 | this.teleportAwait = 0; |
506 509 | } |
507 - | |
510 + | |
508 511 | |
509 512 | public void a(PacketPlayInBlockDig packetplayinblockdig) { |
510 513 | PlayerConnectionUtils.ensureMainThread(packetplayinblockdig, this, this.player.x()); |
511 514 | + if (this.player.dead) return; // CraftBukkit |
512 515 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
513 516 | BlockPosition blockposition = packetplayinblockdig.a(); |
514 517 | |
515 518 | this.player.resetIdleTimer(); |
516 519 | ItemStack itemstack; |
517 520 | |
565 568 | this.player.a(true); |
566 569 | } |
567 570 | |
568 571 | return; |
569 572 | |
570 573 | - case 4: |
571 574 | + case 4: // RELEASE_USE_ITEM |
572 575 | this.player.clearActiveItem(); |
573 576 | itemstack = this.player.getItemInMainHand(); |
574 577 | if (itemstack != null && itemstack.count == 0) { |
575 - | |
578 + | |
576 579 | |
577 580 | return; |
578 581 | |
579 582 | - case 5: |
580 583 | - case 6: |
581 584 | - case 7: |
582 585 | + case 5: // START_DESTROY_BLOCK |
583 586 | + case 6: // ABORT_DESTROY_BLOCK |
584 587 | + case 7: // STOP_DESTROY_BLOCK |
585 588 | double d0 = this.player.locX - ((double) blockposition.getX() + 0.5D); |
586 589 | double d1 = this.player.locY - ((double) blockposition.getY() + 0.5D) + 1.5D; |
587 590 | double d2 = this.player.locZ - ((double) blockposition.getZ() + 0.5D); |
588 - | |
591 + | |
589 592 | if (!this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { |
590 593 | this.player.playerInteractManager.a(blockposition, packetplayinblockdig.b()); |
591 594 | } else { |
592 595 | + // CraftBukkit start - fire PlayerInteractEvent |
593 596 | + CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, blockposition, packetplayinblockdig.b(), this.player.inventory.getItemInHand(), EnumHand.MAIN_HAND); |
594 597 | this.player.playerConnection.sendPacket(new PacketPlayOutBlockChange(worldserver, blockposition)); |
595 598 | + // Update any tile entity data for this block |
596 599 | + TileEntity tileentity = worldserver.getTileEntity(blockposition); |
597 600 | + if (tileentity != null) { |
598 601 | + this.player.playerConnection.sendPacket(tileentity.getUpdatePacket()); |
599 602 | + } |
600 603 | + // CraftBukkit end |
601 604 | } |
602 605 | } else { |
603 606 | if (packetplayinblockdig.c() == PacketPlayInBlockDig.EnumPlayerDigType.STOP_DESTROY_BLOCK) { |
604 - | |
607 + | |
605 608 | default: |
606 609 | throw new IllegalArgumentException("Invalid player action"); |
607 610 | } |
608 611 | + // CraftBukkit end |
609 612 | } |
610 613 | |
611 614 | public void a(PacketPlayInUseItem packetplayinuseitem) { |
612 615 | PlayerConnectionUtils.ensureMainThread(packetplayinuseitem, this, this.player.x()); |
613 616 | + if (this.player.dead) return; // CraftBukkit |
614 617 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
615 618 | EnumHand enumhand = packetplayinuseitem.c(); |
616 619 | ItemStack itemstack = this.player.b(enumhand); |
617 - | |
620 + | |
618 621 | chatmessage.getChatModifier().setColor(EnumChatFormat.RED); |
619 622 | this.player.playerConnection.sendPacket(new PacketPlayOutChat(chatmessage)); |
620 623 | } else if (this.teleportPos == null && this.player.e((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && !this.minecraftServer.a(worldserver, blockposition, this.player) && worldserver.getWorldBorder().a(blockposition)) { |
621 624 | + // CraftBukkit start - Check if we can actually do something over this large a distance |
622 625 | + Location eyeLoc = this.getPlayer().getEyeLocation(); |
623 626 | + double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ()); |
624 627 | + if (reachDistance > (this.getPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) { |
625 628 | + return; |
626 629 | + } |
627 630 | + // CraftBukkit end |
628 631 | this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand, blockposition, enumdirection, packetplayinuseitem.d(), packetplayinuseitem.e(), packetplayinuseitem.f()); |
629 632 | } |
630 633 | |
631 - | |
634 + | |
632 635 | |
633 636 | public void a(PacketPlayInBlockPlace packetplayinblockplace) { |
634 637 | PlayerConnectionUtils.ensureMainThread(packetplayinblockplace, this, this.player.x()); |
635 638 | + if (this.player.dead) return; // CraftBukkit |
636 639 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
637 640 | EnumHand enumhand = packetplayinblockplace.a(); |
638 641 | ItemStack itemstack = this.player.b(enumhand); |
639 642 | |
640 643 | this.player.resetIdleTimer(); |
641 644 | if (itemstack != null) { |
682 685 | + itemstack = this.player.b(enumhand); |
683 686 | + if (itemstack != null && itemstack.count == 0) { |
684 687 | + this.player.a(enumhand, (ItemStack) null); |
685 688 | + itemstack = null; |
686 689 | + } |
687 690 | + } |
688 691 | + // CraftBukkit end |
689 692 | } |
690 693 | } |
691 694 | |
692 - | |
695 + | |
693 696 | WorldServer[] aworldserver = this.minecraftServer.worldServer; |
694 697 | int i = aworldserver.length; |
695 698 | |
696 699 | - for (int j = 0; j < i; ++j) { |
697 700 | - WorldServer worldserver = aworldserver[j]; |
698 701 | + // CraftBukkit - use the worlds array list |
699 702 | + for (WorldServer worldserver : minecraftServer.worlds) { |
700 703 | |
701 704 | if (worldserver != null) { |
702 705 | entity = packetplayinspectate.a(worldserver); |
703 - | |
706 + | |
704 707 | if (entity != null) { |
705 708 | this.player.setSpectatorTarget(this.player); |
706 709 | this.player.stopRiding(); |
707 710 | + |
708 711 | + /* CraftBukkit start - replace with bukkit handling for multi-world |
709 712 | if (entity.world == this.player.world) { |
710 713 | this.player.enderTeleportTo(entity.locX, entity.locY, entity.locZ); |
711 714 | } else { |
712 - | |
715 + | |
713 716 | this.minecraftServer.getPlayerList().b(this.player, worldserver2); |
714 717 | this.minecraftServer.getPlayerList().updateClient(this.player); |
715 718 | } |
716 719 | + */ |
717 720 | + this.player.getBukkitEntity().teleport(entity.getBukkitEntity(), PlayerTeleportEvent.TeleportCause.SPECTATE); |
718 721 | + // CraftBukkit end |
719 722 | } |
720 723 | } |
721 724 | |
722 725 | } |
723 726 | |
724 727 | - public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) {} |
725 728 | + // CraftBukkit start |
726 729 | + public void a(PacketPlayInResourcePackStatus packetplayinresourcepackstatus) { |
727 730 | + this.server.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getPlayer(), PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.status.ordinal()])); |
728 731 | + } |
729 732 | + // CraftBukkit end |
730 733 | |
731 734 | public void a(PacketPlayInBoatMove packetplayinboatmove) { |
732 735 | PlayerConnectionUtils.ensureMainThread(packetplayinboatmove, this, this.player.x()); |
733 - | |
736 + | |
734 737 | } |
735 738 | |
736 739 | public void a(IChatBaseComponent ichatbasecomponent) { |
737 740 | - PlayerConnection.LOGGER.info("{} lost connection: {}", new Object[] { this.player.getName(), ichatbasecomponent}); |
738 741 | + // CraftBukkit start - Rarely it would send a disconnect line twice |
739 742 | + if (this.processedDisconnect) { |
740 743 | + return; |
741 744 | + } else { |
742 745 | + this.processedDisconnect = true; |
743 746 | + } |
755 758 | this.player.t(); |
756 759 | - this.minecraftServer.getPlayerList().disconnect(this.player); |
757 760 | + String quitMessage = this.minecraftServer.getPlayerList().disconnect(this.player); |
758 761 | + if ((quitMessage != null) && (quitMessage.length() > 0)) { |
759 762 | + this.minecraftServer.getPlayerList().sendMessage(CraftChatMessage.fromString(quitMessage)); |
760 763 | + } |
761 764 | + // CraftBukkit end |
762 765 | if (this.minecraftServer.R() && this.player.getName().equals(this.minecraftServer.Q())) { |
763 766 | PlayerConnection.LOGGER.info("Stopping singleplayer server as player logged out"); |
764 767 | this.minecraftServer.safeShutdown(); |
765 - | |
768 + | |
766 769 | } |
767 770 | } |
768 771 | |
769 772 | + // CraftBukkit start |
770 773 | + if (packet == null) { |
771 774 | + return; |
772 775 | + } else if (packet instanceof PacketPlayOutSpawnPosition) { |
773 776 | + PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet; |
774 777 | + this.player.compassTarget = new Location(this.getPlayer().getWorld(), packet6.position.getX(), packet6.position.getY(), packet6.position.getZ()); |
775 778 | + } |
776 779 | + // CraftBukkit end |
777 780 | + |
778 781 | try { |
779 782 | this.networkManager.sendPacket(packet); |
780 783 | } catch (Throwable throwable) { |
781 - | |
784 + | |
782 785 | |
783 786 | public void a(PacketPlayInHeldItemSlot packetplayinhelditemslot) { |
784 787 | PlayerConnectionUtils.ensureMainThread(packetplayinhelditemslot, this, this.player.x()); |
785 788 | + if (this.player.dead) return; // CraftBukkit |
786 789 | if (packetplayinhelditemslot.a() >= 0 && packetplayinhelditemslot.a() < PlayerInventory.getHotbarSize()) { |
787 790 | + PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayer(), this.player.inventory.itemInHandIndex, packetplayinhelditemslot.a()); |
788 791 | + this.server.getPluginManager().callEvent(event); |
789 792 | + if (event.isCancelled()) { |
790 793 | + this.sendPacket(new PacketPlayOutHeldItemSlot(this.player.inventory.itemInHandIndex)); |
791 794 | + this.player.resetIdleTimer(); |
806 809 | + // CraftBukkit start - async chat |
807 810 | + boolean isSync = packetplayinchat.a().startsWith("/"); |
808 811 | + if (packetplayinchat.a().startsWith("/")) { |
809 812 | + PlayerConnectionUtils.ensureMainThread(packetplayinchat, this, this.player.x()); |
810 813 | + } |
811 814 | + // CraftBukkit end |
812 815 | + if (this.player.dead || this.player.getChatFlags() == EntityHuman.EnumChatVisibility.HIDDEN) { // CraftBukkit - dead men tell no tales |
813 816 | ChatMessage chatmessage = new ChatMessage("chat.cannotSend", new Object[0]); |
814 817 | |
815 818 | chatmessage.getChatModifier().setColor(EnumChatFormat.RED); |
816 - | |
819 + | |
817 820 | |
818 821 | for (int i = 0; i < s.length(); ++i) { |
819 822 | if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) { |
820 823 | - this.disconnect("Illegal characters in chat"); |
821 824 | + // CraftBukkit start - threadsafety |
822 825 | + if (!isSync) { |
823 826 | + Waitable waitable = new Waitable() { |
824 827 | + @Override |
825 828 | + protected Object evaluate() { |
826 829 | + PlayerConnection.this.disconnect("Illegal characters in chat"); |
1064 1067 | + |
1065 1068 | + if (e2.isCancelled()) { |
1066 1069 | + return; |
1067 1070 | + } |
1068 1071 | + break; |
1069 1072 | + } |
1070 1073 | + // CraftBukkit end |
1071 1074 | this.player.resetIdleTimer(); |
1072 1075 | IJumpable ijumpable; |
1073 1076 | |
1074 - | |
1077 + | |
1075 1078 | |
1076 1079 | public void a(PacketPlayInUseEntity packetplayinuseentity) { |
1077 1080 | PlayerConnectionUtils.ensureMainThread(packetplayinuseentity, this, this.player.x()); |
1078 1081 | + if (this.player.dead) return; // CraftBukkit |
1079 1082 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
1080 1083 | Entity entity = packetplayinuseentity.a((World) worldserver); |
1081 1084 | |
1082 - | |
1085 + | |
1083 1086 | EnumHand enumhand; |
1084 1087 | ItemStack itemstack; |
1085 1088 | |
1086 1089 | + ItemStack itemInHand = this.player.b(packetplayinuseentity.b() == null ? EnumHand.MAIN_HAND : packetplayinuseentity.b()); // CraftBukkit |
1087 1090 | + |
1088 1091 | + if (packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT |
1089 1092 | + || packetplayinuseentity.a() == PacketPlayInUseEntity.EnumEntityUseAction.INTERACT_AT) { |
1090 1093 | + // CraftBukkit start |
1091 1094 | + boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof EntityInsentient; |
1092 1095 | + Item origItem = this.player.inventory.getItemInHand() == null ? null : this.player.inventory.getItemInHand().getItem(); |
1146 1149 | this.player.attack(entity); |
1147 1150 | + |
1148 1151 | + // CraftBukkit start |
1149 1152 | + if (itemInHand != null && itemInHand.count <= -1) { |
1150 1153 | + this.player.updateInventory(this.player.activeContainer); |
1151 1154 | + } |
1152 1155 | + // CraftBukkit end |
1153 1156 | } |
1154 1157 | } |
1155 1158 | } |
1156 - | |
1159 + | |
1157 1160 | case 1: |
1158 1161 | if (this.player.viewingCredits) { |
1159 1162 | this.player.viewingCredits = false; |
1160 1163 | - this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true); |
1161 1164 | + // this.player = this.minecraftServer.getPlayerList().moveToWorld(this.player, 0, true); |
1162 1165 | + this.minecraftServer.getPlayerList().changeDimension(this.player, 0, PlayerTeleportEvent.TeleportCause.END_PORTAL); // CraftBukkit - reroute logic through custom portal management |
1163 1166 | } else { |
1164 1167 | if (this.player.getHealth() > 0.0F) { |
1165 1168 | return; |
1166 - | |
1169 + | |
1167 1170 | |
1168 1171 | public void a(PacketPlayInCloseWindow packetplayinclosewindow) { |
1169 1172 | PlayerConnectionUtils.ensureMainThread(packetplayinclosewindow, this, this.player.x()); |
1170 1173 | + |
1171 1174 | + if (this.player.dead) return; // CraftBukkit |
1172 1175 | + CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit |
1173 1176 | + |
1174 1177 | this.player.s(); |
1175 1178 | } |
1176 1179 | |
1177 1180 | public void a(PacketPlayInWindowClick packetplayinwindowclick) { |
1178 1181 | PlayerConnectionUtils.ensureMainThread(packetplayinwindowclick, this, this.player.x()); |
1179 1182 | + if (this.player.dead) return; // CraftBukkit |
1180 1183 | this.player.resetIdleTimer(); |
1181 1184 | if (this.player.activeContainer.windowId == packetplayinwindowclick.a() && this.player.activeContainer.c(this.player)) { |
1182 1185 | - if (this.player.isSpectator()) { |
1183 1186 | + boolean cancelled = this.player.isSpectator(); // CraftBukkit - see below if |
1184 1187 | + if (false/*this.player.isSpectator()*/) { // CraftBukkit |
1185 1188 | ArrayList arraylist = Lists.newArrayList(); |
1186 1189 | |
1187 1190 | for (int i = 0; i < this.player.activeContainer.c.size(); ++i) { |
1188 - | |
1191 + | |
1189 1192 | |
1190 1193 | this.player.a(this.player.activeContainer, (List) arraylist); |
1191 1194 | } else { |
1192 1195 | - ItemStack itemstack = this.player.activeContainer.a(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); |
1193 1196 | + // CraftBukkit start - Call InventoryClickEvent |
1194 1197 | + if (packetplayinwindowclick.b() < -1 && packetplayinwindowclick.b() != -999) { |
1195 1198 | + return; |
1196 1199 | + } |
1197 1200 | + |
1198 1201 | + InventoryView inventory = this.player.activeContainer.getBukkitView(); |
1199 1202 | + SlotType type = CraftInventoryView.getSlotType(inventory, packetplayinwindowclick.b()); |
1200 - | |
1203 + | + |
1201 1204 | + InventoryClickEvent event; |
1202 1205 | + ClickType click = ClickType.UNKNOWN; |
1203 1206 | + InventoryAction action = InventoryAction.UNKNOWN; |
1204 1207 | + |
1205 1208 | + ItemStack itemstack = null; |
1206 1209 | + |
1207 1210 | + switch (packetplayinwindowclick.f()) { |
1208 1211 | + case PICKUP: |
1209 1212 | + if (packetplayinwindowclick.c() == 0) { |
1210 1213 | + click = ClickType.LEFT; |
1385 1388 | + if (packetplayinwindowclick.b() == 0 && top instanceof CraftingInventory) { |
1386 1389 | + org.bukkit.inventory.Recipe recipe = ((CraftingInventory) top).getRecipe(); |
1387 1390 | + if (recipe != null) { |
1388 1391 | + if (click == ClickType.NUMBER_KEY) { |
1389 1392 | + event = new CraftItemEvent(recipe, inventory, type, packetplayinwindowclick.b(), click, action, packetplayinwindowclick.c()); |
1390 1393 | + } else { |
1391 1394 | + event = new CraftItemEvent(recipe, inventory, type, packetplayinwindowclick.b(), click, action); |
1392 1395 | + } |
1393 1396 | + } |
1394 1397 | + } |
1395 - | + |
1398 + | |
1396 1399 | + event.setCancelled(cancelled); |
1397 1400 | + server.getPluginManager().callEvent(event); |
1398 1401 | + |
1399 1402 | + switch (event.getResult()) { |
1400 1403 | + case ALLOW: |
1401 1404 | + case DEFAULT: |
1402 1405 | + itemstack = this.player.activeContainer.a(packetplayinwindowclick.b(), packetplayinwindowclick.c(), packetplayinwindowclick.f(), this.player); |
1403 1406 | + break; |
1404 1407 | + case DENY: |
1405 1408 | + /* Needs enum constructor in InventoryAction |
1455 1458 | + if (event instanceof CraftItemEvent) { |
1456 1459 | + // Need to update the inventory on crafting to |
1457 1460 | + // correctly support custom recipes |
1458 1461 | + player.updateInventory(player.activeContainer); |
1459 1462 | + } |
1460 1463 | + } |
1461 1464 | + // CraftBukkit end |
1462 1465 | if (ItemStack.matches(packetplayinwindowclick.e(), itemstack)) { |
1463 1466 | this.player.playerConnection.sendPacket(new PacketPlayOutTransaction(packetplayinwindowclick.a(), packetplayinwindowclick.d(), true)); |
1464 1467 | this.player.f = true; |
1465 - | |
1468 + | |
1466 1469 | |
1467 1470 | public void a(PacketPlayInEnchantItem packetplayinenchantitem) { |
1468 1471 | PlayerConnectionUtils.ensureMainThread(packetplayinenchantitem, this, this.player.x()); |
1469 1472 | + if (this.player.dead) return; // CraftBukkit |
1470 1473 | this.player.resetIdleTimer(); |
1471 1474 | if (this.player.activeContainer.windowId == packetplayinenchantitem.a() && this.player.activeContainer.c(this.player) && !this.player.isSpectator()) { |
1472 1475 | this.player.activeContainer.a(this.player, packetplayinenchantitem.b()); |
1473 - | |
1476 + | |
1474 1477 | } |
1475 1478 | |
1476 1479 | boolean flag1 = packetplayinsetcreativeslot.a() >= 1 && packetplayinsetcreativeslot.a() <= 45; |
1477 1480 | - boolean flag2 = itemstack == null || itemstack.getItem() != null; |
1478 1481 | + // CraftBukkit - Add invalidItems check |
1479 1482 | + boolean flag2 = itemstack == null || itemstack.getItem() != null && !invalidItems.contains(Item.getId(itemstack.getItem())); |
1480 1483 | boolean flag3 = itemstack == null || itemstack.getData() >= 0 && itemstack.count <= 64 && itemstack.count > 0; |
1481 1484 | + // CraftBukkit start - Call click event |
1482 1485 | + if (flag || (flag1 && !ItemStack.matches(this.player.defaultContainer.getSlot(packetplayinsetcreativeslot.a()).getItem(), packetplayinsetcreativeslot.getItemStack()))) { // Insist on valid slot |
1483 1486 | + |
1513 1516 | + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(this.player.defaultContainer.windowId, packetplayinsetcreativeslot.a(), this.player.defaultContainer.getSlot(packetplayinsetcreativeslot.a()).getItem())); |
1514 1517 | + this.player.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, null)); |
1515 1518 | + } |
1516 1519 | + return; |
1517 1520 | + } |
1518 1521 | + } |
1519 1522 | + // CraftBukkit end |
1520 1523 | |
1521 1524 | if (flag1 && flag2 && flag3) { |
1522 1525 | if (itemstack == null) { |
1523 - | |
1526 + | |
1524 1527 | |
1525 1528 | public void a(PacketPlayInTransaction packetplayintransaction) { |
1526 1529 | PlayerConnectionUtils.ensureMainThread(packetplayintransaction, this, this.player.x()); |
1527 1530 | + if (this.player.dead) return; // CraftBukkit |
1528 1531 | Short oshort = (Short) this.k.get(this.player.activeContainer.windowId); |
1529 1532 | |
1530 1533 | if (oshort != null && packetplayintransaction.b() == oshort.shortValue() && this.player.activeContainer.windowId == packetplayintransaction.a() && !this.player.activeContainer.c(this.player) && !this.player.isSpectator()) { |
1531 - | |
1534 + | |
1532 1535 | |
1533 1536 | public void a(PacketPlayInUpdateSign packetplayinupdatesign) { |
1534 1537 | PlayerConnectionUtils.ensureMainThread(packetplayinupdatesign, this, this.player.x()); |
1535 1538 | + if (this.player.dead) return; // CraftBukkit |
1536 1539 | this.player.resetIdleTimer(); |
1537 1540 | WorldServer worldserver = this.minecraftServer.getWorldServer(this.player.dimension); |
1538 1541 | BlockPosition blockposition = packetplayinupdatesign.a(); |
1539 - | |
1542 + | |
1540 1543 | |
1541 1544 | if (!tileentitysign.d() || tileentitysign.e() != this.player) { |
1542 1545 | this.minecraftServer.warning("Player " + this.player.getName() + " just tried to change non-editable sign"); |
1543 1546 | + this.sendPacket(tileentity.getUpdatePacket()); // CraftBukkit |
1544 1547 | return; |
1545 1548 | } |
1546 1549 | |
1547 1550 | String[] astring = packetplayinupdatesign.b(); |
1548 1551 | |
1549 1552 | + // CraftBukkit start |
1561 1564 | + this.server.getPluginManager().callEvent(event); |
1562 1565 | + |
1563 1566 | + if (!event.isCancelled()) { |
1564 1567 | + System.arraycopy(org.bukkit.craftbukkit.block.CraftSign.sanitizeLines(event.getLines()), 0, tileentitysign.lines, 0, 4); |
1565 1568 | + tileentitysign.isEditable = false; |
1566 1569 | + } |
1567 1570 | + // CraftBukkit end |
1568 1571 | |
1569 1572 | tileentitysign.update(); |
1570 1573 | worldserver.notify(blockposition, iblockdata, iblockdata, 3); |
1571 - | |
1574 + | |
1572 1575 | |
1573 1576 | public void a(PacketPlayInAbilities packetplayinabilities) { |
1574 1577 | PlayerConnectionUtils.ensureMainThread(packetplayinabilities, this, this.player.x()); |
1575 1578 | - this.player.abilities.isFlying = packetplayinabilities.isFlying() && this.player.abilities.canFly; |
1576 1579 | + // CraftBukkit start |
1577 1580 | + if (this.player.abilities.canFly && this.player.abilities.isFlying != packetplayinabilities.isFlying()) { |
1578 1581 | + PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.server.getPlayer(this.player), packetplayinabilities.isFlying()); |
1579 1582 | + this.server.getPluginManager().callEvent(event); |
1580 1583 | + if (!event.isCancelled()) { |
1581 1584 | + this.player.abilities.isFlying = packetplayinabilities.isFlying(); // Actually set the player's flying status |
1590 1593 | PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.x()); |
1591 1594 | + // CraftBukkit start |
1592 1595 | + if (chatSpamField.addAndGet(this, 10) > 500 && !this.minecraftServer.getPlayerList().isOp(this.player.getProfile())) { |
1593 1596 | + this.disconnect("disconnect.spam"); |
1594 1597 | + return; |
1595 1598 | + } |
1596 1599 | + // CraftBukkit end |
1597 1600 | ArrayList arraylist = Lists.newArrayList(); |
1598 1601 | Iterator iterator = this.minecraftServer.tabCompleteCommand(this.player, packetplayintabcomplete.a(), packetplayintabcomplete.b(), packetplayintabcomplete.c()).iterator(); |
1599 1602 | |
1600 - | |
1603 + | |
1601 1604 | } |
1602 1605 | |
1603 1606 | if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack.getItem() == itemstack1.getItem()) { |
1604 1607 | + itemstack1 = new ItemStack(Items.WRITABLE_BOOK); // CraftBukkit |
1605 1608 | itemstack1.a("pages", (NBTBase) itemstack.getTag().getList("pages", 8)); |
1606 1609 | + CraftEventFactory.handleEditBookEvent(player, itemstack1); // CraftBukkit |
1607 1610 | } |
1608 1611 | } catch (Exception exception) { |
1609 1612 | PlayerConnection.LOGGER.error("Couldn\'t handle book info", exception); |
1610 1613 | + this.disconnect("Invalid book data!"); // CraftBukkit |
1611 1614 | } |
1612 1615 | } else { |
1613 1616 | String s1; |
1614 - | |
1617 + | |
1615 1618 | } |
1616 1619 | |
1617 1620 | if (itemstack.getItem() == Items.WRITABLE_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) { |
1618 1621 | + itemstack1 = new ItemStack(Items.WRITABLE_BOOK); // CraftBukkit |
1619 1622 | itemstack1.a("author", (NBTBase) (new NBTTagString(this.player.getName()))); |
1620 1623 | itemstack1.a("title", (NBTBase) (new NBTTagString(itemstack.getTag().getString("title")))); |
1621 1624 | NBTTagList nbttaglist = itemstack.getTag().getList("pages", 8); |
1622 - | |
1625 + | |
1623 1626 | |
1624 1627 | itemstack1.a("pages", (NBTBase) nbttaglist); |
1625 1628 | itemstack1.setItem(Items.WRITTEN_BOOK); |
1626 1629 | + CraftEventFactory.handleEditBookEvent(player, itemstack1); // CraftBukkit |
1627 1630 | } |
1628 1631 | } catch (Exception exception1) { |
1629 1632 | PlayerConnection.LOGGER.error("Couldn\'t sign book", exception1); |
1630 1633 | + this.disconnect("Invalid book data!"); // CraftBukkit |
1631 1634 | } |
1632 1635 | } else if ("MC|TrSel".equals(s)) { |
1633 1636 | try { |
1634 - | |
1637 + | |
1635 1638 | } |
1636 1639 | } catch (Exception exception2) { |
1637 1640 | PlayerConnection.LOGGER.error("Couldn\'t select trade", exception2); |
1638 1641 | + this.disconnect("Invalid trade data!"); // CraftBukkit |
1639 1642 | } |
1640 1643 | } else { |
1641 1644 | TileEntity tileentity; |
1642 - | |
1645 + | |
1643 1646 | } |
1644 1647 | } catch (Exception exception3) { |
1645 1648 | PlayerConnection.LOGGER.error("Couldn\'t set command block", exception3); |
1646 1649 | + this.disconnect("Invalid command data!"); // CraftBukkit |
1647 1650 | } |
1648 1651 | } else if ("MC|AutoCmd".equals(s)) { |
1649 1652 | if (!this.minecraftServer.getEnableCommandBlock()) { |
1650 - | |
1653 + | |
1651 1654 | } |
1652 1655 | } catch (Exception exception4) { |
1653 1656 | PlayerConnection.LOGGER.error("Couldn\'t set command block", exception4); |
1654 1657 | + this.disconnect("Invalid command data!"); // CraftBukkit |
1655 1658 | } |
1656 1659 | } else { |
1657 1660 | int k; |
1658 - | |
1661 + | |
1659 1662 | } |
1660 1663 | } catch (Exception exception5) { |
1661 1664 | PlayerConnection.LOGGER.error("Couldn\'t set beacon", exception5); |
1662 1665 | + this.disconnect("Invalid beacon data!"); // CraftBukkit |
1663 1666 | } |
1664 1667 | } |
1665 1668 | } else if ("MC|ItemName".equals(s)) { |
1666 - | |
1669 + | |
1667 1670 | } |
1668 1671 | } catch (Exception exception6) { |
1669 1672 | PlayerConnection.LOGGER.error("Couldn\'t set structure block", exception6); |
1670 1673 | + this.disconnect("Invalid structure data!"); // CraftBukkit |
1671 1674 | } |
1672 1675 | } else if ("MC|PickItem".equals(s)) { |
1673 1676 | packetdataserializer = packetplayincustompayload.b(); |
1674 - | |
1677 + | |
1675 1678 | this.player.playerConnection.sendPacket(new PacketPlayOutHeldItemSlot(this.player.inventory.itemInHandIndex)); |
1676 1679 | } catch (Exception exception7) { |
1677 1680 | PlayerConnection.LOGGER.error("Couldn\'t pick item", exception7); |
1678 1681 | + this.disconnect("Invalid item data!"); // CraftBukkit |
1679 1682 | + } |
1680 1683 | + } |
1681 1684 | + // CraftBukkit start |
1682 1685 | + else if (packetplayincustompayload.a().equals("REGISTER")) { |
1683 1686 | + String channels = packetplayincustompayload.b().toString(com.google.common.base.Charsets.UTF_8); |
1684 1687 | + for (String channel : channels.split("\0")) { |