Merge changes from magma branch (except downgrade)

This commit is contained in:
ThisTestUser
2024-09-18 21:17:35 +00:00
parent c2e2dd4c39
commit e9080595c6
11 changed files with 539 additions and 21 deletions

View File

@@ -12,6 +12,7 @@ public enum EnumTargetGoal {
NEAREST_BOT("Locate the nearest bot."),
NEAREST_BOT_DIFFER("Locate the nearest bot with a different username."),
NEAREST_BOT_DIFFER_ALPHA("Locate the nearest bot with a different username after filtering out non-alpha characters."),
CUSTOM_LIST("Locate only the mob types specified in the custom list of mobs"),
PLAYER("Target a single player. Defaults to NEAREST_VULNERABLE_PLAYER if no player found."),
NONE("No target goal.");
@@ -26,6 +27,7 @@ public enum EnumTargetGoal {
this.put("nearestbot", NEAREST_BOT);
this.put("nearestbotdiffer", NEAREST_BOT_DIFFER);
this.put("nearestbotdifferalpha", NEAREST_BOT_DIFFER_ALPHA);
this.put("customlist", CUSTOM_LIST);
this.put("player", PLAYER);
}
};

View File

@@ -57,6 +57,9 @@ public class LegacyAgent extends Agent {
private double regionWeightY;
private double regionWeightZ;
public static final Set<EntityType> CUSTOM_TYPES_LIST = new HashSet<>();
public static boolean areCustomTypesHostile = false;
public LegacyAgent(BotManager manager, Plugin plugin) {
super(manager, plugin);
@@ -1456,7 +1459,7 @@ public class LegacyAgent extends Agent {
case NEAREST_HOSTILE: {
for (LivingEntity entity : bot.getBukkitEntity().getWorld().getLivingEntities()) {
if (entity instanceof Monster && validateCloserEntity(entity, loc, result)) {
if ((entity instanceof Monster || (areCustomTypesHostile && CUSTOM_TYPES_LIST.contains(entity.getType()))) && validateCloserEntity(entity, loc, result)) {
result = entity;
}
}
@@ -1476,7 +1479,7 @@ public class LegacyAgent extends Agent {
case NEAREST_MOB: {
for (LivingEntity entity : bot.getBukkitEntity().getWorld().getLivingEntities()) {
if (entity instanceof Mob && validateCloserEntity(entity, loc, result)) {
if ((entity instanceof Mob || CUSTOM_TYPES_LIST.contains(entity.getType())) && validateCloserEntity(entity, loc, result)) {
result = entity;
}
}
@@ -1526,15 +1529,29 @@ public class LegacyAgent extends Agent {
}
}
}
break;
}
case PLAYER: { //Target a single player. Defaults to NEAREST_VULNERABLE_PLAYER if no player found.
case CUSTOM_LIST: {
for (LivingEntity entity : bot.getBukkitEntity().getWorld().getLivingEntities()) {
if (CUSTOM_TYPES_LIST.contains(entity.getType()) && validateCloserEntity(entity, loc, result)) {
result = entity;
}
}
break;
}
case PLAYER: {
if (bot.getTargetPlayer() != null) {
Player player = Bukkit.getPlayer(bot.getTargetPlayer());
if (player != null && !botsInPlayerList.contains(player) && validateCloserEntity(player, loc, null)) {
return player;
result = player;
}
}
return locateTarget(bot, loc, EnumTargetGoal.NEAREST_VULNERABLE_PLAYER);
break;
}
}
TerminatorLocateTargetEvent event = new TerminatorLocateTargetEvent(bot, result);

View File

@@ -176,7 +176,7 @@ public class LegacyBlockCheck {
// Blocks before must all be pass-through
Material type = below.getBlock().getType();
if (type.isSolid() || LegacyMats.canStandOn(type))
if (LegacyMats.isSolid(type) || LegacyMats.canStandOn(type))
return false;
below = below.clone();
}
@@ -192,7 +192,7 @@ public class LegacyBlockCheck {
Block next = itr.next().getBlock();
boolean placeable = nether ? LegacyMats.canPlaceTwistingVines(next)
: LegacyMats.canPlaceWater(next, Optional.absent());
if (placeable || (!next.getType().isSolid() && !LegacyMats.canStandOn(next.getType())))
if (placeable || (!LegacyMats.isSolid(next.getType()) && !LegacyMats.canStandOn(next.getType())))
itr.remove();
}

View File

@@ -85,7 +85,7 @@ public class LegacyMats {
Material.JUNGLE_SIGN, Material.JUNGLE_SLAB, Material.JUNGLE_STAIRS, Material.JUNGLE_TRAPDOOR, Material.JUNGLE_WALL_SIGN, Material.JUNGLE_WOOD,
Material.SPRUCE_PLANKS, Material.SPRUCE_DOOR, Material.SPRUCE_FENCE, Material.SPRUCE_FENCE_GATE, Material.SPRUCE_LOG,
Material.SPRUCE_SIGN, Material.SPRUCE_SLAB, Material.SPRUCE_STAIRS, Material.SPRUCE_TRAPDOOR, Material.SPRUCE_WALL_SIGN, Material.SPRUCE_WOOD,
Material.MANGROVE_PLANKS, Material.MANGROVE_DOOR, Material.MANGROVE_FENCE, Material.MANGROVE_FENCE_GATE, Material.MANGROVE_LOG,
Material.MANGROVE_PLANKS, Material.MANGROVE_DOOR, Material.MANGROVE_FENCE, Material.MANGROVE_FENCE_GATE, Material.MANGROVE_LOG,
Material.MANGROVE_SIGN, Material.MANGROVE_SLAB, Material.MANGROVE_STAIRS, Material.MANGROVE_TRAPDOOR, Material.MANGROVE_WALL_SIGN, Material.MANGROVE_WOOD,
Material.CRIMSON_PLANKS, Material.CRIMSON_DOOR, Material.CRIMSON_FENCE, Material.CRIMSON_FENCE_GATE, Material.CRIMSON_STEM,
Material.CRIMSON_SIGN, Material.CRIMSON_SLAB, Material.CRIMSON_STAIRS, Material.CRIMSON_TRAPDOOR, Material.CRIMSON_WALL_SIGN,
@@ -319,7 +319,7 @@ public class LegacyMats {
}
public static boolean canPlaceWater(Block block, Optional<Double> entityYPos) {
if (block.getType().isSolid()) {
if (isSolid(block.getType())) {
if (block.getType() == Material.CHAIN && ((Chain)block.getBlockData()).getAxis() == Axis.Y
&& !((Chain)block.getBlockData()).isWaterlogged())
return false;
@@ -381,7 +381,7 @@ public class LegacyMats {
}
public static boolean canPlaceTwistingVines(Block block) {
if (block.getType().isSolid()) {
if (isSolid(block.getType())) {
if (block.getType().data == Leaves.class)
return false;
if (block.getType().name().endsWith("_CORAL_FAN") || block.getType().name().endsWith("_CORAL")
@@ -515,4 +515,13 @@ public class LegacyMats {
return false;
}
}
/**
* This set stores solid materials that are added by mods.
*/
public static final Set<Material> SOLID_MATERIALS = new HashSet<>();
public static boolean isSolid(Material mat) {
return mat.isSolid() || SOLID_MATERIALS.contains(mat);
}
}

View File

@@ -8,6 +8,8 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import net.nuggetmc.tplus.api.agent.legacyagent.LegacyMats;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
@@ -53,7 +55,7 @@ public class PlayerUtils {
boolean check = false;
for (int i = 0; i <= amount; i++) {
if (loc.clone().add(0, i, 0).getBlock().getType().isSolid()) {
if (LegacyMats.isSolid(loc.clone().add(0, i, 0).getBlock().getType())) {
check = true;
break;
}
@@ -76,7 +78,7 @@ public class PlayerUtils {
break;
}
if (check.getBlock().getType().isSolid()) {
if (LegacyMats.isSolid(check.getBlock().getType())) {
return check.add(0, 1, 0);
}
}

View File

@@ -93,6 +93,11 @@ public class Bot extends ServerPlayer implements Terminator {
inPlayerList = true;
}
// Magma fix - In case a mod causes the Bukkit entity to be created too early
try {
getClass().getMethod("resetBukkitEntity").invoke(this);
} catch (ReflectiveOperationException e) {}
//this.entityData.set(new EntityDataAccessor<>(16, EntityDataSerializers.BYTE), (byte) 0xFF);
}
@@ -544,7 +549,7 @@ public class Bot extends ServerPlayer implements Terminator {
Location loc = new Location(world, x, position().y - 0.01, z);
Block block = world.getBlockAt(loc);
if ((block.getType().isSolid() || LegacyMats.canStandOn(block.getType())) && BotUtils.overlaps(playerBox, block.getBoundingBox())) {
if ((LegacyMats.isSolid(block.getType()) || LegacyMats.canStandOn(block.getType())) && BotUtils.overlaps(playerBox, block.getBoundingBox())) {
if (!locations.contains(block.getLocation())) {
standingOn.add(block);
locations.add(block.getLocation());
@@ -563,7 +568,7 @@ public class Bot extends ServerPlayer implements Terminator {
blockBox.getMinY() + 1.5, blockBox.getMaxZ());
if ((LegacyMats.FENCE.contains(block.getType()) || LegacyMats.GATES.contains(block.getType()))
&& block.getType().isSolid() && BotUtils.overlaps(playerBox, modifiedBox)) {
&& LegacyMats.isSolid(block.getType()) && BotUtils.overlaps(playerBox, modifiedBox)) {
if (!locations.contains(block.getLocation())) {
standingOn.add(block);
locations.add(block.getLocation());
@@ -815,7 +820,7 @@ public class Bot extends ServerPlayer implements Terminator {
Block block = loc.getBlock();
World world = loc.getWorld();
if (!block.getType().isSolid()) {
if (!LegacyMats.isSolid(block.getType())) {
block.setType(type);
if (world != null) world.playSound(loc, Sound.BLOCK_STONE_PLACE, SoundCategory.BLOCKS, 1, 1);
}
@@ -882,6 +887,7 @@ public class Bot extends ServerPlayer implements Terminator {
@Override
public void doTick() {
//detectEquipmentUpdatesPublic();
baseTick();
}

View File

@@ -8,6 +8,7 @@ import net.nuggetmc.tplus.command.annotation.Command;
import net.nuggetmc.tplus.command.annotation.Require;
import net.nuggetmc.tplus.command.commands.AICommand;
import net.nuggetmc.tplus.command.commands.BotCommand;
import net.nuggetmc.tplus.command.commands.BotEnvironmentCommand;
import net.nuggetmc.tplus.command.commands.MainCommand;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@@ -43,7 +44,8 @@ public class CommandHandler {
registerCommands(
new MainCommand(this, "terminatorplus", "The TerminatorPlus main command.", "tplus"),
new BotCommand(this, "bot", "The root command for bot management.", "npc"),
new AICommand(this, "ai", "The root command for bot AI training.")
new AICommand(this, "ai", "The root command for bot AI training."),
new BotEnvironmentCommand(this, "botenvironment", "Do /botenvironment help for more information.", "botenv")
);
}

View File

@@ -64,7 +64,7 @@ public abstract class CommandInstance extends BukkitCommand {
}
protected void addAlias(String alias, String name) {
aliasesToNames.put(alias, name);
aliasesToNames.put(alias, name);
}
@Override
@@ -235,17 +235,25 @@ public abstract class CommandInstance extends BukkitCommand {
@SuppressWarnings("unchecked")
public List<String> tabComplete(@Nonnull CommandSender sender, @Nonnull String label, @Nonnull String[] args) {
if (args.length == 1) {
return methods.keySet().stream().filter(c -> !c.isEmpty()).collect(Collectors.toList());
List<String> result = methods.keySet().stream().filter(c -> !c.isEmpty() && c.contains(args[0])).collect(Collectors.toList());
if (result.isEmpty()) {
// Add aliases also
methods.forEach((s, m) -> result.addAll(m.getAliases()));
return result.stream().filter(c -> c.contains(args[0])).collect(Collectors.toList());
}
return result;
}
if (args.length > 1) {
CommandMethod commandMethod = methods.get(args[0]);
if (commandMethod == null)
commandMethod = methods.values().stream().filter(m -> m.getAliases().contains(args[0])).findFirst().orElse(null);
if (commandMethod == null) return new ArrayList<>();
Method autofiller = commandMethod.getAutofiller();
if (autofiller != null) {
try {
return (List<String>) autofiller.invoke(commandMethod.getHandler(), sender, args);
return ((List<String>) autofiller.invoke(commandMethod.getHandler(), sender, args)).stream().filter(c -> c.contains(args[args.length - 1])).collect(Collectors.toList());
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}

View File

@@ -520,12 +520,18 @@ public class BotCommand extends CommandInstance {
@Command(
name = "debug",
desc = "Debug plugin code.",
visible = false
visible = false,
autofill = "debugAutofill"
)
public void debug(CommandSender sender, @Arg("expression") String expression) {
new Debugger(sender).execute(expression);
}
@Autofill
public List<String> debugAutofill(CommandSender sender, String[] args) {
return args.length == 2 ? new ArrayList<>(Debugger.AUTOFILL_METHODS) : new ArrayList<>();
}
private double parseDoubleOrRelative(String pos, Location loc, int type) {
if (loc == null || pos.length() == 0 || pos.charAt(0) != '~')
return Double.parseDouble(pos);

View File

@@ -0,0 +1,431 @@
package net.nuggetmc.tplus.command.commands;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.nuggetmc.tplus.api.agent.legacyagent.LegacyAgent;
import net.nuggetmc.tplus.api.agent.legacyagent.LegacyMats;
import net.nuggetmc.tplus.api.utils.ChatUtils;
import net.nuggetmc.tplus.command.CommandHandler;
import net.nuggetmc.tplus.command.CommandInstance;
import net.nuggetmc.tplus.command.annotation.Arg;
import net.nuggetmc.tplus.command.annotation.Autofill;
import net.nuggetmc.tplus.command.annotation.Command;
import net.nuggetmc.tplus.command.annotation.OptArg;
public class BotEnvironmentCommand extends CommandInstance {
private static final Set<String> LOADED_MODS = new HashSet<>();
private static boolean loaded;
public BotEnvironmentCommand(CommandHandler handler, String name, String description, String... aliases) {
super(handler, name, description, aliases);
}
@Command
public void root(CommandSender sender, List<String> args) {
commandHandler.sendRootInfo(this, sender);
}
@Command(
name = "help",
desc = "Help for /botenvironment.",
autofill = "autofill"
)
public void help(CommandSender sender, List<String> args) {
if (args.size() > 0 && args.get(0).equals("blocks")) {
sender.sendMessage(ChatUtils.LINE);
sender.sendMessage("If you are running this plugin on a Magma server, keep in mind that blocks added by mods are not considered solid.");
sender.sendMessage("You must manually add solid blocks added by mods with " + ChatColor.YELLOW + "/botenvironment addSolid <material>" + ChatColor.RESET + ".");
sender.sendMessage("The material name is the mod ID and the block name concatted with a \"_\", converted to uppercase.");
sender.sendMessage("For example, if mod \"examplemod\" adds a block \"custom_block\", the material name is EXAMPLEMOD_CUSTOM_BLOCK.");
sender.sendMessage("Additionally, you may use " + ChatColor.YELLOW + "/botenvironment addSolidGroup <modid>" + ChatColor.RESET + ", where modid is the uppercase MODID plus a \"_\"");
sender.sendMessage(ChatUtils.LINE);
} else if (args.size() > 0 && args.get(0).equals("mobs")) {
sender.sendMessage(ChatUtils.LINE);
sender.sendMessage("Sometimes, you may want to have a pre-set list of mob types that the bot will target.");
sender.sendMessage("Additionally, some mobs (especially bosses) may not be considered as hostile.");
sender.sendMessage("To resolve this, use " + ChatColor.YELLOW + "/botenvironment addCustomMob <name>" + ChatColor.RESET + " to add mob types to a list.");
sender.sendMessage(ChatColor.YELLOW + "/botenvironment mobListType" + ChatColor.RESET + " changes if the nearest hostile targeting option should consider this list.");
sender.sendMessage("The nearest mob and custom list targeting options will always include mobs in this list.");
sender.sendMessage(ChatUtils.LINE);
} else {
sender.sendMessage("Do " + ChatColor.YELLOW + "/botenvironment help blocks " + ChatColor.RESET + "for more information on adding solid blocks.");
sender.sendMessage("Do " + ChatColor.YELLOW + "/botenvironment help mobs " + ChatColor.RESET + "for more information on adding custom mobs.");
}
}
@Command(
name = "getMaterial",
desc = "Prints out the current material at the specified location.",
aliases = {"getmat", "getMat", "getmaterial"}
)
public void getMaterial(Player sender, @Arg("x") String x, @Arg("y") String y, @Arg("z") String z) {
Location loc = sender.getLocation().clone();
try {
loc.setX(parseDoubleOrRelative(x, loc, 0));
loc.setY(parseDoubleOrRelative(y, loc, 1));
loc.setZ(parseDoubleOrRelative(z, loc, 2));
} catch (NumberFormatException e) {
sender.sendMessage("A valid location must be provided!");
return;
}
if (!isLocationLoaded(loc)) {
sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is not loaded.",
loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
return;
}
if (Math.abs(loc.getX() - sender.getLocation().getX()) > 250 || Math.abs(loc.getZ() - sender.getLocation().getZ()) > 250) {
sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is too far away.",
loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
return;
}
Material mat = loc.getBlock().getType();
sender.sendMessage(String.format("Material at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + ": " + ChatColor.GREEN + "%s" + ChatColor.RESET,
loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), mat.name()));
}
@Command(
name = "addSolidGroup",
desc = "Adds every block starting with a prefix to the list of solid materials.",
aliases = {"addsolidgroup"},
autofill = "autofill"
)
public void addSolidGroup(CommandSender sender, @Arg("prefix") String prefix, @OptArg("includeNonSolid") boolean includeNonSolid) {
try {
Field byName = Material.class.getDeclaredField("BY_NAME");
byName.setAccessible(true);
Map<String, Material> map = (Map<String, Material>) byName.get(null);
Map<Material, Block> materialsToBlocks = new HashMap<>();
if (!includeNonSolid) {
// Build material -> block map using ForgeRegistries
Object blocksRegistry = Class.forName("net.minecraftforge.registries.ForgeRegistries").getDeclaredField("BLOCKS").get(null);
Set<Entry<ResourceKey<Block>, Block>> blockSet = (Set<Entry<ResourceKey<Block>, Block>>) Class.forName("net.minecraftforge.registries.IForgeRegistry").getMethod("getEntries").invoke(blocksRegistry);
for (Entry<ResourceKey<Block>, Block> entry : blockSet) {
String result = (String) Class.forName("org.magmafoundation.magma.util.ResourceLocationUtil").getMethod("standardize", ResourceLocation.class).invoke(null, entry.getKey().location());
Material material = Material.getMaterial(result);
if (material != null)
materialsToBlocks.put(material, entry.getValue());
}
}
int added = 0;
for (Entry<String, Material> entry : map.entrySet()) {
boolean valid = entry.getValue().isBlock() && entry.getKey().startsWith(prefix);
if (valid && !includeNonSolid)
if (!materialsToBlocks.containsKey(entry.getValue())) {
sender.sendMessage("Warning: The material " + ChatColor.GREEN + entry.getValue().name() + ChatColor.RESET
+ " was not found in the Forge registries, this should not happen!");
} else {
// Check if block is solid
Block block = materialsToBlocks.get(entry.getValue());
valid = false; //TODO: BROKEN
}
if (valid && LegacyMats.SOLID_MATERIALS.add(entry.getValue()))
added++;
}
sender.sendMessage("Successfully added " + ChatColor.BLUE + added + ChatColor.RESET + " materials with prefix " + ChatColor.GREEN + prefix + ChatColor.RESET);
} catch(ReflectiveOperationException e) {
sender.sendMessage("This command only works on Magma servers!");
}
}
@Command(
name = "addSolid",
desc = "Adds a material to the list of solid materials.",
aliases = {"addsolid"},
autofill = "autofill"
)
public void addSolid(CommandSender sender, List<String> args) {
Material mat;
if (args.size() == 1)
mat = Material.getMaterial(args.get(0));
else if (args.size() == 3) {
if (!(sender instanceof Player)) {
sender.sendMessage("You must be a player to specify coordinates!");
return;
}
Location loc = ((Player)sender).getLocation().clone();
try {
loc.setX(parseDoubleOrRelative(args.get(0), loc, 0));
loc.setY(parseDoubleOrRelative(args.get(1), loc, 1));
loc.setZ(parseDoubleOrRelative(args.get(2), loc, 2));
} catch (NumberFormatException e) {
sender.sendMessage("A valid location must be provided! " + ChatColor.YELLOW + "/bot addSolid <x> <y> <z>" + ChatColor.RESET);
return;
}
if (!isLocationLoaded(loc)) {
sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is not loaded.",
loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
return;
}
if (Math.abs(loc.getX() - ((Player)sender).getLocation().getX()) > 250 || Math.abs(loc.getZ() - ((Player)sender).getLocation().getZ()) > 250) {
sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is too far away.",
loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
return;
}
mat = loc.getBlock().getType();
} else {
sender.sendMessage("Invalid syntax!");
sender.sendMessage("To specify a material: " + ChatColor.YELLOW + "/bot addSolid <material>" + ChatColor.RESET);
sender.sendMessage("To specify a location containing a material: " + ChatColor.YELLOW + "/bot addSolid <x> <y> <z>" + ChatColor.RESET);
return;
}
if (mat == null) {
sender.sendMessage("The material you specified does not exist!");
return;
}
if (LegacyMats.SOLID_MATERIALS.add(mat))
sender.sendMessage("Successfully added " + ChatColor.BLUE + mat.name() + ChatColor.RESET + " to the list.");
else
sender.sendMessage(ChatColor.BLUE + mat.name() + ChatColor.RESET + " already exists in the list!");
}
@Command(
name = "removeSolid",
desc = "Removes a material from the list of solid materials.",
aliases = {"removesolid"},
autofill = "autofill"
)
public void removeSolid(CommandSender sender, List<String> args) {
Material mat;
if (args.size() == 1)
mat = Material.getMaterial(args.get(0));
else if (args.size() == 3) {
if (!(sender instanceof Player)) {
sender.sendMessage("You must be a player to specify coordinates!");
return;
}
Location loc = ((Player)sender).getLocation().clone();
try {
loc.setX(parseDoubleOrRelative(args.get(0), loc, 0));
loc.setY(parseDoubleOrRelative(args.get(1), loc, 1));
loc.setZ(parseDoubleOrRelative(args.get(2), loc, 2));
} catch (NumberFormatException e) {
sender.sendMessage("A valid location must be provided! " + ChatColor.YELLOW + "/bot removeSolid <x> <y> <z>" + ChatColor.RESET);
return;
}
if (!isLocationLoaded(loc)) {
sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is not loaded.",
loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
return;
}
if (Math.abs(loc.getX() - ((Player)sender).getLocation().getX()) > 250 || Math.abs(loc.getZ() - ((Player)sender).getLocation().getZ()) > 250) {
sender.sendMessage(String.format("The location at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + " is too far away.",
loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()));
return;
}
mat = loc.getBlock().getType();
} else {
sender.sendMessage("Invalid syntax!");
sender.sendMessage("To specify a material: " + ChatColor.YELLOW + "/bot removeSolid <material>" + ChatColor.RESET);
sender.sendMessage("To specify a location containing a material: " + ChatColor.YELLOW + "/bot removeSolid <x> <y> <z>" + ChatColor.RESET);
return;
}
if (mat == null) {
sender.sendMessage("The material you specified does not exist!");
return;
}
if (LegacyMats.SOLID_MATERIALS.remove(mat))
sender.sendMessage("Successfully removed " + ChatColor.BLUE + mat.name() + ChatColor.RESET + " from the list.");
else
sender.sendMessage(ChatColor.BLUE + mat.name() + ChatColor.RESET + " does not exist in the list!");
}
@Command(
name = "listSolids",
desc = "Displays the list of solid materials manually added.",
aliases = {"listsolids"}
)
public void listSolids(CommandSender sender) {
sender.sendMessage(ChatUtils.LINE);
for (Material mat : LegacyMats.SOLID_MATERIALS)
sender.sendMessage(ChatColor.GREEN + mat.name() + ChatColor.RESET);
sender.sendMessage("Total items: " + ChatColor.BLUE + LegacyMats.SOLID_MATERIALS.size() + ChatColor.RESET);
sender.sendMessage(ChatUtils.LINE);
}
@Command(
name = "clearSolids",
desc = "Clears the list of solid materials manually added.",
aliases = {"clearsolids"}
)
public void clearSolids(CommandSender sender) {
int size = LegacyMats.SOLID_MATERIALS.size();
LegacyMats.SOLID_MATERIALS.clear();
sender.sendMessage("Removed all " + ChatColor.BLUE + size + ChatColor.RESET + " item(s) from the list.");
}
@Command(
name = "addCustomMob",
desc = "Adds a mob type to the list of custom mobs.",
aliases = {"addcustommob"},
autofill = "autofill"
)
public void addCustomMob(CommandSender sender, @Arg("mobName") String mobName) {
EntityType type = EntityType.fromName(mobName);
if (type == null) {
sender.sendMessage("The entity type you specified does not exist!");
return;
}
if (LegacyAgent.CUSTOM_TYPES_LIST.add(type))
sender.sendMessage("Successfully added " + ChatColor.BLUE + type.name() + ChatColor.RESET + " to the list.");
else
sender.sendMessage(ChatColor.BLUE + type.name() + ChatColor.RESET + " already exists in the list!");
}
@Command(
name = "removeCustomMob",
desc = "Removes a mob type to the list of custom mobs.",
aliases = {"removecustommob"},
autofill = "autofill"
)
public void removeCustomMob(CommandSender sender, @Arg("mobName") String mobName) {
EntityType type = EntityType.fromName(mobName);
if (type == null) {
sender.sendMessage("The entity type you specified does not exist!");
return;
}
if (LegacyAgent.CUSTOM_TYPES_LIST.remove(type))
sender.sendMessage("Successfully removed " + ChatColor.BLUE + type.name() + ChatColor.RESET + " from the list.");
else
sender.sendMessage(ChatColor.BLUE + type.name() + ChatColor.RESET + " does not exist in the list!");
}
@Command(
name = "listCustomMobs",
desc = "Displays the list of custom mobs manually added.",
aliases = {"listcustommobs"}
)
public void listCustomMobs(CommandSender sender) {
sender.sendMessage(ChatUtils.LINE);
for (EntityType type : LegacyAgent.CUSTOM_TYPES_LIST)
sender.sendMessage(ChatColor.GREEN + type.name() + ChatColor.RESET);
sender.sendMessage("Total items: " + ChatColor.BLUE + LegacyAgent.CUSTOM_TYPES_LIST.size() + ChatColor.RESET);
sender.sendMessage(ChatUtils.LINE);
}
@Command(
name = "clearCustomMobs",
desc = "Clears the list of custom mobs manually added.",
aliases = {"clearcustommobs"}
)
public void clearCustomMobs(CommandSender sender) {
int size = LegacyAgent.CUSTOM_TYPES_LIST.size();
LegacyAgent.CUSTOM_TYPES_LIST.clear();
sender.sendMessage("Removed all " + ChatColor.BLUE + size + ChatColor.RESET + " item(s) from the list.");
}
@Command(
name = "mobListType",
desc = "Changes the custom mob list type to hostile or passive.",
aliases = {"moblisttype"},
autofill = "autofill"
)
public void mobListType(CommandSender sender, List<String> args) {
if (args.isEmpty()) {
String type = LegacyAgent.areCustomTypesHostile ? "hostile" : "passive";
sender.sendMessage("The custom mob list type is " + ChatColor.BLUE + type + ChatColor.RESET + ".");
} else if (args.size() > 0 && args.get(0).equals("hostile")) {
LegacyAgent.areCustomTypesHostile = true;
sender.sendMessage("The custom mob list type has been set to " + ChatColor.BLUE + "hostile" + ChatColor.RESET + ".");
} else if (args.size() > 0 && args.get(0).equals("passive")) {
LegacyAgent.areCustomTypesHostile = false;
sender.sendMessage("The custom mob list type has been set to " + ChatColor.BLUE + "passive" + ChatColor.RESET + ".");
} else
sender.sendMessage("Usage: " + ChatColor.YELLOW + "/botenvironment mobListType (hostile|passive)" + ChatColor.RESET);
}
@Autofill
public List<String> autofill(CommandSender sender, String[] args) {
List<String> output = new ArrayList<>();
if (args.length == 2) {
if (args[0].equals("help")) {
output.add("blocks");
output.add("mobs");
} else if (matches(args[0], "addSolidGroup")) {
output.addAll(getLoadedMods());
} else if (matches(args[0], "addSolid") || matches(args[0], "removeSolid")) {
for (Material mat : Material.values())
if (!mat.isLegacy())
output.add(mat.name());
} else if (matches(args[0], "addCustomMob") || matches(args[0], "removeCustomMob")) {
for (EntityType type : EntityType.values())
if (type != EntityType.UNKNOWN)
output.add(type.name());
} else if (matches(args[0], "mobListType")) {
output.add("hostile");
output.add("passive");
}
}
return output;
}
private boolean matches(String input, String check) {
return input.equals(check) || input.equals(check.toLowerCase(Locale.ENGLISH));
}
private double parseDoubleOrRelative(String pos, Location loc, int type) {
if (loc == null || pos.length() == 0 || pos.charAt(0) != '~')
return Double.parseDouble(pos);
double relative = pos.length() == 1 ? 0 : Double.parseDouble(pos.substring(1));
switch (type) {
case 0:
return relative + Math.round(loc.getX() * 1000) / 1000D;
case 1:
return relative + Math.round(loc.getY() * 1000) / 1000D;
case 2:
return relative + Math.round(loc.getZ() * 1000) / 1000D;
default:
return 0;
}
}
private boolean isLocationLoaded(Location loc) {
return loc.getWorld().isChunkLoaded(Location.locToBlock(loc.getX()) >> 4, Location.locToBlock(loc.getZ()) >> 4);
}
private static Set<String> getLoadedMods() {
if (!loaded) {
try {
Object blocksRegistry = Class.forName("net.minecraftforge.registries.ForgeRegistries").getDeclaredField("BLOCKS").get(null);
Set<Entry<ResourceKey<Block>, Block>> blockSet = (Set<Entry<ResourceKey<Block>, Block>>) Class.forName("net.minecraftforge.registries.IForgeRegistry").getMethod("getEntries").invoke(blocksRegistry);
for (Entry<ResourceKey<Block>, Block> entry : blockSet) {
String namespace = entry.getKey().location().getNamespace();
if (!namespace.equals(NamespacedKey.MINECRAFT))
LOADED_MODS.add(namespace.toUpperCase() + "_");
}
Object itemsRegistry = Class.forName("net.minecraftforge.registries.ForgeRegistries").getDeclaredField("ITEMS").get(null);
Set<Entry<ResourceKey<Item>, Item>> itemSet = (Set<Entry<ResourceKey<Item>, Item>>) Class.forName("net.minecraftforge.registries.IForgeRegistry").getMethod("getEntries").invoke(itemsRegistry);
for (Entry<ResourceKey<Item>, Item> entry : itemSet) {
String namespace = entry.getKey().location().getNamespace();
if (!namespace.equals(NamespacedKey.MINECRAFT))
LOADED_MODS.add(namespace.toUpperCase() + "_");
}
} catch (ReflectiveOperationException e) {}
loaded = true;
}
return LOADED_MODS;
}
}

View File

@@ -16,6 +16,7 @@ import net.nuggetmc.tplus.command.commands.AICommand;
import org.bukkit.*;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@@ -23,12 +24,30 @@ import org.bukkit.permissions.ServerOperator;
import org.bukkit.util.Vector;
import java.beans.Statement;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;
import java.util.stream.Collectors;
public class Debugger {
private final CommandSender sender;
public static final Set<String> AUTOFILL_METHODS = new HashSet<>();
static {
for (Method method : Debugger.class.getDeclaredMethods()) {
if (!method.getName().equals("print") && !method.getName().equals("execute") && !method.getName().equals("buildObjects")
&& !method.getName().startsWith("lambda$")) {
String autofill = method.getName() + "(";
for (Parameter par : method.getParameters()) {
autofill += par.getType().getSimpleName() + ",";
}
autofill = method.getParameters().length > 0 ? autofill.substring(0, autofill.length() - 1) : autofill;
autofill += ")";
AUTOFILL_METHODS.add(autofill);
}
}
}
public Debugger(CommandSender sender) {
this.sender = sender;
@@ -447,4 +466,20 @@ public class Debugger {
print("The Bot Agent is now " + (b ? ChatColor.RED + "DISABLED" : ChatColor.GREEN + "ENABLED") + ChatColor.RESET + ".");
}
public void printSurroundingMobs(double dist) {
if (!(sender instanceof Player)) {
print("You must be a player to call this.");
return;
}
Player player = (Player) sender;
double distSq = Math.pow(dist, 2);
for (Entity en : player.getWorld().getEntities()) {
Location loc = en.getLocation();
if (loc.distanceSquared(player.getLocation()) < distSq)
print(String.format("Entity at " + ChatColor.BLUE + "(%d, %d, %d)" + ChatColor.RESET + ": Type " + ChatColor.GREEN + "%s" + ChatColor.RESET,
loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), en.getType().toString()));
}
}
}