Merge pull request #68 from ThisTestUser/master

Fixes and more features
This commit is contained in:
Evan
2024-09-26 20:24:48 -04:00
committed by GitHub
23 changed files with 532 additions and 152 deletions

View File

@@ -9,23 +9,20 @@ jobs:
os: [ ubuntu-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Setup Gradle
uses: gradle/gradle-build-action@v2
uses: gradle/actions/setup-gradle@v4
- name: Execute Gradle build
run: ./gradlew build
- name: Upload a Build Artifact
uses: actions/upload-artifact@v2.2.4
uses: actions/upload-artifact@v4
if: success()
with:
name: TerminatorPlus

View File

@@ -17,6 +17,6 @@ repositories {
}
dependencies {
compileOnly("io.papermc.paper:paper-api:1.19.3-R0.1-SNAPSHOT")
compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT")
compileOnly("com.mojang:authlib:3.2.38")
}

View File

@@ -1,6 +1,5 @@
package net.nuggetmc.tplus.api;
import org.bukkit.Sound;
import org.bukkit.block.Block;
/**
@@ -8,6 +7,4 @@ import org.bukkit.block.Block;
*/
public interface InternalBridge {
void sendBlockDestructionPacket(short entityId, Block block, int progress);
Sound breakBlockSound(Block block);
}

View File

@@ -0,0 +1,28 @@
package net.nuggetmc.tplus.api.agent.legacyagent;
import java.util.Arrays;
import java.util.stream.Collectors;
public enum CustomListMode {
HOSTILE,
RAIDER,
MOB,
CUSTOM;
public static boolean isValid(String name) {
return from(name) != null;
}
public static CustomListMode from(String name) {
for (CustomListMode mode : values()) {
if (mode.name().equalsIgnoreCase(name)) {
return mode;
}
}
return null;
}
public static String listModes() {
return Arrays.stream(values()).map(e -> e.name().toLowerCase()).collect(Collectors.joining("|"));
}
}

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_MOB_LIST = new HashSet<>();
public static CustomListMode customListMode = CustomListMode.CUSTOM;
public LegacyAgent(BotManager manager, Plugin plugin) {
super(manager, plugin);
@@ -1017,18 +1020,21 @@ public class LegacyAgent extends Agent {
}
private void preBreak(Terminator bot, LivingEntity player, Block block, LegacyLevel level) {
Material item;
Material type = block.getType();
List<Material> materials = List.of(LegacyItems.PICKAXE, LegacyItems.AXE, LegacyItems.SHOVEL);
ItemStack optimal = new ItemStack(Material.AIR);
float optimalSpeed = 1;
if (LegacyMats.SHOVEL.contains(type)) {
item = LegacyItems.SHOVEL;
} else if (LegacyMats.AXE.contains(type)) {
item = LegacyItems.AXE;
} else {
item = LegacyItems.PICKAXE;
for (Material mat : materials) {
ItemStack tool = new ItemStack(mat);
float destroySpeed = block.getDestroySpeed(tool);
if (destroySpeed > optimalSpeed) {
optimal = tool;
optimalSpeed = destroySpeed;
}
}
bot.setItem(new ItemStack(item));
bot.setItem(optimal);
if (level.isSideDown() || level.isSideDown2()) {
bot.setBotPitch(69);
@@ -1456,7 +1462,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 || (customListMode == CustomListMode.HOSTILE && CUSTOM_MOB_LIST.contains(entity.getType()))) && validateCloserEntity(entity, loc, result)) {
result = entity;
}
}
@@ -1466,7 +1472,8 @@ public class LegacyAgent extends Agent {
case NEAREST_RAIDER: {
for (LivingEntity entity : bot.getBukkitEntity().getWorld().getLivingEntities()) {
if ((entity instanceof Raider || (entity instanceof Vex vex && vex.getSummoner() instanceof Raider)) && validateCloserEntity(entity, loc, result)) {
boolean raider = entity instanceof Raider || (entity instanceof Vex vex && vex.getSummoner() instanceof Raider);
if ((raider || (customListMode == CustomListMode.RAIDER && CUSTOM_MOB_LIST.contains(entity.getType()))) && validateCloserEntity(entity, loc, result)) {
result = entity;
}
}
@@ -1476,7 +1483,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 || (customListMode == CustomListMode.MOB && CUSTOM_MOB_LIST.contains(entity.getType()))) && validateCloserEntity(entity, loc, result)) {
result = entity;
}
}
@@ -1526,15 +1533,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 (customListMode == CustomListMode.CUSTOM && CUSTOM_MOB_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);
@@ -1544,24 +1565,24 @@ public class LegacyAgent extends Agent {
}
private boolean validateCloserEntity(LivingEntity entity, Location loc, LivingEntity result) {
double regionDistEntity = getWeightedRegionDist(entity.getLocation());
if (regionDistEntity == Double.MAX_VALUE)
return false;
double regionDistResult = result == null ? 0 : getWeightedRegionDist(result.getLocation());
return loc.getWorld() == entity.getWorld() && !entity.isDead()
&& (result == null || (loc.distanceSquared(entity.getLocation()) + regionDistEntity) < (loc.distanceSquared(result.getLocation())) + regionDistResult);
double regionDistEntity = getWeightedRegionDist(entity.getLocation());
if (regionDistEntity == Double.MAX_VALUE)
return false;
double regionDistResult = result == null ? 0 : getWeightedRegionDist(result.getLocation());
return loc.getWorld() == entity.getWorld() && !entity.isDead()
&& (result == null || (loc.distanceSquared(entity.getLocation()) + regionDistEntity) < (loc.distanceSquared(result.getLocation())) + regionDistResult);
}
private double getWeightedRegionDist(Location loc) {
if (region == null)
return 0;
double diffX = Math.max(0, Math.abs(region.getCenterX() - loc.getX()) - region.getWidthX() * 0.5);
double diffY = Math.max(0, Math.abs(region.getCenterY() - loc.getY()) - region.getHeight() * 0.5);
double diffZ = Math.max(0, Math.abs(region.getCenterZ() - loc.getZ()) - region.getWidthZ() * 0.5);
if (regionWeightX == 0 && regionWeightY == 0 && regionWeightZ == 0)
if (diffX > 0 || diffY > 0 || diffZ > 0)
return Double.MAX_VALUE;
return diffX * diffX * regionWeightX + diffY * diffY * regionWeightY + diffZ * diffZ * regionWeightZ;
if (region == null)
return 0;
double diffX = Math.max(0, Math.abs(region.getCenterX() - loc.getX()) - region.getWidthX() * 0.5);
double diffY = Math.max(0, Math.abs(region.getCenterY() - loc.getY()) - region.getHeight() * 0.5);
double diffZ = Math.max(0, Math.abs(region.getCenterZ() - loc.getZ()) - region.getWidthZ() * 0.5);
if (regionWeightX == 0 && regionWeightY == 0 && regionWeightZ == 0)
if (diffX > 0 || diffY > 0 || diffZ > 0)
return Double.MAX_VALUE;
return diffX * diffX * regionWeightX + diffY * diffY * regionWeightY + diffZ * diffZ * regionWeightZ;
}
@Override

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

@@ -31,7 +31,7 @@ public class LegacyMats {
Material.VINE,
Material.FERN,
Material.LARGE_FERN,
Material.GRASS,
Material.SHORT_GRASS,
Material.TALL_GRASS,
Material.SEAGRASS,
Material.TALL_SEAGRASS,
@@ -54,46 +54,6 @@ public class LegacyMats {
Material.SOUL_FIRE
));
public static final Set<Material> SHOVEL = new HashSet<>(concatTypes(Lists.newArrayList(
Material.CLAY,
Material.DIRT,
Material.GRASS_BLOCK,
Material.COARSE_DIRT,
Material.PODZOL,
Material.MYCELIUM,
Material.GRAVEL,
Material.MUD,
Material.MUDDY_MANGROVE_ROOTS,
Material.SAND,
Material.RED_SAND,
Material.SOUL_SAND,
Material.SOUL_SOIL,
Material.SNOW,
Material.SNOW_BLOCK
), Arrays.asList(), Arrays.asList(), m -> m.name().endsWith("_CONCRETE_POWDER")));
public static final Set<Material> AXE = new HashSet<>(Arrays.asList(
Material.OAK_PLANKS, Material.OAK_DOOR, Material.OAK_FENCE, Material.OAK_FENCE_GATE, Material.OAK_LOG,
Material.OAK_SIGN, Material.OAK_SLAB, Material.OAK_STAIRS, Material.OAK_TRAPDOOR, Material.OAK_WALL_SIGN, Material.OAK_WOOD,
Material.DARK_OAK_PLANKS, Material.DARK_OAK_DOOR, Material.DARK_OAK_FENCE, Material.DARK_OAK_FENCE_GATE, Material.DARK_OAK_LOG,
Material.DARK_OAK_SIGN, Material.DARK_OAK_SLAB, Material.DARK_OAK_STAIRS, Material.DARK_OAK_TRAPDOOR, Material.DARK_OAK_WALL_SIGN, Material.DARK_OAK_WOOD,
Material.ACACIA_PLANKS, Material.ACACIA_DOOR, Material.ACACIA_FENCE, Material.ACACIA_FENCE_GATE, Material.ACACIA_LOG,
Material.ACACIA_SIGN, Material.ACACIA_SLAB, Material.ACACIA_STAIRS, Material.ACACIA_TRAPDOOR, Material.ACACIA_WALL_SIGN, Material.ACACIA_WOOD,
Material.BIRCH_PLANKS, Material.BIRCH_DOOR, Material.BIRCH_FENCE, Material.BIRCH_FENCE_GATE, Material.BIRCH_LOG,
Material.BIRCH_SIGN, Material.BIRCH_SLAB, Material.BIRCH_STAIRS, Material.BIRCH_TRAPDOOR, Material.BIRCH_WALL_SIGN, Material.BIRCH_WOOD,
Material.JUNGLE_PLANKS, Material.JUNGLE_DOOR, Material.JUNGLE_FENCE, Material.JUNGLE_FENCE_GATE, Material.JUNGLE_LOG,
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_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,
Material.WARPED_PLANKS, Material.WARPED_DOOR, Material.WARPED_FENCE, Material.WARPED_FENCE_GATE, Material.WARPED_STEM,
Material.WARPED_SIGN, Material.WARPED_SLAB, Material.WARPED_STAIRS, Material.WARPED_TRAPDOOR, Material.WARPED_WALL_SIGN,
Material.CHEST, Material.TRAPPED_CHEST
));
public static final Set<Material> BREAK = new HashSet<>(Arrays.asList(
Material.AIR,
Material.WATER,
@@ -112,6 +72,8 @@ public class LegacyMats {
Material.KELP,
Material.KELP_PLANT,
Material.SUNFLOWER,
Material.TORCHFLOWER,
Material.PITCHER_PLANT,
Material.FIRE,
Material.SOUL_FIRE
));
@@ -207,7 +169,7 @@ public class LegacyMats {
public static final Set<Material> INSTANT_BREAK = new HashSet<>(concatTypes(Lists.newArrayList(
Material.TALL_GRASS,
Material.GRASS,
Material.SHORT_GRASS,
Material.FERN,
Material.LARGE_FERN,
Material.KELP_PLANT,
@@ -319,7 +281,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 +343,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 +477,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

@@ -1,6 +1,5 @@
package net.nuggetmc.tplus.api.agent.legacyagent;
import net.nuggetmc.tplus.api.TerminatorPlusAPI;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.block.Block;
@@ -32,6 +31,6 @@ public class LegacyUtils {
}
public static Sound breakBlockSound(Block block) {
return TerminatorPlusAPI.getInternalBridge().breakBlockSound(block);
return block.getBlockData().getSoundGroup().getBreakSound();
}
}

View File

@@ -23,7 +23,7 @@ public class BotFallDamageEvent {
}
public List<Block> getStandingOn() {
return standingOn;
return standingOn;
}
public boolean isCancelled() {

View File

@@ -36,10 +36,10 @@ public class BotUtils {
}
public static boolean overlaps(BoundingBox playerBox, BoundingBox blockBox) {
return playerBox.overlaps(blockBox);
return playerBox.overlaps(blockBox);
}
public static double getHorizSqDist(Location blockLoc, Location pLoc) {
return NumberConversions.square(blockLoc.getX() + 0.5 - pLoc.getX()) + NumberConversions.square(blockLoc.getZ() + 0.5 - pLoc.getZ());
return NumberConversions.square(blockLoc.getX() + 0.5 - pLoc.getX()) + NumberConversions.square(blockLoc.getZ() + 0.5 - pLoc.getZ());
}
}

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

@@ -17,12 +17,6 @@ dependencies {
//add the TerminatorPlus-API module
implementation(project(":TerminatorPlus-API"))
// paperweightDevBundle("com.example.paperfork", "1.19-R0.1-SNAPSHOT")
// You will need to manually specify the full dependency if using the groovy gradle dsl
// (paperDevBundle and paperweightDevBundle functions do not work in groovy)
// paperweightDevelopmentBundle("io.papermc.paper:dev-bundle:1.19-R0.1-SNAPSHOT")
}
tasks {

View File

@@ -52,13 +52,9 @@ public class TerminatorPlus extends JavaPlugin {
instance = this;
version = getDescription().getVersion();
String version = Bukkit.getVersion();
correctVersion = version.contains(REQUIRED_VERSION);
if (version.contains("MC:")) { // git-ABX-123 (MC: ABCD)
version = version.substring(version.indexOf("MC:") + 3, version.indexOf(")")).trim();
}
mcVersion = version;
getLogger().info("Running on version: " + version + ", required version: " + REQUIRED_VERSION + ", correct version: " + correctVersion);
mcVersion = Bukkit.getServer().getMinecraftVersion();
correctVersion = mcVersion.equals(REQUIRED_VERSION);
getLogger().info("Running on version: " + mcVersion + ", required version: " + REQUIRED_VERSION + ", correct version: " + correctVersion);
// Create Instances
this.manager = new BotManagerImpl();
@@ -74,7 +70,7 @@ public class TerminatorPlus extends JavaPlugin {
for (int i = 0; i < 20; i++) { // Kids are stupid so we need to make sure they see this
getLogger().severe("----------------------------------------");
getLogger().severe("TerminatorPlus is not compatible with your server version!");
getLogger().severe("You are running on version: " + version + ", required version: " + REQUIRED_VERSION);
getLogger().severe("You are running on version: " + mcVersion + ", required version: " + REQUIRED_VERSION);
getLogger().severe("Either download the correct version of TerminatorPlus or update your server. (https://papermc.io/downloads)");
getLogger().severe("----------------------------------------");
}

View File

@@ -117,12 +117,15 @@ public class Bot extends ServerPlayer implements Terminator {
bot.setPos(loc.getX(), loc.getY(), loc.getZ());
bot.setRot(loc.getYaw(), loc.getPitch());
bot.getBukkitEntity().setNoDamageTicks(0);
Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send(
new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, bot)));
if (addPlayerList)
if (addPlayerList) {
Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send(
ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(bot))));
nmsWorld.addNewPlayer(bot);
else
} else {
Bukkit.getOnlinePlayers().forEach(p -> ((CraftPlayer) p).getHandle().connection.send(
new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, bot)));
nmsWorld.addFreshEntity(bot);
}
bot.renderAll();
TerminatorPlus.getInstance().getManager().add(bot);
@@ -544,7 +547,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 +566,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 +818,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 +885,7 @@ public class Bot extends ServerPlayer implements Terminator {
@Override
public void doTick() {
detectEquipmentUpdatesPublic();
baseTick();
}

View File

@@ -2,13 +2,8 @@ package net.nuggetmc.tplus.bridge;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundBlockDestructionPacket;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockState;
import net.nuggetmc.tplus.api.InternalBridge;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
@@ -20,19 +15,4 @@ public class InternalBridgeImpl implements InternalBridge {
((CraftPlayer) all).getHandle().connection.send(crack);
}
}
@Override
public Sound breakBlockSound(Block block) {
try {
Level nmsWorld = ((CraftWorld) block.getWorld()).getHandle();
BlockState blockState = nmsWorld.getBlockState(new BlockPos(block.getX(), block.getY(), block.getZ()));
net.minecraft.world.level.block.Block nmsBlock = blockState.getBlock();
SoundType soundEffectType = nmsBlock.getSoundType(blockState);
return Sound.valueOf(soundEffectType.getBreakSound().getLocation().getPath().replace(".", "_").toUpperCase());
} catch (Exception e) { // potentially unsafe, just fallback to stone break sound
return Sound.BLOCK_STONE_BREAK;
}
}
}

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

@@ -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

@@ -188,10 +188,6 @@ public class AICommand extends CommandInstance implements AIManager {
@Autofill
public List<String> infoAutofill(CommandSender sender, String[] args) {
if (args.length == 2) {
return manager.fetchNames();
} else {
return null;
}
return args.length == 2 ? manager.fetchNames() : new ArrayList<>();
}
}

View File

@@ -146,6 +146,13 @@ public class BotCommand extends CommandInstance {
}
private void armorTierSetup() {
armorTiers.put("none", new ItemStack[]{
new ItemStack(Material.AIR),
new ItemStack(Material.AIR),
new ItemStack(Material.AIR),
new ItemStack(Material.AIR),
});
armorTiers.put("leather", new ItemStack[]{
new ItemStack(Material.LEATHER_BOOTS),
new ItemStack(Material.LEATHER_LEGGINGS),
@@ -223,7 +230,7 @@ public class BotCommand extends CommandInstance {
@Autofill
public List<String> armorAutofill(CommandSender sender, String[] args) {
return args.length == 2 ? new ArrayList<>(armorTiers.keySet()) : null;
return args.length == 2 ? new ArrayList<>(armorTiers.keySet()) : new ArrayList<>();
}
@Command(
@@ -280,7 +287,7 @@ public class BotCommand extends CommandInstance {
@Autofill
public List<String> infoAutofill(CommandSender sender, String[] args) {
return args.length == 2 ? manager.fetchNames() : null;
return args.length == 2 ? manager.fetchNames() : new ArrayList<>();
}
@Command(
@@ -520,12 +527,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,323 @@
package net.nuggetmc.tplus.command.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import net.nuggetmc.tplus.api.agent.legacyagent.CustomListMode;
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;
public class BotEnvironmentCommand extends CommandInstance {
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 hybrid 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(ChatUtils.LINE);
} else if (args.size() > 0 && args.get(0).equals("mobs")) {
sender.sendMessage(ChatUtils.LINE);
sender.sendMessage("The custom mob list is a user-defined list of mobs.");
sender.sendMessage("Use " + ChatColor.YELLOW + "/botenvironment addCustomMob <name>" + ChatColor.RESET + " to add mob types to the list.");
sender.sendMessage("The list can be used in the CUSTOM_LIST targeting option, and can also be appended to the hostile, raider, or mob targeting options.");
sender.sendMessage("When appending, the mobs predefined as well as the mobs in the custom list will be considered.");
sender.sendMessage("Use " + ChatColor.YELLOW + "/botenvironment mobListType" + ChatColor.RESET + " to change the behavior of the custom mob 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 creating a custom mob list.");
}
}
@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;
}
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 = "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;
}
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;
}
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 to the custom list.",
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_MOB_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 from the custom list.",
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_MOB_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 custom list of mobs.",
aliases = {"listcustommobs"}
)
public void listCustomMobs(CommandSender sender) {
sender.sendMessage(ChatUtils.LINE);
for (EntityType type : LegacyAgent.CUSTOM_MOB_LIST)
sender.sendMessage(ChatColor.GREEN + type.name() + ChatColor.RESET);
sender.sendMessage("Total items: " + ChatColor.BLUE + LegacyAgent.CUSTOM_MOB_LIST.size() + ChatColor.RESET);
sender.sendMessage(ChatUtils.LINE);
}
@Command(
name = "clearCustomMobs",
desc = "Clears the custom list of mobs.",
aliases = {"clearcustommobs"}
)
public void clearCustomMobs(CommandSender sender) {
int size = LegacyAgent.CUSTOM_MOB_LIST.size();
LegacyAgent.CUSTOM_MOB_LIST.clear();
sender.sendMessage("Removed all " + ChatColor.BLUE + size + ChatColor.RESET + " item(s) from the list.");
}
@Command(
name = "mobListType",
desc = "Changes the behavior of the custom mob list.",
aliases = {"moblisttype"},
autofill = "autofill"
)
public void mobListType(CommandSender sender, List<String> args) {
if (args.isEmpty()) {
sender.sendMessage("The custom mob list type is " + ChatColor.BLUE + LegacyAgent.customListMode + ChatColor.RESET + ".");
} else if (args.size() > 0 && CustomListMode.isValid(args.get(0))) {
LegacyAgent.customListMode = CustomListMode.from(args.get(0));
sender.sendMessage(
"Successfully set the custom mob list type to " + ChatColor.BLUE + args.get(0) + ChatColor.RESET + ".");
} else
sender.sendMessage("Usage: " + ChatColor.YELLOW + "/botenvironment mobListType (" + CustomListMode.listModes() + ")" + 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], "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")) {
for (CustomListMode mode : CustomListMode.values())
output.add(mode.name().toLowerCase(Locale.ENGLISH));
}
}
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);
}
}

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;
@@ -241,6 +260,18 @@ public class Debugger {
TerminatorPlus.getInstance().getManager().fetch().forEach(bot -> bot.setShield(true));
}
public void totem() {
TerminatorPlus.getInstance().getManager().fetch().forEach(bot -> bot.setItemOffhand(new ItemStack(Material.TOTEM_OF_UNDYING)));
}
public void clearMainHand() {
TerminatorPlus.getInstance().getManager().fetch().forEach(bot -> bot.setItem(new ItemStack(Material.AIR)));
}
public void clearOffHand() {
TerminatorPlus.getInstance().getManager().fetch().forEach(bot -> bot.setItemOffhand(new ItemStack(Material.AIR)));
}
public void offsets(boolean b) {
Agent agent = TerminatorPlus.getInstance().getManager().getAgent();
if (!(agent instanceof LegacyAgent)) {
@@ -447,4 +478,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()));
}
}
}

0
gradlew vendored Normal file → Executable file
View File