Option to add bots to player list

-Useful for datapacks that may use commands that target players
-This will count towards the player count
This commit is contained in:
ThisTestUser
2022-11-19 15:58:20 -05:00
parent 9350b6fba3
commit 765c3d6fb4
6 changed files with 63 additions and 10 deletions

View File

@@ -50,4 +50,7 @@ public interface BotManager {
void setMobTarget(boolean mobTarget); void setMobTarget(boolean mobTarget);
boolean addToPlayerList();
void setAddToPlayerList(boolean addPlayerList);
} }

View File

@@ -125,5 +125,7 @@ public interface Terminator {
void setTargetPlayer(UUID target); void setTargetPlayer(UUID target);
boolean isInPlayerList();
World.Environment getDimension(); World.Environment getDimension();
} }

View File

@@ -50,6 +50,7 @@ public class LegacyAgent extends Agent {
private final Map<BukkitRunnable, Byte> mining = new HashMap<>(); private final Map<BukkitRunnable, Byte> mining = new HashMap<>();
private final Set<Terminator> fallDamageCooldown = new HashSet<>(); private final Set<Terminator> fallDamageCooldown = new HashSet<>();
public boolean offsets = true; public boolean offsets = true;
private List<LivingEntity> botEntityCache;
private EnumTargetGoal goal; private EnumTargetGoal goal;
private BoundingBox region; private BoundingBox region;
private double regionWeightX; private double regionWeightX;
@@ -69,7 +70,8 @@ public class LegacyAgent extends Agent {
@Override @Override
protected void tick() { 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) { private void center(Terminator bot) {
@@ -1426,7 +1428,7 @@ public class LegacyAgent extends Agent {
this.goal = goal; this.goal = goal;
} }
public LivingEntity locateTarget(Terminator bot, Location loc, EnumTargetGoal... targetGoal) { private LivingEntity locateTarget(Terminator bot, Location loc, EnumTargetGoal... targetGoal) {
LivingEntity result = null; LivingEntity result = null;
EnumTargetGoal g = goal; EnumTargetGoal g = goal;
@@ -1437,7 +1439,7 @@ public class LegacyAgent extends Agent {
case NEAREST_PLAYER: { case NEAREST_PLAYER: {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
if (validateCloserEntity(player, loc, result)) { if (!botEntityCache.contains(player) && validateCloserEntity(player, loc, result)) {
result = player; result = player;
} }
} }
@@ -1447,7 +1449,7 @@ public class LegacyAgent extends Agent {
case NEAREST_VULNERABLE_PLAYER: { case NEAREST_VULNERABLE_PLAYER: {
for (Player player : Bukkit.getOnlinePlayers()) { 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; 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. case PLAYER: { //Target a single player. Defaults to NEAREST_VULNERABLE_PLAYER if no player found.
if (bot.getTargetPlayer() != null) { if (bot.getTargetPlayer() != null) {
Player player = Bukkit.getPlayer(bot.getTargetPlayer()); 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; return player;
} }
} }

View File

@@ -35,7 +35,6 @@ import org.bukkit.*;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Waterlogged; 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.CraftEquipmentSlot;
import org.bukkit.craftbukkit.v1_19_R1.CraftServer; import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
@@ -78,7 +77,9 @@ public class Bot extends ServerPlayer implements Terminator {
private byte noFallTicks; private byte noFallTicks;
private List<Block> standingOn = new ArrayList<>(); private List<Block> standingOn = new ArrayList<>();
private UUID targetPlayer = null; 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); super(minecraftServer, worldServer, profile, null);
this.plugin = TerminatorPlus.getInstance(); this.plugin = TerminatorPlus.getInstance();
@@ -91,6 +92,10 @@ public class Bot extends ServerPlayer implements Terminator {
this.fireTicks = 0; this.fireTicks = 0;
this.removeOnDeath = true; this.removeOnDeath = true;
this.offset = MathUtils.circleOffset(3); this.offset = MathUtils.circleOffset(3);
if (addToPlayerList) {
minecraftServer.getPlayerList().getPlayers().add(this);
inPlayerList = true;
}
//this.entityData.set(new EntityDataAccessor<>(16, EntityDataSerializers.BYTE), (byte) 0xFF); //this.entityData.set(new EntityDataAccessor<>(16, EntityDataSerializers.BYTE), (byte) 0xFF);
} }
@@ -107,7 +112,9 @@ public class Bot extends ServerPlayer implements Terminator {
CustomGameProfile profile = new CustomGameProfile(uuid, ChatUtils.trim16(name), skin); CustomGameProfile profile = new CustomGameProfile(uuid, ChatUtils.trim16(name), skin);
Bot bot = new Bot(nmsServer, nmsWorld, profile); boolean addPlayerList = TerminatorPlus.getInstance().getManager().addToPlayerList();
Bot bot = new Bot(nmsServer, nmsWorld, profile, addPlayerList);
bot.connection = new ServerGamePacketListenerImpl(nmsServer, new Connection(PacketFlow.CLIENTBOUND) { bot.connection = new ServerGamePacketListenerImpl(nmsServer, new Connection(PacketFlow.CLIENTBOUND) {
@@ -122,7 +129,10 @@ public class Bot extends ServerPlayer implements Terminator {
bot.getBukkitEntity().setNoDamageTicks(0); bot.getBukkitEntity().setNoDamageTicks(0);
Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send( Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send(
new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, bot))); new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, bot)));
nmsWorld.addFreshEntity(bot); if (addPlayerList)
nmsWorld.addNewPlayer(bot);
else
nmsWorld.addFreshEntity(bot);
bot.renderAll(); bot.renderAll();
TerminatorPlus.getInstance().getManager().add(bot); TerminatorPlus.getInstance().getManager().add(bot);
@@ -653,6 +663,8 @@ public class Bot extends ServerPlayer implements Terminator {
scheduler.runTask(plugin, () -> this.remove(RemovalReason.DISCARDED)); scheduler.runTask(plugin, () -> this.remove(RemovalReason.DISCARDED));
} }
this.removeVisually(); this.removeVisually();
if (inPlayerList)
this.server.getPlayerList().getPlayers().remove(this);
} }
private void removeTab() { private void removeTab() {
@@ -921,6 +933,11 @@ public class Bot extends ServerPlayer implements Terminator {
baseTick(); baseTick();
} }
@Override
public boolean isInPlayerList() {
return inPlayerList;
}
@Override @Override
public World.Environment getDimension() { public World.Environment getDimension() {
return getBukkitEntity().getWorld().getEnvironment(); return getBukkitEntity().getWorld().getEnvironment();

View File

@@ -35,6 +35,8 @@ public class BotManagerImpl implements BotManager, Listener {
public boolean joinMessages = false; public boolean joinMessages = false;
private boolean mobTarget = false; private boolean mobTarget = false;
private boolean addPlayerList = false;
public BotManagerImpl() { public BotManagerImpl() {
this.agent = new LegacyAgent(this, TerminatorPlus.getInstance()); this.agent = new LegacyAgent(this, TerminatorPlus.getInstance());
this.bots = ConcurrentHashMap.newKeySet(); //should fix concurrentmodificationexception this.bots = ConcurrentHashMap.newKeySet(); //should fix concurrentmodificationexception
@@ -214,6 +216,16 @@ public class BotManagerImpl implements BotManager, Listener {
this.mobTarget = mobTarget; this.mobTarget = mobTarget;
} }
@Override
public boolean addToPlayerList() {
return addPlayerList;
}
@Override
public void setAddToPlayerList(boolean addPlayerList) {
this.addPlayerList = addPlayerList;
}
@EventHandler @EventHandler
public void onJoin(PlayerJoinEvent event) { public void onJoin(PlayerJoinEvent event) {
ServerGamePacketListenerImpl connection = ((CraftPlayer) event.getPlayer()).getHandle().connection; ServerGamePacketListenerImpl connection = ((CraftPlayer) event.getPlayer()).getHandle().connection;

View File

@@ -287,12 +287,13 @@ public class BotCommand extends CommandInstance {
String extra = ChatColor.GRAY + " [" + ChatColor.YELLOW + "/bot settings" + ChatColor.GRAY + "]"; String extra = ChatColor.GRAY + " [" + ChatColor.YELLOW + "/bot settings" + ChatColor.GRAY + "]";
if (arg1 == null || ((!arg1.equalsIgnoreCase("setgoal")) && !arg1.equalsIgnoreCase("mobtarget") && !arg1.equalsIgnoreCase("playertarget") 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(ChatUtils.LINE);
sender.sendMessage(ChatColor.GOLD + "Bot Settings" + extra); 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 + "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 + "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 + "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.BULLET_FORMATTED + ChatColor.YELLOW + "region" + ChatUtils.BULLET_FORMATTED + "Sets a region for the bots to prioritize entities inside.");
sender.sendMessage(ChatUtils.LINE); sender.sendMessage(ChatUtils.LINE);
return; return;
@@ -341,6 +342,17 @@ public class BotCommand extends CommandInstance {
fetch.setTargetPlayer(player.getUniqueId()); 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."); 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")) { } else if (arg1.equalsIgnoreCase("region")) {
if (arg2 == null) { if (arg2 == null) {
if (agent.getRegion() == null) { if (agent.getRegion() == null) {
@@ -430,6 +442,7 @@ public class BotCommand extends CommandInstance {
output.add("setgoal"); output.add("setgoal");
output.add("mobtarget"); output.add("mobtarget");
output.add("playertarget"); output.add("playertarget");
output.add("addplayerlist");
output.add("region"); output.add("region");
} else if (args.length == 3) { } else if (args.length == 3) {
if (args[1].equalsIgnoreCase("setgoal")) { if (args[1].equalsIgnoreCase("setgoal")) {
@@ -444,6 +457,10 @@ public class BotCommand extends CommandInstance {
output.add(player.getName()); output.add(player.getName());
} }
} }
if (args[1].equalsIgnoreCase("addplayerlist")) {
output.add("true");
output.add("false");
}
} }
return output; return output;