diff --git a/README.md b/README.md
index f6c360c..b824b82 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,47 @@
-# sc-ntfy-plugin
+# NTFYNotifier
-This is a minecraft plugin for the use with ntfy server for notifications
\ No newline at end of file
+A lightweight Minecraft plugin that sends real-time alerts to [ntfy.sh](https://ntfy.sh) when players join, leave, or run specific commands. Designed for Paper/Spigot servers on Minecraft 1.14+, this plugin helps admins stay in-the-know wherever they are.
+
+---
+
+## ๐ Features
+
+- ๐น Join and Quit Notifications
+- ๐น Command Watcher (customizable)
+- ๐น `%player%` and `%server%` placeholder support
+- ๐น Fully configurable messages and settings
+- ๐น ntfy.sh API integration (with optional basic auth)
+
+---
+
+## ๐ Installation
+
+1. Place the compiled `NTFYNotifier-1.0.0.jar` in your serverโs `plugins/` folder.
+2. Start the server to generate `config.yml` and `msg.yml`.
+3. Customize configuration and messages to your liking.
+
+---
+
+## โ Configuration
+
+### `config.yml`
+```yaml
+server-name: "NTFYCraft"
+
+ntfy:
+ server: "https://ntfy.sh"
+ topic: "minecraft-events"
+ auth:
+ enabled: false
+ username: "user"
+ password: "pass"
+
+notifications:
+ join: true
+ quit: true
+ commands:
+ enabled: true
+ watch:
+ - "stop"
+ - "ban"
+ - "kick"
diff --git a/build.bat b/build.bat
new file mode 100644
index 0000000..ec1b2d5
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,15 @@
+@echo off
+REM === Run Maven clean and package ===
+echo Building NTFYNotifier with Maven...
+mvn clean package
+
+REM === Check if the build succeeded ===
+IF EXIST target\NTFYNotifier-1.0.jar (
+ echo.
+ echo โ
Build successful! JAR created at: target\NTFYNotifier-1.0.jar
+) ELSE (
+ echo.
+ echo โ Build failed. Please check for compilation errors.
+)
+
+pause
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..fe85a1c
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+ com.minster586
+ NTFYNotifier
+ 1.0.0
+ jar
+ NTFYNotifier
+
+
+ UTF-8
+ 1.8
+ 1.8
+
+
+
+
+ spigot-repo
+ https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+
+
+
+ org.spigotmc
+ spigot-api
+ 1.14.4-R0.1-SNAPSHOT
+ provided
+
+
+
+
+
+
+ src/main/resources
+ false
+
+
+
+
+ maven-compiler-plugin
+
+
+ maven-jar-plugin
+
+
+
+ true
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/minster586/ntfyplugin/CommandMonitor.java b/src/main/java/com/minster586/ntfyplugin/CommandMonitor.java
new file mode 100644
index 0000000..11077f0
--- /dev/null
+++ b/src/main/java/com/minster586/ntfyplugin/CommandMonitor.java
@@ -0,0 +1,41 @@
+package com.minster586.ntfyplugin;
+
+import org.bukkit.command.CommandSender;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+
+import java.util.List;
+
+public class CommandMonitor implements Listener {
+
+ private final FileConfiguration config;
+ private final MessageManager messageManager;
+ private final NTFYNotifier notifier;
+
+ public CommandMonitor(Main plugin) {
+ this.config = plugin.getConfig();
+ this.messageManager = new MessageManager(plugin);
+ this.notifier = new NTFYNotifier(plugin);
+ }
+
+ @EventHandler
+ public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
+ if (!config.getBoolean("notifications.commands.enabled", true)) return;
+
+ String commandLine = event.getMessage().toLowerCase().trim();
+ CommandSender sender = event.getPlayer();
+
+ List watched = config.getStringList("notifications.commands.watch");
+ for (String keyword : watched) {
+ if (commandLine.startsWith("/" + keyword.toLowerCase())) {
+ String title = messageManager.getMessage(keyword + ".title");
+ String message = messageManager.formatMessage(keyword + ".message", (sender instanceof Player) ? (Player) sender : null);
+ notifier.sendNotification(title, message);
+ break;
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/minster586/ntfyplugin/Main.java b/src/main/java/com/minster586/ntfyplugin/Main.java
new file mode 100644
index 0000000..56b98fa
--- /dev/null
+++ b/src/main/java/com/minster586/ntfyplugin/Main.java
@@ -0,0 +1,41 @@
+package com.minster586.ntfyplugin;
+
+import org.bukkit.plugin.PluginManager;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.io.File;
+
+public class Main extends JavaPlugin {
+
+ private static Main instance;
+
+ @Override
+ public void onEnable() {
+ instance = this;
+
+ // Save default config.yml (Bukkit handles this automatically)
+ saveDefaultConfig();
+
+ // Save msg.yml if it doesn't exist
+ File msgFile = new File(getDataFolder(), "msg.yml");
+ if (!msgFile.exists()) {
+ saveResource("msg.yml", false);
+ }
+
+ // Register listeners
+ PluginManager pm = getServer().getPluginManager();
+ pm.registerEvents(new PlayerEventListener(this), this);
+ pm.registerEvents(new CommandMonitor(this), this);
+
+ getLogger().info("NTFYNotifier has been enabled.");
+ }
+
+ @Override
+ public void onDisable() {
+ getLogger().info("NTFYNotifier has been disabled.");
+ }
+
+ public static Main getInstance() {
+ return instance;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/minster586/ntfyplugin/MessageManager.java b/src/main/java/com/minster586/ntfyplugin/MessageManager.java
new file mode 100644
index 0000000..f66c8f8
--- /dev/null
+++ b/src/main/java/com/minster586/ntfyplugin/MessageManager.java
@@ -0,0 +1,35 @@
+package com.minster586.ntfyplugin;
+
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.entity.Player;
+
+import java.io.File;
+
+public class MessageManager {
+
+ private final Main plugin;
+ private final YamlConfiguration messages;
+
+ public MessageManager(Main plugin) {
+ this.plugin = plugin;
+ File msgFile = new File(plugin.getDataFolder(), "msg.yml");
+ this.messages = YamlConfiguration.loadConfiguration(msgFile);
+ }
+
+ public String getMessage(String path) {
+ return messages.getString("messages." + path, "");
+ }
+
+ public String formatMessage(String path, Player player) {
+ String message = getMessage(path);
+
+ if (player != null) {
+ message = message.replace("%player%", player.getName());
+ }
+
+ String serverName = plugin.getConfig().getString("server-name", "Minecraft Server");
+ message = message.replace("%server%", serverName);
+
+ return message;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/minster586/ntfyplugin/NTFYNotifier.java b/src/main/java/com/minster586/ntfyplugin/NTFYNotifier.java
new file mode 100644
index 0000000..d1f502f
--- /dev/null
+++ b/src/main/java/com/minster586/ntfyplugin/NTFYNotifier.java
@@ -0,0 +1,56 @@
+package com.minster586.ntfyplugin;
+
+import org.bukkit.configuration.file.FileConfiguration;
+
+import javax.net.ssl.HttpsURLConnection;
+import java.io.OutputStream;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Base64;
+
+public class NTFYNotifier {
+
+ private final FileConfiguration config;
+
+ public NTFYNotifier(Main plugin) {
+ this.config = plugin.getConfig();
+ }
+
+ public void sendNotification(String title, String message) {
+ try {
+ String server = config.getString("ntfy.server", "https://ntfy.sh");
+ String topic = config.getString("ntfy.topic", "minecraft-events");
+
+ String urlString = server.endsWith("/") ? server + topic : server + "/" + topic;
+ URL url = new URL(urlString);
+ HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
+
+ conn.setRequestMethod("POST");
+ conn.setDoOutput(true);
+ conn.setRequestProperty("Title", title);
+ conn.setRequestProperty("Content-Type", "text/plain");
+
+ // Optional Basic Auth
+ if (config.getBoolean("ntfy.auth.enabled", false)) {
+ String username = config.getString("ntfy.auth.username");
+ String password = config.getString("ntfy.auth.password");
+ if (username != null && password != null) {
+ String auth = username + ":" + password;
+ String encoded = Base64.getEncoder().encodeToString(auth.getBytes(StandardCharsets.UTF_8));
+ conn.setRequestProperty("Authorization", "Basic " + encoded);
+ }
+ }
+
+ // Send body
+ try (OutputStream os = conn.getOutputStream()) {
+ byte[] input = message.getBytes(StandardCharsets.UTF_8);
+ os.write(input, 0, input.length);
+ }
+
+ // Close connection to complete POST
+ conn.getInputStream().close();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/minster586/ntfyplugin/PlayerEventListener.java b/src/main/java/com/minster586/ntfyplugin/PlayerEventListener.java
new file mode 100644
index 0000000..ffaeb13
--- /dev/null
+++ b/src/main/java/com/minster586/ntfyplugin/PlayerEventListener.java
@@ -0,0 +1,43 @@
+package com.minster586.ntfyplugin;
+
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerQuitEvent;
+
+public class PlayerEventListener implements Listener {
+
+ private final Main plugin;
+ private final FileConfiguration config;
+ private final MessageManager messageManager;
+ private final NTFYNotifier notifier;
+
+ public PlayerEventListener(Main plugin) {
+ this.plugin = plugin;
+ this.config = plugin.getConfig();
+ this.messageManager = new MessageManager(plugin);
+ this.notifier = new NTFYNotifier(plugin);
+ }
+
+ @EventHandler
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ if (config.getBoolean("notifications.join", true)) {
+ Player player = event.getPlayer();
+ String title = messageManager.getMessage("join.title");
+ String message = messageManager.formatMessage("join.message", player);
+ notifier.sendNotification(title, message);
+ }
+ }
+
+ @EventHandler
+ public void onPlayerQuit(PlayerQuitEvent event) {
+ if (config.getBoolean("notifications.quit", true)) {
+ Player player = event.getPlayer();
+ String title = messageManager.getMessage("quit.title");
+ String message = messageManager.formatMessage("quit.message", player);
+ notifier.sendNotification(title, message);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
new file mode 100644
index 0000000..2d9d264
--- /dev/null
+++ b/src/main/resources/config.yml
@@ -0,0 +1,22 @@
+ntfy:
+ server: "https://ntfy.sh" # Default public ntfy.sh server
+ topic: "minecraft-events"
+ auth:
+ enabled: false
+ username: "user"
+ password: "pass"
+
+server-name: "NTFYCraft" # Custom variable used in message placeholders
+
+notifications:
+ join: true
+ quit: true
+ commands:
+ enabled: true
+ watch:
+ - "stop"
+ - "ban"
+ - "kick"
+ - "mute"
+ - "warn"
+ - "op"
\ No newline at end of file
diff --git a/src/main/resources/msg.yml b/src/main/resources/msg.yml
new file mode 100644
index 0000000..2b4d0f3
--- /dev/null
+++ b/src/main/resources/msg.yml
@@ -0,0 +1,25 @@
+messages:
+ join:
+ title: "Player Joined"
+ message: "%player% has joined the server."
+ quit:
+ title: "Player Left"
+ message: "%player% has left the server."
+ stop:
+ title: "Server Stop"
+ message: "%player% issued /stop"
+ ban:
+ title: "Player Banned"
+ message: "%player% used /ban"
+ kick:
+ title: "Player Kicked"
+ message: "%player% used /kick"
+ mute:
+ title: "Player Muted"
+ message: "%player% used /mute"
+ warn:
+ title: "Player Warned"
+ message: "%player% used /warn"
+ op:
+ title: "Player Opped"
+ message: "%player% used /op"
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
new file mode 100644
index 0000000..17b2ab1
--- /dev/null
+++ b/src/main/resources/plugin.yml
@@ -0,0 +1,8 @@
+name: NTFYNotifier
+version: 1.0.0
+main: com.minster586.ntfyplugin.Main
+api-version: 1.14
+author: minster586
+description: Sends customizable join, quit, and command notifications to an ntfy.sh server.
+commands: {}
+permissions: {}
\ No newline at end of file