diff --git a/build.gradle b/build.gradle index bc74953..f538d39 100644 --- a/build.gradle +++ b/build.gradle @@ -23,8 +23,6 @@ repositories { } dependencies { - implementation 'org.projectlombok:lombok:1.18.20' - implementation 'org.postgresql:postgresql:42.2.20' implementation 'org.apache.commons:commons-lang3:3.12.0' implementation 'com.github.Milkbowl:VaultAPI:1.7.1' implementation 'com.google.code.gson:gson:2.8.7' diff --git a/build/resources/main/config.yml b/build/resources/main/config.yml new file mode 100644 index 0000000..e69de29 diff --git a/build/resources/main/db.properties b/build/resources/main/db.properties new file mode 100644 index 0000000..49d9384 --- /dev/null +++ b/build/resources/main/db.properties @@ -0,0 +1,14 @@ +# The SQL driver to use. +driver=jdbc +# The type of database to use. +databaseType=mysql +# The database host. +host=localhost +# The database port. +port=5432 +# The database file name. +databaseFile=database.db +# The database username. +username=admin +# The database password. +password=default \ No newline at end of file diff --git a/build/resources/main/plugin.yml b/build/resources/main/plugin.yml new file mode 100644 index 0000000..635b136 --- /dev/null +++ b/build/resources/main/plugin.yml @@ -0,0 +1,10 @@ +name: Traverse +version: '1.0.0' +main: mc.unraveled.reforged.plugin.Traverse +api-version: 1.19 +authors: [ SimplexDevelopment ] +description: "A plugin designed for the Unraveled: Reforged server." +website: https://github.com/SimplexDevelopment/Traverse +depend: [ Vault ] +softdepend: [ EssentialsX, EssentialsXSpawn ] + diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin new file mode 100644 index 0000000..ee31e97 Binary files /dev/null and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/build/tmp/shadowJar/MANIFEST.MF b/build/tmp/shadowJar/MANIFEST.MF new file mode 100644 index 0000000..d1ef717 --- /dev/null +++ b/build/tmp/shadowJar/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Class-Path: reactor-core-3.4.10.jar reactive-streams-1.0.3.jar + diff --git a/src/main/java/mc/unraveled/reforged/api/Locker.java b/src/main/java/mc/unraveled/reforged/api/Locker.java deleted file mode 100644 index fe0da01..0000000 --- a/src/main/java/mc/unraveled/reforged/api/Locker.java +++ /dev/null @@ -1,9 +0,0 @@ -package mc.unraveled.reforged.api; - -public interface Locker { - Object lock = new Object(); - - default Object lock() { - return lock; - } -} diff --git a/src/main/java/mc/unraveled/reforged/banning/AbstractBan.java b/src/main/java/mc/unraveled/reforged/banning/AbstractBan.java index 9002332..8e54b78 100644 --- a/src/main/java/mc/unraveled/reforged/banning/AbstractBan.java +++ b/src/main/java/mc/unraveled/reforged/banning/AbstractBan.java @@ -1,13 +1,12 @@ package mc.unraveled.reforged.banning; -import lombok.Getter; import mc.unraveled.reforged.api.Serializable; import mc.unraveled.reforged.util.Pair; import mc.unraveled.reforged.util.Utilities; +import org.jetbrains.annotations.NotNull; import java.util.List; -@Getter public abstract class AbstractBan implements Serializable { private final String uuid; private final String ip; @@ -38,6 +37,38 @@ public abstract class AbstractBan implements Serializable { ); } + public String getUuid() { + return uuid; + } + + public String getIp() { + return ip; + } + + public String getSource() { + return source; + } + + public String getReason() { + return reason; + } + + public long getPropagated() { + return propagated; + } + + public long getExpiry() { + return expiry; + } + + public List> getContentPairs() { + return contentPairs; + } + + public boolean isActive() { + return active; + } + public void setActive(boolean active) { this.active = active; } @@ -48,8 +79,7 @@ public abstract class AbstractBan implements Serializable { } @Override - public AbstractBan deserialize(String formatted) { - char delimiter = ':'; + public AbstractBan deserialize(@NotNull String formatted) { char end = ';'; char uuid = 'u'; char ip = 'i'; diff --git a/src/main/java/mc/unraveled/reforged/banning/BanManager.java b/src/main/java/mc/unraveled/reforged/banning/BanManager.java index a88b0b6..7f5bcad 100644 --- a/src/main/java/mc/unraveled/reforged/banning/BanManager.java +++ b/src/main/java/mc/unraveled/reforged/banning/BanManager.java @@ -1,46 +1,44 @@ package mc.unraveled.reforged.banning; -import lombok.Getter; -import lombok.SneakyThrows; import mc.unraveled.reforged.api.Baker; -import mc.unraveled.reforged.api.Locker; import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.storage.DBBan; -import mc.unraveled.reforged.storage.DBUser; import org.bukkit.OfflinePlayer; +import java.sql.Date; +import java.time.Instant; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; -public final class BanManager implements Locker, Baker { - @Getter +public final class BanManager implements Baker { private final Traverse plugin; private Set storedBans; // This should only be reassigned by the baker. - @Getter private boolean baked = false; // This should only be reassigned by the baker. - @SneakyThrows public BanManager(Traverse plugin) { this.storedBans = new HashSet<>(); this.plugin = plugin; - synchronized (lock()) { - DBBan banHandler = new DBBan(plugin.getSQLManager().establish()); - storedBans.addAll(banHandler.all()); - banHandler.close(); - - lock().wait(1000); - } + DBBan banHandler = new DBBan(plugin.getSQLManager().establish()); + storedBans.addAll(banHandler.all()); + banHandler.close(); bake(); } + public Traverse getPlugin() { + return plugin; + } + + public boolean isBaked() { + return baked; + } + public void insert(AbstractBan ban) { if (baked) throw new IllegalStateException("Cannot insert into a baked list."); - lock().notify(); storedBans.add(ban); DBBan db = new DBBan(plugin.getSQLManager().establish()); db.insert(ban); @@ -50,8 +48,7 @@ public final class BanManager implements Locker, Baker { public void eject(AbstractBan ban) { if (baked) throw new IllegalStateException("Cannot eject from a baked list."); - lock().notify(); - + storedBans.remove(ban); DBBan db = new DBBan(plugin.getSQLManager().establish()); db.delete(ban); db.close(); @@ -66,13 +63,22 @@ public final class BanManager implements Locker, Baker { public boolean isBanned(OfflinePlayer player) { return storedBans.stream() + .filter(AbstractBan::isActive) + .filter(ban -> { + Date date = new Date(ban.getExpiry()); + if (date.before(Date.from(Instant.now()))) { + eject(ban); + return false; + } else { + return true; + } + }) .anyMatch(ban -> ban.getUuid().equalsIgnoreCase( player.getUniqueId().toString())); } public void save() { if (!baked) throw new IllegalStateException("Cannot save an unbaked list."); - lock().notify(); DBBan banHandler = new DBBan(plugin.getSQLManager().establish()); storedBans.forEach(banHandler::insert); @@ -83,7 +89,6 @@ public final class BanManager implements Locker, Baker { public void bake() { if (baked) return; - lock().notify(); storedBans = storedBans.stream().collect(Collectors.toUnmodifiableSet()); baked = true; @@ -93,7 +98,6 @@ public final class BanManager implements Locker, Baker { public void unbake() { if (!baked) return; - lock().notify(); storedBans = new HashSet<>(storedBans); baked = false; diff --git a/src/main/java/mc/unraveled/reforged/command/BanInfoCMD.java b/src/main/java/mc/unraveled/reforged/command/BanInfoCMD.java new file mode 100644 index 0000000..66788a8 --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/command/BanInfoCMD.java @@ -0,0 +1,67 @@ +package mc.unraveled.reforged.command; + +import mc.unraveled.reforged.api.annotations.CommandInfo; +import mc.unraveled.reforged.banning.AbstractBan; +import mc.unraveled.reforged.command.base.AbstractCommandBase; +import mc.unraveled.reforged.plugin.Traverse; +import mc.unraveled.reforged.util.ComponentBuilder; +import mc.unraveled.reforged.util.Utilities; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +@CommandInfo( + name = "baninfo", + description = "Shows information about a ban", + usage = "/baninfo ", + aliases = {"bi", "bandata"} +) +public class BanInfoCMD extends AbstractCommandBase { + public BanInfoCMD(@NotNull Traverse plugin) { + super(plugin, "baninfo"); + } + + @Override + public Component cmd(CommandSender sender, String[] args) { + if (args.length != 1) { + return Component.text("Usage: /baninfo "); + } + + OfflinePlayer player = getPlugin().getServer().getOfflinePlayer(args[0]); + AbstractBan ban = getPlugin().getBanManager().getBan(player); + + if (ban == null) { + return Component.text("That player is not banned."); + } + + NamedTextColor GENERAL = NamedTextColor.YELLOW; + NamedTextColor INFO = NamedTextColor.GREEN; + NamedTextColor DETAIL = NamedTextColor.RED; + + return ComponentBuilder.begin() + .append("Ban info for ", GENERAL) + .append(player.getName(), DETAIL) + .append(":", GENERAL) + .append("\nUUID: ", INFO) + .append(ban.getUuid(), DETAIL) + .append("\nIP: ", INFO) + .append(ban.getIp(), DETAIL) + .append("\nReason: ", INFO) + .append(ban.getReason(), DETAIL) + .append("\nBanned by: ", INFO) + .append(ban.getSource(), DETAIL) + .append("\nBanned on: ", INFO) + .append(ban.getPropagated(), DETAIL) + .append("\nExpires on: ", INFO) + .append(ban.getExpiry(), DETAIL).build(); + } + + @Override + public List tab(CommandSender sender, String[] args) { + return Utilities.playerCompletions(args[0]); + } +} diff --git a/src/main/java/mc/unraveled/reforged/command/GroupCMD.java b/src/main/java/mc/unraveled/reforged/command/GroupCMD.java index 38f35f7..667664b 100644 --- a/src/main/java/mc/unraveled/reforged/command/GroupCMD.java +++ b/src/main/java/mc/unraveled/reforged/command/GroupCMD.java @@ -44,7 +44,7 @@ public class GroupCMD extends AbstractCommandBase { Arrays.stream(ranks) .filter(rank -> rank.getAttachment().getName().equalsIgnoreCase(group)) .findFirst() - .ifPresentOrElse(rankContext::setContext, () -> invalid.set(true)); + .ifPresentOrElse(rankContext::setState, () -> invalid.set(true)); if (invalid.get()) return Component.text("Invalid group!").color(NamedTextColor.RED); @@ -79,24 +79,24 @@ public class GroupCMD extends AbstractCommandBase { } if (actionType) { - manager.insertPlayer(rankContext.getContext(), player); + manager.insertPlayer(rankContext.getState(), player); manager.bake(); manager.save(); return Component.text("Added player " + player.getName() + " to group " + group + "!").color(NamedTextColor.GREEN); } else { - manager.ejectPlayer(rankContext.getContext(), player); + manager.ejectPlayer(rankContext.getState(), player); manager.bake(); manager.save(); return Component.text("Removed player " + player.getName() + " from group " + group + "!").color(NamedTextColor.GREEN); } case "permission": if (actionType) { - manager.insertPermission(rankContext.getContext(), value); + manager.insertPermission(rankContext.getState(), value); manager.bake(); manager.save(); return Component.text("Added permission " + value + " to group " + group + "!").color(NamedTextColor.GREEN); } else { - manager.ejectPermission(rankContext.getContext(), value); + manager.ejectPermission(rankContext.getState(), value); manager.bake(); manager.save(); return Component.text("Removed permission " + value + " from group " + group + "!").color(NamedTextColor.GREEN); diff --git a/src/main/java/mc/unraveled/reforged/command/JailCMD.java b/src/main/java/mc/unraveled/reforged/command/JailCMD.java deleted file mode 100644 index b55cbeb..0000000 --- a/src/main/java/mc/unraveled/reforged/command/JailCMD.java +++ /dev/null @@ -1,4 +0,0 @@ -package mc.unraveled.reforged.command; - -public class JailCMD { -} diff --git a/src/main/java/mc/unraveled/reforged/command/KickCMD.java b/src/main/java/mc/unraveled/reforged/command/KickCMD.java new file mode 100644 index 0000000..94b03cb --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/command/KickCMD.java @@ -0,0 +1,44 @@ +package mc.unraveled.reforged.command; + +import mc.unraveled.reforged.api.annotations.CommandInfo; +import mc.unraveled.reforged.command.base.AbstractCommandBase; +import mc.unraveled.reforged.plugin.Traverse; +import mc.unraveled.reforged.util.Utilities; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +@CommandInfo(name = "kick", + description = "Kick a player.", + usage = "/kick ", + aliases = {"k"}) +public class KickCMD extends AbstractCommandBase { + + public KickCMD(@NotNull Traverse plugin) { + super(plugin, "kick", true); + } + + @Override + public Component cmd(CommandSender sender, String[] args) { + if (args.length < 2) return Component.text("Usage: /kick "); + + Player target = Bukkit.getPlayer(args[0]); + if (target == null) return MessageDefaults.MSG_NOT_FOUND; + + String reason = String.join(" ", args).substring(args[0].length() + 1); + target.kick(Component.text(reason)); + broadcast(target.getName() + " has been kicked for " + reason + "."); + return Component.text("You have kicked " + target.getName() + " for " + reason + "."); + } + + @Override + public List tab(CommandSender sender, String[] args) { + if (args.length == 1) return Utilities.playerCompletions(args[0]); + + return super.tab(sender, args); + } +} diff --git a/src/main/java/mc/unraveled/reforged/command/LockCMD.java b/src/main/java/mc/unraveled/reforged/command/LockCMD.java index e37200f..8101f73 100644 --- a/src/main/java/mc/unraveled/reforged/command/LockCMD.java +++ b/src/main/java/mc/unraveled/reforged/command/LockCMD.java @@ -1,4 +1,72 @@ package mc.unraveled.reforged.command; -public class LockCMD { +import mc.unraveled.reforged.api.annotations.CommandInfo; +import mc.unraveled.reforged.command.base.AbstractCommandBase; +import mc.unraveled.reforged.data.InfractionData; +import mc.unraveled.reforged.data.PlayerData; +import mc.unraveled.reforged.plugin.Traverse; +import mc.unraveled.reforged.util.Utilities; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +@CommandInfo( + name = "lock", + usage = "/ ", + description = "Prevents a player from inputting any actions." +) +public class LockCMD extends AbstractCommandBase { + public LockCMD(@NotNull Traverse plugin) { + super(plugin, "lock"); + } + + @Override + public Component cmd(CommandSender sender, String[] args) { + if (args.length != 2) { + return Component.text("Usage: /lock "); + } + + Player player = Bukkit.getPlayer(args[0]); + if (player == null) { + return Component.text("Player not found."); + } + + PlayerData data = getPlugin().getDataManager().getPlayerData(player.getUniqueId()); + if (data == null) { + return Component.text("PlayerData for target user cannot be found!"); + } + + switch (args[1]) { + case "on" -> { + data.getInfractionData().setLocked(true); + data.getInfractionData().increment(); + return Component.text("Locked " + player.getName() + "."); + } + case "off" -> { + data.getInfractionData().setLocked(false); + return Component.text("Unlocked " + player.getName() + "."); + } + default -> { + return Component.text("Usage: /lock "); + } + } + } + + + @Override + public List tab(CommandSender sender, String[] args) { + if (args.length == 1) { + return Utilities.playerCompletions(args[0]); + } + + if (args.length == 2) { + return Utilities.stringCompletions(args[1], "on", "off"); + } + + return super.tab(sender, args); + } } diff --git a/src/main/java/mc/unraveled/reforged/command/base/PlayerDataCMD.java b/src/main/java/mc/unraveled/reforged/command/PlayerDataCMD.java similarity index 97% rename from src/main/java/mc/unraveled/reforged/command/base/PlayerDataCMD.java rename to src/main/java/mc/unraveled/reforged/command/PlayerDataCMD.java index 7af4860..3c81c27 100644 --- a/src/main/java/mc/unraveled/reforged/command/base/PlayerDataCMD.java +++ b/src/main/java/mc/unraveled/reforged/command/PlayerDataCMD.java @@ -1,6 +1,7 @@ -package mc.unraveled.reforged.command.base; +package mc.unraveled.reforged.command; import mc.unraveled.reforged.api.annotations.CommandInfo; +import mc.unraveled.reforged.command.base.AbstractCommandBase; import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.data.PlayerData; import mc.unraveled.reforged.permission.Rank; @@ -24,7 +25,7 @@ public class PlayerDataCMD extends AbstractCommandBase { @Override public Component cmd(CommandSender sender, String[] args) { switch (args.length) { - case 0: + case 0 -> { if (sender instanceof Player player) { PlayerData data = getPlugin().getDataManager().getPlayerData(player.getUniqueId()); @@ -46,8 +47,8 @@ public class PlayerDataCMD extends AbstractCommandBase { return Component.text(sb); } else return Component.text("This command can only be used by players!"); - - case 2: + } + case 2 -> { if (args[1].equalsIgnoreCase("info")) { Player target = getPlugin().getServer().getPlayer(args[0]); if (target == null) return MessageDefaults.MSG_NOT_FOUND; @@ -73,7 +74,8 @@ public class PlayerDataCMD extends AbstractCommandBase { } else { return usage(); } - case 3: + } + case 3 -> { if (args[1].equalsIgnoreCase("reset")) { Player target = getPlugin().getServer().getPlayer(args[0]); if (target == null) return MessageDefaults.MSG_NOT_FOUND; @@ -127,10 +129,10 @@ public class PlayerDataCMD extends AbstractCommandBase { return Component.text("Invalid data type!").color(NamedTextColor.RED); } } - case 4: + } + case 4 -> { Player target = getPlugin().getServer().getPlayer(args[0]); if (target == null) return MessageDefaults.MSG_NOT_FOUND; - if (args[1].equalsIgnoreCase("set")) { switch (args[2]) { case "rank": @@ -183,9 +185,12 @@ public class PlayerDataCMD extends AbstractCommandBase { } else { return usage(); } - default: + } + default -> { return usage(); + } } + return null; } private Component usage() { diff --git a/src/main/java/mc/unraveled/reforged/command/StaffChatCMD.java b/src/main/java/mc/unraveled/reforged/command/StaffChatCMD.java new file mode 100644 index 0000000..33708cb --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/command/StaffChatCMD.java @@ -0,0 +1,46 @@ +package mc.unraveled.reforged.command; + +import mc.unraveled.reforged.api.annotations.CommandInfo; +import mc.unraveled.reforged.command.base.AbstractCommandBase; +import mc.unraveled.reforged.plugin.Traverse; +import net.kyori.adventure.text.Component; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +@CommandInfo(name = "staffchat", + description = "Toggle staff chat.", + usage = "/staffchat [message]", + aliases = {"sc", "ac", "o"}) +public class StaffChatCMD extends AbstractCommandBase { + public StaffChatCMD(@NotNull Traverse plugin) { + super(plugin, "staff", true); + } + + @Override + public Component cmd(CommandSender sender, String[] args) { + if (args.length == 0) { + if (sender instanceof ConsoleCommandSender) { + return Component.text("You must be in game to toggle staff chat."); + } + + getPlugin().getStaffChat().toggleChat(((Player) sender).getUniqueId()); + + boolean chatStat = getPlugin().getStaffChat().inChat(((Player) sender).getUniqueId()); + + return Component.text("Staff chat toggled " + (chatStat ? "on" : "off") + "."); + } + + String message = String.join(" ", args); + getPlugin().getStaffChat().distribute(sender, message); + return null; + } + + @Override + public List tab(CommandSender sender, String[] args) { + return super.tab(sender, args); + } +} diff --git a/src/main/java/mc/unraveled/reforged/command/base/AbstractCommandBase.java b/src/main/java/mc/unraveled/reforged/command/base/AbstractCommandBase.java index f706a23..1f8ac39 100644 --- a/src/main/java/mc/unraveled/reforged/command/base/AbstractCommandBase.java +++ b/src/main/java/mc/unraveled/reforged/command/base/AbstractCommandBase.java @@ -1,6 +1,5 @@ package mc.unraveled.reforged.command.base; -import lombok.Getter; import mc.unraveled.reforged.api.ICommandBase; import mc.unraveled.reforged.permission.TPermission; import mc.unraveled.reforged.plugin.Traverse; @@ -12,7 +11,6 @@ import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -20,7 +18,6 @@ import java.util.List; import java.util.UUID; public abstract class AbstractCommandBase extends TPermission implements ICommandBase { - @Getter private final Traverse plugin; /** @@ -29,7 +26,7 @@ public abstract class AbstractCommandBase extends TPermission implements IComman * @param permissionMessage The message to send when the user does not have the permission to run the command. * @param allowConsole Whether to allow the command to be run anywhere, or only in game. */ - public AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission, String permissionMessage, boolean allowConsole) { + protected AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission, String permissionMessage, boolean allowConsole) { super(permission, permissionMessage, allowConsole); this.plugin = plugin; } @@ -39,7 +36,7 @@ public abstract class AbstractCommandBase extends TPermission implements IComman * @param permission The permission the user should have to run the command * @param permissionMessage The message to send when the user does not have the permission to run the command. */ - public AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission, String permissionMessage) { + protected AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission, String permissionMessage) { this(plugin, permission, permissionMessage, true); } @@ -48,20 +45,24 @@ public abstract class AbstractCommandBase extends TPermission implements IComman * @param permission The permission the user should have to run the command * @param allowConsole Whether to allow the command to be run anywhere, or only in game. */ - public AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission, boolean allowConsole) { - this(plugin, permission, "You do not have permission to use this command!", allowConsole); + protected AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission, boolean allowConsole) { + this(plugin, permission, MessageDefaults.MSG_NO_PERMS.toString(), allowConsole); } /** * @param plugin The plugin that owns this command * @param permission The permission the user should have to run the command */ - public AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission) { - this(plugin, permission, "You do not have permission to use this command!", true); + protected AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission) { + this(plugin, permission, MessageDefaults.MSG_NO_PERMS.toString(), true); } @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String lbl, String[] args) { + if (lbl.equalsIgnoreCase("")) { + return false; + } + if (!hasPermission(sender)) { sender.sendMessage(MessageDefaults.MSG_NO_PERMS); return true; @@ -132,12 +133,8 @@ public abstract class AbstractCommandBase extends TPermission implements IComman Bukkit.getServer().broadcast(msg(text, color)); } - public void enablePlugin(Plugin plugin) { - Bukkit.getServer().getPluginManager().enablePlugin(plugin); - } - - public void disablePlugin(Plugin plugin) { - Bukkit.getServer().getPluginManager().disablePlugin(plugin); + public Traverse getPlugin() { + return plugin; } protected static class MessageDefaults { @@ -149,5 +146,8 @@ public abstract class AbstractCommandBase extends TPermission implements IComman public static final Component MSG_NOT_ENOUGH_ARGS = Component.text("Not enough arguments.").color(NamedTextColor.RED); public static final Component MUTED = Component.text("You are muted!").color(NamedTextColor.RED); public static final Component BANNED = Component.text("You are banned!").color(NamedTextColor.RED); + private MessageDefaults() { + throw new AssertionError(); + } } } diff --git a/src/main/java/mc/unraveled/reforged/config/Yaml.java b/src/main/java/mc/unraveled/reforged/config/Yaml.java index d578983..6796edc 100644 --- a/src/main/java/mc/unraveled/reforged/config/Yaml.java +++ b/src/main/java/mc/unraveled/reforged/config/Yaml.java @@ -1,22 +1,20 @@ package mc.unraveled.reforged.config; -import lombok.Getter; -import lombok.SneakyThrows; import mc.unraveled.reforged.api.Baker; import mc.unraveled.reforged.plugin.Traverse; +import org.bukkit.Bukkit; +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; import java.io.File; +import java.io.IOException; -@Getter public abstract class Yaml extends YamlConfiguration implements Baker { private final String fileName; private final File dataFolder; private final Traverse plugin; private final File yamlFile; - - @Getter private boolean baked = false; Yaml(@NotNull Traverse plugin, String fileName, File dataFolder, boolean copyDefaults) { @@ -40,15 +38,38 @@ public abstract class Yaml extends YamlConfiguration implements Baker { this(plugin, fileName, false); } + public String getFileName() { + return fileName; + } + + public File getDataFolder() { + return dataFolder; + } + + public Traverse getPlugin() { + return plugin; + } + + public File getYamlFile() { + return yamlFile; + } + + public boolean isBaked() { + return baked; + } + /** * Makes the file read only after saving to disk. */ - @SneakyThrows @Override public void bake() { if (baked) return; - super.save(yamlFile); + try { + super.save(yamlFile); + } catch (IOException e) { + Bukkit.getLogger().severe(e.getMessage()); + } if (yamlFile.setWritable(false)) { getPlugin().getLogger().info("Baked " + getFileName()); @@ -73,17 +94,23 @@ public abstract class Yaml extends YamlConfiguration implements Baker { } } - @SneakyThrows public void saveToFile() { unbake(); - super.save(yamlFile); + try { + super.save(yamlFile); + } catch (IOException e) { + Bukkit.getLogger().severe(e.getMessage()); + } bake(); } - @SneakyThrows public void loadFromFile() { unbake(); - super.load(yamlFile); + try { + super.load(yamlFile); + } catch (IOException | InvalidConfigurationException e) { + Bukkit.getLogger().severe(e.getMessage()); + } bake(); } } diff --git a/src/main/java/mc/unraveled/reforged/config/YamlManager.java b/src/main/java/mc/unraveled/reforged/config/YamlManager.java index c8e3969..f4d1a02 100644 --- a/src/main/java/mc/unraveled/reforged/config/YamlManager.java +++ b/src/main/java/mc/unraveled/reforged/config/YamlManager.java @@ -1,8 +1,7 @@ package mc.unraveled.reforged.config; -import lombok.Getter; -import lombok.SneakyThrows; import mc.unraveled.reforged.plugin.Traverse; +import org.bukkit.Bukkit; import org.bukkit.configuration.InvalidConfigurationException; import org.jetbrains.annotations.NotNull; @@ -11,7 +10,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; -@Getter public class YamlManager { private final List configurations = new ArrayList<>(); private final Traverse plugin; @@ -20,6 +18,14 @@ public class YamlManager { this.plugin = plugin; } + public List getConfigurations() { + return configurations; + } + + public Traverse getPlugin() { + return plugin; + } + public Builder bldr() { return new Builder(plugin); } @@ -32,14 +38,20 @@ public class YamlManager { configurations.remove(yaml); } - @SneakyThrows public void load(@NotNull Yaml yaml) { - yaml.load(yaml.getYamlFile()); + try { + yaml.load(yaml.getYamlFile()); + } catch (IOException | InvalidConfigurationException e) { + Bukkit.getLogger().severe("Failed to load " + yaml.getYamlFile().getName() + "!"); + } } - @SneakyThrows public void save(@NotNull Yaml yaml) { - yaml.save(yaml.getYamlFile()); + try { + yaml.save(yaml.getYamlFile()); + } catch (IOException e) { + Bukkit.getLogger().severe("Failed to save " + yaml.getYamlFile().getName() + "!"); + } } public void loadAll() { diff --git a/src/main/java/mc/unraveled/reforged/data/DataManager.java b/src/main/java/mc/unraveled/reforged/data/DataManager.java index 47148a2..5f8549a 100644 --- a/src/main/java/mc/unraveled/reforged/data/DataManager.java +++ b/src/main/java/mc/unraveled/reforged/data/DataManager.java @@ -1,11 +1,8 @@ package mc.unraveled.reforged.data; -import lombok.SneakyThrows; import mc.unraveled.reforged.api.Baker; -import mc.unraveled.reforged.api.Locker; import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.storage.DBUser; -import org.bukkit.entity.Player; import org.jetbrains.annotations.Nullable; import java.util.HashSet; @@ -13,7 +10,8 @@ import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; -public final class DataManager implements Baker, Locker { +public final class DataManager implements Baker { + public static final String MANAGER_IS_BAKED = "Cannot remove player data while the data manager is baked."; private final Traverse plugin; private Set playerDataCache = new HashSet<>(); // Should only be set by the baker. private boolean baked = false; // Should only be set by the baker. @@ -57,19 +55,19 @@ public final class DataManager implements Baker, Locker { } public void removePlayerData(PlayerData data) { - if (baked) throw new IllegalStateException("Cannot remove player data while the data manager is baked."); + if (baked) throw new IllegalStateException(MANAGER_IS_BAKED); playerDataCache.remove(data); } public void removePlayerData(UUID uuid) { - if (baked) throw new IllegalStateException("Cannot remove player data while the data manager is baked."); + if (baked) throw new IllegalStateException(MANAGER_IS_BAKED); playerDataCache.removeIf(data -> data.getUuid().equals(uuid)); } public void removePlayerData(String playerName) { - if (baked) throw new IllegalStateException("Cannot remove player data while the data manager is baked."); + if (baked) throw new IllegalStateException(MANAGER_IS_BAKED); playerDataCache.removeIf(data -> data.getUserName().equals(playerName)); } @@ -86,31 +84,21 @@ public final class DataManager implements Baker, Locker { user.close(); } - @SneakyThrows @Override public void bake() { if (baked) return; - synchronized (lock()) { - this.playerDataCache = playerDataCache.stream().collect(Collectors.toUnmodifiableSet()); - lock().wait(1000); - } + this.playerDataCache = playerDataCache.stream().collect(Collectors.toUnmodifiableSet()); this.baked = true; - lock().notify(); } - @SneakyThrows @Override public void unbake() { if (!baked) return; - synchronized (lock()) { - this.playerDataCache = new HashSet<>(playerDataCache); - lock().wait(1000); - } + this.playerDataCache = new HashSet<>(playerDataCache); this.baked = false; - lock().notify(); } } diff --git a/src/main/java/mc/unraveled/reforged/data/InfractionData.java b/src/main/java/mc/unraveled/reforged/data/InfractionData.java index 8ff7576..ad51528 100644 --- a/src/main/java/mc/unraveled/reforged/data/InfractionData.java +++ b/src/main/java/mc/unraveled/reforged/data/InfractionData.java @@ -1,7 +1,5 @@ package mc.unraveled.reforged.data; -import lombok.Getter; -import lombok.Setter; import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.storage.DBInfraction; import org.bukkit.OfflinePlayer; @@ -12,29 +10,13 @@ import java.util.HashMap; import java.util.Map; public class InfractionData { - private static final Map playerInfractionDataMap = new HashMap<>() {{ - DBInfraction infraction = new DBInfraction(JavaPlugin.getPlugin(Traverse.class).getSQLManager().establish()); - for (InfractionData data : infraction.getInfractionsList()) { - put(data.getPlayer(), data); - } - }}; + private static final Map playerInfractionDataMap = new HashMap<>(); - @Getter private final OfflinePlayer player; - @Getter private int infractions = 0; - - @Getter - @Setter private boolean muted = false; - @Getter - @Setter private boolean frozen = false; - @Getter - @Setter private boolean locked = false; - @Getter - @Setter private boolean jailed = false; public InfractionData(OfflinePlayer player) { @@ -48,6 +30,11 @@ public class InfractionData { this.frozen = frozen; this.locked = locked; this.jailed = jailed; + + DBInfraction infraction = new DBInfraction(JavaPlugin.getPlugin(Traverse.class).getSQLManager().establish()); + for (InfractionData data : infraction.getInfractionsList()) { + playerInfractionDataMap.put(data.getPlayer(), data); + } } public static InfractionData getCachedInfractionData(OfflinePlayer player) { @@ -61,6 +48,50 @@ public class InfractionData { return data; } + public OfflinePlayer getPlayer() { + return player; + } + + public int getInfractions() { + return infractions; + } + + public void setInfractions(int infractions) { + this.infractions = infractions; + } + + public boolean isMuted() { + return muted; + } + + public void setMuted(boolean muted) { + this.muted = muted; + } + + public boolean isFrozen() { + return frozen; + } + + public void setFrozen(boolean frozen) { + this.frozen = frozen; + } + + public boolean isLocked() { + return locked; + } + + public void setLocked(boolean locked) { + this.locked = locked; + } + + public boolean isJailed() { + return jailed; + } + + public void setJailed(boolean jailed) { + this.jailed = jailed; + } + public void increment() { infractions++; } diff --git a/src/main/java/mc/unraveled/reforged/data/LoginInfo.java b/src/main/java/mc/unraveled/reforged/data/LoginInfo.java index 0ad2249..c075af2 100644 --- a/src/main/java/mc/unraveled/reforged/data/LoginInfo.java +++ b/src/main/java/mc/unraveled/reforged/data/LoginInfo.java @@ -1,14 +1,22 @@ package mc.unraveled.reforged.data; -import lombok.Data; -import lombok.NoArgsConstructor; import net.kyori.adventure.text.Component; /** * Login Message Information Bean */ -@Data -@NoArgsConstructor public class LoginInfo { private Component loginMessage; + + public LoginInfo() { + this.loginMessage = Component.empty(); + } + + public Component getLoginMessage() { + return loginMessage; + } + + public void setLoginMessage(Component loginMessage) { + this.loginMessage = loginMessage; + } } diff --git a/src/main/java/mc/unraveled/reforged/data/LoginManager.java b/src/main/java/mc/unraveled/reforged/data/LoginManager.java index 170c81a..e807b6c 100644 --- a/src/main/java/mc/unraveled/reforged/data/LoginManager.java +++ b/src/main/java/mc/unraveled/reforged/data/LoginManager.java @@ -1,30 +1,27 @@ package mc.unraveled.reforged.data; -import lombok.Getter; import mc.unraveled.reforged.api.Baker; import mc.unraveled.reforged.listening.AbstractListener; import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.storage.DBUser; import mc.unraveled.reforged.util.Pair; -import net.kyori.adventure.text.Component; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerLoginEvent; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; -@Getter public class LoginManager implements Baker { private final Traverse plugin; private Set> dataSet = new HashSet<>(); // VALUE ONLY MODIFIED BY BAKER private boolean baked = false; - public LoginManager(Traverse plugin) { + public LoginManager(@NotNull Traverse plugin) { this.plugin = plugin; DBUser user = new DBUser(plugin.getSQLManager().establish()); @@ -36,6 +33,18 @@ public class LoginManager implements Baker { new LoginListener(plugin); } + public Traverse getPlugin() { + return plugin; + } + + public Set> getDataSet() { + return dataSet; + } + + public boolean isBaked() { + return baked; + } + public void add(OfflinePlayer player, LoginInfo data) { dataSet.add(new Pair<>(player, data)); } diff --git a/src/main/java/mc/unraveled/reforged/data/PlayerData.java b/src/main/java/mc/unraveled/reforged/data/PlayerData.java index d4e4e8c..ce11227 100644 --- a/src/main/java/mc/unraveled/reforged/data/PlayerData.java +++ b/src/main/java/mc/unraveled/reforged/data/PlayerData.java @@ -1,14 +1,10 @@ package mc.unraveled.reforged.data; -import lombok.AllArgsConstructor; -import lombok.Data; import mc.unraveled.reforged.permission.Rank; import java.util.Date; import java.util.UUID; -@Data -@AllArgsConstructor public class PlayerData { private UUID uuid; private String userName; @@ -18,4 +14,79 @@ public class PlayerData { private Date lastLogin; private String loginMessage; private InfractionData infractionData; + + public PlayerData(PlayerDataBuilder builder) { + this.uuid = builder.getUuid(); + this.userName = builder.getUserName(); + this.rank = builder.getRank(); + this.playtime = builder.getPlaytime(); + this.coins = builder.getCoins(); + this.lastLogin = builder.getLastLogin(); + this.loginMessage = builder.getLoginMessage(); + this.infractionData = builder.getInfractionData(); + } + + public UUID getUuid() { + return uuid; + } + + public void setUuid(UUID uuid) { + this.uuid = uuid; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Rank getRank() { + return rank; + } + + public void setRank(Rank rank) { + this.rank = rank; + } + + public long getPlaytime() { + return playtime; + } + + public void setPlaytime(long playtime) { + this.playtime = playtime; + } + + public int getCoins() { + return coins; + } + + public void setCoins(int coins) { + this.coins = coins; + } + + public Date getLastLogin() { + return lastLogin; + } + + public void setLastLogin(Date lastLogin) { + this.lastLogin = lastLogin; + } + + public String getLoginMessage() { + return loginMessage; + } + + public void setLoginMessage(String loginMessage) { + this.loginMessage = loginMessage; + } + + public InfractionData getInfractionData() { + return infractionData; + } + + public void setInfractionData(InfractionData infractionData) { + this.infractionData = infractionData; + } } diff --git a/src/main/java/mc/unraveled/reforged/data/PlayerDataBuilder.java b/src/main/java/mc/unraveled/reforged/data/PlayerDataBuilder.java new file mode 100644 index 0000000..07f8b55 --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/data/PlayerDataBuilder.java @@ -0,0 +1,93 @@ +package mc.unraveled.reforged.data; + +import mc.unraveled.reforged.permission.Rank; + +import java.util.Date; +import java.util.UUID; + +public class PlayerDataBuilder { + private UUID uuid; + private String userName; + private Rank rank; + private long playtime; + private int coins; + private Date lastLogin; + private String loginMessage; + private InfractionData infractionData; + + UUID getUuid() { + return uuid; + } + + public PlayerDataBuilder setUuid(UUID uuid) { + this.uuid = uuid; + return this; + } + + String getUserName() { + return userName; + } + + public PlayerDataBuilder setUserName(String userName) { + this.userName = userName; + return this; + } + + Rank getRank() { + return rank; + } + + public PlayerDataBuilder setRank(Rank rank) { + this.rank = rank; + return this; + } + + long getPlaytime() { + return playtime; + } + + public PlayerDataBuilder setPlaytime(long playtime) { + this.playtime = playtime; + return this; + } + + int getCoins() { + return coins; + } + + public PlayerDataBuilder setCoins(int coins) { + this.coins = coins; + return this; + } + + Date getLastLogin() { + return lastLogin; + } + + public PlayerDataBuilder setLastLogin(Date lastLogin) { + this.lastLogin = lastLogin; + return this; + } + + String getLoginMessage() { + return loginMessage; + } + + public PlayerDataBuilder setLoginMessage(String loginMessage) { + this.loginMessage = loginMessage; + return this; + } + + InfractionData getInfractionData() { + return infractionData; + } + + public PlayerDataBuilder setInfractionData(InfractionData infractionData) { + this.infractionData = infractionData; + return this; + } + + public PlayerDataBuilder compile() { + return this; + } +} \ No newline at end of file diff --git a/src/main/java/mc/unraveled/reforged/data/StaffChat.java b/src/main/java/mc/unraveled/reforged/data/StaffChat.java new file mode 100644 index 0000000..68b990a --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/data/StaffChat.java @@ -0,0 +1,50 @@ +package mc.unraveled.reforged.data; + +import mc.unraveled.reforged.permission.RankAttachment; +import mc.unraveled.reforged.plugin.Traverse; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public class StaffChat { + private final Set playersInChat = new HashSet<>(); + private final Traverse plugin; + + public StaffChat(Traverse plugin) { + this.plugin = plugin; + } + + public boolean inChat(UUID uuid) { + return playersInChat.contains(uuid); + } + + public void toggleChat(UUID uuid) { + if (inChat(uuid)) { + playersInChat.remove(uuid); + } else { + playersInChat.add(uuid); + } + } + + public Component formatStaffChatMessage(CommandSender player, String message) { + RankAttachment rank = plugin.getRankManager().getRank(player).getAttachment(); + String legacyStaffFormat = "&8[&bStaff&8]&r"; + String playerName = "&c" + player.getName() + "&r"; + String rankFormat = "&8[" + rank.getColor() + rank.getTag() + "&8]&r"; + + String appended = String.format("%s %s %s: %s", legacyStaffFormat, playerName, rankFormat, message); + + return LegacyComponentSerializer.legacyAmpersand().deserialize(appended); + } + + public void distribute(CommandSender source, String message) { + plugin.getServer().getOnlinePlayers().stream() + .filter(player -> player.hasPermission("traverse.staff")) + .forEach(player -> player.sendMessage(formatStaffChatMessage(source, message))); + } +} diff --git a/src/main/java/mc/unraveled/reforged/economy/EconomyManager.java b/src/main/java/mc/unraveled/reforged/economy/EconomyManager.java index 1e14b29..9fa4e15 100644 --- a/src/main/java/mc/unraveled/reforged/economy/EconomyManager.java +++ b/src/main/java/mc/unraveled/reforged/economy/EconomyManager.java @@ -1,6 +1,5 @@ package mc.unraveled.reforged.economy; -import lombok.Getter; import mc.unraveled.reforged.plugin.Traverse; import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.EconomyResponse; @@ -9,20 +8,16 @@ import org.bukkit.entity.Player; import org.bukkit.plugin.RegisteredServiceProvider; import org.jetbrains.annotations.NotNull; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.MissingResourceException; +import java.util.*; -@Getter public class EconomyManager { private final RegisteredServiceProvider rsp; - private final Map> requests = new HashMap<>(); // This is NOT persistent. + private final Map> requests = new HashMap<>(); // This is NOT persistent. private final Economy economy; public EconomyManager(@NotNull Traverse plugin) { if (plugin.getServer().getPluginManager().getPlugin("Vault") == null) - throw new RuntimeException("Vault is REQUIRED!"); + throw new MissingResourceException("Vault is REQUIRED!", "Vault", "VaultAPI"); rsp = plugin.getServer().getServicesManager().getRegistration(Economy.class); @@ -31,6 +26,18 @@ public class EconomyManager { economy = rsp.getProvider(); } + public RegisteredServiceProvider getRsp() { + return rsp; + } + + public Map> getRequests() { + return requests; + } + + public Economy getEconomy() { + return economy; + } + public EconomyResponse newAccount(OfflinePlayer player) { return economy.createBank(player.getName(), player); } @@ -42,10 +49,10 @@ public class EconomyManager { public EconomyRequest request(@NotNull OfflinePlayer from, @NotNull OfflinePlayer to, int amount) { EconomyRequest request = new EconomyRequest(this, (Player) from, (Player) to, amount); - if (requests.containsKey(to)) { - requests.get(to).add(request); + if (requests.containsKey(to.getUniqueId())) { + requests.get(to.getUniqueId()).add(request); } else { - requests.put((Player) to, List.of(request)); + requests.put(to.getUniqueId(), List.of(request)); } return request; diff --git a/src/main/java/mc/unraveled/reforged/economy/EconomyRequest.java b/src/main/java/mc/unraveled/reforged/economy/EconomyRequest.java index e035b25..6c137d8 100644 --- a/src/main/java/mc/unraveled/reforged/economy/EconomyRequest.java +++ b/src/main/java/mc/unraveled/reforged/economy/EconomyRequest.java @@ -1,18 +1,13 @@ package mc.unraveled.reforged.economy; -import lombok.Getter; -import lombok.Setter; import net.kyori.adventure.text.Component; -import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.EconomyResponse; import org.bukkit.entity.Player; public class EconomyRequest { - @Getter + private final Player sender; - @Getter private final Player target; - @Getter private final int amount; private final EconomyManager economy; @@ -23,6 +18,18 @@ public class EconomyRequest { this.economy = economy; } + public Player getSender() { + return sender; + } + + public Player getTarget() { + return target; + } + + public int getAmount() { + return amount; + } + public EconomyResponse accept() { EconomyResponse r = economy.withdraw(target, amount); if (r.transactionSuccess()) { @@ -34,7 +41,7 @@ public class EconomyRequest { sender.sendMessage(Component.text("Your request has been accepted.")); target.sendMessage(Component.text("You have accepted " + sender.getName() + "'s request.")); - economy.getRequests().get(target).remove(this); + economy.getRequests().get(target.getUniqueId()).remove(this); return r; } @@ -43,6 +50,6 @@ public class EconomyRequest { sender.sendMessage(Component.text("Your request has been denied.")); target.sendMessage(Component.text("You have denied " + sender.getName() + "'s request.")); - economy.getRequests().get(target).remove(this); + economy.getRequests().get(target.getUniqueId()).remove(this); } } diff --git a/src/main/java/mc/unraveled/reforged/gui/AbstractInventory.java b/src/main/java/mc/unraveled/reforged/gui/AbstractInventory.java new file mode 100644 index 0000000..fe72d99 --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/gui/AbstractInventory.java @@ -0,0 +1,20 @@ +package mc.unraveled.reforged.gui; + +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; + +public abstract class AbstractInventory { + private final Inventory inventory; + + protected AbstractInventory(String title, InventoryType type) { + this.inventory = Bukkit.createInventory(null, type, Component.text(title)); + } + + public Inventory getInventory() { + return inventory; + } + + public abstract void update(); +} diff --git a/src/main/java/mc/unraveled/reforged/listening/AbstractListener.java b/src/main/java/mc/unraveled/reforged/listening/AbstractListener.java index b4c1da4..c7104de 100644 --- a/src/main/java/mc/unraveled/reforged/listening/AbstractListener.java +++ b/src/main/java/mc/unraveled/reforged/listening/AbstractListener.java @@ -1,10 +1,16 @@ package mc.unraveled.reforged.listening; -import lombok.Data; import mc.unraveled.reforged.plugin.Traverse; import org.bukkit.event.Listener; -@Data public class AbstractListener implements Listener { private final Traverse plugin; + + public AbstractListener(Traverse plugin) { + this.plugin = plugin; + } + + public Traverse getPlugin() { + return plugin; + } } diff --git a/src/main/java/mc/unraveled/reforged/listening/PlayerDataListener.java b/src/main/java/mc/unraveled/reforged/listening/PlayerDataListener.java index 015b1e7..3e9bee7 100644 --- a/src/main/java/mc/unraveled/reforged/listening/PlayerDataListener.java +++ b/src/main/java/mc/unraveled/reforged/listening/PlayerDataListener.java @@ -2,6 +2,7 @@ package mc.unraveled.reforged.listening; import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.data.PlayerData; +import mc.unraveled.reforged.data.PlayerDataBuilder; import mc.unraveled.reforged.permission.Rank; import mc.unraveled.reforged.plugin.Traverse; import org.bukkit.entity.Player; @@ -22,14 +23,17 @@ public class PlayerDataListener extends AbstractListener { PlayerData data = getPlugin().getDataManager().getPlayerData(player.getUniqueId()); if (data == null) { - data = new PlayerData(player.getUniqueId(), - player.getName(), - Rank.NON_OP, - 0L, - 0, - Date.from(Instant.now()), - null, - InfractionData.getCachedInfractionData(player)); + PlayerDataBuilder builder = new PlayerDataBuilder() + .setUuid(player.getUniqueId()) + .setUserName(player.getName()) + .setRank(Rank.NON_OP) + .setPlaytime(0L) + .setCoins(0) + .setLastLogin(Date.from(Instant.now())) + .setLoginMessage(null) + .setInfractionData(InfractionData.getCachedInfractionData(player)) + .compile(); + data = new PlayerData(builder); getPlugin().getDataManager().addPlayerData(data); } diff --git a/src/main/java/mc/unraveled/reforged/listening/StaffChatListener.java b/src/main/java/mc/unraveled/reforged/listening/StaffChatListener.java new file mode 100644 index 0000000..5bc0341 --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/listening/StaffChatListener.java @@ -0,0 +1,28 @@ +package mc.unraveled.reforged.listening; + +import io.papermc.paper.event.player.AsyncChatEvent; +import mc.unraveled.reforged.plugin.Traverse; +import net.kyori.adventure.text.Component; +import org.bukkit.event.EventHandler; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +public class StaffChatListener extends AbstractListener { + public StaffChatListener(Traverse plugin) { + super(plugin); + } + + @EventHandler + public void onPlayerChat(AsyncChatEvent event) { + if (getPlugin().getStaffChat().inChat(event.getPlayer().getUniqueId())) { + Component message = event.message(); + event.setCancelled(true); + getPlugin().getServer().getOnlinePlayers().stream() + .filter(player -> player.hasPermission("traverse.staff")) + .forEach(player -> player.sendMessage(message)); + + } + } +} diff --git a/src/main/java/mc/unraveled/reforged/permission/Group.java b/src/main/java/mc/unraveled/reforged/permission/Group.java index cf77f46..85eee03 100644 --- a/src/main/java/mc/unraveled/reforged/permission/Group.java +++ b/src/main/java/mc/unraveled/reforged/permission/Group.java @@ -1,16 +1,15 @@ package mc.unraveled.reforged.permission; -import lombok.Data; import mc.unraveled.reforged.api.Baker; import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; -@Data public class Group implements Baker { + + public static final String BAKED_GROUP = "Cannot modify a baked group."; private final Rank rank; private Set permissions = new HashSet<>(); private Set players = new HashSet<>(); @@ -20,23 +19,43 @@ public class Group implements Baker { this.rank = rank; } + public Rank getRank() { + return rank; + } + + public Set getPermissions() { + return permissions; + } + + public Set getPlayers() { + return players; + } + + public boolean isBaked() { + return baked; + } + + public void setBaked(boolean baked) { + this.baked = baked; + } + public void insert(String permission) { - if (baked) throw new IllegalStateException("Cannot modify a baked group."); + if (baked) throw new IllegalStateException(BAKED_GROUP); permissions.add(permission); } public void insert(OfflinePlayer player) { - if (baked) throw new IllegalStateException("Cannot modify a baked group."); + if (baked) throw new IllegalStateException(BAKED_GROUP); players.add(player); } public void eject(String permission) { - if (baked) throw new IllegalStateException("Cannot modify a baked group."); + if (baked) throw new IllegalStateException(BAKED_GROUP); permissions.remove(permission); } public void eject(OfflinePlayer player) { - if (baked) throw new IllegalStateException("Cannot modify a baked group."); + if (baked) throw new IllegalStateException(BAKED_GROUP); players.remove(player); } diff --git a/src/main/java/mc/unraveled/reforged/permission/Rank.java b/src/main/java/mc/unraveled/reforged/permission/Rank.java index 3dc40e6..4b25000 100644 --- a/src/main/java/mc/unraveled/reforged/permission/Rank.java +++ b/src/main/java/mc/unraveled/reforged/permission/Rank.java @@ -4,6 +4,7 @@ import mc.unraveled.reforged.util.BasicColors; import net.kyori.adventure.text.format.TextColor; public enum Rank { + CONSOLE("console", "RCON", BasicColors.PURPLE.getColor(), 8), EXECUTIVE("executive", "Exec", BasicColors.DARK_RED.getColor(), 7), DEV("developer", "Dev", BasicColors.PURPLE.getColor(), 6), ADMIN("admin", "Admin", BasicColors.GOLD.getColor(), 5), diff --git a/src/main/java/mc/unraveled/reforged/permission/RankManager.java b/src/main/java/mc/unraveled/reforged/permission/RankManager.java index 1e2861e..a0124a9 100644 --- a/src/main/java/mc/unraveled/reforged/permission/RankManager.java +++ b/src/main/java/mc/unraveled/reforged/permission/RankManager.java @@ -1,38 +1,38 @@ package mc.unraveled.reforged.permission; -import lombok.Getter; import mc.unraveled.reforged.api.Baker; -import mc.unraveled.reforged.api.Locker; import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.storage.DBGroup; import mc.unraveled.reforged.util.Tuple; +import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.UUID; + +public class RankManager implements Baker { -public class RankManager implements Baker, Locker { - @Getter private final Traverse plugin; - private List, List>> rankQueue = new ArrayList<>(); - private List bakedGroups = new ArrayList<>(); + private final List, List>> rankQueue = new ArrayList<>(); + private final List bakedGroups = new ArrayList<>(); private boolean baked = false; public RankManager(@NotNull Traverse plugin) { this.plugin = plugin; - lock().notify(); - DBGroup groupHandler = new DBGroup(plugin.getSQLManager().establish()); Arrays.stream(Rank.values()).forEach(groupHandler::createTable); Rank[] ranks = Rank.values(); for (Rank rank : ranks) { - Tuple, List> rankTuple; - List playerList; + Tuple, List> rankTuple; + List playerList; List permissionList; playerList = groupHandler.getPlayers(rank); @@ -46,12 +46,28 @@ public class RankManager implements Baker, Locker { bake(); } - public void insert(Rank rank, List player, List args) { - rankQueue.add(new Tuple<>(rank, player, args)); + public Traverse getPlugin() { + return plugin; } - public void eject(Rank rank, List player, List args) { - rankQueue.remove(new Tuple<>(rank, player, args)); + public void insert(Rank rank, List playerList, List args) { + rankQueue.add(new Tuple<>(rank, playerList, args)); + } + + public void eject(Rank rank, List playerList, List args) { + rankQueue.remove(new Tuple<>(rank, playerList, args)); + } + + public Rank getRank(CommandSender player) { + if (player instanceof ConsoleCommandSender) return Rank.CONSOLE; + + Player c = (Player) player; + + return rankQueue.stream() + .filter(tuple -> tuple.getSecond().contains(c.getUniqueId())) + .findFirst() + .map(Tuple::getFirst) + .orElse(Rank.NON_OP); } public void insertPermission(Rank rank, String permission) { @@ -69,13 +85,13 @@ public class RankManager implements Baker, Locker { public void insertPlayer(Rank rank, OfflinePlayer player) { rankQueue.stream() .filter(tuple -> tuple.getFirst().equals(rank)) - .forEach(tuple -> tuple.getSecond().add(player)); + .forEach(tuple -> tuple.getSecond().add(player.getUniqueId())); } public void ejectPlayer(Rank rank, OfflinePlayer player) { rankQueue.stream() .filter(tuple -> tuple.getFirst().equals(rank)) - .forEach(tuple -> tuple.getSecond().remove(player)); + .forEach(tuple -> tuple.getSecond().remove(player.getUniqueId())); } public void save() { @@ -98,36 +114,30 @@ public class RankManager implements Baker, Locker { public void bake() { if (baked) return; - synchronized (lock()) { - rankQueue.forEach(tuple -> { - Rank rank = tuple.getFirst(); - List players = tuple.getSecond(); - List permissions = tuple.getThird(); + rankQueue.forEach(tuple -> { + Rank rank = tuple.getFirst(); + List players = tuple.getSecond(); + List permissions = tuple.getThird(); - Group group = new Group(rank); - for (OfflinePlayer p : players) { - group.insert(p); - } - for (String arg : permissions) { - group.insert(arg); - } - bakedGroups.add(group); - }); - } + Group group = new Group(rank); + for (UUID p : players) { + group.insert(Bukkit.getOfflinePlayer(p)); + } + for (String arg : permissions) { + group.insert(arg); + } + bakedGroups.add(group); + }); baked = true; - lock().notify(); } @Override public void unbake() { if (!baked) return; - synchronized (lock()) { - bakedGroups.clear(); - } + bakedGroups.clear(); baked = false; - lock().notify(); } } diff --git a/src/main/java/mc/unraveled/reforged/permission/TPermission.java b/src/main/java/mc/unraveled/reforged/permission/TPermission.java index b9e0ba0..212a985 100644 --- a/src/main/java/mc/unraveled/reforged/permission/TPermission.java +++ b/src/main/java/mc/unraveled/reforged/permission/TPermission.java @@ -12,7 +12,7 @@ public abstract class TPermission { * @param permissionMessage The message to send when the user does not have the permission to run the command. * @param allowConsole Whether to allow the command to be run anywhere, or only in game. */ - public TPermission(String permission, String permissionMessage, boolean allowConsole) { + protected TPermission(String permission, String permissionMessage, boolean allowConsole) { this.permission = "traverse." + permission; this.permissionMessage = permissionMessage; this.allowConsole = allowConsole; diff --git a/src/main/java/mc/unraveled/reforged/plugin/Traverse.java b/src/main/java/mc/unraveled/reforged/plugin/Traverse.java index 6797b00..f63bc67 100644 --- a/src/main/java/mc/unraveled/reforged/plugin/Traverse.java +++ b/src/main/java/mc/unraveled/reforged/plugin/Traverse.java @@ -1,8 +1,5 @@ package mc.unraveled.reforged.plugin; -import lombok.Getter; -import lombok.SneakyThrows; -import mc.unraveled.reforged.api.Locker; import mc.unraveled.reforged.banning.BanManager; import mc.unraveled.reforged.command.*; import mc.unraveled.reforged.command.base.CommandLoader; @@ -10,52 +7,104 @@ import mc.unraveled.reforged.config.Yaml; import mc.unraveled.reforged.config.YamlManager; import mc.unraveled.reforged.data.DataManager; import mc.unraveled.reforged.data.LoginManager; +import mc.unraveled.reforged.data.StaffChat; import mc.unraveled.reforged.economy.EconomyManager; import mc.unraveled.reforged.listening.InfractionListener; +import mc.unraveled.reforged.listening.PlayerDataListener; +import mc.unraveled.reforged.listening.StaffChatListener; import mc.unraveled.reforged.permission.RankManager; import mc.unraveled.reforged.service.base.Scheduling; import mc.unraveled.reforged.service.base.ServicePool; import mc.unraveled.reforged.storage.DBConnectionHandler; import mc.unraveled.reforged.storage.DBProperties; +import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; +import java.io.IOException; -public final class Traverse extends JavaPlugin implements Locker { +public final class Traverse extends JavaPlugin { // Secondary variable declaration. private final String CONFIG_FILE = "config.yml"; private final File CONFIG = new File(getDataFolder(), CONFIG_FILE); // Primary variable declaration. - @Getter + private DBConnectionHandler SQLManager; - @Getter + private DataManager dataManager; - @Getter + private CommandLoader commandLoader; - @Getter + private BanManager banManager; - @Getter + private RankManager rankManager; - @Getter + private Scheduling scheduler; - @Getter + private ServicePool PIPELINE; - @Getter + private EconomyManager economyManager; - @Getter + private LoginManager loginManager; - @Getter + private YamlManager yamlManager; - @Getter private Yaml yamlConfig; + private StaffChat staffChat; + + public DBConnectionHandler getSQLManager() { + return SQLManager; + } + + public DataManager getDataManager() { + return dataManager; + } + + public CommandLoader getCommandLoader() { + return commandLoader; + } + + public BanManager getBanManager() { + return banManager; + } + + public RankManager getRankManager() { + return rankManager; + } + + public Scheduling getScheduler() { + return scheduler; + } + + public ServicePool getPIPELINE() { + return PIPELINE; + } + + public EconomyManager getEconomyManager() { + return economyManager; + } + + public LoginManager getLoginManager() { + return loginManager; + } + + public YamlManager getYamlManager() { + return yamlManager; + } + + public Yaml getYamlConfig() { + return yamlConfig; + } + + public StaffChat getStaffChat() { + return staffChat; + } @Override - @SneakyThrows public void onEnable() { this.SQLManager = new DBConnectionHandler(new DBProperties("db.properties")); - this.dataManager = new DataManager(this); this.commandLoader = new CommandLoader(this, "TRAVERSE"); + this.dataManager = new DataManager(this); this.banManager = new BanManager(this); this.rankManager = new RankManager(this); this.scheduler = new Scheduling(this); @@ -63,6 +112,7 @@ public final class Traverse extends JavaPlugin implements Locker { this.economyManager = new EconomyManager(this); this.loginManager = new LoginManager(this); this.yamlManager = new YamlManager(this); + this.staffChat = new StaffChat(this); registerCommands(); registerListeners(); @@ -78,48 +128,55 @@ public final class Traverse extends JavaPlugin implements Locker { // Plugin shutdown logic } - @SneakyThrows public void registerCommands() { - synchronized (lock()) { - getCommandLoader().register( - new BanCMD(this), - new BankCMD(this), - new EntityPurgeCMD(this), - new GroupCMD(this), - new MuteCMD(this), - new PardonCMD(this), - new TraverseCMD(this), - new UnmuteCMD(this) - ); - lock().wait(1000); - } + getCommandLoader().register( + new BanCMD(this), + new BanInfoCMD(this), + new BankCMD(this), + new EntityPurgeCMD(this), + new GroupCMD(this), + new KickCMD(this), + new LockCMD(this), + new MuteCMD(this), + new PardonCMD(this), + new PlayerDataCMD(this), + new StaffChatCMD(this), + new TraverseCMD(this), + new UnmuteCMD(this) + ); - lock().notify(); getCommandLoader().load(); } public void registerListeners() { - new InfractionListener(this); + getServer().getPluginManager().registerEvents(new InfractionListener(this), this); + getServer().getPluginManager().registerEvents(new StaffChatListener(this), this); + getServer().getPluginManager().registerEvents(new PlayerDataListener(this), this); } - @SneakyThrows public void registerConfig() { Yaml yaml; - if (CONFIG.createNewFile()) { - yaml = getYamlManager().bldr() - .fileName(CONFIG_FILE) - .dataFolder(getDataFolder()) - .copyDefaults(true) - .build(); - } else { - yaml = getYamlManager().bldr() - .fileName(CONFIG_FILE) - .dataFolder(getDataFolder()) - .copyDefaults(false) - .build(); + try { + if (CONFIG.createNewFile()) { + yaml = getYamlManager().bldr() + .fileName(CONFIG_FILE) + .dataFolder(getDataFolder()) + .copyDefaults(true) + .build(); + } else { + yaml = getYamlManager().bldr() + .fileName(CONFIG_FILE) + .dataFolder(getDataFolder()) + .copyDefaults(false) + .build(); + } + } catch (IOException e) { + Bukkit.getLogger().severe("Could not create config.yml!"); + e.printStackTrace(); + return; } - this.yamlConfig = yaml; + this.yamlConfig = yaml; getYamlConfig().loadFromFile(); } } diff --git a/src/main/java/mc/unraveled/reforged/service/MuteService.java b/src/main/java/mc/unraveled/reforged/service/MuteService.java index 1cf5a3c..2af3a7a 100644 --- a/src/main/java/mc/unraveled/reforged/service/MuteService.java +++ b/src/main/java/mc/unraveled/reforged/service/MuteService.java @@ -1,7 +1,5 @@ package mc.unraveled.reforged.service; -import lombok.Getter; -import lombok.Setter; import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.service.base.AbstractService; import mc.unraveled.reforged.service.base.ServicePool; @@ -10,13 +8,16 @@ import org.jetbrains.annotations.Nullable; import reactor.core.publisher.Mono; public class MuteService extends AbstractService { - @Setter private InfractionData infractionData = null; public MuteService(@Nullable ServicePool parentPool, @NotNull String service_name, long delay) { super(parentPool, service_name, delay); } + public void setInfractionData(InfractionData infractionData) { + this.infractionData = infractionData; + } + @Override public int getServiceId() { return 0; diff --git a/src/main/java/mc/unraveled/reforged/service/base/AbstractService.java b/src/main/java/mc/unraveled/reforged/service/base/AbstractService.java index a027978..fc8b75d 100644 --- a/src/main/java/mc/unraveled/reforged/service/base/AbstractService.java +++ b/src/main/java/mc/unraveled/reforged/service/base/AbstractService.java @@ -48,7 +48,7 @@ public abstract class AbstractService implements IService { * * @param service_name A namespaced key which can be used to identify the service. */ - public AbstractService(@NotNull String service_name) { + protected AbstractService(@NotNull String service_name) { this((new ServicePool("defaultPool" + Scheduling.denom, JavaPlugin.getPlugin(Traverse.class))), service_name, 0L, diff --git a/src/main/java/mc/unraveled/reforged/storage/DBBan.java b/src/main/java/mc/unraveled/reforged/storage/DBBan.java index 8219a8b..855a932 100644 --- a/src/main/java/mc/unraveled/reforged/storage/DBBan.java +++ b/src/main/java/mc/unraveled/reforged/storage/DBBan.java @@ -1,114 +1,128 @@ package mc.unraveled.reforged.storage; -import lombok.Getter; -import lombok.SneakyThrows; import mc.unraveled.reforged.banning.AbstractBan; import mc.unraveled.reforged.banning.SimpleBan; +import org.bukkit.Bukkit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.UUID; -@Getter public class DBBan { - @Getter private Connection connection; public DBBan(Connection connection) { this.connection = connection; } - @SneakyThrows public void createTable() { - PreparedStatement statement = getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS bans (uuid VARCHAR(36), ip VARCHAR(16), reason VARCHAR(64), banned_by VARCHAR(16), banned_at BIGINT, expires_at BIGINT, active BOOLEAN, PRIMARY KEY (uuid));"); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection() + .prepareStatement("CREATE TABLE IF NOT EXISTS bans (uuid VARCHAR(36), ip VARCHAR(16), reason VARCHAR(64), banned_by VARCHAR(16), banned_at BIGINT, expires_at BIGINT, active BOOLEAN, PRIMARY KEY (uuid));")) { + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe(e.getMessage()); + } } - @SneakyThrows public void insert(@NotNull AbstractBan ban) { - PreparedStatement statement = getConnection().prepareStatement("IF NOT EXISTS (SELECT 1 FROM bans WHERE uuid = ?) " + - "BEGIN INSERT INTO bans (uuid, ip, reason, banned_by, banned_at, expires_at, active) VALUES (?, ?, ?, ?, ?, ?, ?) END " + - "ELSE BEGIN UPDATE bans SET ip = ?, reason = ?, banned_by = ?, banned_at = ?, expires_at = ?, active = ? WHERE uuid = ? END;"); - - statement.setString(1, ban.getUuid()); - statement.setString(2, ban.getUuid()); - statement.setString(3, ban.getIp()); - statement.setString(4, ban.getReason()); - statement.setString(5, ban.getSource()); - statement.setLong(6, ban.getPropagated()); - statement.setLong(7, ban.getExpiry()); - statement.setBoolean(8, ban.isActive()); - statement.setString(9, ban.getIp()); - statement.setString(10, ban.getReason()); - statement.setString(11, ban.getSource()); - statement.setLong(12, ban.getPropagated()); - statement.setLong(13, ban.getExpiry()); - statement.setBoolean(14, ban.isActive()); - statement.setString(15, ban.getUuid()); - - statement.executeUpdate(); + try (PreparedStatement statement = getConnection() + .prepareStatement("INSERT INTO bans (uuid, ip, reason, banned_by, banned_at, expires_at, active) VALUES (?, ?, ?, ?, ?, ?, ?);")) { + statement.setString(1, ban.getUuid()); + statement.setString(2, ban.getIp()); + statement.setString(3, ban.getReason()); + statement.setString(4, ban.getSource()); + statement.setLong(5, ban.getPropagated()); + statement.setLong(6, ban.getExpiry()); + statement.setBoolean(7, ban.isActive()); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe(e.getMessage()); + } } - @SneakyThrows @Nullable public AbstractBan getBan(@NotNull UUID uuid) { - PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM bans WHERE uuid = ?;"); - statement.setString(1, uuid.toString()); - ResultSet rs = statement.executeQuery(); - if (rs.next()) { - return new SimpleBan(rs.getString("uuid"), - rs.getString("ip"), - rs.getString("reason"), - rs.getString("banned_by"), - rs.getLong("banned_at"), - rs.getLong("expires_at"), - rs.getBoolean("active")); + try (PreparedStatement statement = getConnection() + .prepareStatement("SELECT * FROM bans WHERE uuid = ?;")) { + statement.setString(1, uuid.toString()); + try (ResultSet rs = statement.executeQuery()) { + if (rs.next()) { + return new SimpleBan(rs.getString("uuid"), + rs.getString("ip"), + rs.getString("reason"), + rs.getString("banned_by"), + rs.getLong("banned_at"), + rs.getLong("expires_at"), + rs.getBoolean("active")); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe(e.getMessage()); } + return null; } - @SneakyThrows public List all() { - PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM bans;"); - ResultSet rs = statement.executeQuery(); List bans = new ArrayList<>(); - while (rs.next()) { - bans.add(new SimpleBan(rs.getString("uuid"), - rs.getString("ip"), - rs.getString("reason"), - rs.getString("banned_by"), - rs.getLong("banned_at"), - rs.getLong("expires_at"), - rs.getBoolean("active"))); + try (PreparedStatement statement = getConnection() + .prepareStatement("SELECT * FROM bans;")) { + try (ResultSet rs = statement.executeQuery()) { + while (rs.next()) { + bans.add(new SimpleBan(rs.getString("uuid"), + rs.getString("ip"), + rs.getString("reason"), + rs.getString("banned_by"), + rs.getLong("banned_at"), + rs.getLong("expires_at"), + rs.getBoolean("active"))); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe(e.getMessage()); } return bans; } - @SneakyThrows public void delete(@NotNull AbstractBan ban) { - PreparedStatement statement = getConnection().prepareStatement("DELETE FROM bans WHERE uuid = ?;"); - statement.setString(1, ban.getUuid()); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection() + .prepareStatement("DELETE FROM bans WHERE uuid = ?;")) { + statement.setString(1, ban.getUuid()); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe(e.getMessage()); + } } - @SneakyThrows public void deleteAll() { - PreparedStatement statement = getConnection().prepareStatement("DELETE FROM bans;"); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection() + .prepareStatement("DELETE FROM bans;")) { + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe(e.getMessage()); + } } - @SneakyThrows public void close() { - getConnection().close(); + try { + getConnection().close(); + } catch (SQLException e) { + Bukkit.getLogger().severe(e.getMessage()); + } this.connection = null; } public void open(Connection connection) { this.connection = connection; } + + public Connection getConnection() { + return connection; + } } diff --git a/src/main/java/mc/unraveled/reforged/storage/DBConnectionHandler.java b/src/main/java/mc/unraveled/reforged/storage/DBConnectionHandler.java index f57b7c5..da06dc4 100644 --- a/src/main/java/mc/unraveled/reforged/storage/DBConnectionHandler.java +++ b/src/main/java/mc/unraveled/reforged/storage/DBConnectionHandler.java @@ -1,31 +1,44 @@ package mc.unraveled.reforged.storage; -import lombok.SneakyThrows; +import org.bukkit.Bukkit; -import java.sql.*; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; public class DBConnectionHandler { private final DBProperties properties; - public DBConnectionHandler(DBProperties properties) throws SQLException { + public DBConnectionHandler(DBProperties properties) { this.properties = properties; } - @SneakyThrows public Connection establish() { - return DriverManager.getConnection(properties.getUrl(), properties.getUsername(), properties.getPassword()); + try { + return DriverManager.getConnection(properties.getUrl(), properties.getUsername(), properties.getPassword()); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to establish connection: " + e.getMessage()); + return null; + } } - @SneakyThrows public ContextConnection establishContext() { - return new ContextConnection(DriverManager.getConnection(properties.getUrl(), properties.getUsername(), properties.getPassword())); + try { + return new ContextConnection(DriverManager.getConnection(properties.getUrl(), properties.getUsername(), properties.getPassword())); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to establish connection: " + e.getMessage()); + return null; + } } public record ContextConnection(Connection connection) implements AutoCloseable { - @SneakyThrows @Override public void close() { - connection.close(); + try { + connection.close(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to close connection: " + e.getMessage()); + } } } } diff --git a/src/main/java/mc/unraveled/reforged/storage/DBGroup.java b/src/main/java/mc/unraveled/reforged/storage/DBGroup.java index fbb5929..62dddf5 100644 --- a/src/main/java/mc/unraveled/reforged/storage/DBGroup.java +++ b/src/main/java/mc/unraveled/reforged/storage/DBGroup.java @@ -1,92 +1,111 @@ package mc.unraveled.reforged.storage; -import lombok.Getter; -import lombok.Setter; -import lombok.SneakyThrows; import mc.unraveled.reforged.permission.Rank; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import org.bukkit.permissions.Permission; +import org.jetbrains.annotations.NotNull; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.UUID; public class DBGroup { - @Getter private Connection connection; public DBGroup(Connection connection) { this.connection = connection; } - @SneakyThrows public void createTable(Rank rank) { - PreparedStatement statement = getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS " + rank.getAttachment().getName() + " (uuid VARCHAR(36), permissions VARCHAR(64));"); - statement.execute(); + try (PreparedStatement statement = getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS " + rank.getAttachment().getName() + " (uuid VARCHAR(36), permissions VARCHAR(64));")) { + statement.execute(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to create table: " + e.getMessage()); + } } - @SneakyThrows public void addPermission(Rank rank, String permission) { - PreparedStatement statement = getConnection().prepareStatement("INSERT INTO " + rank.getAttachment().getName() + " (permissions) VALUES (?);"); - statement.setString(1, permission); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("INSERT INTO " + rank.getAttachment().getName() + " (permissions) VALUES (?);")) { + statement.setString(1, permission); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to add permission: " + e.getMessage()); + } } - @SneakyThrows public void removePermission(Rank rank, String permission) { - PreparedStatement statement = getConnection().prepareStatement("DELETE FROM " + rank.getAttachment().getName() + " WHERE permissions = ?;"); - statement.setString(1, permission); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("DELETE FROM " + rank.getAttachment().getName() + " WHERE permissions = ?;")) { + statement.setString(1, permission); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to remove permission: " + e.getMessage()); + } } - @SneakyThrows public List getPermissions(Rank rank) { List permissions = new ArrayList<>(); - PreparedStatement statement = getConnection().prepareStatement("SELECT permissions FROM " + rank.getAttachment().getName() + ";"); - ResultSet rs = statement.executeQuery(); - while (rs.next()) { - permissions.add(rs.getString("permissions")); + try (PreparedStatement statement = getConnection().prepareStatement("SELECT permissions FROM " + rank.getAttachment().getName() + ";")) { + ResultSet rs = statement.executeQuery(); + while (rs.next()) { + permissions.add(rs.getString("permissions")); + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to get permissions: " + e.getMessage()); } return permissions; } - @SneakyThrows - public void addPlayer(Rank rank, OfflinePlayer player) { - PreparedStatement statement = getConnection().prepareStatement("INSERT INTO " + rank.getAttachment().getName() + " (uuid) VALUES (?);"); - statement.setString(1, player.getUniqueId().toString()); - statement.executeUpdate(); - } - - @SneakyThrows - public void removePlayer(Rank rank, OfflinePlayer player) { - PreparedStatement statement = getConnection().prepareStatement("DELETE FROM " + rank.getAttachment().getName() + " WHERE uuid = ?;"); - statement.setString(1, player.getUniqueId().toString()); - statement.executeUpdate(); - } - - @SneakyThrows - public List getPlayers(Rank rank) { - List players = new ArrayList<>(); - PreparedStatement statement = getConnection().prepareStatement("SELECT uuid FROM " + rank.getAttachment().getName() + ";"); - ResultSet rs = statement.executeQuery(); - while (rs.next()) { - UUID uuid = UUID.fromString(rs.getString("uuid")); - players.add(Bukkit.getOfflinePlayer(uuid)); + public void addPlayer(@NotNull Rank rank, @NotNull OfflinePlayer player) { + try (PreparedStatement statement = getConnection().prepareStatement("INSERT INTO " + rank.getAttachment().getName() + " (uuid) VALUES (?);")) { + statement.setString(1, player.getUniqueId().toString()); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to add player: " + e.getMessage()); } + } + + public void removePlayer(@NotNull Rank rank, @NotNull OfflinePlayer player) { + try (PreparedStatement statement = getConnection().prepareStatement("DELETE FROM " + rank.getAttachment().getName() + " WHERE uuid = ?;")) { + statement.setString(1, player.getUniqueId().toString()); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to remove player: " + e.getMessage()); + } + } + + public List getPlayers(Rank rank) { + List players = new ArrayList<>(); + + try (PreparedStatement statement = getConnection().prepareStatement("SELECT uuid FROM " + rank.getAttachment().getName() + ";")) { + ResultSet rs = statement.executeQuery(); + while (rs.next()) { + UUID uuid = UUID.fromString(rs.getString("uuid")); + players.add(uuid); + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to get players: " + e.getMessage()); + } + return players; } - @SneakyThrows public void close() { - getConnection().close(); + try { + getConnection().close(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Failed to close connection: " + e.getMessage()); + } } public void open(Connection connection) { this.connection = connection; } + + public Connection getConnection() { + return connection; + } } diff --git a/src/main/java/mc/unraveled/reforged/storage/DBInfraction.java b/src/main/java/mc/unraveled/reforged/storage/DBInfraction.java index 91035a5..461a652 100644 --- a/src/main/java/mc/unraveled/reforged/storage/DBInfraction.java +++ b/src/main/java/mc/unraveled/reforged/storage/DBInfraction.java @@ -1,6 +1,5 @@ package mc.unraveled.reforged.storage; -import lombok.SneakyThrows; import mc.unraveled.reforged.data.InfractionData; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; @@ -9,96 +8,112 @@ import org.bukkit.entity.Player; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.UUID; public class DBInfraction { - private final String INSERT = "INSERT INTO infractions (uuid, infractions, muted, frozen, locked, jailed) VALUES (?, ?, ?, ?, ?, ?);"; - private final String UPDATE = "UPDATE infractions SET infractions = ?, muted = ?, frozen = ?, locked = ?, jailed = ? WHERE uuid = ?;"; - private final String SELECT = "SELECT * FROM infractions;"; - private final String SELECT_UUID = "SELECT * FROM infractions WHERE uuid = ?;"; - private final String DELETE = "DELETE FROM infractions WHERE uuid = ?;"; - private final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS infractions (uuid VARCHAR(36), infractions INT, muted BOOLEAN, frozen BOOLEAN, locked BOOLEAN, jailed BOOLEAN, PRIMARY KEY (uuid));"; private final Connection connection; + private final String INF = "infractions"; public DBInfraction(Connection connection) { this.connection = connection; } - @SneakyThrows public void createTable() { - PreparedStatement statement = connection.prepareStatement(CREATE_TABLE); - statement.executeUpdate(); + String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS infractions (uuid VARCHAR(36), infractions INT, muted BOOLEAN, frozen BOOLEAN, locked BOOLEAN, jailed BOOLEAN, PRIMARY KEY (uuid));"; + try (PreparedStatement statement = connection.prepareStatement(CREATE_TABLE)) { + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Error while creating infractions table"); + } } - @SneakyThrows public void insert(Player player, InfractionData data) { - PreparedStatement statement = connection.prepareStatement(SQLConst.IF("infractions", "uuid") + + String INSERT = "INSERT INTO infractions (uuid, infractions, muted, frozen, locked, jailed) VALUES (?, ?, ?, ?, ?, ?);"; + String UPDATE = "UPDATE infractions SET infractions = ?, muted = ?, frozen = ?, locked = ?, jailed = ? WHERE uuid = ?;"; + try (PreparedStatement statement = connection.prepareStatement(SQLConst.IF(INF, "uuid", player.getUniqueId().toString()) + SQLConst.BEGIN + INSERT + SQLConst.END_SPACE + SQLConst.ELSE + UPDATE + SQLConst.END + - SQLConst.SEMICOLON); - statement.setString(1, player.getUniqueId().toString()); - statement.setString(2, player.getUniqueId().toString()); - statement.setInt(3, data.getInfractions()); - statement.setBoolean(4, data.isMuted()); - statement.setBoolean(5, data.isFrozen()); - statement.setBoolean(6, data.isLocked()); - statement.setBoolean(7, data.isJailed()); - statement.setInt(8, data.getInfractions()); - statement.setBoolean(9, data.isMuted()); - statement.setBoolean(10, data.isFrozen()); - statement.setBoolean(11, data.isLocked()); - statement.setBoolean(12, data.isJailed()); - statement.setString(13, player.getUniqueId().toString()); - statement.executeUpdate(); + SQLConst.SEMICOLON)) { + statement.setString(1, player.getUniqueId().toString()); + statement.setInt(2, data.getInfractions()); + statement.setBoolean(3, data.isMuted()); + statement.setBoolean(4, data.isFrozen()); + statement.setBoolean(5, data.isLocked()); + statement.setBoolean(6, data.isJailed()); + statement.setInt(7, data.getInfractions()); + statement.setBoolean(8, data.isMuted()); + statement.setBoolean(9, data.isFrozen()); + statement.setBoolean(10, data.isLocked()); + statement.setBoolean(11, data.isJailed()); + statement.setString(12, player.getUniqueId().toString()); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Error while inserting " + player.getName()); + } } - @SneakyThrows public void eject(Player player) { - PreparedStatement statement = connection.prepareStatement(DELETE); - statement.setString(1, player.getUniqueId().toString()); - statement.executeUpdate(); + String DELETE = "DELETE FROM infractions WHERE uuid = ?;"; + try (PreparedStatement statement = connection.prepareStatement(DELETE)) { + statement.setString(1, player.getUniqueId().toString()); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Error while ejecting " + player.getName()); + } } - @SneakyThrows public List getInfractionsList() { List temp = new ArrayList<>(); - PreparedStatement statement = connection.prepareStatement(SELECT); - ResultSet rs = statement.executeQuery(); - while (rs.next()) { - OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("uuid"))); - int infractions = rs.getInt("infractions"); - boolean muted = rs.getBoolean("muted"); - boolean frozen = rs.getBoolean("frozen"); - boolean locked = rs.getBoolean("locked"); - boolean jailed = rs.getBoolean("jailed"); + String SELECT = "SELECT * FROM infractions;"; + try (PreparedStatement statement = connection.prepareStatement(SELECT); + ResultSet rs = statement.executeQuery()) { + while (rs.next()) { + OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("uuid"))); + int infractions = rs.getInt(INF); + boolean muted = rs.getBoolean("muted"); + boolean frozen = rs.getBoolean("frozen"); + boolean locked = rs.getBoolean("locked"); + boolean jailed = rs.getBoolean("jailed"); - temp.add(new InfractionData(player, infractions, muted, frozen, locked, jailed)); + temp.add(new InfractionData(player, infractions, muted, frozen, locked, jailed)); + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Error while getting infractions list"); } + return temp; } - @SneakyThrows public InfractionData getInfraction(String uuid) { - PreparedStatement statement = connection.prepareStatement(SELECT_UUID); - statement.setString(1, uuid); - ResultSet rs = statement.executeQuery(); - if (rs.next()) { - return new InfractionData(Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("uuid"))), rs.getInt("infractions"), rs.getBoolean("muted"), rs.getBoolean("frozen"), rs.getBoolean("locked"), rs.getBoolean("jailed")); + String SELECT_UUID = "SELECT * FROM infractions WHERE uuid = ?;"; + try (PreparedStatement statement = connection.prepareStatement(SELECT_UUID)) { + statement.setString(1, uuid); + try (ResultSet rs = statement.executeQuery()) { + if (rs.next()) { + return new InfractionData(Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("uuid"))), rs.getInt(INF), rs.getBoolean("muted"), rs.getBoolean("frozen"), rs.getBoolean("locked"), rs.getBoolean("jailed")); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Error while getting infraction data for " + uuid); } return new InfractionData(Bukkit.getOfflinePlayer(UUID.fromString(uuid))); } - @SneakyThrows public void close() { - connection.close(); + try { + connection.close(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Error while closing connection"); + } } } diff --git a/src/main/java/mc/unraveled/reforged/storage/DBProperties.java b/src/main/java/mc/unraveled/reforged/storage/DBProperties.java index d5f53dd..e1b064e 100644 --- a/src/main/java/mc/unraveled/reforged/storage/DBProperties.java +++ b/src/main/java/mc/unraveled/reforged/storage/DBProperties.java @@ -1,12 +1,11 @@ package mc.unraveled.reforged.storage; -import lombok.Getter; +import org.bukkit.Bukkit; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; -@Getter public class DBProperties { private final Properties properties; private final String url; @@ -20,10 +19,10 @@ public class DBProperties { public DBProperties(String fileName) { properties = new Properties(); - try { - properties.load(new FileInputStream(fileName)); + try (FileInputStream fileInputStream = new FileInputStream(fileName)) { + properties.load(fileInputStream); } catch (IOException e) { - e.printStackTrace(); + Bukkit.getLogger().severe("Could not load database properties file!"); } driver = properties.getProperty("driver"); databaseType = properties.getProperty("databaseType"); @@ -34,4 +33,40 @@ public class DBProperties { password = properties.getProperty("password"); url = driver + ":" + databaseType + "://" + host + ":" + port + "/" + databaseFile; } + + public Properties getProperties() { + return properties; + } + + public String getUrl() { + return url; + } + + public String getDriver() { + return driver; + } + + public String getDatabaseType() { + return databaseType; + } + + public String getDatabaseFile() { + return databaseFile; + } + + public String getHost() { + return host; + } + + public String getPort() { + return port; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } } diff --git a/src/main/java/mc/unraveled/reforged/storage/DBUser.java b/src/main/java/mc/unraveled/reforged/storage/DBUser.java index 0995417..74eaa72 100644 --- a/src/main/java/mc/unraveled/reforged/storage/DBUser.java +++ b/src/main/java/mc/unraveled/reforged/storage/DBUser.java @@ -1,10 +1,9 @@ package mc.unraveled.reforged.storage; -import lombok.Getter; -import lombok.SneakyThrows; import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.data.LoginInfo; import mc.unraveled.reforged.data.PlayerData; +import mc.unraveled.reforged.data.PlayerDataBuilder; import mc.unraveled.reforged.permission.Rank; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; @@ -14,186 +13,228 @@ import org.jetbrains.annotations.NotNull; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; public class DBUser { - @Getter - private Connection connection; + public static final String LOGIN_MESSAGE = "login_message"; + private final String COIN_LITERAL = "coins"; + + private final Connection connection; public DBUser(Connection connection) { this.connection = connection; } - @SneakyThrows public void createTable() { - PreparedStatement statement = getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS users (uuid VARCHAR(36), username VARCHAR(16), rank VARCHAR(64), play_time BIGINT, coins BIGINT, last_login BIGINT, login_message VARCHAR(64), PRIMARY KEY (uuid));"); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS users (uuid VARCHAR(36), username VARCHAR(16), rank VARCHAR(64), play_time BIGINT, coins BIGINT, last_login BIGINT, login_message VARCHAR(64), PRIMARY KEY (uuid));")) { + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not create users table!"); + } } - @SneakyThrows public void insert(@NotNull PlayerData playerData) { - PreparedStatement statement = getConnection().prepareStatement("IF NOT EXISTS (SELECT 1 FROM users WHERE uuid = ?) " + + try (PreparedStatement statement = getConnection().prepareStatement("IF NOT EXISTS (SELECT 1 FROM users WHERE uuid = ?) " + "BEGIN INSERT INTO users (uuid, username, rank, play_time, coins, last_login, login_message) VALUES (?, ?, ?, ?, ?, ?, ?) END " + - "ELSE BEGIN UPDATE users SET username = ?, rank = ?, play_time = ?, coins = ?, last_login = ?, login_message = ?, WHERE uuid = ? END;"); + "ELSE BEGIN UPDATE users SET username = ?, rank = ?, play_time = ?, coins = ?, last_login = ?, login_message = ?, WHERE uuid = ? END;")) { + statement.setString(1, playerData.getUuid().toString()); + statement.setString(2, playerData.getUuid().toString()); + statement.setString(3, playerData.getUserName()); + statement.setString(4, playerData.getRank().name()); + statement.setLong(5, playerData.getPlaytime()); + statement.setInt(6, playerData.getCoins()); + statement.setLong(7, playerData.getLastLogin().getTime()); + statement.setString(8, playerData.getLoginMessage()); + statement.setString(9, playerData.getUserName()); + statement.setString(10, playerData.getRank().name()); + statement.setLong(11, playerData.getPlaytime()); + statement.setInt(12, playerData.getCoins()); + statement.setLong(13, playerData.getLastLogin().getTime()); + statement.setString(14, playerData.getLoginMessage()); + statement.setString(15, playerData.getUuid().toString()); - statement.setString(1, playerData.getUuid().toString()); - statement.setString(2, playerData.getUuid().toString()); - statement.setString(3, playerData.getUserName()); - statement.setString(4, playerData.getRank().name()); - statement.setLong(5, playerData.getPlaytime()); - statement.setInt(6, playerData.getCoins()); - statement.setLong(7, playerData.getLastLogin().getTime()); - statement.setString(8, playerData.getLoginMessage()); - statement.setString(9, playerData.getUserName()); - statement.setString(10, playerData.getRank().name()); - statement.setLong(11, playerData.getPlaytime()); - statement.setInt(12, playerData.getCoins()); - statement.setLong(13, playerData.getLastLogin().getTime()); - statement.setString(14, playerData.getLoginMessage()); - statement.setString(15, playerData.getUuid().toString()); - - statement.executeUpdate(); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not insert player data into users table!"); + } } - @SneakyThrows public void delete(@NotNull PlayerData playerData) { - PreparedStatement statement = getConnection().prepareStatement("DELETE FROM users WHERE uuid = ?;"); - statement.setString(1, playerData.getUuid().toString()); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("DELETE FROM users WHERE uuid = ?;")) { + statement.setString(1, playerData.getUuid().toString()); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not delete player data from users table!"); + } } - @SneakyThrows public void deleteAll() { - PreparedStatement statement = getConnection().prepareStatement("DELETE FROM users;"); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("DELETE FROM users;")) { + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not delete all player data from users table!"); + } } - @SneakyThrows public void setLastLogin(String uuid, long lastLogin) { - PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET last_login = ? WHERE uuid = ?;"); - statement.setLong(1, lastLogin); - statement.setString(2, uuid); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET last_login = ? WHERE uuid = ?;")) { + statement.setLong(1, lastLogin); + statement.setString(2, uuid); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not update last login for player " + uuid + "!"); + } } - @SneakyThrows public Date getLastLogin(String uuid) { - PreparedStatement statement = getConnection().prepareStatement("SELECT last_login FROM users WHERE uuid = ?;"); - statement.setString(1, uuid); - ResultSet resultSet = statement.executeQuery(); - long lastLogin = 0; + AtomicLong lastLogin = new AtomicLong(0L); - while (resultSet.next()) { - lastLogin = resultSet.getLong("last_login"); + try (PreparedStatement statement = getConnection().prepareStatement("SELECT last_login FROM users WHERE uuid = ?;")) { + statement.setString(1, uuid); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + lastLogin.set(resultSet.getLong("last_login")); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not get last login for player " + uuid + "!"); } - return new Date(lastLogin); + return new Date(lastLogin.get()); } - @SneakyThrows public void setCoins(String uuid, int coins) { - PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET coins = ? WHERE uuid = ?;"); - statement.setInt(1, coins); - statement.setString(2, uuid); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET coins = ? WHERE uuid = ?;")) { + statement.setInt(1, coins); + statement.setString(2, uuid); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not update coins for player " + uuid + "!"); + } } - @SneakyThrows public int getCoins(String uuid) { - PreparedStatement statement = getConnection().prepareStatement("SELECT coins FROM users WHERE uuid = ?;"); - statement.setString(1, uuid); - ResultSet resultSet = statement.executeQuery(); - int coins = 0; + AtomicInteger coins = new AtomicInteger(0); - while (resultSet.next()) { - coins = resultSet.getInt("coins"); + try (PreparedStatement statement = getConnection().prepareStatement("SELECT coins FROM users WHERE uuid = ?;")) { + statement.setString(1, uuid); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + coins.set(resultSet.getInt(COIN_LITERAL)); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not get coins for player " + uuid + "!"); } - return coins; + return coins.get(); } - @SneakyThrows public void setRank(String uuid, @NotNull Rank rank) { - PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET rank = ? WHERE uuid = ?;"); - statement.setString(1, rank.name()); - statement.setString(2, uuid); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET rank = ? WHERE uuid = ?;")) { + statement.setString(1, rank.name()); + statement.setString(2, uuid); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not update rank for player " + uuid + "!"); + } } - @SneakyThrows public Rank getRank(String uuid) { - PreparedStatement statement = getConnection().prepareStatement("SELECT rank FROM users WHERE uuid = ?;"); - statement.setString(1, uuid); - ResultSet resultSet = statement.executeQuery(); - Rank rank = Rank.NON_OP; + AtomicReference rank = new AtomicReference<>(Rank.NON_OP); - while (resultSet.next()) { - rank = Rank.valueOf(resultSet.getString("rank")); + try (PreparedStatement statement = getConnection().prepareStatement("SELECT rank FROM users WHERE uuid = ?;")) { + statement.setString(1, uuid); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + rank.set(Rank.valueOf(resultSet.getString("rank"))); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not get rank for player " + uuid + "!"); } - return rank; + return rank.get(); } - @SneakyThrows public void setLoginMessage(String uuid, String message) { - PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET login_message = ? WHERE uuid = ?;"); - statement.setString(1, message); - statement.setString(2, uuid); - statement.executeUpdate(); + try (PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET login_message = ? WHERE uuid = ?;")) { + statement.setString(1, message); + statement.setString(2, uuid); + statement.executeUpdate(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not update login message for player " + uuid + "!"); + } } - @SneakyThrows public Map getLoginMessages() { - PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users;"); - ResultSet resultSet = statement.executeQuery(); Map loginInfoMap = new HashMap<>(); - while (resultSet.next()) { - OfflinePlayer player = Bukkit.getPlayer(UUID.fromString(resultSet.getString("uuid"))); - LoginInfo loginInfo = new LoginInfo(); - loginInfoMap.put(player, loginInfo); + try (PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users;")) { + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + OfflinePlayer player = Bukkit.getPlayer(UUID.fromString(resultSet.getString("uuid"))); + LoginInfo loginInfo = new LoginInfo(); + loginInfo.setLoginMessage(Component.text(resultSet.getString(LOGIN_MESSAGE))); + loginInfoMap.put(player, loginInfo); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not get login messages!"); } + return loginInfoMap; } - @SneakyThrows public LoginInfo getLoginInfo(String uuid) { - PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users WHERE uuid = ?;"); - statement.setString(1, uuid); - ResultSet resultSet = statement.executeQuery(); LoginInfo loginInfo = new LoginInfo(); - while (resultSet.next()) { - Component c = Component.text(resultSet.getString("login_message")); - loginInfo.setLoginMessage(c); + try (PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users WHERE uuid = ?;")) { + statement.setString(1, uuid); + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + Component c = Component.text(resultSet.getString(LOGIN_MESSAGE)); + loginInfo.setLoginMessage(c); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not get login message for player " + uuid + "!"); } return loginInfo; } - @SneakyThrows public List all() { - PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users;"); - ResultSet resultSet = statement.executeQuery(); List dataList = new ArrayList<>(); - InfractionData data = InfractionData.getCachedInfractionData(Bukkit.getOfflinePlayer(UUID.fromString(resultSet.getString("uuid")))); - while (resultSet.next()) { - PlayerData playerData = new PlayerData(UUID.fromString(resultSet.getString("uuid")), - resultSet.getString("username"), - Rank.valueOf(resultSet.getString("rank")), - resultSet.getLong("play_time"), - resultSet.getInt("coins"), - new Date(resultSet.getLong("last_login")), - resultSet.getString("login_message"), - data); - dataList.add(playerData); + try (PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users;")) { + try (ResultSet resultSet = statement.executeQuery()) { + while (resultSet.next()) { + PlayerDataBuilder playerDataBuilder = new PlayerDataBuilder().setUuid(UUID.fromString(resultSet.getString("uuid"))).setUserName(resultSet.getString("username")).setRank(Rank.valueOf(resultSet.getString("rank"))).setPlaytime(resultSet.getLong("play_time")).setCoins(resultSet.getInt(COIN_LITERAL)).setLastLogin(new Date(resultSet.getLong("last_login"))).setLoginMessage(resultSet.getString(LOGIN_MESSAGE)).setInfractionData(InfractionData.getCachedInfractionData(Bukkit.getOfflinePlayer(UUID.fromString(resultSet.getString("uuid"))))).compile(); + PlayerData playerData = new PlayerData(playerDataBuilder); + dataList.add(playerData); + } + } + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not get all player data from users table!"); } + return dataList; } - @SneakyThrows public void close() { - getConnection().close(); + try { + getConnection().close(); + } catch (SQLException e) { + Bukkit.getLogger().severe("Could not close database connection!"); + } + } + + public Connection getConnection() { + return connection; } } diff --git a/src/main/java/mc/unraveled/reforged/storage/SQLConst.java b/src/main/java/mc/unraveled/reforged/storage/SQLConst.java index 36198eb..2498dab 100644 --- a/src/main/java/mc/unraveled/reforged/storage/SQLConst.java +++ b/src/main/java/mc/unraveled/reforged/storage/SQLConst.java @@ -15,7 +15,7 @@ public final class SQLConst { return "IF NOT EXISTS (SELECT * FROM " + v + ") "; } - public static String IF(String v, String u) { - return "IF NOT EXISTS (SELECT * FROM " + v + " WHERE " + u + " = ?) "; + public static String IF(String v, String u, String literal) { + return "IF NOT EXISTS (SELECT * FROM " + v + " WHERE " + u + " = " + literal + ") "; } } diff --git a/src/main/java/mc/unraveled/reforged/util/ComponentBuilder.java b/src/main/java/mc/unraveled/reforged/util/ComponentBuilder.java new file mode 100644 index 0000000..c36843d --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/util/ComponentBuilder.java @@ -0,0 +1,40 @@ +package mc.unraveled.reforged.util; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; + +public class ComponentBuilder { + private Component master = Component.empty(); + + public static ComponentBuilder begin() { + return new ComponentBuilder(); + } + + public ComponentBuilder append(String text) { + Component i = Component.text(text); + master = master.append(i); + return this; + } + + public ComponentBuilder append(String text, NamedTextColor color) { + Component i = Component.text(text, color); + master = master.append(i); + return this; + } + + public ComponentBuilder append(long value) { + Component i = Component.text(value); + master = master.append(i); + return this; + } + + public ComponentBuilder append(long value, NamedTextColor color) { + Component i = Component.text(value, color); + master = master.append(i); + return this; + } + + public Component build() { + return master; + } +} diff --git a/src/main/java/mc/unraveled/reforged/util/Context.java b/src/main/java/mc/unraveled/reforged/util/Context.java index 6eed82c..b7a91ea 100644 --- a/src/main/java/mc/unraveled/reforged/util/Context.java +++ b/src/main/java/mc/unraveled/reforged/util/Context.java @@ -1,10 +1,17 @@ package mc.unraveled.reforged.util; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor public class Context { - private S context; + private S state; + + public Context(S state) { + this.state = state; + } + + public S getState() { + return state; + } + + public void setState(S state) { + this.state = state; + } } diff --git a/src/main/java/mc/unraveled/reforged/util/Lock.java b/src/main/java/mc/unraveled/reforged/util/Lock.java new file mode 100644 index 0000000..7e6aaac --- /dev/null +++ b/src/main/java/mc/unraveled/reforged/util/Lock.java @@ -0,0 +1,30 @@ +package mc.unraveled.reforged.util; + +import org.bukkit.entity.Player; + +public class Lock { + private volatile boolean locked = false; + private final Player player; + + public Lock(Player player) { + this.player = player; + } + + public void lock() { + locked = true; + + while (locked) { + Thread.onSpinWait(); + player.openInventory(player.getInventory()); + player.closeInventory(); + } + } + + public void unlock() { + locked = false; + } + + public boolean isLocked() { + return locked; + } +} diff --git a/src/main/resources/db.properties b/src/main/resources/db.properties index 5ba6a08..49d9384 100644 --- a/src/main/resources/db.properties +++ b/src/main/resources/db.properties @@ -1,7 +1,7 @@ # The SQL driver to use. driver=jdbc # The type of database to use. -databaseType=postgresql +databaseType=mysql # The database host. host=localhost # The database port.