From 765c3d6fb409f9ed339d8c8e9d1e484fb8f84527 Mon Sep 17 00:00:00 2001 From: ThisTestUser Date: Sat, 19 Nov 2022 15:58:20 -0500 Subject: [PATCH] Option to add bots to player list -Useful for datapacks that may use commands that target players -This will count towards the player count --- .../net/nuggetmc/tplus/api/BotManager.java | 3 +++ .../net/nuggetmc/tplus/api/Terminator.java | 2 ++ .../api/agent/legacyagent/LegacyAgent.java | 12 +++++---- .../main/java/net/nuggetmc/tplus/bot/Bot.java | 25 ++++++++++++++++--- .../nuggetmc/tplus/bot/BotManagerImpl.java | 12 +++++++++ .../tplus/command/commands/BotCommand.java | 19 +++++++++++++- 6 files changed, 63 insertions(+), 10 deletions(-) diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/BotManager.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/BotManager.java index 5d37bea..a04bc76 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/BotManager.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/BotManager.java @@ -50,4 +50,7 @@ public interface BotManager { void setMobTarget(boolean mobTarget); + boolean addToPlayerList(); + + void setAddToPlayerList(boolean addPlayerList); } diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/Terminator.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/Terminator.java index 6fb50ce..c43f686 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/Terminator.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/Terminator.java @@ -125,5 +125,7 @@ public interface Terminator { void setTargetPlayer(UUID target); + boolean isInPlayerList(); + World.Environment getDimension(); } diff --git a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyAgent.java b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyAgent.java index 2bd0d4c..4b789b6 100644 --- a/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyAgent.java +++ b/TerminatorPlus-API/src/main/java/net/nuggetmc/tplus/api/agent/legacyagent/LegacyAgent.java @@ -50,6 +50,7 @@ public class LegacyAgent extends Agent { private final Map mining = new HashMap<>(); private final Set fallDamageCooldown = new HashSet<>(); public boolean offsets = true; + private List botEntityCache; private EnumTargetGoal goal; private BoundingBox region; private double regionWeightX; @@ -69,7 +70,8 @@ public class LegacyAgent extends Agent { @Override protected void tick() { - manager.fetch().forEach(this::tickBot); + botEntityCache = manager.fetch().stream().filter(t -> t.isInPlayerList()).map(b -> b.getBukkitEntity()).toList(); + manager.fetch().forEach(this::tickBot); } private void center(Terminator bot) { @@ -1426,7 +1428,7 @@ public class LegacyAgent extends Agent { this.goal = goal; } - public LivingEntity locateTarget(Terminator bot, Location loc, EnumTargetGoal... targetGoal) { + private LivingEntity locateTarget(Terminator bot, Location loc, EnumTargetGoal... targetGoal) { LivingEntity result = null; EnumTargetGoal g = goal; @@ -1437,7 +1439,7 @@ public class LegacyAgent extends Agent { case NEAREST_PLAYER: { for (Player player : Bukkit.getOnlinePlayers()) { - if (validateCloserEntity(player, loc, result)) { + if (!botEntityCache.contains(player) && validateCloserEntity(player, loc, result)) { result = player; } } @@ -1447,7 +1449,7 @@ public class LegacyAgent extends Agent { case NEAREST_VULNERABLE_PLAYER: { for (Player player : Bukkit.getOnlinePlayers()) { - if (!PlayerUtils.isInvincible(player.getGameMode()) && validateCloserEntity(player, loc, result)) { + if (!botEntityCache.contains(player) && !PlayerUtils.isInvincible(player.getGameMode()) && validateCloserEntity(player, loc, result)) { result = player; } } @@ -1521,7 +1523,7 @@ public class LegacyAgent extends Agent { case PLAYER: { //Target a single player. Defaults to NEAREST_VULNERABLE_PLAYER if no player found. if (bot.getTargetPlayer() != null) { Player player = Bukkit.getPlayer(bot.getTargetPlayer()); - if (player != null && validateCloserEntity(player, loc, null)) { + if (player != null && !botEntityCache.contains(player) && validateCloserEntity(player, loc, null)) { return player; } } diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/Bot.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/Bot.java index 9ef3a15..c8dacd6 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/Bot.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/Bot.java @@ -35,7 +35,6 @@ import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.block.data.Waterlogged; -import org.bukkit.block.data.type.Candle; import org.bukkit.craftbukkit.v1_19_R1.CraftEquipmentSlot; import org.bukkit.craftbukkit.v1_19_R1.CraftServer; import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; @@ -78,7 +77,9 @@ public class Bot extends ServerPlayer implements Terminator { private byte noFallTicks; private List standingOn = new ArrayList<>(); private UUID targetPlayer = null; - private Bot(MinecraftServer minecraftServer, ServerLevel worldServer, GameProfile profile) { + private boolean inPlayerList; + + private Bot(MinecraftServer minecraftServer, ServerLevel worldServer, GameProfile profile, boolean addToPlayerList) { super(minecraftServer, worldServer, profile, null); this.plugin = TerminatorPlus.getInstance(); @@ -91,6 +92,10 @@ public class Bot extends ServerPlayer implements Terminator { this.fireTicks = 0; this.removeOnDeath = true; this.offset = MathUtils.circleOffset(3); + if (addToPlayerList) { + minecraftServer.getPlayerList().getPlayers().add(this); + inPlayerList = true; + } //this.entityData.set(new EntityDataAccessor<>(16, EntityDataSerializers.BYTE), (byte) 0xFF); } @@ -106,8 +111,10 @@ public class Bot extends ServerPlayer implements Terminator { UUID uuid = BotUtils.randomSteveUUID(); CustomGameProfile profile = new CustomGameProfile(uuid, ChatUtils.trim16(name), skin); + + boolean addPlayerList = TerminatorPlus.getInstance().getManager().addToPlayerList(); - Bot bot = new Bot(nmsServer, nmsWorld, profile); + Bot bot = new Bot(nmsServer, nmsWorld, profile, addPlayerList); bot.connection = new ServerGamePacketListenerImpl(nmsServer, new Connection(PacketFlow.CLIENTBOUND) { @@ -122,7 +129,10 @@ public class Bot extends ServerPlayer implements Terminator { bot.getBukkitEntity().setNoDamageTicks(0); Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send( new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, bot))); - nmsWorld.addFreshEntity(bot); + if (addPlayerList) + nmsWorld.addNewPlayer(bot); + else + nmsWorld.addFreshEntity(bot); bot.renderAll(); TerminatorPlus.getInstance().getManager().add(bot); @@ -653,6 +663,8 @@ public class Bot extends ServerPlayer implements Terminator { scheduler.runTask(plugin, () -> this.remove(RemovalReason.DISCARDED)); } this.removeVisually(); + if (inPlayerList) + this.server.getPlayerList().getPlayers().remove(this); } private void removeTab() { @@ -921,6 +933,11 @@ public class Bot extends ServerPlayer implements Terminator { baseTick(); } + @Override + public boolean isInPlayerList() { + return inPlayerList; + } + @Override public World.Environment getDimension() { return getBukkitEntity().getWorld().getEnvironment(); diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/BotManagerImpl.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/BotManagerImpl.java index 38d25db..aaec0d0 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/BotManagerImpl.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/bot/BotManagerImpl.java @@ -35,6 +35,8 @@ public class BotManagerImpl implements BotManager, Listener { public boolean joinMessages = false; private boolean mobTarget = false; + private boolean addPlayerList = false; + public BotManagerImpl() { this.agent = new LegacyAgent(this, TerminatorPlus.getInstance()); this.bots = ConcurrentHashMap.newKeySet(); //should fix concurrentmodificationexception @@ -213,6 +215,16 @@ public class BotManagerImpl implements BotManager, Listener { public void setMobTarget(boolean mobTarget) { this.mobTarget = mobTarget; } + + @Override + public boolean addToPlayerList() { + return addPlayerList; + } + + @Override + public void setAddToPlayerList(boolean addPlayerList) { + this.addPlayerList = addPlayerList; + } @EventHandler public void onJoin(PlayerJoinEvent event) { diff --git a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotCommand.java b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotCommand.java index 2d2b729..7a13905 100644 --- a/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotCommand.java +++ b/TerminatorPlus-Plugin/src/main/java/net/nuggetmc/tplus/command/commands/BotCommand.java @@ -287,12 +287,13 @@ public class BotCommand extends CommandInstance { String extra = ChatColor.GRAY + " [" + ChatColor.YELLOW + "/bot settings" + ChatColor.GRAY + "]"; if (arg1 == null || ((!arg1.equalsIgnoreCase("setgoal")) && !arg1.equalsIgnoreCase("mobtarget") && !arg1.equalsIgnoreCase("playertarget") - && !arg1.equalsIgnoreCase("region"))) { + && !arg1.equalsIgnoreCase("addplayerlist") && !arg1.equalsIgnoreCase("region"))) { sender.sendMessage(ChatUtils.LINE); sender.sendMessage(ChatColor.GOLD + "Bot Settings" + extra); sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "setgoal" + ChatUtils.BULLET_FORMATTED + "Set the global bot target selection method."); sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "mobtarget" + ChatUtils.BULLET_FORMATTED + "Allow all bots to be targeted by hostile mobs."); sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "playertarget" + ChatUtils.BULLET_FORMATTED + "Sets a player name for spawned bots to focus on if the goal is PLAYER."); + sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "addplayerlist" + ChatUtils.BULLET_FORMATTED + "Adds newly spawned bots to the player list. This allows the bots to be affected by player selectors like @a and @p."); sender.sendMessage(ChatUtils.BULLET_FORMATTED + ChatColor.YELLOW + "region" + ChatUtils.BULLET_FORMATTED + "Sets a region for the bots to prioritize entities inside."); sender.sendMessage(ChatUtils.LINE); return; @@ -341,6 +342,17 @@ public class BotCommand extends CommandInstance { fetch.setTargetPlayer(player.getUniqueId()); } sender.sendMessage("All spawned bots are now set to target " + ChatColor.BLUE + player.getName() + ChatColor.RESET + ". They will target the closest player if they can't be found.\nYou may need to set the goal to PLAYER."); + } else if (arg1.equalsIgnoreCase("addplayerlist")) { + if (arg2 == null) { + sender.sendMessage("Adding bots to the player list is currently " + (manager.addToPlayerList() ? ChatColor.GREEN + "enabled" : ChatColor.RED + "disabled") + ChatColor.RESET + "."); + return; + } + if (!arg2.equals("true") && !arg2.equals("false")) { + sender.sendMessage(ChatColor.RED + "You must specify true or false!"); + return; + } + manager.setAddToPlayerList(Boolean.parseBoolean(arg2)); + sender.sendMessage("Adding bots to the player list is now " + (manager.addToPlayerList() ? ChatColor.GREEN + "enabled" : ChatColor.RED + "disabled") + ChatColor.RESET + "."); } else if (arg1.equalsIgnoreCase("region")) { if (arg2 == null) { if (agent.getRegion() == null) { @@ -430,6 +442,7 @@ public class BotCommand extends CommandInstance { output.add("setgoal"); output.add("mobtarget"); output.add("playertarget"); + output.add("addplayerlist"); output.add("region"); } else if (args.length == 3) { if (args[1].equalsIgnoreCase("setgoal")) { @@ -444,6 +457,10 @@ public class BotCommand extends CommandInstance { output.add(player.getName()); } } + if (args[1].equalsIgnoreCase("addplayerlist")) { + output.add("true"); + output.add("false"); + } } return output;