This commit is contained in:
minster586
2025-06-19 22:00:23 -04:00
parent e455136bcb
commit d43794f34b
30 changed files with 292 additions and 681 deletions

View File

@@ -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());
}
}
}

View File

@@ -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 <ping|status>");
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;
}
}

View File

@@ -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<String, String> 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);
}
}

View File

@@ -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();
}
});
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}
}

View File

@@ -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}");
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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}"
# Token from your Gotify app
token: "REPLACE_WITH_YOUR_TOKEN"

View File

@@ -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}"
player-join: "{player} joined {server}."
player-leave: "{player} left {server}."

View File

@@ -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 <ping|status>
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
smartcraft.notify:
description: Allows use of SmartCraft Notifier commands
default: op