diff --git a/build.gradle b/build.gradle index 489c8ab..07160dc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id("xyz.jpenilla.run-paper") version "2.3.1" + id 'com.rikonardo.papermake' version '1.0.6' } group = 'hdvtdev' @@ -8,6 +9,7 @@ version = '0.0.1-a' repositories { mavenCentral() + maven { url 'https://repo.md-5.net/content/groups/public/' } maven { name = "papermc-repo" url = "https://repo.papermc.io/repository/maven-public/" @@ -20,6 +22,7 @@ repositories { dependencies { compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") + implementation group: 'me.libraryaddict.disguises', name: 'libsdisguises', version: '11.0.6' } tasks { @@ -31,7 +34,7 @@ tasks { } } -def targetJavaVersion = 17 +def targetJavaVersion = 21 java { def javaVersion = JavaVersion.toVersion(targetJavaVersion) sourceCompatibility = javaVersion @@ -57,3 +60,8 @@ processResources { expand props } } + +jar { + destinationDirectory.set(file("/home/hadvart/Documents/Minecraft/Pufferfish 1.20.4/plugins")) +} + diff --git a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java index c95ed3d..de5db00 100644 --- a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java +++ b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java @@ -1,17 +1,42 @@ package hdvtdev.blockAndSeek; +import me.libraryaddict.disguise.LibsDisguises; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandExecutor; import org.bukkit.plugin.java.JavaPlugin; -public final class BlockAndSeek extends JavaPlugin { +import java.io.File; +import java.util.Objects; + +public class BlockAndSeek extends JavaPlugin implements CommandExecutor { + + private static File dataFolder; + + public static File getPluginDataFolder() { + return dataFolder; + } @Override public void onEnable() { - // Plugin startup logic + + dataFolder = getDataFolder(); + + LibsDisguises libsDisguises = (LibsDisguises) Bukkit.getPluginManager().getPlugin("LibsDisguises"); + if (libsDisguises == null) { + getLogger().severe("LibsDisguises не найден!"); + super.onDisable(); + } + + Localization.load(this); + ConfigManager.load(); + + Objects.requireNonNull(getCommand("blockandseek")).setExecutor(new CommandListener()); } @Override public void onDisable() { - // Plugin shutdown logic + } + } diff --git a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java new file mode 100644 index 0000000..2bf70e5 --- /dev/null +++ b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java @@ -0,0 +1,29 @@ +package hdvtdev.blockAndSeek; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class BlockAndSeekGame { + + private final Set players = Collections.synchronizedSet(new HashSet<>()); + + public BlockAndSeekGame(String name, List players) { + for (String player : players) { + this.addPlayer(player); + } + } + + public void addPlayer(String name) { + Player p = Bukkit.getPlayerExact(name); + if (p != null) players.add(p); + } + + + + +} diff --git a/src/main/java/hdvtdev/blockAndSeek/CommandListener.java b/src/main/java/hdvtdev/blockAndSeek/CommandListener.java new file mode 100644 index 0000000..1d45ab3 --- /dev/null +++ b/src/main/java/hdvtdev/blockAndSeek/CommandListener.java @@ -0,0 +1,131 @@ +package hdvtdev.blockAndSeek; + +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.disguisetypes.Disguise; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.MiscDisguise; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CommandListener implements CommandExecutor, TabCompleter { + + public static List getAllCommands() { + return List.of("tpp", "morph"); + } + + + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + + + + int argsLen = args.length; + + if (argsLen == 0) { + sender.sendMessage(Localization.get("bs-usage")); + return true; + } + + switch (args[0]) { + case "map" -> { + if (argsLen > 1) { + switch (args[1]) { + case "list" -> sender.sendMessage(Localization.get("maps-list", "{maps}", ConfigManager.createdMaps().toString())); + case "create" -> { + if (argsLen > 2) { + String mapName = args[2]; + World world = Bukkit.getWorld(mapName); + if (world == null) { + sender.sendMessage(Localization.get("map-missing-world", "{world}", mapName)); + } else { + try { + if (ConfigManager.addMap(mapName)) sender.sendMessage(Localization.get("map-created", "{map}", mapName)); + else sender.sendMessage(Localization.get("map-already-exist", "{map}", mapName)); + } catch (IOException e) { + sender.sendMessage(Localization.get("map-creation-failed", "{error}", e.getMessage())); + } + } + } else sender.sendMessage(Localization.get("not-enough-arguments", "{usage}", "/blockandseek create [MAP NAME]")); + } + default -> { + if (ConfigManager.createdMaps().contains(args[1])) { + if (argsLen > 2) { + switch (args[2]) { + case "setspawn" -> {} + case "setlobby" -> {} + case "setduration" -> {} + default -> sender.sendMessage(Localization.get("unknown-subcommand", "{subcommand}", args[2])); + } + } else sender.sendMessage(Localization.get("not-enough-arguments", "{usage}", String.format("/blockandseek create %s [SUBCOMMAND]", args[1]))); + } else sender.sendMessage(Localization.get("map-not-exist", "{map}", args[1])); + } + } + } else sender.sendMessage(Localization.get("not-enough-arguments", "{usage}", "/blockandseek map [MAP NAME | SUBCOMMAND]")); + } + case "reload" -> { + if (argsLen > 1) { + switch (args[1]) { + case "messages" -> { + Localization.reload(); + sender.sendMessage(Localization.get("messages-reload")); + } + case "maps" -> { + ConfigManager.load(); + sender.sendMessage(Localization.get("maps-reload")); + } + } + } + } + + } + + /* + + */ + + + + return true; + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + sender.sendActionBar(MiniMessage.miniMessage().deserialize("" + args.length)); + return switch (args.length) { + case 1 -> List.of("reload", "help", "map", "join"); + case 2 -> switch (args[0]) { + case "map" -> { + List scmds = new ArrayList<>(List.of("create", "list")); + scmds.addAll(ConfigManager.createdMaps()); + yield scmds; + } + case "join" -> List.of("test"); + case "reload" -> List.of("messages", "maps"); + default -> List.of(); + }; + case 3 -> switch (args[1]) { + case "create", "list" -> List.of(); + default -> { + if (ConfigManager.createdMaps().contains(args[1])) { + yield List.of("setspawn", "setlobby", "setduration"); + } else yield List.of(); + } + }; + default -> List.of(); + }; + } +} diff --git a/src/main/java/hdvtdev/blockAndSeek/ConfigManager.java b/src/main/java/hdvtdev/blockAndSeek/ConfigManager.java new file mode 100644 index 0000000..f7c3539 --- /dev/null +++ b/src/main/java/hdvtdev/blockAndSeek/ConfigManager.java @@ -0,0 +1,58 @@ +package hdvtdev.blockAndSeek; + +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +public class ConfigManager { + + private static final File mapsConfigFile = new File(BlockAndSeek.getPluginDataFolder(), "maps.yml"); + private static final ConcurrentHashMap mapsConfigs = new ConcurrentHashMap<>(); + + public static Set createdMaps() { + return mapsConfigs.keySet(); + } + + public static MapConfig getMapConfig(@NotNull String name) { + return mapsConfigs.get(name); + } + + public static boolean addMap(String name) throws IOException { + if (mapsConfigs.containsKey(name)) return false; + mapsConfigs.put(name, MapConfig.defaults()); + YamlConfiguration config = YamlConfiguration.loadConfiguration(mapsConfigFile); + config.set(name + ".spawn", "null"); + config.set(name + ".duration", "null"); + config.set(name + ".lobby", "null"); + + config.save(mapsConfigFile); + + return true; + } + + + public static void load() { + mapsConfigs.clear(); + YamlConfiguration config = YamlConfiguration.loadConfiguration(mapsConfigFile); + for (String mapKey : config.getKeys(false)) { + List spawn = config.getLongList(mapKey + ".spawn"); + List lobby = config.getLongList(mapKey + ".lobby"); + int duration = config.getInt(mapKey + ".duration"); + MapConfig mapConfig = new MapConfig(spawn, lobby, duration); + mapsConfigs.put(mapKey, mapConfig); + } + } + + public record MapConfig(List spawn, List lobby, int duration) { + public static MapConfig defaults() { + return new MapConfig(null, null, -1); + } + } + + +} diff --git a/src/main/java/hdvtdev/blockAndSeek/GamesManager.java b/src/main/java/hdvtdev/blockAndSeek/GamesManager.java new file mode 100644 index 0000000..50a7e58 --- /dev/null +++ b/src/main/java/hdvtdev/blockAndSeek/GamesManager.java @@ -0,0 +1,25 @@ +package hdvtdev.blockAndSeek; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +public class GamesManager { + + private static final ConcurrentHashMap games = new ConcurrentHashMap<>(); + + public static void createGame(String name, ArrayList players) { + games.put(name, new BlockAndSeekGame(name, players)); + } + + public static boolean joinGame(String name) { + return false; + } + + public static void endGame(String name) { + games.remove(name); + } + + + +} diff --git a/src/main/java/hdvtdev/blockAndSeek/Localization.java b/src/main/java/hdvtdev/blockAndSeek/Localization.java new file mode 100644 index 0000000..fb496b2 --- /dev/null +++ b/src/main/java/hdvtdev/blockAndSeek/Localization.java @@ -0,0 +1,68 @@ +package hdvtdev.blockAndSeek; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + +import org.jetbrains.annotations.Nullable; + +import java.io.*; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; + +public class Localization { + + private static final Map localization = new ConcurrentHashMap<>(); + private static JavaPlugin javaPlugin; + + public static void reload() { + File localizationFile = new File(javaPlugin.getDataFolder(), "messages.yml"); + if (!localizationFile.exists()) javaPlugin.saveResource("messages.yml", false); + + YamlConfiguration locale = YamlConfiguration.loadConfiguration(localizationFile); + YamlConfiguration defaultLocale = YamlConfiguration.loadConfiguration( + new InputStreamReader(Objects.requireNonNull(javaPlugin.getResource("messages.yml")))); + + String prefix = locale.getString("prefix"); + prefix = prefix == null ? defaultLocale.getString("prefix") : prefix; + + for (String defaultElement : defaultLocale.getKeys(false)) { + String element = locale.getString(defaultElement); + localization.put(defaultElement, String.format("%s%s", prefix, element == null ? defaultLocale.getString(defaultElement) : element)); + } + } + + public static void load(JavaPlugin plugin) { + javaPlugin = plugin; + File localizationFile = new File(plugin.getDataFolder(), "messages.yml"); + if (!localizationFile.exists()) plugin.saveResource("messages.yml", false); + + YamlConfiguration locale = YamlConfiguration.loadConfiguration(localizationFile); + YamlConfiguration defaultLocale = YamlConfiguration.loadConfiguration( + new InputStreamReader(Objects.requireNonNull(plugin.getResource("messages.yml")))); + + String prefix = locale.getString("prefix"); + prefix = prefix == null ? defaultLocale.getString("prefix") : prefix; + + for (String defaultElement : defaultLocale.getKeys(false)) { + String element = locale.getString(defaultElement); + localization.put(defaultElement, String.format("%s%s", prefix, element == null ? defaultLocale.getString(defaultElement) : element)); + } + + } + + + public static Component get(String key, String... replacements) { + String s = localization.get(key); + for (int i = 0; i < replacements.length; i+=2) { + s = s.replace(replacements[i], replacements[i + 1]); + } + + return MiniMessage.miniMessage().deserialize(s); + } + + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..4287ca8 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1 @@ +# \ No newline at end of file diff --git a/src/main/resources/maps.yml b/src/main/resources/maps.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml new file mode 100644 index 0000000..8bab099 --- /dev/null +++ b/src/main/resources/messages.yml @@ -0,0 +1,15 @@ +prefix: "[BlockAndSeek] " +bs-usage: "Usage: /blockandseek [SUBCOMMAND]" + +messages-reload: "Successfully reload messages.yml" +not-enough-arguments: "Too few args. Usage: {usage}." +unknown-subcommand: "Unknown subcommand {subcommand}." + +#Map +maps-list: "Available maps: {maps}" +maps-reload: "Successfully reload maps.yml" +map-created: "Successfully created map {map}." +map-missing-world: "Could not find world {world} in server folder. An existing world is required to create a map" +map-creation-failed: "Failed to create map {map}. Error: {error}." +map-already-exist: "Map {map} already exist!" +map-not-exist: "Map {map} does not exist!" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a70c898..c6029b2 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,3 +2,8 @@ name: BlockAndSeek version: '0.0.1-a' main: hdvtdev.blockAndSeek.BlockAndSeek api-version: '1.20' +commands: + blockandseek: + aliases: + - bs + usage: "Usage: /blockandseek [subcommand]" \ No newline at end of file