From 5a83b4ee93f7e88f2855f49c1f63e79339b4dfad Mon Sep 17 00:00:00 2001 From: Alex 'mcmonkey' Goodwin Date: Fri, 18 Dec 2020 10:59:27 -0800 Subject: [PATCH] send self-disguise update packets faster to reduce awkward delays --- .../denizen/nms/interfaces/PlayerHelper.java | 5 +-- .../commands/player/DisguiseCommand.java | 33 +++++++++++++---- .../denizen/utilities/entity/FakeEntity.java | 14 ++++---- .../nms/v1_15/helpers/PlayerHelperImpl.java | 36 ++++++++++++++++--- .../nms/v1_16/helpers/PlayerHelperImpl.java | 29 ++++++++++++--- 5 files changed, 92 insertions(+), 25 deletions(-) diff --git a/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/PlayerHelper.java b/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/PlayerHelper.java index a73952da10..9dc482d3bd 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/PlayerHelper.java +++ b/plugin/src/main/java/com/denizenscript/denizen/nms/interfaces/PlayerHelper.java @@ -1,8 +1,9 @@ package com.denizenscript.denizen.nms.interfaces; import com.denizenscript.denizen.nms.abstracts.ImprovedOfflinePlayer; -import com.denizenscript.denizen.objects.EntityTag; +import com.denizenscript.denizen.objects.LocationTag; import com.denizenscript.denizen.objects.PlayerTag; +import com.denizenscript.denizen.utilities.entity.FakeEntity; import com.denizenscript.denizencore.objects.Mechanism; import org.bukkit.*; import org.bukkit.boss.BossBar; @@ -16,7 +17,7 @@ public abstract class PlayerHelper { public abstract void stopSound(Player player, String sound, SoundCategory category); - public EntityTag sendEntitySpawn(List players, EntityType entityType, Location location, ArrayList mechanisms, int customId, UUID customUUID, boolean autoTrack) { + public FakeEntity sendEntitySpawn(List players, EntityType entityType, LocationTag location, ArrayList mechanisms, int customId, UUID customUUID, boolean autoTrack) { throw new UnsupportedOperationException(); } diff --git a/plugin/src/main/java/com/denizenscript/denizen/scripts/commands/player/DisguiseCommand.java b/plugin/src/main/java/com/denizenscript/denizen/scripts/commands/player/DisguiseCommand.java index 802df5adc7..cf0bb7f1ab 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/scripts/commands/player/DisguiseCommand.java +++ b/plugin/src/main/java/com/denizenscript/denizen/scripts/commands/player/DisguiseCommand.java @@ -15,12 +15,14 @@ import com.denizenscript.denizencore.scripts.ScriptEntry; import com.denizenscript.denizencore.scripts.commands.AbstractCommand; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.scheduler.BukkitRunnable; @@ -152,6 +154,11 @@ else if (player.isOnline()) { } } + public void moveFakeNow(Location position) { + NMSHandler.getEntityHelper().snapPositionTo(fake.entity.getBukkitEntity(), position.toVector()); + NMSHandler.getEntityHelper().look(fake.entity.getBukkitEntity(), position.getYaw(), position.getPitch()); + } + public void startFake(PlayerTag player) { if (fake != null) { stopFake(player); @@ -173,8 +180,7 @@ public void run() { cancel(); return; } - NMSHandler.getEntityHelper().snapPositionTo(fake.entity.getBukkitEntity(), player.getLocation().toVector()); - NMSHandler.getEntityHelper().look(fake.entity.getBukkitEntity(), player.getLocation().getYaw(), player.getLocation().getPitch()); + moveFakeNow(player.getLocation()); } }.runTaskTimer(Denizen.getInstance(), 1, 1); } @@ -213,9 +219,9 @@ public void sendTo(List players) { NMSHandler.getPlayerHelper().sendEntitySpawn(players, as.getBukkitEntityType(), entity.getLocation(), as.getWaitingMechanisms(), entity.getBukkitEntity().getEntityId(), entity.getUUID(), false); } - @EventHandler(priority = EventPriority.MONITOR) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onJoin(PlayerJoinEvent event) { - if (!event.getPlayer().getUniqueId().equals(entity.getUUID()) || !shouldFake) { + if (!shouldFake || !event.getPlayer().getUniqueId().equals(entity.getUUID())) { return; } new BukkitRunnable() { @@ -229,9 +235,9 @@ public void run() { }.runTaskLater(Denizen.getInstance(), 2); } - @EventHandler(priority = EventPriority.MONITOR) + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onTeleport(PlayerTeleportEvent event) { - if (!event.getPlayer().getUniqueId().equals(entity.getUUID()) || fake == null) { + if (fake == null || !event.getPlayer().getUniqueId().equals(entity.getUUID())) { return; } stopFake(new PlayerTag(event.getPlayer())); @@ -245,6 +251,21 @@ public void run() { } }.runTaskLater(Denizen.getInstance(), 2); } + + + @EventHandler(priority = EventPriority.MONITOR) + public void onMove(PlayerMoveEvent event) { + if (fake == null || !event.getPlayer().getUniqueId().equals(entity.getUUID())) { + return; + } + if (event.getTo() == null) { + return; + } + moveFakeNow(event.getTo()); + if (fake.triggerUpdatePacket != null) { + fake.triggerUpdatePacket.run(); + } + } } public static HashMap> disguises = new HashMap<>(); diff --git a/plugin/src/main/java/com/denizenscript/denizen/utilities/entity/FakeEntity.java b/plugin/src/main/java/com/denizenscript/denizen/utilities/entity/FakeEntity.java index 01d8bed2aa..1c028a818d 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/utilities/entity/FakeEntity.java +++ b/plugin/src/main/java/com/denizenscript/denizen/utilities/entity/FakeEntity.java @@ -38,19 +38,19 @@ public static FakeEntity getFakeEntityFor(UUID uuid, int id) { public EntityTag entity; public LocationTag location; public BukkitTask currentTask = null; + public Runnable triggerUpdatePacket; - private FakeEntity(List player, LocationTag location, int id) { + public FakeEntity(List player, LocationTag location, int id) { this.players = player; this.location = location; this.id = id; } public static FakeEntity showFakeEntityTo(List players, EntityTag typeToSpawn, LocationTag location, DurationTag duration) { - EntityTag entTag = NMSHandler.getPlayerHelper().sendEntitySpawn(players, typeToSpawn.getBukkitEntityType(), location, typeToSpawn.getWaitingMechanisms(), -1, null, true); - entTag.isFake = true; - entTag.isFakeValid = true; - FakeEntity fakeEntity = new FakeEntity(players, location, entTag.getBukkitEntity().getEntityId()); - idsToEntities.put(entTag.getUUID(), fakeEntity); + FakeEntity fakeEntity = NMSHandler.getPlayerHelper().sendEntitySpawn(players, typeToSpawn.getBukkitEntityType(), location, typeToSpawn.getWaitingMechanisms(), -1, null, true); + fakeEntity.entity.isFake = true; + fakeEntity.entity.isFakeValid = true; + idsToEntities.put(fakeEntity.entity.getUUID(), fakeEntity); for (PlayerTag player : players) { UUID uuid = player.getPlayerEntity().getUniqueId(); FakeEntity.FakeEntityMap playerEntities = playersToEntities.get(uuid); @@ -60,7 +60,7 @@ public static FakeEntity showFakeEntityTo(List players, EntityTag typ } playerEntities.byId.put(fakeEntity.id, fakeEntity); } - fakeEntity.updateEntity(entTag, duration); + fakeEntity.updateEntity(fakeEntity.entity, duration); return fakeEntity; } diff --git a/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/helpers/PlayerHelperImpl.java b/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/helpers/PlayerHelperImpl.java index c5f72bdc14..6e9d321e67 100644 --- a/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/helpers/PlayerHelperImpl.java +++ b/v1_15/src/main/java/com/denizenscript/denizen/nms/v1_15/helpers/PlayerHelperImpl.java @@ -5,7 +5,9 @@ import com.denizenscript.denizen.nms.v1_15.impl.network.handlers.AbstractListenerPlayInImpl; import com.denizenscript.denizen.nms.v1_15.impl.network.handlers.DenizenNetworkManagerImpl; import com.denizenscript.denizen.objects.EntityTag; +import com.denizenscript.denizen.objects.LocationTag; import com.denizenscript.denizen.objects.PlayerTag; +import com.denizenscript.denizen.utilities.entity.FakeEntity; import com.denizenscript.denizencore.objects.Mechanism; import com.mojang.authlib.GameProfile; import com.denizenscript.denizen.nms.abstracts.ImprovedOfflinePlayer; @@ -67,7 +69,7 @@ public void deTrackEntity(Player player, Entity entity) { } @Override - public EntityTag sendEntitySpawn(List players, EntityType entityType, Location location, ArrayList mechanisms, int customId, UUID customUUID, boolean autoTrack) { + public FakeEntity sendEntitySpawn(List players, EntityType entityType, LocationTag location, ArrayList mechanisms, int customId, UUID customUUID, boolean autoTrack) { CraftWorld world = ((CraftWorld) location.getWorld()); net.minecraft.server.v1_15_R1.Entity nmsEntity = world.createEntity(location, entityType.getEntityClass()); if (customUUID != null) { @@ -79,26 +81,50 @@ public EntityTag sendEntitySpawn(List players, EntityType entityType, entity.safeAdjust(mechanism); } nmsEntity.dead = false; - EntityTag entTag = new EntityTag(entity.getBukkitEntity()); + FakeEntity fake = new FakeEntity(players, location, entity.getBukkitEntity().getEntityId()); + fake.entity = new EntityTag(entity.getBukkitEntity()); + List trackers = new ArrayList<>(); for (PlayerTag player : players) { EntityPlayer nmsPlayer = ((CraftPlayer) player.getPlayerEntity()).getHandle(); PlayerConnection conn = nmsPlayer.playerConnection; final EntityTrackerEntry tracker = new EntityTrackerEntry(world.getHandle(), nmsEntity, 1, true, conn::sendPacket, Collections.singleton(nmsPlayer)); tracker.b(nmsPlayer); + trackers.add(tracker); if (autoTrack) { new BukkitRunnable() { + boolean wasOnline = true; @Override public void run() { - if (!entTag.isFakeValid || !player.isOnline()) { + if (!fake.entity.isFakeValid) { + trackers.remove(tracker); cancel(); return; } - tracker.a(); + if (player.isOnline()) { + if (!wasOnline) { + trackers.add(tracker); + tracker.b(((CraftPlayer) player.getPlayerEntity()).getHandle()); + wasOnline = true; + } + tracker.a(); + } + else if (wasOnline) { + trackers.remove(tracker); + wasOnline = false; + } } }.runTaskTimer(Denizen.getInstance(), 1, 1); } } - return entTag; + fake.triggerUpdatePacket = new Runnable() { + @Override + public void run() { + for (EntityTrackerEntry tracker : trackers) { + tracker.a(); + } + } + }; + return fake; } @Override diff --git a/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/helpers/PlayerHelperImpl.java b/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/helpers/PlayerHelperImpl.java index bd4cd83195..0b41ddda84 100644 --- a/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/helpers/PlayerHelperImpl.java +++ b/v1_16/src/main/java/com/denizenscript/denizen/nms/v1_16/helpers/PlayerHelperImpl.java @@ -6,8 +6,10 @@ import com.denizenscript.denizen.nms.v1_16.impl.network.handlers.AbstractListenerPlayInImpl; import com.denizenscript.denizen.nms.v1_16.impl.network.handlers.DenizenNetworkManagerImpl; import com.denizenscript.denizen.objects.EntityTag; +import com.denizenscript.denizen.objects.LocationTag; import com.denizenscript.denizen.objects.PlayerTag; import com.denizenscript.denizen.utilities.FormattedTextHelper; +import com.denizenscript.denizen.utilities.entity.FakeEntity; import com.denizenscript.denizencore.objects.Mechanism; import com.mojang.authlib.GameProfile; import com.denizenscript.denizen.nms.abstracts.ImprovedOfflinePlayer; @@ -71,7 +73,7 @@ public void deTrackEntity(Player player, Entity entity) { } @Override - public EntityTag sendEntitySpawn(List players, EntityType entityType, Location location, ArrayList mechanisms, int customId, UUID customUUID, boolean autoTrack) { + public FakeEntity sendEntitySpawn(List players, EntityType entityType, LocationTag location, ArrayList mechanisms, int customId, UUID customUUID, boolean autoTrack) { CraftWorld world = ((CraftWorld) location.getWorld()); net.minecraft.server.v1_16_R3.Entity nmsEntity = world.createEntity(location, entityType.getEntityClass()); if (customUUID != null) { @@ -83,33 +85,50 @@ public EntityTag sendEntitySpawn(List players, EntityType entityType, entity.safeAdjust(mechanism); } nmsEntity.dead = false; - EntityTag entTag = new EntityTag(entity.getBukkitEntity()); + FakeEntity fake = new FakeEntity(players, location, entity.getBukkitEntity().getEntityId()); + fake.entity = new EntityTag(entity.getBukkitEntity()); + List trackers = new ArrayList<>(); for (PlayerTag player : players) { EntityPlayer nmsPlayer = ((CraftPlayer) player.getPlayerEntity()).getHandle(); PlayerConnection conn = nmsPlayer.playerConnection; final EntityTrackerEntry tracker = new EntityTrackerEntry(world.getHandle(), nmsEntity, 1, true, conn::sendPacket, Collections.singleton(nmsPlayer)); tracker.b(nmsPlayer); + trackers.add(tracker); if (autoTrack) { new BukkitRunnable() { boolean wasOnline = true; @Override public void run() { - if (!entTag.isFakeValid) { + if (!fake.entity.isFakeValid) { + trackers.remove(tracker); cancel(); return; } if (player.isOnline()) { if (!wasOnline) { - tracker.b(nmsPlayer); + trackers.add(tracker); + tracker.b(((CraftPlayer) player.getPlayerEntity()).getHandle()); wasOnline = true; } tracker.a(); } + else if (wasOnline) { + trackers.remove(tracker); + wasOnline = false; + } } }.runTaskTimer(Denizen.getInstance(), 1, 1); } } - return entTag; + fake.triggerUpdatePacket = new Runnable() { + @Override + public void run() { + for (EntityTrackerEntry tracker : trackers) { + tracker.a(); + } + } + }; + return fake; } @Override