-
Bug
-
Resolution: Unresolved
-
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); }