From 585696552a282c89d075c7b7c006894d2ecc6bc7 Mon Sep 17 00:00:00 2001 From: MrTransistor Date: Sun, 3 Apr 2022 01:41:51 +0300 Subject: [PATCH] [-] move xp calculation to DummyPlayer#die() - can`t do but fixed some problems with xp drops [+] use kick instead of force disconnecting when removing with specified command [+] Prevent dummies from overwriting online players [+] test if dummy can be auto-kicked by a player for duplicate login [+] test if player cache works in offline mode - works but players somehow get different uuids from what they had with online mode [+] remove dropping inventory and xp on disconnect [+] reimplement saving bots (maybe with manually refreshed skins if there`s no native way to do that) [+] add a method to rejoin bots without resetting position, gamemode, etc. [+] remove command for removing bots by name [+] delete messages for spawning/removing bots [+] fix bots teleporting to their disconnect coords if being removed after kill [+] fix bots rejoining while server is running delayed init tasks [+] fix bot disconnect not removing them from bot list [+] move event listeners into separate class [+] fix a bug that newly added players that are not actual accounts will be invincible and don`t load all skin layers [+] fix a bug with bot names using registered account names [+] add a system for storing active server players to prevent bots using their names [+] 1.18.2 update [+] bump the version number --- build.gradle | 17 +-- .../java/plugin/mrtransistor/AFK/AFK.java | 100 ++++++-------- .../plugin/mrtransistor/AFK/DummyPlayer.java | 129 +++++++++--------- .../mrtransistor/AFK/EventListener.java | 41 ++++++ .../AFK/commands/CommandDispatcher.java | 53 +------ src/main/resources/botSave.yml | 1 + src/main/resources/config.yml | 18 +-- src/main/resources/plugin.yml | 8 -- 8 files changed, 155 insertions(+), 212 deletions(-) create mode 100644 src/main/java/plugin/mrtransistor/AFK/EventListener.java diff --git a/build.gradle b/build.gradle index 1742237..8ac0d09 100644 --- a/build.gradle +++ b/build.gradle @@ -3,12 +3,12 @@ plugins { } apply from: rootProject.file('specialSource.gradle') -version = '2.6.1' +version = '3.0.0' group = 'plugin.mrtransistor.AFK' ext { author = 'MrTransistor' - spigotVersion = '1.18.1-R0.1-SNAPSHOT' + spigotVersion = '1.18.2-R0.1-SNAPSHOT' remapServerCode = true mainClass = group + '.' + rootProject.getName() @@ -18,19 +18,6 @@ ext { repositories { mavenCentral() mavenLocal() - maven { - url = 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' - - // As of Gradle 5.1, you can limit this to only those - // dependencies you expect from it - content { - includeGroup 'org.bukkit' - includeGroup 'org.spigotmc' - } - } - - maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' } - maven { url = 'https://oss.sonatype.org/content/repositories/central' } maven { url = 'https://libraries.minecraft.net/' } } diff --git a/src/main/java/plugin/mrtransistor/AFK/AFK.java b/src/main/java/plugin/mrtransistor/AFK/AFK.java index bcb59be..cbfa4c1 100644 --- a/src/main/java/plugin/mrtransistor/AFK/AFK.java +++ b/src/main/java/plugin/mrtransistor/AFK/AFK.java @@ -18,25 +18,23 @@ */ package plugin.mrtransistor.AFK; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.FoodLevelChangeEvent; -import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.plugin.java.JavaPlugin; import plugin.mrtransistor.AFK.commands.CommandDispatcher; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; -public class AFK extends JavaPlugin implements Listener { +public class AFK extends JavaPlugin { private File botSaveFile; private FileConfiguration botSaveYml; @@ -44,64 +42,65 @@ public class AFK extends JavaPlugin implements Listener { @Override public void onEnable() { saveDefaultConfig(); - createBotSaveFile(); + loadBotSaveFile(); - Bukkit.getPluginManager().registerEvents(this, this); CommandDispatcher commandDispatcher = new CommandDispatcher(this); + EventListener eventListener = new EventListener(); + Bukkit.getPluginManager().registerEvents(eventListener, this); + getCommand("spawnBot").setExecutor(commandDispatcher); getCommand("spawnBot").setTabCompleter(commandDispatcher); - getCommand("removeBot").setExecutor(commandDispatcher); - getCommand("removeBot").setTabCompleter(commandDispatcher); getCommand("removeAllBots").setExecutor(commandDispatcher); getCommand("removeAllBots").setTabCompleter(commandDispatcher); getCommand("afkutils").setExecutor(commandDispatcher); getCommand("afkutils").setTabCompleter(commandDispatcher); - spawnBotsOnLoad(); + Bukkit.getScheduler().runTaskLater(this, this::loadBots, 20); getLogger().info("AFK plugin started!"); } @Override public void onDisable() { - removeBotsOnUnload(); + saveBots(); getLogger().info("AFK plugin stopped!"); } - private void spawnBotsOnLoad() { - int bots_spawned = 0; - for (String name : botSaveYml.getKeys(false)) { - /*Player spawner = (Player) getServer().getOfflinePlayer(UUID.fromString(botSaveYml.getConfigurationSection(name) - .getString("spawner")));*/ - World world = getServer().getWorld(botSaveYml.getConfigurationSection(name).getString("level")); - double x = botSaveYml.getConfigurationSection(name).getDouble("x"); - double y = botSaveYml.getConfigurationSection(name).getDouble("y"); - double z = botSaveYml.getConfigurationSection(name).getDouble("z"); - float yaw = (float) botSaveYml.getConfigurationSection(name).getDouble("yaw"); - float pitch = (float) botSaveYml.getConfigurationSection(name).getDouble("pitch"); - Location location = new Location(world, x, y, z, yaw, pitch); - DummyPlayer.spawnBot(name, location, null); + private void loadBots() { + ConfigurationSection section = botSaveYml.getConfigurationSection("botsToReload"); + if(section == null) return; + List botsToLoad = new ArrayList<>(botSaveYml.getConfigurationSection("botsToReload").getKeys(false)); + System.out.println("satsrtbreab"); + if (botsToLoad.isEmpty()) return; + getLogger().info(ChatColor.GREEN + "Loading " + botsToLoad.size() + + (botsToLoad.size() == 1 ? " bot" : " bots")); + for (String bot : botsToLoad) { + DummyPlayer.spawnBot(bot, null, null, false); } } - private void removeBotsOnUnload() { - int botsRemoved = 0; - int numBots = DummyPlayer.dummies.size(); - for (int i = 0; i < numBots; i++) { - DummyPlayer dummy = DummyPlayer.dummies.get(0); - getLogger().info("Bot '" + ChatColor.DARK_GREEN + dummy.getName().getContents() + ChatColor.RESET + "' with UUID:[" - + ChatColor.GOLD + dummy.getStringUUID() + ChatColor.RESET + "] was removed"); - dummy.softRemove(); - botsRemoved++; + private void saveBots() { + if (!DummyPlayer.dummies.isEmpty()) + getLogger().info(ChatColor.GREEN + "Saving " + DummyPlayer.dummies.size() + + (DummyPlayer.dummies.size() == 1 ? " bot" : " bots")); + botSaveYml.set("botsToReload", null); + botSaveYml.createSection("botsToReload"); + while (!DummyPlayer.dummies.isEmpty()) { + DummyPlayer botToSave = DummyPlayer.dummies.get(0); + botSaveYml.createSection("botsToReload." + botToSave.getScoreboardName()); + GameProfile gameProfile = botToSave.getGameProfile(); + if(gameProfile.getProperties().containsKey("textures")) { + Property textures = gameProfile.getProperties().get("textures").iterator().next(); + botSaveYml.set("botsToReload." + botToSave.getScoreboardName() + ".texture", textures.getValue().toString()); + botSaveYml.set("botsToReload." + botToSave.getScoreboardName() + ".signature", textures.getSignature().toString()); + } + botToSave.disconnect("Plugin unload"); } - if (botsRemoved == 0) getLogger().info(ChatColor.GREEN + "No bots were removed"); - else if (botsRemoved == 1) - getLogger().info(ChatColor.GREEN + "1 bot was removed"); - else getLogger().info(ChatColor.GREEN + Integer.toString(botsRemoved) + " bots were removed"); + saveBotSaveFile(); } - private void createBotSaveFile() { + private void loadBotSaveFile() { botSaveFile = new File(getDataFolder(), "botSave.yml"); if (!botSaveFile.exists()) { botSaveFile.getParentFile().mkdirs(); @@ -116,10 +115,6 @@ public class AFK extends JavaPlugin implements Listener { } } - public FileConfiguration getBotSaveFile() { - return botSaveYml; - } - public void saveBotSaveFile() { try { botSaveYml.save(botSaveFile); @@ -128,18 +123,7 @@ public class AFK extends JavaPlugin implements Listener { } } - @EventHandler - public void onPlayerDeath(PlayerDeathEvent e) { - if (((CraftEntity) e.getEntity()).getHandle() instanceof DummyPlayer) { - e.setDroppedExp(e.getEntity().getTotalExperience()); - } - } - - @EventHandler - public void onFoodLevelChange(FoodLevelChangeEvent e) { - if (((CraftEntity) e.getEntity()).getHandle() instanceof DummyPlayer) { - e.setCancelled(true); - e.getEntity().setFoodLevel(20); - } + public FileConfiguration getBotSaveYml(){ + return botSaveYml; } } diff --git a/src/main/java/plugin/mrtransistor/AFK/DummyPlayer.java b/src/main/java/plugin/mrtransistor/AFK/DummyPlayer.java index 559e2cd..908d4b3 100644 --- a/src/main/java/plugin/mrtransistor/AFK/DummyPlayer.java +++ b/src/main/java/plugin/mrtransistor/AFK/DummyPlayer.java @@ -20,39 +20,41 @@ package plugin.mrtransistor.AFK; import com.mojang.authlib.GameProfile; import com.mojang.authlib.properties.Property; +import net.minecraft.nbt.CompoundTag; import net.minecraft.server.MinecraftServer; import net.minecraft.server.TickTask; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.server.players.PlayerList; import net.minecraft.world.InteractionHand; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.level.GameType; +import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; import org.bukkit.*; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.craftbukkit.v1_18_R1.CraftServer; -import org.bukkit.craftbukkit.v1_18_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R1.entity.CraftEntity; -import org.bukkit.craftbukkit.v1_18_R1.entity.CraftLivingEntity; -import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer; +import org.bukkit.craftbukkit.v1_18_R2.CraftServer; +import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftLivingEntity; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; import org.bukkit.entity.Entity; -import org.bukkit.entity.ExperienceOrb; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.RayTraceResult; import org.bukkit.util.Vector; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.UUID; import java.util.function.Predicate; public class DummyPlayer extends ServerPlayer { public static ArrayList dummies = new ArrayList<>(); - public static ArrayList dummyNames = new ArrayList<>(); - + public boolean isFullyConnected = false; private boolean isSelfDefending = false; private boolean isAttackingContinuous = false; private boolean isForcePoI = false; @@ -61,71 +63,73 @@ public class DummyPlayer extends ServerPlayer { private Location PoI_loc; private final float[] PoI_yawpitch = new float[2]; - private static String[] getSkin(ServerPlayer player) { - GameProfile gameProfile = player.getGameProfile(); - if (!gameProfile.getProperties().containsKey("textures")) return null; - Property property = gameProfile.getProperties().get("textures").iterator().next(); - String texture = property.getValue(); - String signature = property.getSignature(); - return new String[]{texture, signature}; + private String[] getSkin(Player spawner) { + if (spawner != null) { + GameProfile gameProfile = ((CraftPlayer) spawner).getHandle().getGameProfile(); + if (!gameProfile.getProperties().containsKey("textures")) return null; + Property property = gameProfile.getProperties().get("textures").iterator().next(); + String texture = property.getValue(); + String signature = property.getSignature(); + return new String[]{texture, signature}; + } else { + ConfigurationSection botsToReload = ((AFK) server.server.getPluginManager().getPlugin("AFK")).getBotSaveYml() + .getConfigurationSection("botsToReload"); + if(botsToReload.getKeys(false).contains(getScoreboardName())) { + String texture = botsToReload.getConfigurationSection(getScoreboardName()).getString("texture"); + String signature = botsToReload.getConfigurationSection(getScoreboardName()).getString("signature"); + if(texture != null && signature != null) + return new String[]{texture, signature}; + } + return null; + } } public DummyPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) { super(server, world, profile); - dummyNames.add(getName().getContents()); dummies.add(this); } - public static DummyPlayer spawnBot(String name, Location location, org.bukkit.entity.Player spawner) { // some of this crap is redundant but it works - //TODO: check userCache for existing bots, update skin if spawner is not null (as it will be on server restart) - MinecraftServer server = ((CraftServer) (Bukkit.getServer())).getServer(); - ServerLevel world = ((CraftWorld) location.getWorld()).getHandle(); + public static DummyPlayer spawnBot(String name, Location location, org.bukkit.entity.Player spawner, boolean updateStats) { // some of this crap is redundant but it works + MinecraftServer server = ((CraftServer) Bukkit.getServer()).getServer(); + ServerLevel world = (location != null && location.getWorld() != null) ? ((CraftWorld) location.getWorld()).getHandle() + : server.getLevel(Level.OVERWORLD); + GameProfile gameProfile = server.getProfileCache().get(name).orElse(new GameProfile(UUID.randomUUID(), name)); // maybe needs something else? - GameProfile gameProfile = new GameProfile(UUID.randomUUID(), name); DummyPlayer dummy = new DummyPlayer(server, world, gameProfile); - String[] texSign = null; - if (spawner != null) - texSign = getSkin(((CraftPlayer) spawner).getHandle()); + String[] texSign;// maybe simplify this? + texSign = dummy.getSkin(spawner); if (texSign != null) gameProfile.getProperties().put("textures", new Property("textures", texSign[0], texSign[1])); + /* spawning entity */ server.getPlayerList().placeNewPlayer(new DummyConnection(), dummy); new BukkitRunnable() { - @Override - public void run() { // Fix for Paper`s post-chunk-load player join - dummy.connection.tick(); + public void run() { // ensuring that the bot has been connected and started ticking + if (!dummy.isFullyConnected) { + dummy.connection.tick(); + return; + } else if (location != null && location.getWorld() != null) + dummy.teleportTo(world, location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + this.cancel(); } - }.runTaskLater(server.server.getPluginManager().getPlugin("AFK"), 2); + }.runTaskTimer(server.server.getPluginManager().getPlugin("AFK"), 0, 10); - dummy.teleportTo(world, location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); - dummy.setHealth(20.0F); - dummy.unsetRemoved(); - dummy.setGameMode(GameType.SURVIVAL); + if (updateStats) { + dummy.setHealth(20.0F); + dummy.unsetRemoved(); + dummy.setGameMode(GameType.SURVIVAL); + } dummy.getEntityData().set(DATA_PLAYER_MODE_CUSTOMISATION, (byte) 0xf7); - - //TODO: move to AFK#onDisable(); - AFK _plg = (AFK) Bukkit.getServer().getPluginManager().getPlugin("AFK"); - FileConfiguration botSaveYml = _plg.getBotSaveFile(); - Map botCoords = new HashMap<>(); - if (spawner != null) - botCoords.put("spawner", spawner.getUniqueId().toString()); - botCoords.put("level", dummy.getBukkitEntity().getLocation().getWorld().getName()); - botCoords.put("x", dummy.getBukkitEntity().getLocation().getX()); - botCoords.put("y", dummy.getBukkitEntity().getLocation().getY()); - botCoords.put("z", dummy.getBukkitEntity().getLocation().getZ()); - botCoords.put("yaw", dummy.getBukkitEntity().getLocation().getYaw()); - botCoords.put("pitch", dummy.getBukkitEntity().getLocation().getPitch()); - botSaveYml.createSection(dummy.getBukkitEntity().getName(), botCoords); - _plg.saveBotSaveFile(); return dummy; } @Override public void tick() { // some of this crap is not necessary but it works + isFullyConnected = true; if (!isTicking) return; super.tick(); // handle gamemode and inventory doTick(); // update health, air and other levels @@ -135,6 +139,9 @@ public class DummyPlayer extends ServerPlayer { getLevel().getChunkSource().move(this); } + if (getServer().getTickCount() % 20 == 0) // prevents hunger + getBukkitEntity().setFoodLevel(20); + if (isForcePoI) goToPoI(); selfDefence(); if (isAttackingContinuous) attackContinuous(); @@ -282,31 +289,17 @@ public class DummyPlayer extends ServerPlayer { attack(((CraftEntity) entity).getHandle()); } - public void remove(String reason) { - dropEquipment(); - CraftPlayer bEntity = getBukkitEntity(); - World xpWorld = bEntity.getWorld(); - Location xpLoc = bEntity.getLocation(); - int xp = bEntity.getTotalExperience(); + public void disconnect(String reason) { connection.disconnect(reason); - xpWorld.spawn(xpLoc, ExperienceOrb.class).setExperience(xp); - dummyNames.remove(getName().getContents()); - dummies.remove(this); - AFK _plg = (AFK) Bukkit.getServer().getPluginManager().getPlugin("AFK"); - FileConfiguration botSaveYml = _plg.getBotSaveFile(); - botSaveYml.set(bEntity.getName(), null); - _plg.saveBotSaveFile(); - } - - public void softRemove() { - connection.disconnect("soft removed"); - dummyNames.remove(getName().getContents()); dummies.remove(this); } @Override public void die(DamageSource damagesource) { super.die(damagesource); - getServer().execute(new TickTask(getServer().getTickCount(), () -> remove("Died"))); + setExperienceLevels(0); // idk why we need this but without this bot does not clear xp on death + setExperiencePoints(0); + getBukkitEntity().setTotalExperience(0); // needed to simplify xp reward calculation + getServer().execute(new TickTask(getServer().getTickCount(), () -> disconnect("Died"))); } } diff --git a/src/main/java/plugin/mrtransistor/AFK/EventListener.java b/src/main/java/plugin/mrtransistor/AFK/EventListener.java new file mode 100644 index 0000000..d3c7bb3 --- /dev/null +++ b/src/main/java/plugin/mrtransistor/AFK/EventListener.java @@ -0,0 +1,41 @@ +package plugin.mrtransistor.AFK; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.craftbukkit.v1_18_R2.entity.CraftEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.ArrayList; +import java.util.List; + +public class EventListener implements Listener { + @EventHandler // handles removing of player exp cap on death for bots + public void onPlayerDeath(PlayerDeathEvent e) { + if (((CraftEntity) e.getEntity()).getHandle() instanceof DummyPlayer) + e.setDroppedExp(e.getEntity().getTotalExperience()); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent e){ + if (!(((CraftEntity) e.getPlayer()).getHandle() instanceof DummyPlayer)) { + FileConfiguration botSaveYml = Bukkit.getPluginManager().getPlugin("AFK").getConfig(); + List blacklistedNames = new ArrayList<>(); + if(botSaveYml.contains("blacklistedNames")) + blacklistedNames = botSaveYml.getStringList("blacklistedNames"); + if(!blacklistedNames.contains(e.getPlayer().getName())) + blacklistedNames.add(e.getPlayer().getName()); + botSaveYml.set("blacklistedNames", blacklistedNames); + Bukkit.getPluginManager().getPlugin("AFK").saveConfig(); + } + } + + @EventHandler // handles removing bot from list if lost connection not by DummyPlayer#die() or #disconnect() + public void onPlayerDisconnect(PlayerQuitEvent e) { + if (((CraftEntity) e.getPlayer()).getHandle() instanceof DummyPlayer) + DummyPlayer.dummies.remove((DummyPlayer) ((CraftEntity) e.getPlayer()).getHandle()); + } +} diff --git a/src/main/java/plugin/mrtransistor/AFK/commands/CommandDispatcher.java b/src/main/java/plugin/mrtransistor/AFK/commands/CommandDispatcher.java index 25f6994..1b13904 100644 --- a/src/main/java/plugin/mrtransistor/AFK/commands/CommandDispatcher.java +++ b/src/main/java/plugin/mrtransistor/AFK/commands/CommandDispatcher.java @@ -5,7 +5,6 @@ import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import org.bukkit.plugin.PluginDescriptionFile; import plugin.mrtransistor.AFK.AFK; @@ -151,57 +150,19 @@ public class CommandDispatcher implements TabExecutor { sender.sendMessage(ChatColor.RED + "Player names can`t be longer than 16 symbols"); return; } - if (!DummyPlayer.dummyNames.contains(args[0])) { - DummyPlayer dummy = DummyPlayer.spawnBot(args[0], ((Player) sender).getLocation(), (Player) sender); - - String json = "[{\"text\":\"Bot '\", \"color\":\"white\"}," + - "{\"text\":\"" + dummy.getName().getContents() + "\", \"color\":\"dark_green\"}," + - "{\"text\":\"' with UUID:[\", \"color\":\"white\"}," + - "{\"text\":\"" + dummy.getStringUUID() + "\", \"color\":\"gold\"," + - " \"clickEvent\":{\"action\":\"copy_to_clipboard\",\"value\":\"" + dummy.getStringUUID() + "\"}," + - " \"hoverEvent\":{\"action\":\"show_text\", \"value\":\"Click to copy to clipboard\"}}," + - "{\"text\":\"] spawned\", \"color\":\"white\"}]"; - - Bukkit.dispatchCommand(sender, "tellraw " + sender.getName() + " " + json); - } else { - sender.sendMessage(ChatColor.RED + "Bot with name '" + ChatColor.DARK_GREEN + args[0] + ChatColor.RED - + "' already exists"); - } + if (!_plg.getConfig().getStringList("blacklistedNames").contains(args[0])) + DummyPlayer.spawnBot(args[0], ((Player) sender).getLocation(), (Player) sender, true); + else + sender.sendMessage(ChatColor.RED + "There`s already a player with that name"); return; } sender.sendMessage("Sorry, this command is only for players"); } - public static void removeBot(CommandSender sender, String[] args) { - for (DummyPlayer dummy : DummyPlayer.dummies) { - if (dummy.getName().getContents().equals(args[0])) { - sender.sendMessage("Bot '" + ChatColor.DARK_GREEN + args[0] + ChatColor.RESET + "' with UUID:[" - + ChatColor.GOLD + dummy.getStringUUID() + ChatColor.RESET + "] was removed"); - dummy.remove("Removed using command"); - FileConfiguration botSaveYml = _plg.getBotSaveFile(); - botSaveYml.set(args[0], null); - _plg.saveBotSaveFile(); - return; - } - } - sender.sendMessage(ChatColor.RED + "There is no bot with specified name"); - } - public static void removeAllBots(CommandSender sender, String[] args) { - int botsRemoved = 0; - int numBots = DummyPlayer.dummies.size(); - for (int i = 0; i < numBots; i++) { - DummyPlayer dummy = DummyPlayer.dummies.get(0); - sender.sendMessage("Bot '" + ChatColor.DARK_GREEN + dummy.getName().getContents() + ChatColor.RESET - + "' with UUID:[" - + ChatColor.GOLD + dummy.getStringUUID() + ChatColor.RESET + "] was removed"); - dummy.remove("Removed using command"); - botsRemoved++; - } - if (botsRemoved == 0) sender.sendMessage(ChatColor.RED + "There are no bots"); - else if (botsRemoved == 1) - sender.sendMessage(ChatColor.GREEN + "1 bot was removed"); - else sender.sendMessage(ChatColor.GREEN + Integer.toString(botsRemoved) + " bots were removed"); + if (DummyPlayer.dummies.isEmpty()) sender.sendMessage(ChatColor.RED + "There are no bots"); + while (!DummyPlayer.dummies.isEmpty()) + DummyPlayer.dummies.get(0).disconnect("Removed using command"); } } \ No newline at end of file diff --git a/src/main/resources/botSave.yml b/src/main/resources/botSave.yml index e69de29..b882faa 100644 --- a/src/main/resources/botSave.yml +++ b/src/main/resources/botSave.yml @@ -0,0 +1 @@ +botsToReload: \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 66f8ec5..6c698f4 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,17 +1 @@ -# Nothing here yet -# Except for this cat -# _ -# \`*-. -# ) _`-. -# . : `. . -# : _ ' \ -# ; *` _. `*-._ -# `-.-' `-. -# ; ` `. -# :. . \ -# . \ . : .-' . -# ' `+.; ; ' : -# : ' | ; ;-. -# ; ' : :`-: _.`* ; -# .*' / .*' ; .*`- +' `*' -# `*-* `*-* `*-*' \ No newline at end of file +blacklistedNames: [] \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c5335dd..0031935 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -38,14 +38,6 @@ commands: __text__: tabCompletion: [ ] handler: spawnBot - removebot: - usage: "Usage: /removebot " - description: "Removes all bots with specified name" - tabCompletion: [ ] - args: - __text__: - tabCompletion: [ ] - handler: removeBot removeallbots: usage: "Usage: /removeallbots" description: "Removes all bots"