Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-3955

Inconsistency between client and server if minecraft's tp command with relative coordinates is run from within the bukkit scheduler

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • None
    • None
    • git-Spigot-1503de9-4487c1f
    • Yes

      Use case: Trying to create a moving platform that moves players on top of it while still allowing players to move independently from that on their own.

      This can be achieved in minecraft by using a repeating command block that executes this command every tick:

      minecraft:execute @p[name=blablubbabc] ~ ~ ~ minecraft:tp blablubbabc ~0.1 ~ ~
      

      If one however attempts to reproduce this with bukkit by using a repeating bukkit scheduler task, the behavior is a different one:
      This code shows the above minecraft command getting run from within a bukkit task each tick:

      Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "minecraft:execute @p[name=blablubbabc] ~ ~ ~ minecraft:tp blablubbabc ~0.1 ~ ~");
      

      Result here: The player's position doesn't get updated correctly on the server. The player can move around on the client, but the server is not aware of the player's movement / ignores it (outputting the player's current position every tick confirms this). Eventually (when the repeating tasks stops) the player's position gets reset on the client to the one the server believes is correct.

      I believe the issue is somehow related to the order in which the server processes the bukkit scheduler tasks and its own tasks (position updates it receives from the player).
      If I revert this commit (https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/6b843d995ffa4b1d5e50124bb67ea58289598596#nms-patches/MinecraftServer.patch) the issue is gone. (Relates to https://hub.spigotmc.org/jira/browse/SPIGOT-1284)

      Edit: Plugin code for reproduction:

      @EventHandler(priority = EventPriority.MONITOR)
      void onBlockClicked(PlayerInteractEvent event) {
      	if (event.getHand() != EquipmentSlot.HAND) return;
      	Block block = event.getClickedBlock();
      	if (block == null || event.getAction() == Action.LEFT_CLICK_BLOCK || block.getType() != Material.IRON_BLOCK || (event.getItem() != null && event.getItem().getType() != Material.AIR)) return;
      
      	event.getPlayer().sendMessage("Start!");
      	new BukkitRunnable() {
      		
      		int counter = 0;
      			
      		@Override
      		public void run() {
      			counter++;
      			event.getPlayer().sendMessage("Pos: " + event.getPlayer().getLocation());
      			if (counter == 100) {
      			event.getPlayer().sendMessage("End teleport!");
      			}
      			if (counter > 140) {
      				event.getPlayer().sendMessage("End!");
      				this.cancel();
      				return;
      			} else if (counter >= 100) {
      				return; // skip teleport
      			}
      				
      			//Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "minecraft:execute @p[name=blablubbabc] ~ ~ ~ minecraft:tp blablubbabc ~0.1 ~ ~");
      			Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "minecraft:execute as @p[name=blablubbabc] at @p[name=blablubbabc] run tp blablubbabc ~0.1 ~ ~");
      		}
      	}.runTaskTimer(Test.INSTANCE, 1L, 1L);
      }
      

            Unassigned Unassigned
            blablubbabc blablubbabc
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: