diff --git a/README.md b/README.md
index 147ef42..436010b 100644
--- a/README.md
+++ b/README.md
@@ -1,31 +1,37 @@
# SimplePushEvents Plugin
## Description
-This Spigot plugin, for use with the latest Minecraft version, automatically sends notifications to a push service (ntfy.sh), when players join, leave, execute specific commands or the server starts/shuts down.
-It helps server you and your players to stay informed about server activities in real-time.
+This Spigot plugin, for use with the latest Minecraft version, automatically sends notifications to a push service (ntfy.sh), when players join, leave, execute specific commands, do certain things or the server starts/shuts down.
+This helps server owners and players stay informed about server activities in real-time.
## Ideas
If you have ideas for more events, open an issue.
+
## Java Version
Compatible with Minecraft 1.20.6 and requires Java 21.
## Features
-- Sends push notifications when a player joins or leaves the server.
- Notifies when the server starts up or shuts down.
-- Configurable message content and status for each event.
+- Sends push notifications when
+ - a player joins or leaves the server.
+ - a player unlocks an advancement.
+ - a player creates a portal.
+ - a player dies (including the death message).
+ - executes `/spe [message content]` for custom notifications (with custom permissions).
+- Change the message format or disable/enable them entirely.
- Easy integration with the ntfy.sh push service.
- Quick setup with minimal configuration required.
- Checks and notifies for specific player commands:
- - `op`
- - `deop`
- - `ban`
- - `banip`
- - `pardon`
- - `pardonip`
- - `whitelist`
+ - `/op`
+ - `/deop`
+ - `/ban`
+ - `/banip`
+ - `/pardon`
+ - `/pardonip`
+ - `/whitelist`
## Setup
@@ -45,13 +51,12 @@ To set up the SimplePushEvents plugin, follow these steps:
## Plugin Configuration
-
Before deploying the plugin, ensure you configure the following parameters in the `options.yml` file:
```yaml
donottouch:
configexists: true
- pushchannel: 1dea3f4db2bb
+ pushchannel: 7fc647dd98
messages:
general:
title: 'Minecraft Server:'
@@ -61,11 +66,31 @@ messages:
poweroff:
status: true
content: The server is shutting down!
+ chatcommand:
+ status: true
+ content: '[%PLAYER%] wrote: %MESSAGE%'
+ permission: spe.usechatcommand
player:
advancement:
status: true
content: 'The player %PLAYER% unlocked the advancement: %NAME%'
+ join:
+ status: true
+ content: The player %PLAYER% joined!
+ leave:
+ status: true
+ content: The player %PLAYER% left!
+ count:
+ status: true
+ content: 'Players online right now: %ONLINE%/%MAX%'
+ death:
+ status: true
+ content: 'The Player %PLAYER% died: %MESSAGE%'
+ portalcreation:
+ status: true
+ content: The Player %PLAYER% created a portal at %LOCATION%
command:
+ disableall: false
op:
status: true
content: The player %PLAYER% executed /op for %TARGET% !
@@ -87,13 +112,6 @@ messages:
whitelist:
status: true
content: 'The player %PLAYER% used a whitelist command: %CONTENT%'
- join:
- status: true
- content: The player %PLAYER% joined!
- leave:
- status: true
- content: The player %PLAYER% left!
-
```
diff --git a/pom.xml b/pom.xml
index 4c6978f..ad9ca84 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,10 +4,16 @@
4.0.0
de.liebki
simplepushevents
- 0.0.4
+ 0.0.5
simplepushevents
+
+ 21
+ 21
+
+
+
jar
@@ -35,7 +41,7 @@
org.apache.maven.plugins
maven-shade-plugin
- 3.1.0
+ 3.6.0
package
diff --git a/src/main/java/de/liebki/Config.java b/src/main/java/de/liebki/KonfigurationsManager.java
similarity index 75%
rename from src/main/java/de/liebki/Config.java
rename to src/main/java/de/liebki/KonfigurationsManager.java
index b189763..44669a4 100644
--- a/src/main/java/de/liebki/Config.java
+++ b/src/main/java/de/liebki/KonfigurationsManager.java
@@ -1,3 +1,10 @@
+/*
+ *
+ * Copyright liebki: https://github.com/liebki | https://kmliebl.de
+ * You may use this class when stating where it is from and from whom.
+ *
+ */
+
package de.liebki;
import java.io.File;
@@ -7,43 +14,52 @@
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
-public class Config {
+/**
+ * Custom class to create and use config files more easy in a plugin
+ */
+public class KonfigurationsManager {
private File file;
private FileConfiguration fileConfig;
- public Config(String path, String fileName, Runnable callback, Plugin plugin) {
+ public KonfigurationsManager(String path, String fileName, Runnable callback, Plugin plugin) {
if (!fileName.contains(".yml")) {
fileName = fileName + ".yml";
}
+
file = new File(path, fileName);
fileConfig = YamlConfiguration.loadConfiguration(file);
if (!file.exists()) {
fileConfig.options().copyDefaults(true);
callback.run();
+
try {
fileConfig.save(file);
} catch (IOException exception) {
exception.printStackTrace();
}
+
}
}
- public Config(String path, String fileName, Plugin plugin) {
+ public KonfigurationsManager(String path, String fileName, Plugin plugin) {
if (!fileName.contains(".yml")) {
fileName = fileName + ".yml";
}
+
file = new File(path, fileName);
fileConfig = YamlConfiguration.loadConfiguration(file);
if (!file.exists()) {
+
fileConfig.options().copyDefaults(true);
try {
fileConfig.save(file);
} catch (IOException exception) {
exception.printStackTrace();
}
+
}
}
@@ -54,6 +70,7 @@ public FileConfiguration getConfig() {
public void saveConfig() {
try {
fileConfig.save(file);
+
} catch (IOException exception) {
exception.printStackTrace();
}
@@ -63,6 +80,7 @@ public Boolean check(String path) {
if (fileConfig.get(path) == null) {
return false;
}
+
return true;
}
@@ -71,7 +89,7 @@ public void set(String path, Object wert) {
saveConfig();
}
- public T get(String path) {
+ public T get(String path) {
if (fileConfig.getString(path) == null) {
return null;
}
diff --git a/src/main/java/de/liebki/Start.java b/src/main/java/de/liebki/Start.java
index 496b242..5904a14 100644
--- a/src/main/java/de/liebki/Start.java
+++ b/src/main/java/de/liebki/Start.java
@@ -3,6 +3,9 @@
import java.util.UUID;
import org.bukkit.Bukkit;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import de.liebki.events.EventManager;
@@ -10,79 +13,126 @@
public class Start extends JavaPlugin {
- public Config config;
+ public KonfigurationsManager config;
private PushManager pushManager;
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (sender instanceof Player) {
+ Player player = (Player) sender;
+ boolean isActive = config.get("messages.general.chatcommand.status");
+
+ String commandPermission = config.get("messages.general.chatcommand.permission");
+ if (player.hasPermission(commandPermission) && isActive) {
+ String msg = String.join(" ", args);
+ String configMessage = config.get("messages.general.chatcommand.content");
+
+ configMessage = configMessage.replace("%PLAYER%", player.getName()).replace("%MESSAGE%", msg);
+ pushManager.SendMessage(configMessage);
+ }
+
+ }
+
+ return true;
+ }
+
@Override
public void onEnable() {
- config = new Config("plugins/simplepushevents", "options.yml", this);
- if (!config.check("donottouch.configexists")) {
+ config = new KonfigurationsManager("plugins/simplepushevents", "options.yml", this);
+ boolean configExists = config.check("donottouch.configexists");
- String uuid = CreateShortUuid();
+ if (!configExists) {
+ CreateConfigDefaults();
+ }
- config.set("donottouch.configexists", true);
- config.set("donottouch.pushchannel", uuid);
+ pushManager = new PushManager(this);
+ EventManager eventManager = new EventManager(this, pushManager);
- config.set("messages.general.title", "Minecraft Server:");
+ getServer().getPluginManager().registerEvents(eventManager, this);
+ Bukkit.getConsoleSender().sendMessage("§4SimplePushEvents powering on");
- config.set("messages.general.startup.status", true);
- config.set("messages.general.startup.content", "The server is online now!");
+ boolean isActive = config.get("messages.general.startup.status");
+ if (isActive) {
+ String configMessage = config.get("messages.general.startup.content");
+ pushManager.SendMessage(configMessage);
+ }
+ }
- config.set("messages.general.poweroff.status", true);
- config.set("messages.general.poweroff.content", "The server is shutting down!");
+ /**
+ * To create the default config values at the first starts or after deletion
+ */
+ private void CreateConfigDefaults() {
+ String uuid = CreateShortUuid();
- config.set("messages.player.advancement.status", true);
- config.set("messages.player.advancement.content", "The player %PLAYER% unlocked the advancement: %NAME%");
+ config.set("donottouch.configexists", true);
+ config.set("donottouch.pushchannel", uuid);
- config.set("messages.player.command.op.status", true);
- config.set("messages.player.command.op.content", "The player %PLAYER% executed /op for %TARGET% !");
+ config.set("messages.general.title", "Minecraft Server:");
- config.set("messages.player.command.deop.status", true);
- config.set("messages.player.command.deop.content", "The player %PLAYER% executed /deop for %TARGET% !");
+ config.set("messages.general.startup.status", true);
+ config.set("messages.general.startup.content", "The server is online now!");
- config.set("messages.player.command.ban.status", true);
- config.set("messages.player.command.ban.content", "The player %PLAYER% executed /ban for %TARGET% !");
+ config.set("messages.general.poweroff.status", true);
+ config.set("messages.general.poweroff.content", "The server is shutting down!");
- config.set("messages.player.command.banip.status", true);
- config.set("messages.player.command.banip.content", "The player %PLAYER% executed /ban-ip for %TARGET% !");
+ config.set("messages.general.chatcommand.status", true);
+ config.set("messages.general.chatcommand.content", "[%PLAYER%] wrote: %MESSAGE%");
+ config.set("messages.general.chatcommand.permission", "spe.usechatcommand");
- config.set("messages.player.command.pardon.status", true);
- config.set("messages.player.command.pardon.content", "The player %PLAYER% executed /pardon for %TARGET% !");
+ config.set("messages.player.advancement.status", true);
+ config.set("messages.player.advancement.content", "The player %PLAYER% unlocked the advancement: %NAME%");
- config.set("messages.player.command.pardonip.status", true);
- config.set("messages.player.command.pardonip.content",
- "The player %PLAYER% executed /pardon-ip for %TARGET% !");
+ config.set("messages.player.join.status", true);
+ config.set("messages.player.join.content", "The player %PLAYER% joined!");
- config.set("messages.player.command.whitelist.status", true);
- config.set("messages.player.command.whitelist.content",
- "The player %PLAYER% used a whitelist command: %CONTENT%");
+ config.set("messages.player.leave.status", true);
+ config.set("messages.player.leave.content", "The player %PLAYER% left!");
- config.set("messages.player.join.status", true);
- config.set("messages.player.join.content", "The player %PLAYER% joined!");
+ config.set("messages.player.count.status", true);
+ config.set("messages.player.count.content", "Players online right now: %ONLINE%/%MAX%");
- config.set("messages.player.leave.status", true);
- config.set("messages.player.leave.content", "The player %PLAYER% left!");
+ config.set("messages.player.death.status", true);
+ config.set("messages.player.death.content", "The Player %PLAYER% died: %MESSAGE%");
- config.saveConfig();
- }
+ config.set("messages.player.portalcreation.status", true);
+ config.set("messages.player.portalcreation.content", "The Player %PLAYER% created a portal at %LOCATION%");
- pushManager = new PushManager(this);
- EventManager eventManager = new EventManager(this, pushManager);
+ config.set("messages.player.command.disableall", false);
- getServer().getPluginManager().registerEvents(eventManager, this);
- Bukkit.getConsoleSender().sendMessage("§4SimplePushEvents powering on");
+ config.set("messages.player.command.op.status", true);
+ config.set("messages.player.command.op.content", "The player %PLAYER% executed /op for %TARGET% !");
- boolean IsActive = (boolean) config.get("messages.general.startup.status");
- if (IsActive) {
- String configMessage = (String) config.get("messages.general.startup.content");
- pushManager.SendMessage(configMessage);
- }
+ config.set("messages.player.command.deop.status", true);
+ config.set("messages.player.command.deop.content", "The player %PLAYER% executed /deop for %TARGET% !");
+
+ config.set("messages.player.command.ban.status", true);
+ config.set("messages.player.command.ban.content", "The player %PLAYER% executed /ban for %TARGET% !");
+
+ config.set("messages.player.command.banip.status", true);
+ config.set("messages.player.command.banip.content", "The player %PLAYER% executed /ban-ip for %TARGET% !");
+
+ config.set("messages.player.command.pardon.status", true);
+ config.set("messages.player.command.pardon.content", "The player %PLAYER% executed /pardon for %TARGET% !");
+ config.set("messages.player.command.pardonip.status", true);
+ config.set("messages.player.command.pardonip.content",
+ "The player %PLAYER% executed /pardon-ip for %TARGET% !");
+
+ config.set("messages.player.command.whitelist.status", true);
+ config.set("messages.player.command.whitelist.content",
+ "The player %PLAYER% used a whitelist command: %CONTENT%");
+
+ config.saveConfig();
}
- String CreateShortUuid() {
+ /**
+ * To create a (hopefully) short UUID-like string, unique for every server
+ *
+ * @return UUID-like string
+ */
+ private String CreateShortUuid() {
String base = (UUID.randomUUID() + Bukkit.getServer().getIp()).trim();
- base = base.replace("-", "").substring(6, base.length() / 2);
+ base = base.replace("-", "").substring(8, base.length() / 2);
return base;
}
@@ -91,12 +141,11 @@ String CreateShortUuid() {
public void onDisable() {
Bukkit.getConsoleSender().sendMessage("§4SimplePushEvents powering off");
- boolean IsActive = (boolean) config.get("messages.general.poweroff.status");
- if (IsActive) {
- String configMessage = (String) config.get("messages.general.poweroff.content");
+ boolean isActive = config.get("messages.general.poweroff.status");
+ if (isActive) {
+ String configMessage = config.get("messages.general.poweroff.content");
pushManager.SendMessage(configMessage);
}
-
}
}
\ No newline at end of file
diff --git a/src/main/java/de/liebki/events/EventManager.java b/src/main/java/de/liebki/events/EventManager.java
index c4b0bcf..e1d01dd 100644
--- a/src/main/java/de/liebki/events/EventManager.java
+++ b/src/main/java/de/liebki/events/EventManager.java
@@ -3,14 +3,19 @@
import java.util.HashMap;
import java.util.Map;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
import org.bukkit.advancement.Advancement;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
+import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerAdvancementDoneEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.event.world.PortalCreateEvent;
import de.liebki.Start;
import de.liebki.manager.PushManager;
@@ -37,90 +42,146 @@ public EventManager(Start plugin, PushManager pushManager) {
commandMap.put("/whitelist", "messages.player.command.whitelist");
}
+ private boolean ConfigStatus(String configPath) {
+ return plugin.config.get(configPath);
+ }
+
@EventHandler
public void onPlayerCommand(PlayerCommandPreprocessEvent e) {
- String commandText = e.getMessage();
- Player player = e.getPlayer();
-
- if (player.isOp()) {
- String playerName = player.getName();
- String messageToPushSend = "";
-
- for (Map.Entry entry : commandMap.entrySet()) {
- if (commandText.startsWith(entry.getKey())) {
- boolean isActive = (boolean) plugin.config.get(entry.getValue() + ".status");
-
- if (isActive) {
- if (entry.getKey().equals("/whitelist")) {
- messageToPushSend = (String) plugin.config.get(entry.getValue() + ".content");
- messageToPushSend = messageToPushSend.replace("%CONTENT%", commandText).replace("%PLAYER%",
- playerName);
- } else {
- String[] parts = commandText.split(" ");
- if (parts.length > 1) {
- String targetPlayer = parts[1];
- messageToPushSend = (String) plugin.config.get(entry.getValue() + ".content");
-
- messageToPushSend = messageToPushSend.replace("%PLAYER%", playerName)
- .replace("%TARGET%", targetPlayer);
+ if (!ConfigStatus("messages.player.command.disableall")) {
+ String commandText = e.getMessage();
+ Player player = e.getPlayer();
+
+ if (player.isOp()) {
+ String playerName = player.getName();
+ String messageToPushSend = "";
+
+ for (Map.Entry entry : commandMap.entrySet()) {
+ if (commandText.startsWith(entry.getKey())) {
+ boolean isActive = plugin.config.get(entry.getValue() + ".status");
+
+ if (isActive) {
+ if (entry.getKey().equals("/whitelist")) {
+ messageToPushSend = plugin.config.get(entry.getValue() + ".content");
+ messageToPushSend = messageToPushSend.replace("%CONTENT%", commandText)
+ .replace("%PLAYER%", playerName);
+
+ } else {
+ String[] parts = commandText.split(" ");
+ if (parts.length > 1) {
+ String targetPlayer = parts[1];
+ messageToPushSend = plugin.config.get(entry.getValue() + ".content");
+
+ messageToPushSend = messageToPushSend.replace("%PLAYER%", playerName)
+ .replace("%TARGET%", targetPlayer);
+ }
}
+
}
+ break;
}
- break;
+ }
+
+ if (!messageToPushSend.isEmpty()) {
+ pushManager.SendMessage(messageToPushSend);
}
}
+ }
+
+ }
- if (!messageToPushSend.isEmpty()) {
- pushManager.SendMessage(messageToPushSend);
+ @EventHandler
+ public void OnPortalCreate(PortalCreateEvent event) {
+ if (event.getEntity() instanceof Player && ConfigStatus("messages.player.portalcreation.status")) {
+ try {
+ String playerName = event.getEntity().getName();
+ Location portalLocation = event.getBlocks().get(0).getLocation();
+
+ World world = portalLocation.getWorld();
+ String locationText = "[World: " + world + ", X: " + portalLocation.getX() + ", Y: "
+ + portalLocation.getY() + ",Z: " + portalLocation.getZ() + "]";
+
+ String configMessage = plugin.config.get("messages.player.portalcreation.content");
+ configMessage = configMessage.replace("%PLAYER%", playerName).replace("%LOCATION%", locationText);
+
+ pushManager.SendMessage(configMessage);
+ } catch (Exception e) {
+ Bukkit.getConsoleSender().sendMessage("Error in OnPortalCreate(): \n" + e.getMessage());
}
}
+
}
@EventHandler
public void OnPlayerAdvancement(PlayerAdvancementDoneEvent event) {
- boolean IsActive = (boolean) plugin.config.get("messages.player.advancement.status");
-
- if (IsActive) {
+ if (ConfigStatus("messages.player.advancement.status")) {
try {
String playerName = event.getPlayer().getName();
Advancement AdvancementObj = event.getAdvancement();
String AdvancementName = AdvancementObj.getDisplay().getTitle();
- String configMessage = (String) plugin.config.get("messages.player.advancement.content");
+ String configMessage = plugin.config.get("messages.player.advancement.content");
configMessage = configMessage.replace("%PLAYER%", playerName).replace("%NAME%", AdvancementName);
pushManager.SendMessage(configMessage);
} catch (Exception e) {
if (!e.getMessage().contains("Cannot invoke")) {
- throw e;
+ Bukkit.getConsoleSender().sendMessage("Error in OnPlayerAdvancement(): \n" + e.getMessage());
}
}
}
}
@EventHandler
- public void OnPlayerJoin(PlayerJoinEvent event) {
- boolean IsActive = (boolean) plugin.config.get("messages.player.join.status");
+ public void OnPlayerDeath(PlayerDeathEvent event) {
+ if (ConfigStatus("messages.player.death.status")) {
+ String playerName = event.getEntity().getName();
+ String deathCause = event.getDeathMessage();
+
+ String configMessage = plugin.config.get("messages.player.death.content");
+ configMessage = configMessage.replace("%PLAYER%", playerName).replace("%MESSAGE%", deathCause);
- if (IsActive) {
+ pushManager.SendMessage(configMessage);
+ }
+ }
+
+ @EventHandler
+ public void OnPlayerJoin(PlayerJoinEvent event) {
+ if (ConfigStatus("messages.player.join.status")) {
String playerName = event.getPlayer().getName();
- String configMessage = (String) plugin.config.get("messages.player.join.content");
+ String configMessage = plugin.config.get("messages.player.join.content");
configMessage = configMessage.replace("%PLAYER%", playerName);
pushManager.SendMessage(configMessage);
}
+
+ MessagePlayerCount();
}
@EventHandler
public void OnPlayerLeave(PlayerQuitEvent event) {
- boolean IsActive = (boolean) plugin.config.get("messages.player.leave.status");
-
- if (IsActive) {
+ if (ConfigStatus("messages.player.leave.status")) {
String playerName = event.getPlayer().getName();
- String configMessage = (String) plugin.config.get("messages.player.leave.content");
+ String configMessage = plugin.config.get("messages.player.leave.content");
configMessage = configMessage.replace("%PLAYER%", playerName);
pushManager.SendMessage(configMessage);
}
+
+ MessagePlayerCount();
+ }
+
+ /**
+ * If enabled, sends a push of the current and max players online
+ */
+ private void MessagePlayerCount() {
+ if (ConfigStatus("messages.player.count.status")) {
+ String configMessage = plugin.config.get("messages.player.count.content");
+
+ configMessage = configMessage.replace("%ONLINE%", String.valueOf(Bukkit.getOnlinePlayers().size() - 1))
+ .replace("%MAX%", String.valueOf(Bukkit.getMaxPlayers()));
+ pushManager.SendMessage(configMessage);
+ }
}
+
}
diff --git a/src/main/java/de/liebki/manager/PushManager.java b/src/main/java/de/liebki/manager/PushManager.java
index 35df3b5..16dfc7f 100644
--- a/src/main/java/de/liebki/manager/PushManager.java
+++ b/src/main/java/de/liebki/manager/PushManager.java
@@ -19,19 +19,24 @@ public PushManager(Start plugin) {
this.plugin = plugin;
}
+ /**
+ * To send a certain message to ntfy.sh to be pushed to all subscribers
+ *
+ * @param content The message to push
+ */
public void SendMessage(String content) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
- .uri(URI.create("http://ntfy.sh/" + (String) plugin.config.get("donottouch.pushchannel")))
+ .uri(URI.create("http://ntfy.sh/" + plugin.config.get("donottouch.pushchannel")))
.POST(BodyPublishers.ofString(content))
- .setHeader("Title", (String) plugin.config.get("messages.general.title"))
+ .setHeader("Title", plugin.config.get("messages.general.title"))
.setHeader("Priority", "urgent").setHeader("Content-Type", "application/x-www-form-urlencoded").build();
try {
client.send(request, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
- Bukkit.getConsoleSender().sendMessage("The message could not be sent using the push service!");
+ Bukkit.getConsoleSender().sendMessage("Error in SendMessage(): \n" + e.getMessage());
}
}
}
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 4e096e5..7a8357a 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,5 +1,6 @@
name: SimplePushEvents
main: de.liebki.Start
-version: 0.0.4
+version: 0.0.5
api-version: "1.16"
-commands:
\ No newline at end of file
+commands:
+ spe:
\ No newline at end of file