From d43794f34b153ec886371c5de5891fc6747962db Mon Sep 17 00:00:00 2001 From: minster586 <43217359+minster586@users.noreply.github.com> Date: Thu, 19 Jun 2025 22:00:23 -0400 Subject: [PATCH] Redo --- .gitignore | 2 - README.md | 45 +++----- build.bat | 14 +-- pom.xml | 71 ++++++------ .../notifier/BungeeMessageListener.java | 50 --------- .../smartcraft/notifier/CommandHandler.java | 36 +++++++ .../smartcraft/notifier/ConfigManager.java | 31 ++++++ .../com/smartcraft/notifier/GotifySender.java | 75 +++++++++++++ .../notifier/SmartCraftNotifier.java | 72 +++---------- .../commands/GotifyStatusCommand.java | 58 ---------- .../notifier/config/ConfigManager.java | 101 ------------------ .../notifier/gotify/GotifyClient.java | 82 -------------- .../listeners/CoreJoinQuitListener.java | 32 ++++++ .../bungee/ServerSwitchListener.java | 42 -------- .../listeners/core/AdvancementListener.java | 45 -------- .../listeners/core/JoinQuitListener.java | 51 --------- .../litebans/PunishmentListener.java | 71 ------------ src/main/resources/config.yml | 34 ++---- src/main/resources/messages.yml | 13 +-- src/main/resources/plugin.yml | 21 ++-- .../smartcraft/notifier/CommandHandler.class | Bin 0 -> 2507 bytes .../smartcraft/notifier/ConfigManager.class | Bin 0 -> 2326 bytes .../smartcraft/notifier/GotifySender$1.class | Bin 0 -> 1877 bytes .../smartcraft/notifier/GotifySender$2.class | Bin 0 -> 1655 bytes .../smartcraft/notifier/GotifySender.class | Bin 0 -> 3186 bytes .../notifier/SmartCraftNotifier.class | Bin 0 -> 2453 bytes .../listeners/CoreJoinQuitListener.class | Bin 0 -> 1795 bytes target/classes/config.yml | 9 ++ target/classes/messages.yml | 2 + target/classes/plugin.yml | 16 +++ 30 files changed, 292 insertions(+), 681 deletions(-) delete mode 100644 .gitignore delete mode 100644 src/main/java/com/smartcraft/notifier/BungeeMessageListener.java create mode 100644 src/main/java/com/smartcraft/notifier/CommandHandler.java create mode 100644 src/main/java/com/smartcraft/notifier/ConfigManager.java create mode 100644 src/main/java/com/smartcraft/notifier/GotifySender.java delete mode 100644 src/main/java/com/smartcraft/notifier/commands/GotifyStatusCommand.java delete mode 100644 src/main/java/com/smartcraft/notifier/config/ConfigManager.java delete mode 100644 src/main/java/com/smartcraft/notifier/gotify/GotifyClient.java create mode 100644 src/main/java/com/smartcraft/notifier/listeners/CoreJoinQuitListener.java delete mode 100644 src/main/java/com/smartcraft/notifier/listeners/bungee/ServerSwitchListener.java delete mode 100644 src/main/java/com/smartcraft/notifier/listeners/core/AdvancementListener.java delete mode 100644 src/main/java/com/smartcraft/notifier/listeners/core/JoinQuitListener.java delete mode 100644 src/main/java/com/smartcraft/notifier/listeners/litebans/PunishmentListener.java create mode 100644 target/classes/com/smartcraft/notifier/CommandHandler.class create mode 100644 target/classes/com/smartcraft/notifier/ConfigManager.class create mode 100644 target/classes/com/smartcraft/notifier/GotifySender$1.class create mode 100644 target/classes/com/smartcraft/notifier/GotifySender$2.class create mode 100644 target/classes/com/smartcraft/notifier/GotifySender.class create mode 100644 target/classes/com/smartcraft/notifier/SmartCraftNotifier.class create mode 100644 target/classes/com/smartcraft/notifier/listeners/CoreJoinQuitListener.class create mode 100644 target/classes/config.yml create mode 100644 target/classes/messages.yml create mode 100644 target/classes/plugin.yml diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 11759d0..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -dependency-reduced-pom.xml -/target diff --git a/README.md b/README.md index c09a551..0e98cd6 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,23 @@ -# SmartCraft Notifier +# SmartCraftNotifier -A lightweight Paper plugin that sends player events (join, leave, server switch, and advancements) to a Gotify server via HTTP notifications. Designed for Minecraft 1.19+ networks using BungeeCord or standalone setups. +**SmartCraftNotifier** is a lightweight Spigot plugin that sends real-time join/leave notifications to your [Gotify](https://gotify.net) server. It’s clean, customizable, and built with zero external punishment dependencies. -## 🧰 Features +## 🚀 Features -- Optional BungeeCord integration via Plugin Messaging Channel -- Detects player join/leave and advancement events -- Sends customizable notifications to Gotify servers -- Configurable via `config.yml` (no in-game commands except `/gotifystatus`) -- Console/log alert if Gotify connection fails at startup +- Sends join and leave messages to Gotify +- Uses templates with `{player}` and `{server}` placeholders +- `/scnotify ping` – checks if Gotify is online +- `/scnotify status` – confirms the configured server name +- Fully configurable `config.yml` and `messages.yml` +- Lightweight: ~2.5MB shaded JAR with OkHttp -## ⚙️ Requirements +## 🛠 Configuration -- Minecraft Paper server 1.19+ -- Java 17+ -- [Gotify](https://gotify.net/) server for receiving notifications -- If using BungeeCord, set `bungeecord: true` in `spigot.yml` and enable the flag in the plugin config +### `config.yml` -## 🔧 Build Instructions +```yaml +server-name: SERVER-NAME -1. Install [Apache Maven](https://maven.apache.org/) -2. Run `build.bat` (Windows) or `mvn clean package` (Linux/macOS) -3. Your compiled plugin will be at `target/SmartCraftNotifier.jar` - -## 🚀 Usage - -- Drop the plugin into your server’s `plugins/` folder -- Edit `config.yml` to set your Gotify server URL, app token, and feature toggles -- Restart your server to generate logs or test with `/gotifystatus` - ---- - -🧠 Inspired by the idea of keeping server owners effortlessly informed. - -*Built with care by Eric’s Copilot.* \ No newline at end of file +gotify: + url: "https://gotify.example.com" + token: "REPLACE_WITH_YOUR_TOKEN" \ No newline at end of file diff --git a/build.bat b/build.bat index 3b8b8ee..faac277 100644 --- a/build.bat +++ b/build.bat @@ -1,14 +1,14 @@ @echo off -echo Building SmartCraft Notifier... +echo Building SmartCraftNotifier... -REM Run Maven clean & package +:: Ensure Maven is installed and on your PATH mvn clean package -IF %ERRORLEVEL% NEQ 0 ( - echo Build failed! Check errors above. - pause - exit /b %ERRORLEVEL% +:: Check if build succeeded +if exist target\SmartCraftNotifier.jar ( + echo Build successful! JAR located at: target\SmartCraftNotifier.jar +) else ( + echo Build failed. Check for errors above. ) -echo Build completed! Check the 'target' folder for your .jar pause \ No newline at end of file diff --git a/pom.xml b/pom.xml index be4cb77..f18dbdc 100644 --- a/pom.xml +++ b/pom.xml @@ -6,41 +6,13 @@ com.smartcraft.notifier SmartCraftNotifier - 1.1.0 - SmartCraftNotifier + 1.2.0 - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - 17 - 17 - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.5.0 - - - package - - shade - - - true - - - - - - + + 17 + 17 + UTF-8 + @@ -58,11 +30,40 @@ provided - + com.squareup.okhttp3 okhttp 4.12.0 + + + SmartCraftNotifier + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + shade + + false + true + + + + + + \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/BungeeMessageListener.java b/src/main/java/com/smartcraft/notifier/BungeeMessageListener.java deleted file mode 100644 index 5acead2..0000000 --- a/src/main/java/com/smartcraft/notifier/BungeeMessageListener.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.smartcraft.notifier; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.plugin.messaging.PluginMessageListener; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -public class BungeeMessageListener implements PluginMessageListener { - - @Override - public void onPluginMessageReceived(String channel, Player player, byte[] message) { - if (!channel.equals("BungeeCord")) return; - - try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(message))) { - String subChannel = in.readUTF(); - - if (subChannel.equals("PlayerJoin")) { - String joinedPlayer = in.readUTF(); - SmartCraftNotifier.instance.getGotifyClient().sendMessage( - "👤 Player Joined", - joinedPlayer + " connected to the network.", - 4 - ); - - } else if (subChannel.equals("PlayerQuit")) { - String leftPlayer = in.readUTF(); - SmartCraftNotifier.instance.getGotifyClient().sendMessage( - "🚪 Player Left", - leftPlayer + " disconnected from the network.", - 4 - ); - - } else if (subChannel.equals("ServerSwitch")) { - String playerName = in.readUTF(); - String fromServer = in.readUTF(); - String toServer = in.readUTF(); - SmartCraftNotifier.instance.getGotifyClient().sendMessage( - "🔁 Server Switch", - playerName + " switched from " + fromServer + " to " + toServer, - 3 - ); - } - } catch (IOException e) { - Bukkit.getLogger().warning("[SmartCraftNotifier] Failed to parse BungeeCord message: " + e.getMessage()); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/CommandHandler.java b/src/main/java/com/smartcraft/notifier/CommandHandler.java new file mode 100644 index 0000000..846734d --- /dev/null +++ b/src/main/java/com/smartcraft/notifier/CommandHandler.java @@ -0,0 +1,36 @@ +package com.smartcraft.notifier; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class CommandHandler implements CommandExecutor { + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!sender.hasPermission("smartcraft.notify")) { + sender.sendMessage(ChatColor.RED + "You don't have permission to use this command."); + return true; + } + + if (args.length == 0) { + sender.sendMessage(ChatColor.YELLOW + "Usage: /scnotify "); + return true; + } + + switch (args[0].toLowerCase()) { + case "ping": + GotifySender.ping(sender); + break; + case "status": + String serverName = SmartCraftNotifier.getInstance().getServerName(); + sender.sendMessage(ChatColor.AQUA + "SmartCraftNotifier is running on: " + ChatColor.GOLD + serverName); + break; + default: + sender.sendMessage(ChatColor.RED + "Unknown subcommand. Try /scnotify ping or /scnotify status."); + } + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/ConfigManager.java b/src/main/java/com/smartcraft/notifier/ConfigManager.java new file mode 100644 index 0000000..1c002ed --- /dev/null +++ b/src/main/java/com/smartcraft/notifier/ConfigManager.java @@ -0,0 +1,31 @@ +package com.smartcraft.notifier; + +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +public class ConfigManager { + + private static Map messages = new HashMap<>(); + + public static void reload(Plugin plugin) { + File messageFile = new File(plugin.getDataFolder(), "messages.yml"); + if (!messageFile.exists()) { + plugin.saveResource("messages.yml", false); + } + + FileConfiguration config = YamlConfiguration.loadConfiguration(messageFile); + + for (String key : config.getKeys(false)) { + messages.put(key, config.getString(key)); + } + } + + public static String getMessage(String key) { + return messages.getOrDefault(key, "Missing message: " + key); + } +} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/GotifySender.java b/src/main/java/com/smartcraft/notifier/GotifySender.java new file mode 100644 index 0000000..1850c3b --- /dev/null +++ b/src/main/java/com/smartcraft/notifier/GotifySender.java @@ -0,0 +1,75 @@ +package com.smartcraft.notifier; + +import okhttp3.*; +import org.bukkit.command.CommandSender; + +import java.io.IOException; + +public class GotifySender { + + private static final OkHttpClient client = new OkHttpClient(); + + public static void ping(CommandSender sender) { + String url = SmartCraftNotifier.getInstance().getConfig().getString("gotify.url"); + + if (url == null || url.isEmpty()) { + sender.sendMessage("§cGotify URL is missing in config.yml"); + return; + } + + Request request = new Request.Builder() + .url(url + "/version") + .get() + .build(); + + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + sender.sendMessage("§c❌ Gotify server unreachable: " + e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()) { + sender.sendMessage("§a✅ Gotify server is reachable."); + } else { + sender.sendMessage("§e⚠️ Gotify responded, but returned HTTP " + response.code()); + } + response.close(); + } + }); + } + + public static void send(String message) { + String url = SmartCraftNotifier.getInstance().getConfig().getString("gotify.url"); + String token = SmartCraftNotifier.getInstance().getConfig().getString("gotify.token"); + + if (url == null || token == null || url.isEmpty() || token.isEmpty()) { + SmartCraftNotifier.getInstance().getLogger().warning("Gotify URL or token is missing in config.yml"); + return; + } + + RequestBody body = new FormBody.Builder() + .add("title", "SmartCraft Notifier") + .add("message", message) + .add("priority", "5") + .build(); + + Request request = new Request.Builder() + .url(url + "/message?token=" + token) + .post(body) + .build(); + + client.newCall(request).enqueue(new Callback() { + @Override + public void onFailure(Call call, IOException e) { + SmartCraftNotifier.getInstance().getLogger().warning("Failed to send Gotify message: " + e.getMessage()); + } + + @Override + public void onResponse(Call call, Response response) { + response.close(); + } + }); + } +} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/SmartCraftNotifier.java b/src/main/java/com/smartcraft/notifier/SmartCraftNotifier.java index 13b054f..3e6cd4e 100644 --- a/src/main/java/com/smartcraft/notifier/SmartCraftNotifier.java +++ b/src/main/java/com/smartcraft/notifier/SmartCraftNotifier.java @@ -1,80 +1,34 @@ package com.smartcraft.notifier; -import com.smartcraft.notifier.commands.GotifyStatusCommand; -import com.smartcraft.notifier.config.ConfigManager; -import com.smartcraft.notifier.gotify.GotifyClient; -import com.smartcraft.notifier.listeners.core.JoinQuitListener; -import com.smartcraft.notifier.listeners.core.AdvancementListener; -import com.smartcraft.notifier.listeners.litebans.PunishmentListener; -import com.smartcraft.notifier.listeners.bungee.ServerSwitchListener; - -import org.bukkit.Bukkit; +import com.smartcraft.notifier.listeners.CoreJoinQuitListener; import org.bukkit.plugin.java.JavaPlugin; public class SmartCraftNotifier extends JavaPlugin { - public static SmartCraftNotifier instance; - private ConfigManager configManager; - private GotifyClient gotifyClient; + private static SmartCraftNotifier instance; + private String serverName = "Unknown"; @Override public void onEnable() { instance = this; saveDefaultConfig(); - this.configManager = new ConfigManager(this); - this.gotifyClient = new GotifyClient(configManager); + saveResource("messages.yml", false); + ConfigManager.reload(this); - if (configManager.isDebugMode()) { - getLogger().info("[Debug] Debug mode is enabled."); - } + serverName = getConfig().getString("server-name", "Unknown"); - if (configManager.isGotifyEnabled()) { - getLogger().info("Gotify is ready to send messages."); - getLogger().info("Connected to Gotify server: " + configManager.getGotifyUrl()); - } else { - getLogger().warning("Gotify is disabled in the config."); - } + getServer().getPluginManager().registerEvents(new CoreJoinQuitListener(), this); + getCommand("scnotify").setExecutor(new CommandHandler()); - getCommand("gotifystatus").setExecutor(new GotifyStatusCommand(this)); - - Bukkit.getPluginManager().registerEvents(new JoinQuitListener(this), this); - Bukkit.getPluginManager().registerEvents(new AdvancementListener(this), this); - - if (configManager.isLiteBansEnabled()) { - try { - Bukkit.getPluginManager().registerEvents(new PunishmentListener(this), this); - getLogger().info("LiteBans integration enabled."); - } catch (Throwable t) { - getLogger().warning("LiteBans not found or failed to initialize."); - if (configManager.isDebugMode()) t.printStackTrace(); - } - } - - if (configManager.isBungeeCordEnabled()) { - try { - Bukkit.getPluginManager().registerEvents(new ServerSwitchListener(this), this); - getLogger().info("BungeeCord server switch tracking is enabled."); - } catch (Throwable t) { - getLogger().warning("Failed to register BungeeCord listener."); - if (configManager.isDebugMode()) t.printStackTrace(); - } - } else { - getLogger().info("BungeeCord integration is disabled."); - } - - getLogger().info("SmartCraft Notifier has been enabled."); - } - - public ConfigManager getConfigManager() { - return configManager; - } - - public GotifyClient getGotifyClient() { - return gotifyClient; + getLogger().info("SmartCraftNotifier enabled for server: " + serverName); } public static SmartCraftNotifier getInstance() { return instance; } + + public String getServerName() { + return serverName; + } } \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/commands/GotifyStatusCommand.java b/src/main/java/com/smartcraft/notifier/commands/GotifyStatusCommand.java deleted file mode 100644 index f325671..0000000 --- a/src/main/java/com/smartcraft/notifier/commands/GotifyStatusCommand.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.smartcraft.notifier.commands; - -import com.smartcraft.notifier.SmartCraftNotifier; -import com.smartcraft.notifier.config.ConfigManager; -import com.smartcraft.notifier.gotify.GotifyClient; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; - -public class GotifyStatusCommand implements CommandExecutor { - - private final SmartCraftNotifier plugin; - private final ConfigManager config; - private final GotifyClient gotify; - - public GotifyStatusCommand(SmartCraftNotifier plugin) { - this.plugin = plugin; - this.config = plugin.getConfigManager(); - this.gotify = plugin.getGotifyClient(); - } - - @Override - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { - if (!sender.hasPermission("smartcraftnotifier.command.status")) { - sender.sendMessage("§cYou do not have permission to use this command."); - return true; - } - - String subcommand = (args.length == 0) ? "ping" : args[0].toLowerCase(); - - switch (subcommand) { - case "ping": - if (!sender.hasPermission("smartcraftnotifier.command.status.ping")) { - sender.sendMessage("§cYou do not have permission to ping Gotify."); - return true; - } - boolean reachable = gotify.ping(); - sender.sendMessage(reachable - ? "§a✅ Gotify is reachable." - : "§c❌ Could not reach Gotify server."); - return true; - - case "server": - if (!sender.hasPermission("smartcraftnotifier.command.status.server")) { - sender.sendMessage("§cYou do not have permission to view Gotify server info."); - return true; - } - String url = config.getGotifyUrl(); - sender.sendMessage("§7🌐 Gotify server: §e" + url); - return true; - - default: - sender.sendMessage("§7Usage: §f/gotifystatus §8[ping|server]"); - return true; - } - } -} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/config/ConfigManager.java b/src/main/java/com/smartcraft/notifier/config/ConfigManager.java deleted file mode 100644 index 4c1aae9..0000000 --- a/src/main/java/com/smartcraft/notifier/config/ConfigManager.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.smartcraft.notifier.config; - -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.Plugin; - -import java.io.File; - -public class ConfigManager { - - private final Plugin plugin; - private final FileConfiguration config; - private FileConfiguration messageConfig; - - public ConfigManager(Plugin plugin) { - this.plugin = plugin; - this.config = plugin.getConfig(); - loadMessages(); - } - - private void loadMessages() { - File messageFile = new File(plugin.getDataFolder(), "messages.yml"); - if (!messageFile.exists()) { - plugin.saveResource("messages.yml", false); - } - this.messageConfig = YamlConfiguration.loadConfiguration(messageFile); - } - - // 🧠 Global settings - public boolean isDebugMode() { - return config.getBoolean("debug", false); - } - - public boolean isBungeeCordEnabled() { - return config.getBoolean("bungeecord.enabled", false); - } - - // ✅ Gotify settings - public boolean isGotifyEnabled() { - return config.getBoolean("gotify.enabled", false); - } - - public String getGotifyUrl() { - return config.getString("gotify.serverUrl", "NOT SET"); - } - - public String getGotifyToken() { - return config.getString("gotify.appToken", ""); - } - - public int getDefaultPriority() { - return config.getInt("gotify.defaultPriority", 1); - } - - // 📢 Core Event toggles - public boolean logJoins() { - return config.getBoolean("events.logJoins", true); - } - - public boolean logLeaves() { - return config.getBoolean("events.logLeaves", true); - } - - public boolean logAdvancements() { - return config.getBoolean("events.logAdvancements", true); - } - - public boolean logServerSwitches() { - return config.getBoolean("events.logServerSwitch", false); - } - - public String getEventMessage(String key) { - return messageConfig.getString("events." + key, "{player} triggered " + key); - } - - // 🔨 LiteBans Integration - public boolean isLiteBansEnabled() { - return config.getBoolean("litebans.enabled", false); - } - - public boolean logBans() { - return config.getBoolean("litebans.logBans", true); - } - - public boolean logMutes() { - return config.getBoolean("litebans.logMutes", true); - } - - public boolean logKicks() { - return config.getBoolean("litebans.logKicks", true); - } - - public boolean logWarns() { - return config.getBoolean("litebans.logWarns", true); - } - - public String getLiteBansMessage(String type) { - return messageConfig.getString("litebans." + type, - "🔔 {player} received a " + type + ": {reason}"); - } -} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/gotify/GotifyClient.java b/src/main/java/com/smartcraft/notifier/gotify/GotifyClient.java deleted file mode 100644 index adf2c58..0000000 --- a/src/main/java/com/smartcraft/notifier/gotify/GotifyClient.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.smartcraft.notifier.gotify; - -import com.smartcraft.notifier.SmartCraftNotifier; -import com.smartcraft.notifier.config.ConfigManager; -import okhttp3.*; - -import java.io.IOException; - -public class GotifyClient { - - private final OkHttpClient httpClient = new OkHttpClient(); - private final ConfigManager config; - - public GotifyClient(ConfigManager config) { - this.config = config; - } - - public void sendMessage(String title, String message, int priority) { - if (!config.isGotifyEnabled()) return; - - String serverUrl = config.getGotifyUrl(); - String token = config.getGotifyToken(); - - if (serverUrl == null || token == null || serverUrl.isEmpty() || token.isEmpty()) { - log("❌ Gotify server URL or App Token is missing."); - return; - } - - String url = serverUrl + "/message?token=" + token; - - RequestBody body = new FormBody.Builder() - .add("title", title) - .add("message", message) - .add("priority", String.valueOf(priority)) - .build(); - - Request request = new Request.Builder() - .url(url) - .post(body) - .build(); - - httpClient.newCall(request).enqueue(new Callback() { - @Override public void onFailure(Call call, IOException e) { - log("❌ Failed to send Gotify message: " + e.getMessage()); - if (config.isDebugMode()) e.printStackTrace(); - } - - @Override public void onResponse(Call call, Response response) { - if (!response.isSuccessful() && config.isDebugMode()) { - log("⚠️ Gotify responded with status code: " + response.code()); - } - response.close(); - } - }); - - if (config.isDebugMode()) { - log("[Debug] Gotify message sent: " + title + " | " + message + " (Priority " + priority + ")"); - } - } - - public boolean ping() { - if (!config.isGotifyEnabled()) return false; - - String pingUrl = config.getGotifyUrl() + "/application"; - - Request request = new Request.Builder() - .url(pingUrl) - .header("X-Gotify-Key", config.getGotifyToken()) - .build(); - - try (Response response = httpClient.newCall(request).execute()) { - return response.isSuccessful(); - } catch (IOException e) { - if (config.isDebugMode()) e.printStackTrace(); - return false; - } - } - - private void log(String msg) { - SmartCraftNotifier.getInstance().getLogger().warning(msg); - } -} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/listeners/CoreJoinQuitListener.java b/src/main/java/com/smartcraft/notifier/listeners/CoreJoinQuitListener.java new file mode 100644 index 0000000..caa31ca --- /dev/null +++ b/src/main/java/com/smartcraft/notifier/listeners/CoreJoinQuitListener.java @@ -0,0 +1,32 @@ +package com.smartcraft.notifier.listeners; + +import com.smartcraft.notifier.ConfigManager; +import com.smartcraft.notifier.GotifySender; +import com.smartcraft.notifier.SmartCraftNotifier; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class CoreJoinQuitListener implements Listener { + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + String player = event.getPlayer().getName(); + String server = SmartCraftNotifier.getInstance().getServerName(); + String message = ConfigManager.getMessage("player-join") + .replace("{player}", player) + .replace("{server}", server); + GotifySender.send(message); + } + + @EventHandler + public void onQuit(PlayerQuitEvent event) { + String player = event.getPlayer().getName(); + String server = SmartCraftNotifier.getInstance().getServerName(); + String message = ConfigManager.getMessage("player-leave") + .replace("{player}", player) + .replace("{server}", server); + GotifySender.send(message); + } +} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/listeners/bungee/ServerSwitchListener.java b/src/main/java/com/smartcraft/notifier/listeners/bungee/ServerSwitchListener.java deleted file mode 100644 index 3cce645..0000000 --- a/src/main/java/com/smartcraft/notifier/listeners/bungee/ServerSwitchListener.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.smartcraft.notifier.listeners.bungee; - -import com.smartcraft.notifier.SmartCraftNotifier; -import com.smartcraft.notifier.config.ConfigManager; -import com.smartcraft.notifier.gotify.GotifyClient; -import net.md_5.bungee.api.connection.ProxiedPlayer; -import net.md_5.bungee.api.event.ServerSwitchEvent; -import net.md_5.bungee.api.plugin.Listener; -import net.md_5.bungee.event.EventHandler; - -public class ServerSwitchListener implements Listener { - - private final SmartCraftNotifier plugin; - private final ConfigManager config; - private final GotifyClient gotify; - - public ServerSwitchListener(SmartCraftNotifier plugin) { - this.plugin = plugin; - this.config = plugin.getConfigManager(); - this.gotify = plugin.getGotifyClient(); - } - - @EventHandler - public void onServerSwitch(ServerSwitchEvent event) { - if (!config.logServerSwitches()) return; - - ProxiedPlayer player = event.getPlayer(); - String serverName = (player.getServer() != null) - ? player.getServer().getInfo().getName() - : "Unknown"; - - String message = config.getEventMessage("serverSwitch") - .replace("{player}", player.getName()) - .replace("{server}", serverName); - - gotify.sendMessage("Server Switched", message, config.getDefaultPriority()); - - if (config.isDebugMode()) { - plugin.getLogger().info("[Debug] " + player.getName() + " switched to " + serverName); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/listeners/core/AdvancementListener.java b/src/main/java/com/smartcraft/notifier/listeners/core/AdvancementListener.java deleted file mode 100644 index 05558b3..0000000 --- a/src/main/java/com/smartcraft/notifier/listeners/core/AdvancementListener.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.smartcraft.notifier.listeners.core; - -import com.smartcraft.notifier.SmartCraftNotifier; -import com.smartcraft.notifier.config.ConfigManager; -import com.smartcraft.notifier.gotify.GotifyClient; -import org.bukkit.Bukkit; -import org.bukkit.advancement.Advancement; -import org.bukkit.advancement.AdvancementDisplay; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerAdvancementDoneEvent; - -public class AdvancementListener implements Listener { - - private final SmartCraftNotifier plugin; - private final ConfigManager config; - private final GotifyClient gotify; - - public AdvancementListener(SmartCraftNotifier plugin) { - this.plugin = plugin; - this.config = plugin.getConfigManager(); - this.gotify = plugin.getGotifyClient(); - } - - @EventHandler - public void onAdvancement(PlayerAdvancementDoneEvent event) { - if (!config.logAdvancements()) return; - - Advancement adv = event.getAdvancement(); - AdvancementDisplay display = adv.getDisplay(); - if (display == null || !display.shouldAnnounceToChat()) return; - - String player = event.getPlayer().getName(); - String title = display.getTitle(); - String message = config.getEventMessage("advancement") - .replace("{player}", player) - .replace("{advancement}", title); - - gotify.sendMessage("Advancement Unlocked", message, config.getDefaultPriority()); - - if (config.isDebugMode()) { - Bukkit.getLogger().info("[Debug] Advancement event triggered for " + player + ": " + title); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/listeners/core/JoinQuitListener.java b/src/main/java/com/smartcraft/notifier/listeners/core/JoinQuitListener.java deleted file mode 100644 index 97c7bb8..0000000 --- a/src/main/java/com/smartcraft/notifier/listeners/core/JoinQuitListener.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.smartcraft.notifier.listeners.core; - -import com.smartcraft.notifier.SmartCraftNotifier; -import com.smartcraft.notifier.config.ConfigManager; -import com.smartcraft.notifier.gotify.GotifyClient; -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; - -public class JoinQuitListener implements Listener { - - private final SmartCraftNotifier plugin; - private final ConfigManager config; - private final GotifyClient gotify; - - public JoinQuitListener(SmartCraftNotifier plugin) { - this.plugin = plugin; - this.config = plugin.getConfigManager(); - this.gotify = plugin.getGotifyClient(); - } - - @EventHandler - public void onJoin(PlayerJoinEvent event) { - if (!config.logJoins()) return; - - String player = event.getPlayer().getName(); - String message = config.getEventMessage("join").replace("{player}", player); - - gotify.sendMessage("Player Joined", message, config.getDefaultPriority()); - - if (config.isDebugMode()) { - Bukkit.getLogger().info("[Debug] Join event triggered for " + player); - } - } - - @EventHandler - public void onQuit(PlayerQuitEvent event) { - if (!config.logLeaves()) return; - - String player = event.getPlayer().getName(); - String message = config.getEventMessage("leave").replace("{player}", player); - - gotify.sendMessage("Player Left", message, config.getDefaultPriority()); - - if (config.isDebugMode()) { - Bukkit.getLogger().info("[Debug] Quit event triggered for " + player); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/smartcraft/notifier/listeners/litebans/PunishmentListener.java b/src/main/java/com/smartcraft/notifier/listeners/litebans/PunishmentListener.java deleted file mode 100644 index 40ab448..0000000 --- a/src/main/java/com/smartcraft/notifier/listeners/litebans/PunishmentListener.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.smartcraft.notifier.listeners.litebans; - -import com.smartcraft.notifier.SmartCraftNotifier; -import com.smartcraft.notifier.config.ConfigManager; -import com.smartcraft.notifier.gotify.GotifyClient; -import litebans.api.Punishment; -import litebans.api.events.PunishmentExecuteEvent; -import org.bukkit.Bukkit; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; - -public class PunishmentListener implements Listener { - - private final SmartCraftNotifier plugin; - private final ConfigManager config; - private final GotifyClient gotify; - - public PunishmentListener(SmartCraftNotifier plugin) { - this.plugin = plugin; - this.config = plugin.getConfigManager(); - this.gotify = plugin.getGotifyClient(); - } - - @EventHandler - public void onPunishment(PunishmentExecuteEvent event) { - if (!config.isLiteBansEnabled()) return; - - Punishment punishment = event.getPunishment(); - String type = punishment.getType(); // "ban", "mute", "kick", "warn" - String playerName = punishment.getName(); // not UUID - String reason = punishment.getReason(); - - // Check if this type is allowed in config - switch (type.toLowerCase()) { - case "ban": - if (!config.logBans()) return; - break; - case "mute": - if (!config.logMutes()) return; - break; - case "kick": - if (!config.logKicks()) return; - break; - case "warn": - if (!config.logWarns()) return; - break; - default: - return; // Unknown type - } - - // Build message from template - String template = config.getLiteBansMessage(type.toLowerCase()); - String message = template - .replace("{player}", playerName) - .replace("{reason}", (reason != null && !reason.isEmpty()) ? reason : "No reason provided"); - - String title = switch (type.toLowerCase()) { - case "ban" -> "🔨 Player Banned"; - case "mute" -> "🔇 Player Muted"; - case "kick" -> "👢 Player Kicked"; - case "warn" -> "⚠️ Player Warned"; - default -> "⚔️ Punishment Issued"; - }; - - gotify.sendMessage(title, message, config.getDefaultPriority()); - - if (config.isDebugMode()) { - Bukkit.getLogger().info("[Debug] LiteBans " + type + " issued to " + playerName + ": " + reason); - } - } -} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index dc68e16..c800c7c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,31 +1,9 @@ -debug: false +# Logical name for this server (shown in /scnotify status) +server-name: Lobby gotify: - enabled: true - serverUrl: "https://your.gotify.instance" # Replace with your Gotify server - appToken: "your_app_token_here" # Replace with your Gotify app token - defaultPriority: 4 # Use -2 (silent) to 10 (urgent) + # Gotify server base URL (no trailing slash) + url: "https://gotify.example.com" -events: - logJoins: true - logLeaves: true - logServerSwitch: true - logAdvancements: true - - messages: - join: "👤 {player} has joined the server!" - leave: "🚪 {player} has left the server." - advancement: "📜 {player} unlocked: {advancement}" - -litebans: - enabled: true - logBans: true - logMutes: true - logKicks: true - logWarns: true - - messages: - ban: "🔨 {player} was banned for: {reason}" - mute: "🔇 {player} was muted for: {reason}" - kick: "👢 {player} was kicked for: {reason}" - warn: "⚠️ {player} was warned: {reason}" \ No newline at end of file + # Token from your Gotify app + token: "REPLACE_WITH_YOUR_TOKEN" \ No newline at end of file diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index 6c3d458..9ebfc2d 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -1,11 +1,2 @@ -events: - join: "👤 {player} has joined the server!" - leave: "🚪 {player} has left the server." - advancement: "📜 {player} unlocked: {advancement}" - serverSwitch: "🔁 {player} switched to: {server}" - -litebans: - ban: "🔨 {player} was banned for: {reason}" - mute: "🔇 {player} was muted for: {reason}" - kick: "👢 {player} was kicked for: {reason}" - warn: "⚠️ {player} was warned: {reason}" \ No newline at end of file +player-join: "{player} joined {server}." +player-leave: "{player} left {server}." \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 15edc57..0eace40 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,15 +1,16 @@ name: SmartCraftNotifier -version: 1.1.0 +version: 1.2.0 main: com.smartcraft.notifier.SmartCraftNotifier api-version: 1.20 -description: Notifies your Gotify server on key in-game events: joins, advancements, bans, and more. -authors: minster586 + commands: - gotifystatus: - description: Ping the Gotify server to check connectivity. - usage: /gotifystatus - permission: smartcraftnotifier.command.status + scnotify: + description: SmartCraft Notifier utility command + usage: /scnotify + permission: smartcraft.notify + permission-message: You do not have permission to use this command. + permissions: - smartcraftnotifier.command.status: - description: Allows access to the /gotifystatus command - default: true \ No newline at end of file + smartcraft.notify: + description: Allows use of SmartCraft Notifier commands + default: op \ No newline at end of file diff --git a/target/classes/com/smartcraft/notifier/CommandHandler.class b/target/classes/com/smartcraft/notifier/CommandHandler.class new file mode 100644 index 0000000000000000000000000000000000000000..df3982ffb266a0a75501b3012537031c018dc945 GIT binary patch literal 2507 zcma)7-*XdH6#j0SW<$DINlT$v$^wO^R1-xIY)Z9+0>!ii(iRIU-XyollFi<*KMGaH z86N!)93Gu<`k*iJPzw+I0n9l5FFrbsN6eZu24nu6xv`ue{p({1E%n;4VvPhr{JvubR8G7@k zE$01tQ8}#!YcD~I?m%`hB(!NZeAu^qVQ}S#H|>m;rXsIyP#tVpU{@L?{kYX+jX&R zn1~wFME(X*CxIMhG*C@OUd81rsukBmUh0^}Wrh=Pz~Hgv1g_$mhFOMFuku|`9iLMj zKi_P49iJgjuvCOM8`P&nsip~*H+Mlix{7%n3ku)835JBbgAHL-@OY^<#~V$VOBAHt~W#n^HvnL`=Q-Mj$2m2^hCBdhDsbHdKtDN zeWNVxQO~IIHDNS%6w∾k&|69|faXvUD5`MxT++)}8%#-!@H@4}9qii5sM zCs=zI805+EZJTTjX-^o8#o;kbvL(A_%LlgM`o--?#-g*{58mBu~vl%bi?+1B2oQE~-rjVF^&(I3HM42(a)p)DBCa1wZmQxQae z9gIE?57NQG2Q3F(r#EqWWuki%AN@j(=*Q_FdGW`ef6+XIGmjja#|FET6PuWPj6)m9 z(!;00Lu>=-@hx23!1*m)*~HvLjG|wsAWu-BaWM7_%gtaL=-;{7%FYGIcNgUcOi*?z z(;murh}OfD;|P*Ci$0vg0KTEm?)MnPBhscH$l@m)#?Lr{O&kj_nj*vqhbBg9bsKjA z+_vxqz9i7q-dDIw@zm;T$}<{xD$-sICEDGG`0&AhkkW8e*JH>3CZM}erh^CsR%t#& buUO=?9*i;=?+2p`pUx9>wuXmv*}?w+HRG=1 literal 0 HcmV?d00001 diff --git a/target/classes/com/smartcraft/notifier/ConfigManager.class b/target/classes/com/smartcraft/notifier/ConfigManager.class new file mode 100644 index 0000000000000000000000000000000000000000..c617aaa0d0d6e80b77681de54304af3c0543d062 GIT binary patch literal 2326 zcma)7ZBrXn6n-uNHY7`d(9(iZDTOwKm$lkzCA`>z2sVM*APDvC5^jh8Bj=qEj=x z8h2&U~X+Lr1|Z+gvtW!EmQ}btd@qa}}g(+U4w7%N*s1&lD}wHsu^cEIqct(7NF4 z3JskMJ*WFEbFV^sCZMBBM>i4-?K6H@2N+U1+R&~lG;OiksO<=Mo$pvwRVwEcxwXMv zQ+@l!1Y+o-ZDhqHP&ae0MGqC)?h4D{y9|Troa2^_okq24N~3Ny%BF2R^dH%=4GnKF z=zisXIaQaF8PvU?FyIlNRI`ig_*K(T&LtGl1v@c ztON!ysu;P!a6R4ZeU|XC4dtKKF@_8w5>HG|5(z~7wyJVM$0Vj`2aoTIN5XR&Zjngr z3-dWE|;cb8zsVTZ1I{EG+Sua@h)zYzKYML1%`XCU>J*X z{W`g`3A~598s7ikvXnMWyX*J>(+nD^@IV|8FRAo)D1hJe1tGIZ%wSH#EQxj6owT51 z9v@OSn^F*Ths5hU5zmiZ3GI~NJ{C1BQ1;UVC#yO>!V>kSEuPTqT|CJUnaHe$<)%Rm zhD(9|M8^ZxsbGaXu@ z*+Y|pysqOj)pJ^fd#gUW_F!@t2BH!-j}t>OY<49U!-eJsrxp%cg5g#)$vJ&;Mr@ks zSXCUTBf{4qN(a$Uki1wW2EubBL7e7;lQ2bRE7!53sJ>j|Rnj)QqM$b?5 z*@9mBufl*%T=Xp}8C^_apg~Wy+Lk%OrB_3eeuy48pbwYHu>)7o9|r$PRkV?9>jeh3 zGRJt6xEemfNN)TPH=jb!q=sY17>{B67Z~}8*dgv5gBp6e^#=_0w;tmj!*BR_^%;65 zCngWEa*TWon`))N@bu*$s-T#UVVK~8>h4Alm64)*=n_WhZJx?mrRV2#UnqPTDv1ih z1~z^F6EMrQ%x?7-K^ zg=l9fL{ZgC=FXaFu}p zvdU&dsn#{8%zeMc-6n&%!~J{|hcZl7WVq$j+Rdh?9Ll!MgSt~reiQf-!@x~1@YHRF z>B5WMXEzx7%d#$pz;M!nfk6{}7_~5jF^0Z^b{MUAfmm&C*F?C^YrbH}R;0`Q4IX-W zpBnpB!;2USm6zjzN*$8HBKQ1uNRTsBZCCfDO3aWao#nNKFI>@5o(xK}8zx@GSp#Pn zCVDtncn#->v@M}lL=^EY0zOrkO|W9Nt19$@tx}fecEQ3$*bJw)c~g{S;BxiQQw>^0 ziU*2Xp_-28lt%Ud8^$E^2BsM77tP1QG-eov^+b;<%=Jp62SXhD3?t7H!@#JkTu*+e zbs5|jQHy#Yr>W;T?J(SNi3y#@8wQ*%^>zNWa20PdSYA|ZyDss$*`{(x6ORUQoz!@+ z#}9w_(oW=UMD7f3u!k9NPkGCzngLic|B(petIZI-@q1h)5ZMO_k?*wp(&bcq5d_~G;yOkb|ZaH_!^qIi*-InO#{ZuOY7_RY(^qm4gwLDeI7+3GC=B|{ttD%$T093!-fBMr8_ZUjx@9?BDEwV z1)DV3N6!hcv8=xL=tk(HX9y-)hiP>k8Tta|+?8Kp&Hav%pJ|uDIK2nR2RH+Lk67{A z!~{;!jueeoQiKQOtuZI&et}i|4X5{U9{2;7GB}1Z<0R(@>U<1mCm|^u1>-Ubaf%7d zVvf8SuArEv_$p0NB>30A!?@0ry%wj~LoUtx);``#^OD<5ox3k?<194-T%z_TDfbkW zo~LXxgnzlKmf}$@#iLq^cpo27?hh%xADP@Z5qXE!8ItxH4O%td;5AYD56P1r>ox#Gtf^Xzu literal 0 HcmV?d00001 diff --git a/target/classes/com/smartcraft/notifier/GotifySender$2.class b/target/classes/com/smartcraft/notifier/GotifySender$2.class new file mode 100644 index 0000000000000000000000000000000000000000..4d7850345c242446310d859567dac902a0c6c842 GIT binary patch literal 1655 zcma)6*-{fh6g?dh2I43Zz`AfKYHW#MgKznQAy-x|_cwXqnR&dJ*4tjlP$>Ujjzxxk zB^SBpw*rEkD3p_#70d1HJ>{&dFMM)EQ+rAlCpWVg!ia@ohN;8CR7`tHrafzMcWj)% zNrodep;u(6xpXPubYb$)O#g-`n!u-RoWWVjn}EuyRucikIf7}Y+R~oy__XR#!=t~n z={zo4xWF*fr5qc1Tw=%)+NuacUZbprJ8*5@DmoyvVvZCrYGVxJ3@01BE=o$eT)*-3 zHd&@1O^v4x9xxv7jB`tZWpM?Q777ff4$Ird6s|H@A9)}tKEp^iXd@L;fzNR4cj_1z zRWj0*K`K|tS0Zdu-sCj;C+i&zbX?k$-^N`FcM{s|{Izk<2sGpR%AoZH`@p2oSmzyI z(p$EoT7fGTJ)_~lCVQuuA-#!gdoaetfek1mU1QaUk&xiTuA7R7;HJn6$SL*ATUQO#?WHN_a1>K6Wu*z`Z->!6bMI9jS*F>n7RjBDu(M?8ghE7cn zy>y4ste-50Mn+?1>MOEe$VkDaZ*P0?5ss2=M-DiK0h$q$7^JV+{F=NC+|W1Vc5&+3 zF3#=YGO&w@1E?%Hfw<10)P~DPTVgocjBB{w4l#sj$|ptk4cv@FEYWB}WC;A$pP)-f zV>tnu*$2(+gJy6a4+u1ahXj+t42m?SF^hRTCd)Kpk=`Y&&@9&uPX;~DQN|ihW1Z|2 GW`6-9Xs%!Y literal 0 HcmV?d00001 diff --git a/target/classes/com/smartcraft/notifier/GotifySender.class b/target/classes/com/smartcraft/notifier/GotifySender.class new file mode 100644 index 0000000000000000000000000000000000000000..fc8aa33d020e58a86595301733060205ef11bbdd GIT binary patch literal 3186 zcmb7GX>-$76g@8_k>e-?%o4VOp#ich>;bc<>`rJ21Oi=99K{iqB_qi|TDmXLeQ$y8 z`)Ar2Q(&eu?FT;eH?^IfCppB4oes@7dQb1&cb9X|y-$DsbLTezJMg1|DuL#dlhwSe z?)oWLAN4ic@y$`waJ2(+GCp9~BZjM>T42sO{erGpx}DaJ4xckpzCdltG7X!Pg-Itf z=KHw~+R@BGj=jNpLLjo8BDU%86qwc0Iw(-x>x>u*>ILRkIub<`4Ju|MLhajwlXakN z6*Z_8XiS>6(Vx!_8}4y^*fIoSNhhUSgSuXxMArnTXGCS&><&t`RdMC%R55ROFaU=)k7RKXH~wwcrqNKktvsQpDuRV>3p0`+Ob zKV*BpZl@SPS4-=R9+s;}NW&{s#IaJKj*5C6d(@=c8>nWA-*P$c>b~jN+Nfz6+I~Jl z>Ed!Cf`jFg7{Cby#|6|)Xow(3O8BO484=Lud6PXSKGC#ov4I+84-S5&-;*W?A@c&wxDGPX<5N*F)AxD;G{Q1Y*j;)=YRYJyDD z_z+al<&CX626ZFu9d=9lnxahUUSlMGWlGhJjW#~Qw|;<&lwfO z&y>iAUlCI-g`x`CQwB`mNHo^sy$C*KSqbfe;d;ExBDhX0gjVFvt^mm$f+cy#whgz} z(ml`c6nxIBybOX$K`HoBVEKQGve$$NDENk`Pp>Fax!C^|e9y0xiTxr|c(3&Hj_5Pw zcZ-LWB{8RP~#|fYuavM-t;4p;D{OuU_KU5unr5+R6P7Uy^vldf5oB#md92V(41_)hiH2N zZP%f;#ky}}eHCurMGw8&)_w;Gpn#nP>@8q_-_L05DB$p2^bgVeqqlL4veY*#aJvij zoHsy4BQ4Is3a-ZK#ajB&O)oZZbu-_$u$3M`Yv5}<^arOf#Iy3Q+>O)pb_>s(!Q%}7 z39i?n>Mt}YXpeCEBsT*PMK=%EaQkX$IK}x>46To$E$Fz1xiY*Ph|+gP*%(OZF{6Mq z1GN~a9dlym3-DqW+vIaR_6&ytp6#E&q2mr-2!QA;;AJAQt(s6Qt`4xcLItl+gW_-y zTn7W{#3E??$mzybtiv{J#2##7$J@*satltdHJ#$x5O>ZJ>vPx+oAr90?;dusk%XEy zhH>H&!I3asF2b}3IlRHODr(U1Cf*_Vicn9xtoXy$C v#PXBic?~zX)<#SH9Od7YaKLBy0$(v{7QV)}9DDE`$2$DL{aWhi$CZBp<&IN( literal 0 HcmV?d00001 diff --git a/target/classes/com/smartcraft/notifier/SmartCraftNotifier.class b/target/classes/com/smartcraft/notifier/SmartCraftNotifier.class new file mode 100644 index 0000000000000000000000000000000000000000..e67420d442c3319731a3bc7be6440318de7da790 GIT binary patch literal 2453 zcma)7>sAw26#fo@OqdK8qf%(GhKdMNW!lWF}|NzJ7b}@BH)c%fA84hQ7K9Qj z7jGHpLt3YQV+P)aPELJ$pWotDyXgi+DXLB_gK-9g4CkgxoxO=#Qc&I* zrVY%%WazK)IB$ll(=$o4N?1QL)!CdSxoF#^{?Io5&aUqLqxUS(dYG)$n z=%axGZZHfJP7#1H3`mf4>sa zz=1+^*}w|Eq16nBrqQqk&Dva-9=$O~p{5lfQOm zeqb0qE}#J$TSR$|s7f`}og1JSF-v_~KH}e5DuBv9A;S~D4v=}Y1Q7|JIYgkHhV^nt zW{MlA_|CgxRuw@TbW_T}4?KHsl?OX=+t*P?LxamO`5FR8?8`cjIX(h$(XLPf4-~qB z;pb$nv3BGz8Ww-DBxSw1SLlQ!A!##QKiK14)E_7GZ*T4LN>E5LP3)p*yKdPDcws1w z-3)#rYVCv|&%-NZJ71MvJ|fHOc}BOvvY_=Zy0-6gUqe8A-vLFp;xz2jmGb|pbR9%U zV1iaRMFZLcU0q+{Ke`F&-AiBSs-$O@PV=O}=$$p6!!UD$e`5HzP+3j)VCW)ECdwd< z(@riNm-MafzTPq6P%UeT#eC4RMLZdlQ=2nDpq(geuDNKl}|}5Pk3i z{3y%QnIK68ij>3 zj$&n082N=DR4)Q;-ZXSvZ0$No2^?6FtJ1GYQ}tghuBb}vU{D|%gjIjB@!^AxeYL7g z>~CHY7`&~Gj_(Te=cX0}QiWhix#-7`2M1|^{Y7n5sZn24;XAolQv#V{P?5C-8EU(3 zZKmS)Iuf{1{6Fz|3JHvLNnj>d?9%(OCf68&*UiD2J+^M-t>Wz4hKY4uE$B#7&jZ7F z$yf)5a>l!nniro*vs6=I-o+stad24RT#u9f#ajKElKs)L4V; z8G#`}KQ~bkGZv)3jk^x+2u$we_fz{KYh`7YtlRf+ zpQRRYC2*)+PwTO5UJo=YRiHDun$??l-Bk^&q2$EYXjcO9G?B|-)HkEeqO(1uhoZA) zn?>j1g)N(xyOzzrOKHptc!|2%nv$!0h}|6fcbUz>EeDOTqMm5mfU?`Qzd7qLYlMxA z{{i+>JF + permission: smartcraft.notify + permission-message: You do not have permission to use this command. + +permissions: + smartcraft.notify: + description: Allows use of SmartCraft Notifier commands + default: op \ No newline at end of file