Commits
Christopher Bohn authored and md_5 committed eb7a2dcc515
337 337 | |
338 338 | if (stringreader.canRead() && stringreader.peek() == '/') { |
339 339 | |
340 340 | ParseResults<CommandListenerWrapper> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack()); |
341 341 | |
342 342 | this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> { |
343 343 | + if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer |
344 344 | this.connection.send(new PacketPlayOutTabComplete(packetplayintabcomplete.getId(), suggestions)); |
345 345 | }); |
346 346 | } |
347 - | |
347 + | |
348 348 | |
349 349 | if (container instanceof ContainerMerchant) { |
350 350 | ContainerMerchant containermerchant = (ContainerMerchant) container; |
351 - | + CraftEventFactory.callTradeSelectEvent(this.player, i, containermerchant); // CraftBukkit |
351 + | + // CraftBukkit start |
352 + | + final org.bukkit.event.inventory.TradeSelectEvent tradeSelectEvent = CraftEventFactory.callTradeSelectEvent(this.player, i, containermerchant); |
353 + | + if (tradeSelectEvent.isCancelled()) { |
354 + | + this.player.getBukkitEntity().updateInventory(); |
355 + | + return; |
356 + | + } |
357 + | + // CraftBukkit end |
352 358 | |
353 359 | containermerchant.setSelectionHint(i); |
354 360 | containermerchant.tryMoveItems(i); |
355 - | |
361 + | |
356 362 | |
357 363 | @Override |
358 364 | public void handleEditBook(PacketPlayInBEdit packetplayinbedit) { |
359 365 | + // CraftBukkit start |
360 366 | + if (this.lastBookTick + 20 > MinecraftServer.currentTick) { |
361 367 | + this.disconnect("Book edited too quickly!"); |
362 368 | + return; |
363 369 | + } |
364 370 | + this.lastBookTick = MinecraftServer.currentTick; |
365 371 | + // CraftBukkit end |
366 372 | int i = packetplayinbedit.getSlot(); |
367 373 | |
368 374 | if (PlayerInventory.isHotbarSlot(i) || i == 40) { |
369 - | |
375 + | |
370 376 | |
371 377 | Objects.requireNonNull(list); |
372 378 | optional.ifPresent(list::add); |
373 379 | - Stream stream = packetplayinbedit.getPages().stream().limit(100L); |
374 380 | + Stream<String> stream = packetplayinbedit.getPages().stream().limit(100L); // CraftBukkit - decompile error |
375 381 | |
376 382 | Objects.requireNonNull(list); |
377 383 | stream.forEach(list::add); |
378 - | |
384 + | |
379 385 | ItemStack itemstack = this.player.getInventory().getItem(i); |
380 386 | |
381 387 | if (itemstack.is(Items.WRITABLE_BOOK)) { |
382 388 | - this.updateBookPages(list, UnaryOperator.identity(), itemstack); |
383 389 | + this.updateBookPages(list, UnaryOperator.identity(), itemstack.copy(), i, itemstack); // CraftBukkit |
384 390 | } |
385 391 | } |
386 392 | |
387 - | |
393 + | |
388 394 | |
389 395 | this.updateBookPages(list, (s) -> { |
390 396 | return IChatBaseComponent.ChatSerializer.toJson(new ChatComponentText(s)); |
391 397 | - }, itemstack1); |
392 398 | - this.player.getInventory().setItem(i, itemstack1); |
393 399 | + }, itemstack1, i, itemstack); // CraftBukkit |
394 400 | + this.player.getInventory().setItem(i, itemstack); // CraftBukkit - event factory updates the hand book |
395 401 | } |
396 402 | } |
397 403 | |
398 404 | - private void updateBookPages(List<ITextFilter.a> list, UnaryOperator<String> unaryoperator, ItemStack itemstack) { |
399 405 | + private void updateBookPages(List<ITextFilter.a> list, UnaryOperator<String> unaryoperator, ItemStack itemstack, int slot, ItemStack handItem) { // CraftBukkit |
400 406 | NBTTagList nbttaglist = new NBTTagList(); |
401 407 | |
402 408 | if (this.player.isTextFilteringEnabled()) { |
403 409 | - Stream stream = list.stream().map((itextfilter_a) -> { |
404 410 | + Stream<NBTTagString> stream = list.stream().map((itextfilter_a) -> { // CraftBukkit - decompile error |
405 411 | return NBTTagString.valueOf((String) unaryoperator.apply(itextfilter_a.getFiltered())); |
406 412 | }); |
407 413 | |
408 - | |
414 + | |
409 415 | } |
410 416 | |
411 417 | itemstack.addTagElement("pages", nbttaglist); |
412 418 | + CraftEventFactory.handleEditBookEvent(player, slot, handItem, itemstack); // CraftBukkit |
413 419 | } |
414 420 | |
415 421 | @Override |
416 - | |
422 + | |
417 423 | } else { |
418 424 | WorldServer worldserver = this.player.getLevel(); |
419 425 | |
420 426 | - if (!this.player.wonGame) { |
421 427 | + if (!this.player.wonGame && !this.player.isImmobile()) { // CraftBukkit |
422 428 | if (this.tickCount == 0) { |
423 429 | this.resetPosition(); |
424 430 | } |
425 - | |
431 + | |
426 432 | this.awaitingTeleportTime = this.tickCount; |
427 433 | this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot()); |
428 434 | } |
429 435 | - |
430 436 | + this.allowedPlayerTicks = 20; // CraftBukkit |
431 437 | } else { |
432 438 | this.awaitingTeleportTime = this.tickCount; |
433 439 | double d0 = clampHorizontal(packetplayinflying.getX(this.player.getX())); |
434 - | |
440 + | |
435 441 | if (this.player.isPassenger()) { |
436 442 | this.player.absMoveTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1); |
437 443 | this.player.getLevel().getChunkSource().move(this.player); |
438 444 | + this.allowedPlayerTicks = 20; // CraftBukkit |
439 445 | } else { |
440 446 | + // CraftBukkit - Make sure the move is valid but then reset it for plugins to modify |
441 447 | + double prevX = player.getX(); |
442 448 | + double prevY = player.getY(); |
443 449 | + double prevZ = player.getZ(); |
444 450 | + float prevYaw = player.getYRot(); |
445 451 | + float prevPitch = player.getXRot(); |
446 452 | + // CraftBukkit end |
447 453 | double d3 = this.player.getX(); |
448 454 | double d4 = this.player.getY(); |
449 455 | double d5 = this.player.getZ(); |
450 - | |
456 + | |
451 457 | ++this.receivedMovePacketCount; |
452 458 | int i = this.receivedMovePacketCount - this.knownMovePacketCount; |
453 459 | |
454 460 | - if (i > 5) { |
455 461 | + // CraftBukkit start - handle custom speeds and skipped ticks |
456 462 | + this.allowedPlayerTicks += (System.currentTimeMillis() / 50) - this.lastTick; |
457 463 | + this.allowedPlayerTicks = Math.max(this.allowedPlayerTicks, 1); |
458 464 | + this.lastTick = (int) (System.currentTimeMillis() / 50); |
459 465 | + |
460 466 | + if (i > Math.max(this.allowedPlayerTicks, 5)) { |
476 482 | + |
477 483 | if (!this.player.isChangingDimension() && (!this.player.getLevel().getGameRules().getBoolean(GameRules.RULE_DISABLE_ELYTRA_MOVEMENT_CHECK) || !this.player.isFallFlying())) { |
478 484 | float f2 = this.player.isFallFlying() ? 300.0F : 100.0F; |
479 485 | |
480 486 | - if (d11 - d10 > (double) (f2 * (float) i) && !this.isSingleplayerOwner()) { |
481 487 | + if (d11 - d10 > Math.max(f2, Math.pow((double) (10.0F * (float) i * speed), 2)) && !this.isSingleplayerOwner()) { |
482 488 | + // CraftBukkit end |
483 489 | PlayerConnection.LOGGER.warn("{} moved too quickly! {},{},{}", this.player.getName().getString(), d7, d8, d9); |
484 490 | this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot()); |
485 491 | return; |
486 - | |
492 + | |
487 493 | } |
488 494 | |
489 495 | this.player.move(EnumMoveType.PLAYER, new Vec3D(d7, d8, d9)); |
490 496 | + this.player.onGround = packetplayinflying.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move |
491 497 | double d12 = d8; |
492 498 | |
493 499 | d7 = d0 - this.player.getX(); |
494 - | |
500 + | |
495 501 | if (!this.player.noPhysics && !this.player.isSleeping() && (flag1 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb))) { |
496 502 | this.teleport(d3, d4, d5, f, f1); |
497 503 | } else { |
498 504 | - this.clientIsFloating = d12 >= -0.03125D && this.player.gameMode.getGameModeForPlayer() != EnumGamemode.SPECTATOR && !this.server.isFlightAllowed() && !this.player.getAbilities().mayfly && !this.player.hasEffect(MobEffects.LEVITATION) && !this.player.isFallFlying() && this.noBlocksAround(this.player); |
499 505 | + // CraftBukkit start - fire PlayerMoveEvent |
500 506 | + // Rest to old location first |
501 507 | + this.player.absMoveTo(prevX, prevY, prevZ, prevYaw, prevPitch); |
502 508 | + |
503 509 | + Player player = this.getCraftPlayer(); |
504 510 | + Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. |
557 563 | + } |
558 564 | + } |
559 565 | + this.player.absMoveTo(d0, d1, d2, f, f1); // Copied from above |
560 566 | + |
561 567 | + // MC-135989, SPIGOT-5564: isRiptiding |
562 568 | + this.clientIsFloating = d12 >= -0.03125D && this.player.gameMode.getGameModeForPlayer() != EnumGamemode.SPECTATOR && !this.server.isFlightAllowed() && !this.player.getAbilities().mayfly && !this.player.hasEffect(MobEffects.LEVITATION) && !this.player.isFallFlying() && this.noBlocksAround(this.player) && !this.player.isAutoSpinAttack(); |
563 569 | + // CraftBukkit end |
564 570 | this.player.getLevel().getChunkSource().move(this.player); |
565 571 | this.player.doCheckFallDamage(this.player.getY() - d6, packetplayinflying.isOnGround()); |
566 572 | this.player.setOnGround(packetplayinflying.isOnGround()); |
567 - | |
573 + | |
568 574 | return true; |
569 575 | } |
570 576 | |
571 577 | + // CraftBukkit start - Delegate to teleport(Location) |
572 578 | public void dismount(double d0, double d1, double d2, float f, float f1) { |
573 579 | - this.teleport(d0, d1, d2, f, f1, Collections.emptySet(), true); |
574 580 | + this.dismount(d0, d1, d2, f, f1, PlayerTeleportEvent.TeleportCause.UNKNOWN); |
575 581 | + } |
576 582 | + |
577 583 | + public void dismount(double d0, double d1, double d2, float f, float f1, PlayerTeleportEvent.TeleportCause cause) { |
583 589 | + this.teleport(d0, d1, d2, f, f1, PlayerTeleportEvent.TeleportCause.UNKNOWN); |
584 590 | + } |
585 591 | + |
586 592 | + public void teleport(double d0, double d1, double d2, float f, float f1, PlayerTeleportEvent.TeleportCause cause) { |
587 593 | + this.teleport(d0, d1, d2, f, f1, Collections.emptySet(), false, cause); |
588 594 | } |
589 595 | |
590 596 | public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set) { |
591 597 | - this.teleport(d0, d1, d2, f, f1, set, false); |
592 598 | + this.teleport(d0, d1, d2, f, f1, set, PlayerTeleportEvent.TeleportCause.UNKNOWN); |
593 - | } |
594 - | |
595 - | - public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag) { |
599 + | + } |
600 + | + |
596 601 | + public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, PlayerTeleportEvent.TeleportCause cause) { |
597 602 | + this.teleport(d0, d1, d2, f, f1, set, false, cause); |
598 603 | + } |
599 604 | + |
600 605 | + public boolean teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag, PlayerTeleportEvent.TeleportCause cause) { // CraftBukkit - Return event status |
601 606 | + Player player = this.getCraftPlayer(); |
602 607 | + Location from = player.getLocation(); |
603 608 | + |
604 609 | + double x = d0; |
605 610 | + double y = d1; |
622 627 | + to = event.isCancelled() ? event.getFrom() : event.getTo(); |
623 628 | + d0 = to.getX(); |
624 629 | + d1 = to.getY(); |
625 630 | + d2 = to.getZ(); |
626 631 | + f = to.getYaw(); |
627 632 | + f1 = to.getPitch(); |
628 633 | + } |
629 634 | + |
630 635 | + this.internalTeleport(d0, d1, d2, f, f1, set, flag); |
631 636 | + return event.isCancelled(); // CraftBukkit - Return event status |
632 - | + } |
633 - | + |
637 + | } |
638 + | |
639 + | - public void teleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag) { |
634 640 | + public void teleport(Location dest) { |
635 641 | + internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.<PacketPlayOutPosition.EnumPlayerTeleportFlags>emptySet(), true); |
636 642 | + } |
637 643 | + |
638 644 | + private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<PacketPlayOutPosition.EnumPlayerTeleportFlags> set, boolean flag) { |
639 645 | + // CraftBukkit start |
640 646 | + if (Float.isNaN(f)) { |
641 647 | + f = 0; |
642 648 | + } |
643 649 | + if (Float.isNaN(f1)) { |
644 650 | + f1 = 0; |
645 651 | + } |
646 652 | + |
647 653 | + this.justTeleported = true; |
648 654 | + // CraftBukkit end |
649 655 | double d3 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.X) ? this.player.getX() : 0.0D; |
650 656 | double d4 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Y) ? this.player.getY() : 0.0D; |
651 657 | double d5 = set.contains(PacketPlayOutPosition.EnumPlayerTeleportFlags.Z) ? this.player.getZ() : 0.0D; |
652 - | |
658 + | |
653 659 | this.awaitingTeleport = 0; |
654 660 | } |
655 661 | |
656 662 | + // CraftBukkit start - update last location |
657 663 | + this.lastPosX = this.awaitingPositionFromClient.x; |
658 664 | + this.lastPosY = this.awaitingPositionFromClient.y; |
659 665 | + this.lastPosZ = this.awaitingPositionFromClient.z; |
660 666 | + this.lastYaw = f; |
661 667 | + this.lastPitch = f1; |
662 668 | + // CraftBukkit end |
663 669 | + |
664 670 | this.awaitingTeleportTime = this.tickCount; |
665 671 | this.player.absMoveTo(d0, d1, d2, f, f1); |
666 672 | this.player.connection.send(new PacketPlayOutPosition(d0 - d3, d1 - d4, d2 - d5, f - f2, f1 - f3, set, this.awaitingTeleport, flag)); |
667 - | |
673 + | |
668 674 | @Override |
669 675 | public void handlePlayerAction(PacketPlayInBlockDig packetplayinblockdig) { |
670 676 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinblockdig, this, this.player.getLevel()); |
671 677 | + if (this.player.isImmobile()) return; // CraftBukkit |
672 678 | BlockPosition blockposition = packetplayinblockdig.getPos(); |
673 679 | |
674 680 | this.player.resetLastActionTime(); |
675 - | |
681 + | |
676 682 | if (!this.player.isSpectator()) { |
677 683 | ItemStack itemstack = this.player.getItemInHand(EnumHand.OFF_HAND); |
678 684 | |
679 685 | - this.player.setItemInHand(EnumHand.OFF_HAND, this.player.getItemInHand(EnumHand.MAIN_HAND)); |
680 686 | - this.player.setItemInHand(EnumHand.MAIN_HAND, itemstack); |
681 687 | + // CraftBukkit start - inspiration taken from DispenserRegistry (See SpigotCraft#394) |
682 688 | + CraftItemStack mainHand = CraftItemStack.asCraftMirror(itemstack); |
683 689 | + CraftItemStack offHand = CraftItemStack.asCraftMirror(this.player.getItemInHand(EnumHand.MAIN_HAND)); |
684 690 | + PlayerSwapHandItemsEvent swapItemsEvent = new PlayerSwapHandItemsEvent(getCraftPlayer(), mainHand.clone(), offHand.clone()); |
685 691 | + this.cserver.getPluginManager().callEvent(swapItemsEvent); |
714 720 | + if (this.dropCount >= 20) { |
715 721 | + LOGGER.warn(this.player.getScoreboardName() + " dropped their items too quickly!"); |
716 722 | + this.disconnect("You dropped your items too quickly (Hacking?)"); |
717 723 | + return; |
718 724 | + } |
719 725 | + } |
720 726 | + // CraftBukkit end |
721 727 | this.player.drop(false); |
722 728 | } |
723 729 | |
724 - | |
730 + | |
725 731 | @Override |
726 732 | public void handleUseItemOn(PacketPlayInUseItem packetplayinuseitem) { |
727 733 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinuseitem, this, this.player.getLevel()); |
728 734 | + if (this.player.isImmobile()) return; // CraftBukkit |
729 735 | WorldServer worldserver = this.player.getLevel(); |
730 736 | EnumHand enumhand = packetplayinuseitem.getHand(); |
731 737 | ItemStack itemstack = this.player.getItemInHand(enumhand); |
732 - | |
738 + | |
733 739 | |
734 740 | if (blockposition.getY() < i) { |
735 741 | if (this.awaitingPositionFromClient == null && this.player.distanceToSqr((double) blockposition.getX() + 0.5D, (double) blockposition.getY() + 0.5D, (double) blockposition.getZ() + 0.5D) < 64.0D && worldserver.mayInteract(this.player, blockposition)) { |
736 742 | + // CraftBukkit start - Check if we can actually do something over this large a distance |
737 743 | + Location eyeLoc = this.getCraftPlayer().getEyeLocation(); |
738 744 | + double reachDistance = NumberConversions.square(eyeLoc.getX() - blockposition.getX()) + NumberConversions.square(eyeLoc.getY() - blockposition.getY()) + NumberConversions.square(eyeLoc.getZ() - blockposition.getZ()); |
739 745 | + if (reachDistance > (this.getCraftPlayer().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) { |
740 746 | + return; |
741 747 | + } |
742 748 | + this.player.stopUsingItem(); // SPIGOT-4706 |
743 749 | + // CraftBukkit end |
744 750 | EnumInteractionResult enuminteractionresult = this.player.gameMode.useItemOn(this.player, worldserver, itemstack, enumhand, movingobjectpositionblock); |
745 751 | |
746 752 | if (enumdirection == EnumDirection.UP && !enuminteractionresult.consumesAction() && blockposition.getY() >= i - 1 && wasBlockPlacementAttempt(this.player, itemstack)) { |
747 - | |
753 + | |
748 754 | @Override |
749 755 | public void handleUseItem(PacketPlayInBlockPlace packetplayinblockplace) { |
750 756 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinblockplace, this, this.player.getLevel()); |
751 757 | + if (this.player.isImmobile()) return; // CraftBukkit |
752 758 | WorldServer worldserver = this.player.getLevel(); |
753 759 | EnumHand enumhand = packetplayinblockplace.getHand(); |
754 760 | ItemStack itemstack = this.player.getItemInHand(enumhand); |
755 761 | |
756 762 | this.player.resetLastActionTime(); |
757 763 | if (!itemstack.isEmpty()) { |
789 795 | + player.gameMode.firedInteract = false; |
790 796 | + } |
791 797 | + |
792 798 | + if (cancelled) { |
793 799 | + this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524 |
794 800 | + return; |
795 801 | + } |
796 802 | EnumInteractionResult enuminteractionresult = this.player.gameMode.useItem(this.player, worldserver, itemstack, enumhand); |
797 803 | |
798 804 | if (enuminteractionresult.shouldSwing()) { |
799 - | |
805 + | |
800 806 | Entity entity = packetplayinspectate.getEntity(worldserver); |
801 807 | |
802 808 | if (entity != null) { |
803 809 | - this.player.teleportTo(worldserver, entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot()); |
804 810 | + this.player.teleportTo(worldserver, entity.getX(), entity.getY(), entity.getZ(), entity.getYRot(), entity.getXRot(), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.SPECTATE); // CraftBukkit |
805 811 | return; |
806 812 | } |
807 813 | } |
808 - | |
814 + | |
809 815 | PlayerConnection.LOGGER.info("Disconnecting {} due to resource pack rejection", this.player.getName()); |
810 816 | this.disconnect(new ChatMessage("multiplayer.requiredTexturePrompt.disconnect")); |
811 817 | } |
812 818 | + this.cserver.getPluginManager().callEvent(new PlayerResourcePackStatusEvent(getCraftPlayer(), PlayerResourcePackStatusEvent.Status.values()[packetplayinresourcepackstatus.action.ordinal()])); // CraftBukkit |
813 819 | |
814 820 | } |
815 821 | |
816 - | |
822 + | |
817 823 | |
818 824 | @Override |
819 825 | public void onDisconnect(IChatBaseComponent ichatbasecomponent) { |
820 826 | + // CraftBukkit start - Rarely it would send a disconnect line twice |
821 827 | + if (this.processedDisconnect) { |
822 828 | + return; |
823 829 | + } else { |
824 830 | + this.processedDisconnect = true; |
825 831 | + } |
826 832 | + // CraftBukkit end |
834 840 | this.player.disconnect(); |
835 841 | - this.server.getPlayerList().remove(this.player); |
836 842 | + String quitMessage = this.server.getPlayerList().remove(this.player); |
837 843 | + if ((quitMessage != null) && (quitMessage.length() > 0)) { |
838 844 | + this.server.getPlayerList().broadcastMessage(CraftChatMessage.fromString(quitMessage)); |
839 845 | + } |
840 846 | + // CraftBukkit end |
841 847 | this.player.getTextFilter().leave(); |
842 848 | if (this.isSingleplayerOwner()) { |
843 849 | PlayerConnection.LOGGER.info("Stopping singleplayer server as player logged out"); |
844 - | |
850 + | |
845 851 | } |
846 852 | |
847 853 | public void send(Packet<?> packet, @Nullable GenericFutureListener<? extends Future<? super Void>> genericfuturelistener) { |
848 854 | + // CraftBukkit start |
849 855 | + if (packet == null) { |
850 856 | + return; |
851 857 | + } else if (packet instanceof PacketPlayOutSpawnPosition) { |
852 858 | + PacketPlayOutSpawnPosition packet6 = (PacketPlayOutSpawnPosition) packet; |
853 859 | + this.player.compassTarget = new Location(this.getCraftPlayer().getWorld(), packet6.pos.getX(), packet6.pos.getY(), packet6.pos.getZ()); |
854 860 | + } |
855 861 | + // CraftBukkit end |
856 862 | + |
857 863 | try { |
858 864 | this.connection.send(packet, genericfuturelistener); |
859 865 | } catch (Throwable throwable) { |
860 - | |
866 + | |
861 867 | @Override |
862 868 | public void handleSetCarriedItem(PacketPlayInHeldItemSlot packetplayinhelditemslot) { |
863 869 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinhelditemslot, this, this.player.getLevel()); |
864 870 | + if (this.player.isImmobile()) return; // CraftBukkit |
865 871 | if (packetplayinhelditemslot.getSlot() >= 0 && packetplayinhelditemslot.getSlot() < PlayerInventory.getSelectionSize()) { |
866 872 | + PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getCraftPlayer(), this.player.getInventory().selected, packetplayinhelditemslot.getSlot()); |
867 873 | + this.cserver.getPluginManager().callEvent(event); |
868 874 | + if (event.isCancelled()) { |
869 875 | + this.send(new PacketPlayOutHeldItemSlot(this.player.getInventory().selected)); |
870 876 | + this.player.resetLastActionTime(); |
871 877 | + return; |
872 878 | + } |
873 879 | + // CraftBukkit end |
874 880 | if (this.player.getInventory().selected != packetplayinhelditemslot.getSlot() && this.player.getUsedItemHand() == EnumHand.MAIN_HAND) { |
875 881 | this.player.stopUsingItem(); |
876 882 | } |
877 - | |
883 + | |
878 884 | this.player.resetLastActionTime(); |
879 885 | } else { |
880 886 | PlayerConnection.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString()); |
881 887 | + this.disconnect("Invalid hotbar selection (Hacking?)"); // CraftBukkit |
882 888 | } |
883 889 | } |
884 890 | |
885 891 | @Override |
886 892 | public void handleChat(PacketPlayInChat packetplayinchat) { |
887 893 | + // CraftBukkit start - async chat |
888 894 | + // SPIGOT-3638 |
889 895 | + if (this.server.isStopped()) { |
890 896 | + return; |
891 897 | + } |
892 898 | + // CraftBukkit end |
893 899 | String s = StringUtils.normalizeSpace(packetplayinchat.getMessage()); |
894 900 | |
895 901 | for (int i = 0; i < s.length(); ++i) { |
896 - | |
902 + | |
897 903 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinchat, this, this.player.getLevel()); |
898 904 | this.handleChat(ITextFilter.a.passThrough(s)); |
899 905 | } else { |
900 906 | - this.filterTextPacket(s, this::handleChat); |
901 907 | + this.handleChat(ITextFilter.a.passThrough(s)); // CraftBukkit - filter NYI |
902 908 | } |
903 909 | |
904 910 | } |
905 911 | |
906 912 | private void handleChat(ITextFilter.a itextfilter_a) { |
933 939 | + } |
934 940 | + }); |
935 941 | + } else if (this.player.getChatVisibility() == EnumChatVisibility.SYSTEM) { // Re-add "Command Only" flag check |
936 942 | + this.send(new PacketPlayOutChat((new ChatMessage("chat.cannotSend")).withStyle(EnumChatFormat.RED), ChatMessageType.SYSTEM, SystemUtils.NIL_UUID)); |
937 943 | + } else if (true) { |
938 944 | + this.chat(s, true); |
939 945 | + // CraftBukkit end - the below is for reference. :) |
940 946 | } else { |
941 947 | String s1 = itextfilter_a.getFiltered(); |
942 948 | ChatMessage chatmessage = s1.isEmpty() ? null : new ChatMessage("chat.type.text", new Object[]{this.player.getDisplayName(), s1}); |
943 - | |
949 + | |
944 950 | }, ChatMessageType.CHAT, this.player.getUUID()); |
945 951 | } |
946 952 | |
947 953 | - this.chatSpamTickCount += 20; |
948 954 | - if (this.chatSpamTickCount > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { |
949 955 | - this.disconnect(new ChatMessage("disconnect.spam")); |
950 956 | + // CraftBukkit start - replaced with thread safe throttle |
951 957 | + // this.chatSpamTickCount += 20; |
952 958 | + if (chatSpamTickCount.addAndGet(20) > 200 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { |
953 959 | + if (!isSync) { |
1136 1142 | + |
1137 1143 | + if (e2.isCancelled()) { |
1138 1144 | + return; |
1139 1145 | + } |
1140 1146 | + break; |
1141 1147 | + } |
1142 1148 | + // CraftBukkit end |
1143 1149 | this.player.resetLastActionTime(); |
1144 1150 | IJumpable ijumpable; |
1145 1151 | |
1146 - | |
1152 + | |
1147 1153 | @Override |
1148 1154 | public void handleInteract(PacketPlayInUseEntity packetplayinuseentity) { |
1149 1155 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinuseentity, this, this.player.getLevel()); |
1150 1156 | + if (this.player.isImmobile()) return; // CraftBukkit |
1151 1157 | WorldServer worldserver = this.player.getLevel(); |
1152 1158 | final Entity entity = packetplayinuseentity.getTarget(worldserver); |
1153 1159 | |
1154 - | |
1160 + | |
1155 1161 | |
1156 1162 | if (this.player.distanceToSqr(entity) < 36.0D) { |
1157 1163 | packetplayinuseentity.dispatch(new PacketPlayInUseEntity.c() { |
1158 1164 | - private void performInteraction(EnumHand enumhand, PlayerConnection.a playerconnection_a) { |
1159 1165 | + private void performInteraction(EnumHand enumhand, PlayerConnection.a playerconnection_a, PlayerInteractEntityEvent event) { // CraftBukkit |
1160 1166 | ItemStack itemstack = PlayerConnection.this.player.getItemInHand(enumhand).copy(); |
1161 1167 | + // CraftBukkit start |
1162 1168 | + ItemStack itemInHand = PlayerConnection.this.player.getItemInHand(enumhand); |
1163 1169 | + boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.LEAD && entity instanceof EntityInsentient; |
1164 1170 | + Item origItem = player.getInventory().getSelected() == null ? null : player.getInventory().getSelected().getItem(); |
1190 1196 | |
1191 1197 | + // CraftBukkit start |
1192 1198 | + if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) { |
1193 1199 | + player.containerMenu.sendAllDataToRemote(); |
1194 1200 | + } |
1195 1201 | + // CraftBukkit end |
1196 1202 | + |
1197 1203 | if (enuminteractionresult.consumesAction()) { |
1198 1204 | CriterionTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(PlayerConnection.this.player, itemstack, entity); |
1199 1205 | if (enuminteractionresult.shouldSwing()) { |
1200 - | |
1206 + | |
1201 1207 | |
1202 1208 | @Override |
1203 1209 | public void onInteraction(EnumHand enumhand) { |
1204 1210 | - this.performInteraction(enumhand, EntityHuman::interactOn); |
1205 1211 | + this.performInteraction(enumhand, EntityHuman::interactOn, new PlayerInteractEntityEvent(getCraftPlayer(), entity.getBukkitEntity(), (enumhand == EnumHand.OFF_HAND) ? EquipmentSlot.OFF_HAND : EquipmentSlot.HAND)); |
1206 1212 | } |
1207 1213 | |
1208 1214 | @Override |
1209 1215 | public void onInteraction(EnumHand enumhand, Vec3D vec3d) { |
1210 1216 | this.performInteraction(enumhand, (entityplayer, entity1, enumhand1) -> { |
1221 1227 | + ItemStack itemInHand = PlayerConnection.this.player.getMainHandItem(); |
1222 1228 | PlayerConnection.this.player.attack(entity); |
1223 1229 | + |
1224 1230 | + if (!itemInHand.isEmpty() && itemInHand.getCount() <= -1) { |
1225 1231 | + player.containerMenu.sendAllDataToRemote(); |
1226 1232 | + } |
1227 1233 | + // CraftBukkit end |
1228 1234 | } else { |
1229 1235 | PlayerConnection.this.disconnect(new ChatMessage("multiplayer.disconnect.invalid_entity_attacked")); |
1230 1236 | PlayerConnection.LOGGER.warn("Player {} tried to attack an invalid entity", PlayerConnection.this.player.getName().getString()); |
1231 - | |
1237 + | |
1232 1238 | @Override |
1233 1239 | public void handleContainerClose(PacketPlayInCloseWindow packetplayinclosewindow) { |
1234 1240 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinclosewindow, this, this.player.getLevel()); |
1235 1241 | + |
1236 1242 | + if (this.player.isImmobile()) return; // CraftBukkit |
1237 1243 | + CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit |
1238 1244 | + |
1239 1245 | this.player.doCloseContainer(); |
1240 1246 | } |
1241 1247 | |
1529 1535 | + if (event instanceof CraftItemEvent || event instanceof SmithItemEvent) { |
1530 1536 | + // Need to update the inventory on crafting to |
1531 1537 | + // correctly support custom recipes |
1532 1538 | + player.containerMenu.sendAllDataToRemote(); |
1533 1539 | + } |
1534 1540 | + } |
1535 1541 | + // CraftBukkit end |
1536 1542 | ObjectIterator objectiterator = Int2ObjectMaps.fastIterable(packetplayinwindowclick.getChangedSlots()).iterator(); |
1537 1543 | |
1538 1544 | while (objectiterator.hasNext()) { |
1539 - | |
1545 + | |
1540 1546 | @Override |
1541 1547 | public void handleContainerButtonClick(PacketPlayInEnchantItem packetplayinenchantitem) { |
1542 1548 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinenchantitem, this, this.player.getLevel()); |
1543 1549 | + if (this.player.isImmobile()) return; // CraftBukkit |
1544 1550 | this.player.resetLastActionTime(); |
1545 1551 | if (this.player.containerMenu.containerId == packetplayinenchantitem.getContainerId() && !this.player.isSpectator()) { |
1546 1552 | this.player.containerMenu.clickMenuButton(this.player, packetplayinenchantitem.getButtonId()); |
1547 - | |
1553 + | |
1548 1554 | |
1549 1555 | boolean flag1 = packetplayinsetcreativeslot.getSlotNum() >= 1 && packetplayinsetcreativeslot.getSlotNum() <= 45; |
1550 1556 | boolean flag2 = itemstack.isEmpty() || itemstack.getDamageValue() >= 0 && itemstack.getCount() <= 64 && !itemstack.isEmpty(); |
1551 1557 | + if (flag || (flag1 && !ItemStack.matches(this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).getItem(), packetplayinsetcreativeslot.getItem()))) { // Insist on valid slot |
1552 1558 | + // CraftBukkit start - Call click event |
1553 1559 | + InventoryView inventory = this.player.inventoryMenu.getBukkitView(); |
1554 1560 | + org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(packetplayinsetcreativeslot.getItem()); |
1555 1561 | + |
1556 1562 | + SlotType type = SlotType.QUICKBAR; |
1557 1563 | + if (flag) { |
1581 1587 | + this.player.connection.send(new PacketPlayOutSetSlot(this.player.inventoryMenu.containerId, this.player.inventoryMenu.incrementStateId(), packetplayinsetcreativeslot.getSlotNum(), this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).getItem())); |
1582 1588 | + this.player.connection.send(new PacketPlayOutSetSlot(-1, this.player.inventoryMenu.incrementStateId(), -1, ItemStack.EMPTY)); |
1583 1589 | + } |
1584 1590 | + return; |
1585 1591 | + } |
1586 1592 | + } |
1587 1593 | + // CraftBukkit end |
1588 1594 | |
1589 1595 | if (flag1 && flag2) { |
1590 1596 | this.player.inventoryMenu.getSlot(packetplayinsetcreativeslot.getSlotNum()).set(itemstack); |
1591 - | |
1597 + | |
1592 1598 | } |
1593 1599 | |
1594 1600 | private void updateSignText(PacketPlayInUpdateSign packetplayinupdatesign, List<ITextFilter.a> list) { |
1595 1601 | + if (this.player.isImmobile()) return; // CraftBukkit |
1596 1602 | this.player.resetLastActionTime(); |
1597 1603 | WorldServer worldserver = this.player.getLevel(); |
1598 1604 | BlockPosition blockposition = packetplayinupdatesign.getPos(); |
1599 - | |
1605 + | |
1600 1606 | |
1601 1607 | if (!tileentitysign.isEditable() || !this.player.getUUID().equals(tileentitysign.getPlayerWhoMayEdit())) { |
1602 1608 | PlayerConnection.LOGGER.warn("Player {} just tried to change non-editable sign", this.player.getName().getString()); |
1603 1609 | + this.send(tileentity.getUpdatePacket()); // CraftBukkit |
1604 1610 | return; |
1605 1611 | } |
1606 1612 | |
1607 1613 | + // CraftBukkit start |
1608 1614 | + Player player = this.player.getBukkitEntity(); |
1609 1615 | + int x = packetplayinupdatesign.getPos().getX(); |
1629 1635 | + IChatBaseComponent[] components = org.bukkit.craftbukkit.block.CraftSign.sanitizeLines(event.getLines()); |
1630 1636 | + for (int i = 0; i < components.length; i++) { |
1631 1637 | + tileentitysign.setMessage(i, components[i]); |
1632 1638 | } |
1633 1639 | + tileentitysign.isEditable = false; |
1634 1640 | } |
1635 1641 | + // CraftBukkit end |
1636 1642 | |
1637 1643 | tileentitysign.setChanged(); |
1638 1644 | worldserver.sendBlockUpdated(blockposition, iblockdata, iblockdata, 3); |
1639 - | |
1645 + | |
1640 1646 | |
1641 1647 | @Override |
1642 1648 | public void handleKeepAlive(PacketPlayInKeepAlive packetplayinkeepalive) { |
1643 1649 | + PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinkeepalive, this, this.player.getLevel()); // CraftBukkit |
1644 1650 | if (this.keepAlivePending && packetplayinkeepalive.getId() == this.keepAliveChallenge) { |
1645 1651 | int i = (int) (SystemUtils.getMillis() - this.keepAliveTime); |
1646 1652 | |
1647 - | |
1653 + | |
1648 1654 | @Override |
1649 1655 | public void handlePlayerAbilities(PacketPlayInAbilities packetplayinabilities) { |
1650 1656 | PlayerConnectionUtils.ensureRunningOnSameThread(packetplayinabilities, this, this.player.getLevel()); |
1651 1657 | - this.player.getAbilities().flying = packetplayinabilities.isFlying() && this.player.getAbilities().mayfly; |
1652 1658 | + // CraftBukkit start |
1653 1659 | + if (this.player.getAbilities().mayfly && this.player.getAbilities().flying != packetplayinabilities.isFlying()) { |
1654 1660 | + PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.player.getBukkitEntity(), packetplayinabilities.isFlying()); |
1655 1661 | + this.cserver.getPluginManager().callEvent(event); |
1656 1662 | + if (!event.isCancelled()) { |
1657 1663 | + this.player.getAbilities().flying = packetplayinabilities.isFlying(); // Actually set the player's flying status |
1658 1664 | + } else { |
1659 1665 | + this.player.onUpdateAbilities(); // Tell the player their ability was reverted |
1660 1666 | + } |
1661 1667 | + } |
1662 1668 | + // CraftBukkit end |
1663 1669 | } |
1664 1670 | |
1665 1671 | @Override |
1666 - | |
1672 + | |
1667 1673 | this.player.updateOptions(packetplayinsettings); |
1668 1674 | } |
1669 1675 | |
1670 1676 | - @Override |
1671 1677 | - public void handleCustomPayload(PacketPlayInCustomPayload packetplayincustompayload) {} |
1672 1678 | + // CraftBukkit start |
1673 1679 | + private static final MinecraftKey CUSTOM_REGISTER = new MinecraftKey("register"); |
1674 1680 | + private static final MinecraftKey CUSTOM_UNREGISTER = new MinecraftKey("unregister"); |
1675 1681 | + |
1676 1682 | + @Override |