2 Commits

Author SHA1 Message Date
660c3c3098 add mysql support 2025-05-08 17:31:54 -07:00
9dabc86d48 add admin command 2025-05-08 12:15:29 -07:00
6 changed files with 148 additions and 26 deletions

View File

@ -4,11 +4,11 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.sophiaatkinson</groupId>
<artifactId>PronounsPlugin</artifactId>
<version>1.0.1</version>
<artifactId>PronounsPlaceholder</artifactId>
<version>1.0.3</version>
<packaging>jar</packaging>
<name>PronounsPlugin</name>
<name>PronounsPlaceholder</name>
<properties>
<java.version>21</java.version>

View File

@ -4,9 +4,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@ -78,22 +81,23 @@ public class PronounsCommand implements CommandExecutor, TabCompleter {
}
case "reset" -> {
plugin.setPronouns(player.getUniqueId(), null); // Reset the player's pronouns
plugin.setPronouns(player.getUniqueId(), null);
player.sendMessage(ChatColor.GREEN + "Your pronouns have been reset.");
}
case "help" -> {
player.sendMessage(ChatColor.AQUA + "=== Pronouns Plugin Help ===");
player.sendMessage(ChatColor.YELLOW + "/pronouns set <pronouns> " + ChatColor.WHITE + "- Set your pronouns");
player.sendMessage(ChatColor.YELLOW + "/pronouns view [player] " + ChatColor.WHITE + "- View your or another player's pronouns");
player.sendMessage(ChatColor.YELLOW + "/pronouns view <player> " + ChatColor.WHITE + "- View your own or another player's pronouns");
player.sendMessage(ChatColor.YELLOW + "/pronouns reset " + ChatColor.WHITE + "- Reset your pronouns");
player.sendMessage(ChatColor.YELLOW + "/pronouns version " + ChatColor.WHITE + "- Show plugin and server version info");
player.sendMessage(ChatColor.YELLOW + "/pronouns debug " + ChatColor.WHITE + "- Generate a debug file");
player.sendMessage(ChatColor.YELLOW + "/pronouns version " + ChatColor.WHITE + "- Show plugin version info");
player.sendMessage(ChatColor.YELLOW + "/pronouns debug " + ChatColor.WHITE + "- Generate debug file");
player.sendMessage(ChatColor.YELLOW + "/pronouns admin " + ChatColor.WHITE + "- Admin tools (list, set, remove)");
}
case "version" -> {
player.sendMessage(ChatColor.AQUA + "=== Version Info ===");
player.sendMessage(ChatColor.YELLOW + "PronounsPlugin: " + ChatColor.WHITE + plugin.getDescription().getVersion());
player.sendMessage(ChatColor.YELLOW + "PronounsPlaceholder: " + ChatColor.WHITE + plugin.getDescription().getVersion());
player.sendMessage(ChatColor.YELLOW + "Server Version: " + ChatColor.WHITE + Bukkit.getVersion());
}
@ -102,6 +106,56 @@ public class PronounsCommand implements CommandExecutor, TabCompleter {
player.sendMessage(ChatColor.GREEN + "Debug file written to plugin folder as debug.txt");
}
case "admin" -> {
if (!player.hasPermission("pronouns.admin")) {
player.sendMessage(ChatColor.RED + "You don't have permission to use admin commands.");
return true;
}
if (args.length < 2) {
player.sendMessage(ChatColor.RED + "Usage: /pronouns admin <list|remove|set>");
return true;
}
switch (args[1].toLowerCase()) {
case "list" -> {
Map<UUID, String> all = plugin.getAllPronouns();
if (all.isEmpty()) {
player.sendMessage(ChatColor.YELLOW + "No pronouns have been set.");
} else {
player.sendMessage(ChatColor.AQUA + "=== All Player Pronouns ===");
for (Map.Entry<UUID, String> entry : all.entrySet()) {
OfflinePlayer p = Bukkit.getOfflinePlayer(entry.getKey());
player.sendMessage(ChatColor.YELLOW + p.getName() + ": " + ChatColor.AQUA + entry.getValue());
}
}
}
case "remove" -> {
if (args.length < 3) {
player.sendMessage(ChatColor.RED + "Usage: /pronouns admin remove <player>");
return true;
}
OfflinePlayer target = Bukkit.getOfflinePlayer(args[2]);
plugin.setPronouns(target.getUniqueId(), null);
player.sendMessage(ChatColor.GREEN + "Removed pronouns for " + target.getName());
}
case "set" -> {
if (args.length < 4) {
player.sendMessage(ChatColor.RED + "Usage: /pronouns admin set <player> <pronouns>");
return true;
}
OfflinePlayer target = Bukkit.getOfflinePlayer(args[2]);
String pronouns = String.join(" ", Arrays.copyOfRange(args, 3, args.length));
plugin.setPronouns(target.getUniqueId(), pronouns);
player.sendMessage(ChatColor.GREEN + "Set " + target.getName() + "'s pronouns to: " + ChatColor.AQUA + pronouns);
}
default -> player.sendMessage(ChatColor.RED + "Unknown admin subcommand.");
}
}
default -> player.sendMessage(ChatColor.RED + "Unknown subcommand. Use /pronouns help for options.");
}
@ -111,7 +165,7 @@ public class PronounsCommand implements CommandExecutor, TabCompleter {
@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 1) {
return Arrays.asList("set", "view", "reset", "help", "version", "debug");
return Arrays.asList("set", "view", "reset", "help", "version", "debug", "admin");
}
if (args.length == 2 && args[0].equalsIgnoreCase("view")) {
@ -123,9 +177,27 @@ public class PronounsCommand implements CommandExecutor, TabCompleter {
}
if (args.length == 2 && args[0].equalsIgnoreCase("set")) {
return Arrays.asList("she/her", "he/him", "they/them", "xe/xem", "it/its");
return plugin.getPronounSuggestions();
}
if (args.length == 2 && args[0].equalsIgnoreCase("admin")) {
return Arrays.asList("list", "remove", "set");
}
if (args.length == 3 && args[0].equalsIgnoreCase("admin")) {
if (args[1].equalsIgnoreCase("remove") || args[1].equalsIgnoreCase("set")) {
List<String> names = new ArrayList<>();
for (OfflinePlayer p : Bukkit.getOfflinePlayers()) {
names.add(p.getName());
}
return names;
}
}
if (args.length == 4 && args[0].equalsIgnoreCase("admin") && args[1].equalsIgnoreCase("set")) {
return plugin.getPronounSuggestions();
}
return Collections.emptyList();
}
}

View File

@ -16,7 +16,7 @@ public class PronounsPlaceholder extends PlaceholderExpansion {
@Override
public @NotNull String getIdentifier() {
return "pronounsplugin";
return "PronounsPlaceholder";
}
@Override

View File

@ -10,13 +10,16 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.plugin.java.JavaPlugin;
public class PronounsPlugin extends JavaPlugin {
private Connection connection;
private boolean usingMySQL;
private List<String> blockedPronouns;
private List<String> pronounSuggestions;
private final List<String> errorLog = new ArrayList<>();
@ -52,15 +55,27 @@ public class PronounsPlugin extends JavaPlugin {
}
private void initDatabase() {
try {
File dbFile = new File(getDataFolder(), "pronouns.db");
if (!getDataFolder().exists()) getDataFolder().mkdirs();
usingMySQL = getConfig().getBoolean("mysql.enabled", false);
String url = "jdbc:sqlite:" + dbFile.getAbsolutePath();
connection = DriverManager.getConnection(url);
try {
if (usingMySQL) {
String host = getConfig().getString("mysql.host");
int port = getConfig().getInt("mysql.port");
String database = getConfig().getString("mysql.database");
String user = getConfig().getString("mysql.user");
String password = getConfig().getString("mysql.password");
String url = "jdbc:mysql://" + host + ":" + port + "/" + database + "?useSSL=false&autoReconnect=true";
connection = DriverManager.getConnection(url, user, password);
} else {
File dbFile = new File(getDataFolder(), "pronouns.db");
if (!getDataFolder().exists()) getDataFolder().mkdirs();
String url = "jdbc:sqlite:" + dbFile.getAbsolutePath();
connection = DriverManager.getConnection(url);
}
Statement stmt = connection.createStatement();
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS pronouns (uuid TEXT PRIMARY KEY, pronouns TEXT);");
stmt.executeUpdate("CREATE TABLE IF NOT EXISTS pronouns (uuid VARCHAR(36) PRIMARY KEY, pronouns TEXT);");
} catch (SQLException e) {
errorLog.add("Database initialization error: " + e.getMessage());
e.printStackTrace();
@ -80,9 +95,7 @@ public class PronounsPlugin extends JavaPlugin {
}
for (String blocked : blockedPronouns) {
if (pronouns.contains(blocked)) {
return;
}
if (pronouns.contains(blocked)) return;
}
try (PreparedStatement ps = connection.prepareStatement("REPLACE INTO pronouns (uuid, pronouns) VALUES (?, ?)")) {
@ -90,6 +103,18 @@ public class PronounsPlugin extends JavaPlugin {
ps.setString(2, pronouns);
ps.executeUpdate();
} catch (SQLException e) {
// Fallback for MySQL since REPLACE INTO isn't ideal for all cases
if (usingMySQL) {
try (PreparedStatement ps = connection.prepareStatement("INSERT INTO pronouns (uuid, pronouns) VALUES (?, ?) ON DUPLICATE KEY UPDATE pronouns = VALUES(pronouns)")) {
ps.setString(1, uuid.toString());
ps.setString(2, pronouns);
ps.executeUpdate();
return;
} catch (SQLException ex) {
errorLog.add("MySQL upsert error: " + ex.getMessage());
ex.printStackTrace();
}
}
errorLog.add("Database update error: " + e.getMessage());
e.printStackTrace();
}
@ -108,6 +133,19 @@ public class PronounsPlugin extends JavaPlugin {
}
return null;
}
public Map<UUID, String> getAllPronouns() {
Map<UUID, String> result = new HashMap<>();
try (Statement stmt = connection.createStatement()) {
ResultSet rs = stmt.executeQuery("SELECT uuid, pronouns FROM pronouns");
while (rs.next()) {
result.put(UUID.fromString(rs.getString("uuid")), rs.getString("pronouns"));
}
} catch (SQLException e) {
errorLog.add("Database fetch all error: " + e.getMessage());
e.printStackTrace();
}
return result;
}
public void generateDebugFile() {
File debugFile = new File(getDataFolder(), "debug.txt");
@ -119,6 +157,7 @@ public class PronounsPlugin extends JavaPlugin {
writer.write("=== PronounsPlugin Debug Report ===\n");
writer.write("Plugin Enabled: " + isEnabled() + "\n");
writer.write("Database Connected: " + (connection != null) + "\n");
writer.write("Using MySQL: " + usingMySQL + "\n");
writer.write("Blocked Pronouns: " + blockedPronouns + "\n");
writer.write("Pronoun Suggestions: " + pronounSuggestions + "\n");
writer.write("Error Log:\n");

View File

@ -27,12 +27,18 @@ debug: true
generate-debug-file: true
database:
use-sqlite: true
mysql:
enabled: false # Setting to false uses SQLite
host: localhost
port: 3306
database: example
user: example
password: example
admin-permissions:
- "pronouns.admin"
- "pronouns.override"
- "pronouns.reload"
player-permissions:
- "pronouns.set"

View File

@ -1,7 +1,9 @@
name: PronounsPlugin
version: 1.0.1
name: PronounsPlaceholder
version: 1.0.3
main: com.sophiaatkinson.pronouns.PronounsPlugin
api-version: 1.16
authors: [Sophia Atkinson]
website: https://sophia.wtf
commands:
pronouns:
description: Manage pronouns for players
@ -17,7 +19,10 @@ commands:
description: Allows players to use the debug command
default: op
pronouns.admin:
description: Allows admin to view all pronouns
description: Allows admin to list, set, remove pronouns
default: op
pronouns.reload:
description: Reloads plugin configuration
default: op
aliases:
- mypronouns