Updated Source Files for Version 0.3-Pre
This commit is contained in:
@ -4,7 +4,7 @@
|
||||
<groupId>com.adzel.velocitybroadcast</groupId>
|
||||
<artifactId>velocitybroadcast</artifactId>
|
||||
<name>VelocityBroadcast</name>
|
||||
<version>0.2-pre</version>
|
||||
<version>0.3-pre</version>
|
||||
<description>Broadcast plugin for Minecraft Velocity proxy.</description>
|
||||
<build>
|
||||
<plugins>
|
||||
@ -25,7 +25,7 @@
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<minimizeJar>false</minimizeJar>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@ -37,6 +37,10 @@
|
||||
<id>velocitypowered-repo</id>
|
||||
<url>https://repo.velocitypowered.com/releases/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>https://repo.maven.apache.org/maven2</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
39
pom.xml
39
pom.xml
@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>com.adzel.velocitybroadcast</groupId>
|
||||
<artifactId>velocitybroadcast</artifactId>
|
||||
<version>0.2-pre</version>
|
||||
<version>0.3-pre</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>VelocityBroadcast</name>
|
||||
<description>Broadcast plugin for Minecraft Velocity proxy.</description>
|
||||
@ -21,6 +21,10 @@
|
||||
<id>velocitypowered-repo</id>
|
||||
<url>https://repo.velocitypowered.com/releases/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>central</id>
|
||||
<url>https://repo.maven.apache.org/maven2</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
@ -45,6 +49,34 @@
|
||||
<artifactId>adventure-text-minimessage</artifactId>
|
||||
<version>4.15.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON Wrapper -->
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20240303</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SQLite -->
|
||||
<dependency>
|
||||
<groupId>org.xerial</groupId>
|
||||
<artifactId>sqlite-jdbc</artifactId>
|
||||
<version>3.43.2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MySQL Connector -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>8.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Snake YAML -->
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>2.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@ -71,8 +103,7 @@
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<minimizeJar>true</minimizeJar>
|
||||
<!-- No relocations anymore -->
|
||||
<minimizeJar>false</minimizeJar>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@ -80,3 +111,5 @@
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
<!-- This is a Maven POM file for the VelocityBroadcast plugin.
|
||||
It defines the project structure, dependencies, and build configuration. -->
|
@ -2,8 +2,10 @@ package com.adzel.velocitybroadcast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.adzel.velocitybroadcast.util.DatabaseManager;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.command.SimpleCommand;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
@ -11,9 +13,11 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
public class BroadcastCommand implements SimpleCommand {
|
||||
|
||||
private final VelocityBroadcast plugin;
|
||||
private final DatabaseManager databaseManager;
|
||||
|
||||
public BroadcastCommand(VelocityBroadcast plugin) {
|
||||
this.plugin = plugin;
|
||||
this.databaseManager = plugin.getDatabaseManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -42,5 +46,13 @@ public class BroadcastCommand implements SimpleCommand {
|
||||
if (plugin.getConfigHandler().isDebugEnabled()) {
|
||||
plugin.getLogger().info("[Broadcast] Sent: " + fullMessage);
|
||||
}
|
||||
|
||||
// ✅ Log to the database
|
||||
String sender = (source instanceof Player)
|
||||
? ((Player) source).getUsername()
|
||||
: "Console";
|
||||
|
||||
String sourceServer = plugin.getServer().getBoundAddress().toString(); // optional
|
||||
databaseManager.logBroadcast(sender, messageRaw, sourceServer);
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
package com.adzel.velocitybroadcast;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.representer.Representer;
|
||||
|
||||
public class ConfigHandler {
|
||||
private final Path configPath;
|
||||
@ -20,14 +20,34 @@ public class ConfigHandler {
|
||||
private boolean versionCheckEnabled = true;
|
||||
private String prefix = "&9&l[&3&lServer&9&l]&r ";
|
||||
|
||||
private String dbType = "sqlite";
|
||||
private String dbHost = "localhost";
|
||||
private int dbPort = 3306;
|
||||
private String dbName = "velocitybroadcast";
|
||||
private String dbUser = "vb_user";
|
||||
private String dbPassword = "securepassword";
|
||||
|
||||
private static final String CURRENT_VERSION = VelocityBroadcast.PLUGIN_VERSION;
|
||||
private static final String VERSION_LINE = "# DO NOT EDIT\nPlugin Version: '" + CURRENT_VERSION + "' # Do not edit this value, as it will mess up version checking and break the plugin";
|
||||
|
||||
private final Yaml yaml;
|
||||
|
||||
public ConfigHandler(Path configPath, Logger logger) {
|
||||
this.configPath = configPath;
|
||||
this.logger = logger;
|
||||
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
options.setIndent(2);
|
||||
options.setPrettyFlow(true);
|
||||
|
||||
Representer representer = new Representer(options);
|
||||
representer.getPropertyUtils().setSkipMissingProperties(true);
|
||||
|
||||
yaml = new Yaml(representer, options);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void load() {
|
||||
try {
|
||||
Files.createDirectories(configPath.getParent());
|
||||
@ -39,38 +59,34 @@ public class ConfigHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> lines = Files.readAllLines(configPath);
|
||||
String fileVersion = null;
|
||||
|
||||
for (String line : lines) {
|
||||
if (line.trim().startsWith("Plugin Version:")) {
|
||||
fileVersion = line.replaceAll(".*'(.*?)'.*", "$1").trim();
|
||||
break;
|
||||
}
|
||||
}
|
||||
String fileVersion = Files.readAllLines(configPath).stream()
|
||||
.filter(line -> line.startsWith("Plugin Version:"))
|
||||
.map(line -> line.replaceAll(".*'(.*?)'.*", "$1").trim())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (fileVersion == null || !fileVersion.equals(CURRENT_VERSION)) {
|
||||
shouldSave = true;
|
||||
}
|
||||
|
||||
try (BufferedReader reader = Files.newBufferedReader(configPath)) {
|
||||
Map<String, String> configMap = reader.lines()
|
||||
.filter(line -> line.contains(":") && !line.trim().startsWith("#"))
|
||||
.map(line -> line.replaceAll("#.*", "").split(":", 2))
|
||||
.collect(Collectors.toMap(
|
||||
a -> a[0].trim(),
|
||||
a -> a[1].trim().replaceAll("^['\"]|['\"]$", ""),
|
||||
(a, b) -> b,
|
||||
LinkedHashMap::new
|
||||
));
|
||||
Map<String, Object> root = yaml.load(Files.newBufferedReader(configPath));
|
||||
if (root == null) root = new LinkedHashMap<>();
|
||||
|
||||
debugEnabled = Boolean.parseBoolean(configMap.getOrDefault("debug-messages-enabled", "false"));
|
||||
versionCheckEnabled = Boolean.parseBoolean(configMap.getOrDefault("version-check-enabled", "true"));
|
||||
prefix = configMap.getOrDefault("prefix", "&9&l[&3&lServer&9&l]&r ");
|
||||
}
|
||||
Map<String, Object> general = (Map<String, Object>) root.getOrDefault("general", new LinkedHashMap<>());
|
||||
debugEnabled = Boolean.parseBoolean(String.valueOf(general.getOrDefault("debug-messages-enabled", "false")));
|
||||
versionCheckEnabled = Boolean.parseBoolean(String.valueOf(general.getOrDefault("version-check-enabled", "true")));
|
||||
prefix = String.valueOf(general.getOrDefault("prefix", "&9&l[&3&lServer&9&l]&r "));
|
||||
|
||||
Map<String, Object> database = (Map<String, Object>) root.getOrDefault("database", new LinkedHashMap<>());
|
||||
dbType = String.valueOf(database.getOrDefault("type", "sqlite"));
|
||||
dbHost = String.valueOf(database.getOrDefault("host", "localhost"));
|
||||
dbPort = Integer.parseInt(String.valueOf(database.getOrDefault("port", "3306")));
|
||||
dbName = String.valueOf(database.getOrDefault("name", "velocitybroadcast"));
|
||||
dbUser = String.valueOf(database.getOrDefault("user", "vb_user"));
|
||||
dbPassword = String.valueOf(database.getOrDefault("password", "securepassword"));
|
||||
|
||||
if (shouldSave) {
|
||||
save(); // Update config with new version and preserve user values
|
||||
save();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
@ -82,26 +98,28 @@ public class ConfigHandler {
|
||||
try {
|
||||
Files.createDirectories(configPath.getParent());
|
||||
|
||||
String editableSection = "";
|
||||
if (Files.exists(configPath)) {
|
||||
editableSection = Files.readAllLines(configPath).stream()
|
||||
.dropWhile(line -> !line.trim().equalsIgnoreCase("# ONLY EDIT BELOW THIS LINE"))
|
||||
.skip(1)
|
||||
.collect(Collectors.joining("\n"));
|
||||
}
|
||||
Map<String, Object> general = new LinkedHashMap<>();
|
||||
general.put("debug-messages-enabled", debugEnabled);
|
||||
general.put("version-check-enabled", versionCheckEnabled);
|
||||
general.put("prefix", prefix);
|
||||
|
||||
Map<String, Object> database = new LinkedHashMap<>();
|
||||
database.put("type", dbType);
|
||||
database.put("host", dbHost);
|
||||
database.put("port", dbPort);
|
||||
database.put("name", dbName);
|
||||
database.put("user", dbUser);
|
||||
database.put("password", dbPassword);
|
||||
|
||||
Map<String, Object> root = new LinkedHashMap<>();
|
||||
root.put("general", general);
|
||||
root.put("database", database);
|
||||
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(configPath)) {
|
||||
writer.write(VERSION_LINE + "\n\n");
|
||||
writer.write("# ONLY EDIT BELOW THIS LINE\n");
|
||||
|
||||
if (!editableSection.isEmpty()) {
|
||||
writer.write(editableSection + "\n");
|
||||
} else {
|
||||
writer.write("debug-messages-enabled: false # Enables/disables debug messages (Default: false)\n");
|
||||
writer.write("version-check-enabled: true # Toggles version update messages for admins (Default: true)\n");
|
||||
writer.write("prefix: '&9&l[&3&lServer&9&l]&r ' # The prefix for broadcasts and messages\n");
|
||||
}
|
||||
yaml.dump(root, writer);
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to save VelocityBroadcast config!", e);
|
||||
}
|
||||
@ -127,4 +145,28 @@ public class ConfigHandler {
|
||||
this.prefix = newPrefix;
|
||||
save();
|
||||
}
|
||||
|
||||
public String getDbType() {
|
||||
return dbType;
|
||||
}
|
||||
|
||||
public String getDbHost() {
|
||||
return dbHost;
|
||||
}
|
||||
|
||||
public int getDbPort() {
|
||||
return dbPort;
|
||||
}
|
||||
|
||||
public String getDbName() {
|
||||
return dbName;
|
||||
}
|
||||
|
||||
public String getDbUser() {
|
||||
return dbUser;
|
||||
}
|
||||
|
||||
public String getDbPassword() {
|
||||
return dbPassword;
|
||||
}
|
||||
}
|
||||
|
50
src/main/java/com/adzel/velocitybroadcast/LoginListener.java
Normal file
50
src/main/java/com/adzel/velocitybroadcast/LoginListener.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.adzel.velocitybroadcast;
|
||||
|
||||
import com.adzel.velocitybroadcast.util.DatabaseManager;
|
||||
import com.adzel.velocitybroadcast.util.UpdateChecker;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
|
||||
public class LoginListener {
|
||||
private final ProxyServer server;
|
||||
private final String currentVersion;
|
||||
private final UpdateChecker updateChecker;
|
||||
private final DatabaseManager databaseManager;
|
||||
|
||||
private static final MiniMessage MINI_MESSAGE = MiniMessage.miniMessage();
|
||||
|
||||
public LoginListener(ProxyServer server, String currentVersion, UpdateChecker updateChecker, DatabaseManager databaseManager) {
|
||||
this.server = server;
|
||||
this.currentVersion = currentVersion;
|
||||
this.updateChecker = updateChecker;
|
||||
this.databaseManager = databaseManager;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onPlayerJoin(PostLoginEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("vb.admin")) {
|
||||
// ✅ Log admin join to DB
|
||||
String serverName = server.getBoundAddress().toString(); // Optional
|
||||
databaseManager.logAdminJoin(player.getUsername(), serverName);
|
||||
|
||||
// ✅ Notify if update is available
|
||||
updateChecker.checkForUpdate().thenAccept(latest -> {
|
||||
if (latest != null && !latest.equalsIgnoreCase(currentVersion)) {
|
||||
Component message = MINI_MESSAGE.deserialize(
|
||||
"<bold><gold>[VelocityBroadcast]</gold></bold> " +
|
||||
"<gradient:yellow:red>A new version is available: </gradient:yellow:red>" +
|
||||
"<bold><green>" + latest + "</green></bold> " +
|
||||
"<gray>(You are on <red>" + currentVersion + "</red>)</gray>"
|
||||
);
|
||||
player.sendMessage(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
63
src/main/java/com/adzel/velocitybroadcast/UpdateChecker.java
Normal file
63
src/main/java/com/adzel/velocitybroadcast/UpdateChecker.java
Normal file
@ -0,0 +1,63 @@
|
||||
package com.adzel.velocitybroadcast.util;
|
||||
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Logger;
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONTokener;
|
||||
|
||||
public class UpdateChecker {
|
||||
private static final String ENDPOINT = "https://api.github.com/repos/AdzelFirestar/velocitybroadcast-reborn/releases/latest";
|
||||
private final String currentVersion;
|
||||
private final Logger logger;
|
||||
|
||||
public UpdateChecker(String currentVersion, Logger logger) {
|
||||
this.currentVersion = currentVersion;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public CompletableFuture<String> checkForUpdate() {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
HttpURLConnection connection = (HttpURLConnection) new URL(ENDPOINT).openConnection();
|
||||
connection.setRequestProperty("Accept", "application/json");
|
||||
connection.setConnectTimeout(3000);
|
||||
connection.setReadTimeout(3000);
|
||||
|
||||
try (InputStreamReader reader = new InputStreamReader(connection.getInputStream())) {
|
||||
JSONObject json = new JSONObject(new JSONTokener(reader));
|
||||
String latestVersion = json.getString("tag_name").trim();
|
||||
|
||||
if (!latestVersion.equalsIgnoreCase(currentVersion)) {
|
||||
logger.info("[VelocityBroadcast] Update available: " + latestVersion + " (you are on " + currentVersion + ")");
|
||||
return latestVersion;
|
||||
} else {
|
||||
logger.info("[VelocityBroadcast] You are running the latest version (" + currentVersion + ").");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warning("[VelocityBroadcast] Failed to check for updates: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void notifyPlayerIfOutdated(ProxyServer server, String latestVersion) {
|
||||
if (latestVersion != null && !latestVersion.equalsIgnoreCase(currentVersion)) {
|
||||
String message = String.format("[VelocityBroadcast] A new version (%s) is available! You are running %s.", latestVersion, currentVersion);
|
||||
Component component = Component.text(message);
|
||||
for (Player player : server.getAllPlayers()) {
|
||||
if (player.hasPermission("vb.admin")) {
|
||||
player.sendMessage(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,8 +2,10 @@ package com.adzel.velocitybroadcast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.adzel.velocitybroadcast.util.DatabaseManager;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.command.SimpleCommand;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
@ -11,10 +13,12 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
public class VBCommand implements SimpleCommand {
|
||||
|
||||
private final VelocityBroadcast plugin;
|
||||
private final DatabaseManager databaseManager;
|
||||
private final MiniMessage mm = MiniMessage.miniMessage();
|
||||
|
||||
public VBCommand(VelocityBroadcast plugin) {
|
||||
this.plugin = plugin;
|
||||
this.databaseManager = plugin.getDatabaseManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -22,68 +26,91 @@ public class VBCommand implements SimpleCommand {
|
||||
CommandSource source = invocation.source();
|
||||
List<String> args = List.of(invocation.arguments());
|
||||
|
||||
if (args.isEmpty() || args.get(0).equalsIgnoreCase("help")) {
|
||||
source.sendMessage(parseFormatted("<gold><bold>VelocityBroadcast Commands:</bold></gold>"));
|
||||
source.sendMessage(parseFormatted("<yellow>/vb <message></yellow> <gray>- Broadcast a message to all players</gray>"));
|
||||
String fullCommand = "/vb" + (args.isEmpty() ? "" : " " + String.join(" ", args));
|
||||
String username = (source instanceof Player) ? ((Player) source).getUsername() : "Console";
|
||||
|
||||
if (source.hasPermission("vb.admin")) {
|
||||
source.sendMessage(parseFormatted("<yellow>/vb prefix <newPrefix></yellow> <gray>- Change the broadcast prefix</gray>"));
|
||||
source.sendMessage(parseFormatted("<yellow>/vb reload</yellow> <gray>- Reload the plugin config</gray>"));
|
||||
boolean success = true;
|
||||
|
||||
try {
|
||||
if (args.isEmpty() || args.get(0).equalsIgnoreCase("help")) {
|
||||
source.sendMessage(parseFormatted("<gold><bold>VelocityBroadcast Commands:</bold></gold>"));
|
||||
source.sendMessage(parseFormatted("<yellow>/vb <message></yellow> <gray>- Broadcast a message to all players</gray>"));
|
||||
|
||||
if (source.hasPermission("vb.admin")) {
|
||||
source.sendMessage(parseFormatted("<yellow>/vb prefix <newPrefix></yellow> <gray>- Change the broadcast prefix</gray>"));
|
||||
source.sendMessage(parseFormatted("<yellow>/vb reload</yellow> <gray>- Reload the plugin config</gray>"));
|
||||
}
|
||||
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
String sub = args.get(0).toLowerCase();
|
||||
List<String> subArgs = args.subList(1, args.size());
|
||||
String sub = args.get(0).toLowerCase();
|
||||
List<String> subArgs = args.subList(1, args.size());
|
||||
|
||||
switch (sub) {
|
||||
case "prefix":
|
||||
if (!source.hasPermission("vb.admin")) {
|
||||
source.sendMessage(parseFormatted("<red>You don't have permission to change the broadcast prefix.</red>"));
|
||||
return;
|
||||
switch (sub) {
|
||||
case "prefix" -> {
|
||||
if (!source.hasPermission("vb.admin")) {
|
||||
source.sendMessage(parseFormatted("<red>You don't have permission to change the broadcast prefix.</red>"));
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (subArgs.isEmpty()) {
|
||||
source.sendMessage(parseFormatted("<red>Usage: /vb prefix <newPrefix></red>"));
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
String newPrefix = String.join(" ", subArgs);
|
||||
plugin.getConfigHandler().setPrefix(newPrefix);
|
||||
source.sendMessage(parseFormatted("<green>Prefix updated to:</green> <gray>" + newPrefix + "</gray>"));
|
||||
|
||||
if (plugin.getConfigHandler().isDebugEnabled()) {
|
||||
plugin.getLogger().info("[Prefix] Updated prefix to: " + newPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
if (subArgs.isEmpty()) {
|
||||
source.sendMessage(parseFormatted("<red>Usage: /vb prefix <newPrefix></red>"));
|
||||
return;
|
||||
case "reload" -> {
|
||||
if (!source.hasPermission("vb.admin")) {
|
||||
source.sendMessage(parseFormatted("<red>You don't have permission to reload the config.</red>"));
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.getConfigHandler().reload();
|
||||
source.sendMessage(parseFormatted("<green>VelocityBroadcast config reloaded.</green>"));
|
||||
|
||||
if (plugin.getConfigHandler().isDebugEnabled()) {
|
||||
plugin.getLogger().info("[Reload] Config reloaded by " + source.toString());
|
||||
}
|
||||
}
|
||||
|
||||
String newPrefix = String.join(" ", subArgs);
|
||||
plugin.getConfigHandler().setPrefix(newPrefix);
|
||||
source.sendMessage(parseFormatted("<green>Prefix updated to:</green> <gray>" + newPrefix + "</gray>"));
|
||||
if (plugin.getConfigHandler().isDebugEnabled()) {
|
||||
plugin.getLogger().info("[Prefix] Updated prefix to: " + newPrefix);
|
||||
}
|
||||
break;
|
||||
default -> {
|
||||
// Treat as broadcast message
|
||||
if (!source.hasPermission("vb.broadcast")) {
|
||||
source.sendMessage(parseFormatted("<red>You don't have permission to broadcast.</red>"));
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
case "reload":
|
||||
if (!source.hasPermission("vb.admin")) {
|
||||
source.sendMessage(parseFormatted("<red>You don't have permission to reload the config.</red>"));
|
||||
return;
|
||||
}
|
||||
String fullMessage = plugin.getConfigHandler().getPrefix() + String.join(" ", args);
|
||||
Component broadcast = parseFormatted(fullMessage);
|
||||
|
||||
plugin.getConfigHandler().reload();
|
||||
source.sendMessage(parseFormatted("<green>VelocityBroadcast config reloaded.</green>"));
|
||||
if (plugin.getConfigHandler().isDebugEnabled()) {
|
||||
plugin.getLogger().info("[Reload] Config reloaded by " + source.toString());
|
||||
}
|
||||
break;
|
||||
plugin.getServer().getAllPlayers().forEach(p -> p.sendMessage(broadcast));
|
||||
|
||||
default:
|
||||
// Treat as broadcast message
|
||||
if (!source.hasPermission("vb.broadcast")) {
|
||||
source.sendMessage(parseFormatted("<red>You don't have permission to broadcast.</red>"));
|
||||
return;
|
||||
if (plugin.getConfigHandler().isDebugEnabled()) {
|
||||
plugin.getLogger().info("[Broadcast] Sent: " + fullMessage);
|
||||
}
|
||||
}
|
||||
|
||||
String fullMessage = plugin.getConfigHandler().getPrefix() + String.join(" ", args);
|
||||
Component broadcast = parseFormatted(fullMessage);
|
||||
plugin.getServer().getAllPlayers().forEach(p -> p.sendMessage(broadcast));
|
||||
|
||||
if (plugin.getConfigHandler().isDebugEnabled()) {
|
||||
plugin.getLogger().info("[Broadcast] Sent: " + fullMessage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().error("Error executing /vb command", e);
|
||||
source.sendMessage(parseFormatted("<red>An error occurred while executing the command.</red>"));
|
||||
success = false;
|
||||
} finally {
|
||||
// ✅ Log the command usage
|
||||
databaseManager.logCommand(username, fullCommand, success);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,8 @@ import java.nio.file.Path;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import com.adzel.velocitybroadcast.util.DatabaseManager;
|
||||
import com.adzel.velocitybroadcast.util.UpdateChecker;
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
@ -18,19 +20,21 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
@Plugin(
|
||||
id = "velocitybroadcast",
|
||||
name = "VelocityBroadcast",
|
||||
version = "0.2-pre",
|
||||
version = "0.3-pre",
|
||||
description = "A proxy-wide broadcast plugin for Velocity.",
|
||||
authors = {"Adzel"}
|
||||
)
|
||||
public class VelocityBroadcast {
|
||||
|
||||
public static final String PLUGIN_VERSION = "0.2-pre";
|
||||
public static final String PLUGIN_VERSION = "0.3-pre";
|
||||
public static final MiniMessage MINI_MESSAGE = MiniMessage.miniMessage();
|
||||
|
||||
private final ProxyServer server;
|
||||
private final Logger logger;
|
||||
private final Path dataDirectory;
|
||||
|
||||
private ConfigHandler config;
|
||||
private DatabaseManager databaseManager;
|
||||
|
||||
@Inject
|
||||
public VelocityBroadcast(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) {
|
||||
@ -49,7 +53,25 @@ public class VelocityBroadcast {
|
||||
logger.info("[VelocityBroadcast] Debug mode is enabled.");
|
||||
}
|
||||
|
||||
// Register the root /vb command handler
|
||||
// Initialize database manager
|
||||
java.util.logging.Logger jdkLogger = java.util.logging.Logger.getLogger("VelocityBroadcast");
|
||||
this.databaseManager = new DatabaseManager(config, jdkLogger, dataDirectory);
|
||||
databaseManager.initialize();
|
||||
|
||||
// Check for updates (async)
|
||||
UpdateChecker updateChecker = new UpdateChecker(PLUGIN_VERSION, jdkLogger);
|
||||
updateChecker.checkForUpdate().thenAccept(latest -> {
|
||||
if (latest != null) {
|
||||
logger.warn("[VelocityBroadcast] A new version is available: " + latest + " (You are on " + PLUGIN_VERSION + ")");
|
||||
} else {
|
||||
logger.info("[VelocityBroadcast] You are running the latest version (" + PLUGIN_VERSION + ").");
|
||||
}
|
||||
});
|
||||
|
||||
// ✅ Register login listener with DatabaseManager
|
||||
server.getEventManager().register(this, new LoginListener(server, PLUGIN_VERSION, updateChecker, databaseManager));
|
||||
|
||||
// Register root command
|
||||
server.getCommandManager().register(
|
||||
server.getCommandManager().metaBuilder("vb").plugin(this).build(),
|
||||
new VBCommand(this)
|
||||
@ -78,4 +100,8 @@ public class VelocityBroadcast {
|
||||
public ConfigHandler getConfigHandler() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public DatabaseManager getDatabaseManager() {
|
||||
return databaseManager;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,127 @@
|
||||
package com.adzel.velocitybroadcast.util;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.sql.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.adzel.velocitybroadcast.ConfigHandler;
|
||||
|
||||
public class DatabaseManager {
|
||||
private final Logger logger;
|
||||
private final ConfigHandler config;
|
||||
private final Path dataDirectory;
|
||||
private Connection connection;
|
||||
private final ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
public DatabaseManager(ConfigHandler config, Logger logger, Path dataDirectory) {
|
||||
this.config = config;
|
||||
this.logger = logger;
|
||||
this.dataDirectory = dataDirectory;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
try {
|
||||
if (config.getDbType().equalsIgnoreCase("mysql")) {
|
||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||
connection = DriverManager.getConnection(
|
||||
"jdbc:mysql://" + config.getDbHost() + ":" + config.getDbPort() + "/" + config.getDbName() + "?useSSL=false&autoReconnect=true",
|
||||
config.getDbUser(),
|
||||
config.getDbPassword()
|
||||
);
|
||||
} else {
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
Path dbFile = dataDirectory.resolve(config.getDbName() + ".db");
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile.toAbsolutePath());
|
||||
}
|
||||
|
||||
logger.info("[VelocityBroadcast] Connected to " + config.getDbType().toUpperCase() + " database.");
|
||||
initializeTables();
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.warning("[VelocityBroadcast] Failed to connect to database: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeTables() {
|
||||
boolean isMySQL = config.getDbType().equalsIgnoreCase("mysql");
|
||||
String idSyntax = isMySQL ? "INT AUTO_INCREMENT PRIMARY KEY" : "INTEGER PRIMARY KEY AUTOINCREMENT";
|
||||
|
||||
String broadcastTable = "CREATE TABLE IF NOT EXISTS vb_broadcast_logs (" +
|
||||
"id " + idSyntax + "," +
|
||||
"timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP," +
|
||||
"sender VARCHAR(64) NOT NULL," +
|
||||
"message TEXT NOT NULL," +
|
||||
"source_server VARCHAR(64)" +
|
||||
");";
|
||||
|
||||
String commandTable = "CREATE TABLE IF NOT EXISTS vb_command_logs (" +
|
||||
"id " + idSyntax + "," +
|
||||
"timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP," +
|
||||
"user VARCHAR(64) NOT NULL," +
|
||||
"command TEXT NOT NULL," +
|
||||
"success BOOLEAN" +
|
||||
");";
|
||||
|
||||
String joinTable = "CREATE TABLE IF NOT EXISTS vb_admin_joins (" +
|
||||
"id " + idSyntax + "," +
|
||||
"timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP," +
|
||||
"username VARCHAR(64) NOT NULL," +
|
||||
"server VARCHAR(64)" +
|
||||
");";
|
||||
|
||||
executeUpdate(broadcastTable);
|
||||
executeUpdate(commandTable);
|
||||
executeUpdate(joinTable);
|
||||
}
|
||||
|
||||
public void logBroadcast(String sender, String message, String sourceServer) {
|
||||
String sql = "INSERT INTO vb_broadcast_logs (sender, message, source_server) VALUES (?, ?, ?)";
|
||||
executeAsync(sql, sender, message, sourceServer);
|
||||
}
|
||||
|
||||
public void logCommand(String user, String command, boolean success) {
|
||||
String sql = "INSERT INTO vb_command_logs (user, command, success) VALUES (?, ?, ?)";
|
||||
executeAsync(sql, user, command, success);
|
||||
}
|
||||
|
||||
public void logAdminJoin(String username, String serverName) {
|
||||
String sql = "INSERT INTO vb_admin_joins (username, server) VALUES (?, ?)";
|
||||
executeAsync(sql, username, serverName);
|
||||
}
|
||||
|
||||
private void executeAsync(String sql, Object... params) {
|
||||
executor.submit(() -> {
|
||||
try (PreparedStatement stmt = connection.prepareStatement(sql)) {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
stmt.setObject(i + 1, params[i]);
|
||||
}
|
||||
stmt.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
logger.warning("[VelocityBroadcast] Database query failed: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void executeUpdate(String sql) {
|
||||
executor.submit(() -> {
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
stmt.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
logger.warning("[VelocityBroadcast] Failed to initialize table: " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void close() {
|
||||
try {
|
||||
if (connection != null && !connection.isClosed()) {
|
||||
connection.close();
|
||||
executor.shutdown();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
logger.warning("[VelocityBroadcast] Failed to close database: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "velocitybroadcast",
|
||||
"name": "VelocityBroadcast",
|
||||
"version": "0.2-pre",
|
||||
"version": "0.3-pre",
|
||||
"authors": ["Adzel"],
|
||||
"main": "com.adzel.velocitybroadcast.VelocityBroadcast",
|
||||
"description": "A proxy-wide broadcast plugin for Velocity.",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "velocitybroadcast",
|
||||
"name": "VelocityBroadcast",
|
||||
"version": "0.2-pre",
|
||||
"version": "0.3-pre",
|
||||
"authors": ["Adzel"],
|
||||
"main": "com.adzel.velocitybroadcast.VelocityBroadcast",
|
||||
"description": "A proxy-wide broadcast plugin for Velocity.",
|
||||
|
@ -1 +1 @@
|
||||
{"id":"velocitybroadcast","name":"VelocityBroadcast","version":"0.2-pre","description":"A proxy-wide broadcast plugin for Velocity.","authors":["Adzel"],"dependencies":[],"main":"com.adzel.velocitybroadcast.VelocityBroadcast"}
|
||||
{"id":"velocitybroadcast","name":"VelocityBroadcast","version":"0.3-pre","description":"A proxy-wide broadcast plugin for Velocity.","authors":["Adzel"],"dependencies":[],"main":"com.adzel.velocitybroadcast.VelocityBroadcast"}
|
@ -1,3 +1,3 @@
|
||||
artifactId=velocitybroadcast
|
||||
groupId=com.adzel.velocitybroadcast
|
||||
version=0.2-pre
|
||||
version=0.3-pre
|
||||
|
@ -4,4 +4,7 @@ com\adzel\velocitybroadcast\BroadcastCommand.class
|
||||
com\adzel\velocitybroadcast\ConfigHandler.class
|
||||
com\adzel\velocitybroadcast\ReloadCommand.class
|
||||
velocity-plugin.json
|
||||
com\adzel\velocitybroadcast\util\DatabaseManager.class
|
||||
com\adzel\velocitybroadcast\PrefixCommand.class
|
||||
com\adzel\velocitybroadcast\util\UpdateChecker.class
|
||||
com\adzel\velocitybroadcast\LoginListener.class
|
||||
|
@ -2,5 +2,8 @@ C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\veloci
|
||||
C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\velocitybroadcast\ReloadCommand.java
|
||||
C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\velocitybroadcast\BroadcastCommand.java
|
||||
C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\velocitybroadcast\ConfigHandler.java
|
||||
C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\velocitybroadcast\UpdateChecker.java
|
||||
C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\velocitybroadcast\util\DatabaseManager.java
|
||||
C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\velocitybroadcast\LoginListener.java
|
||||
C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\velocitybroadcast\VelocityBroadcast.java
|
||||
C:\Users\theon\OneDrive\Desktop\VelocityBroadcast\src\main\java\com\adzel\velocitybroadcast\PrefixCommand.java
|
||||
|
Reference in New Issue
Block a user