Fishnets and Baubles

This commit is contained in:
Paul Reilly 2023-03-17 22:11:00 -05:00
parent 8f84583e4e
commit 31b0a8a3fe
50 changed files with 1489 additions and 550 deletions

View File

@ -23,8 +23,6 @@ repositories {
} }
dependencies { 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 'org.apache.commons:commons-lang3:3.12.0'
implementation 'com.github.Milkbowl:VaultAPI:1.7.1' implementation 'com.github.Milkbowl:VaultAPI:1.7.1'
implementation 'com.google.code.gson:gson:2.8.7' implementation 'com.google.code.gson:gson:2.8.7'

View File

View File

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

View File

@ -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 ]

Binary file not shown.

View File

@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path: reactor-core-3.4.10.jar reactive-streams-1.0.3.jar

View File

@ -1,9 +0,0 @@
package mc.unraveled.reforged.api;
public interface Locker {
Object lock = new Object();
default Object lock() {
return lock;
}
}

View File

@ -1,13 +1,12 @@
package mc.unraveled.reforged.banning; package mc.unraveled.reforged.banning;
import lombok.Getter;
import mc.unraveled.reforged.api.Serializable; import mc.unraveled.reforged.api.Serializable;
import mc.unraveled.reforged.util.Pair; import mc.unraveled.reforged.util.Pair;
import mc.unraveled.reforged.util.Utilities; import mc.unraveled.reforged.util.Utilities;
import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
@Getter
public abstract class AbstractBan implements Serializable<AbstractBan> { public abstract class AbstractBan implements Serializable<AbstractBan> {
private final String uuid; private final String uuid;
private final String ip; private final String ip;
@ -38,6 +37,38 @@ public abstract class AbstractBan implements Serializable<AbstractBan> {
); );
} }
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<Pair<String, String>> getContentPairs() {
return contentPairs;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) { public void setActive(boolean active) {
this.active = active; this.active = active;
} }
@ -48,8 +79,7 @@ public abstract class AbstractBan implements Serializable<AbstractBan> {
} }
@Override @Override
public AbstractBan deserialize(String formatted) { public AbstractBan deserialize(@NotNull String formatted) {
char delimiter = ':';
char end = ';'; char end = ';';
char uuid = 'u'; char uuid = 'u';
char ip = 'i'; char ip = 'i';

View File

@ -1,46 +1,44 @@
package mc.unraveled.reforged.banning; package mc.unraveled.reforged.banning;
import lombok.Getter;
import lombok.SneakyThrows;
import mc.unraveled.reforged.api.Baker; import mc.unraveled.reforged.api.Baker;
import mc.unraveled.reforged.api.Locker;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import mc.unraveled.reforged.storage.DBBan; import mc.unraveled.reforged.storage.DBBan;
import mc.unraveled.reforged.storage.DBUser;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import java.sql.Date;
import java.time.Instant;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public final class BanManager implements Locker, Baker { public final class BanManager implements Baker {
@Getter
private final Traverse plugin; private final Traverse plugin;
private Set<AbstractBan> storedBans; // This should only be reassigned by the baker. private Set<AbstractBan> storedBans; // This should only be reassigned by the baker.
@Getter
private boolean baked = false; // This should only be reassigned by the baker. private boolean baked = false; // This should only be reassigned by the baker.
@SneakyThrows
public BanManager(Traverse plugin) { public BanManager(Traverse plugin) {
this.storedBans = new HashSet<>(); this.storedBans = new HashSet<>();
this.plugin = plugin; this.plugin = plugin;
synchronized (lock()) { DBBan banHandler = new DBBan(plugin.getSQLManager().establish());
DBBan banHandler = new DBBan(plugin.getSQLManager().establish()); storedBans.addAll(banHandler.all());
storedBans.addAll(banHandler.all()); banHandler.close();
banHandler.close();
lock().wait(1000);
}
bake(); bake();
} }
public Traverse getPlugin() {
return plugin;
}
public boolean isBaked() {
return baked;
}
public void insert(AbstractBan ban) { public void insert(AbstractBan ban) {
if (baked) throw new IllegalStateException("Cannot insert into a baked list."); if (baked) throw new IllegalStateException("Cannot insert into a baked list.");
lock().notify();
storedBans.add(ban); storedBans.add(ban);
DBBan db = new DBBan(plugin.getSQLManager().establish()); DBBan db = new DBBan(plugin.getSQLManager().establish());
db.insert(ban); db.insert(ban);
@ -50,8 +48,7 @@ public final class BanManager implements Locker, Baker {
public void eject(AbstractBan ban) { public void eject(AbstractBan ban) {
if (baked) throw new IllegalStateException("Cannot eject from a baked list."); if (baked) throw new IllegalStateException("Cannot eject from a baked list.");
lock().notify(); storedBans.remove(ban);
DBBan db = new DBBan(plugin.getSQLManager().establish()); DBBan db = new DBBan(plugin.getSQLManager().establish());
db.delete(ban); db.delete(ban);
db.close(); db.close();
@ -66,13 +63,22 @@ public final class BanManager implements Locker, Baker {
public boolean isBanned(OfflinePlayer player) { public boolean isBanned(OfflinePlayer player) {
return storedBans.stream() 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( .anyMatch(ban -> ban.getUuid().equalsIgnoreCase(
player.getUniqueId().toString())); player.getUniqueId().toString()));
} }
public void save() { public void save() {
if (!baked) throw new IllegalStateException("Cannot save an unbaked list."); if (!baked) throw new IllegalStateException("Cannot save an unbaked list.");
lock().notify();
DBBan banHandler = new DBBan(plugin.getSQLManager().establish()); DBBan banHandler = new DBBan(plugin.getSQLManager().establish());
storedBans.forEach(banHandler::insert); storedBans.forEach(banHandler::insert);
@ -83,7 +89,6 @@ public final class BanManager implements Locker, Baker {
public void bake() { public void bake() {
if (baked) return; if (baked) return;
lock().notify();
storedBans = storedBans.stream().collect(Collectors.toUnmodifiableSet()); storedBans = storedBans.stream().collect(Collectors.toUnmodifiableSet());
baked = true; baked = true;
@ -93,7 +98,6 @@ public final class BanManager implements Locker, Baker {
public void unbake() { public void unbake() {
if (!baked) return; if (!baked) return;
lock().notify();
storedBans = new HashSet<>(storedBans); storedBans = new HashSet<>(storedBans);
baked = false; baked = false;

View File

@ -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 <player>",
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 <player>");
}
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<String> tab(CommandSender sender, String[] args) {
return Utilities.playerCompletions(args[0]);
}
}

View File

@ -44,7 +44,7 @@ public class GroupCMD extends AbstractCommandBase {
Arrays.stream(ranks) Arrays.stream(ranks)
.filter(rank -> rank.getAttachment().getName().equalsIgnoreCase(group)) .filter(rank -> rank.getAttachment().getName().equalsIgnoreCase(group))
.findFirst() .findFirst()
.ifPresentOrElse(rankContext::setContext, () -> invalid.set(true)); .ifPresentOrElse(rankContext::setState, () -> invalid.set(true));
if (invalid.get()) return Component.text("Invalid group!").color(NamedTextColor.RED); if (invalid.get()) return Component.text("Invalid group!").color(NamedTextColor.RED);
@ -79,24 +79,24 @@ public class GroupCMD extends AbstractCommandBase {
} }
if (actionType) { if (actionType) {
manager.insertPlayer(rankContext.getContext(), player); manager.insertPlayer(rankContext.getState(), player);
manager.bake(); manager.bake();
manager.save(); manager.save();
return Component.text("Added player " + player.getName() + " to group " + group + "!").color(NamedTextColor.GREEN); return Component.text("Added player " + player.getName() + " to group " + group + "!").color(NamedTextColor.GREEN);
} else { } else {
manager.ejectPlayer(rankContext.getContext(), player); manager.ejectPlayer(rankContext.getState(), player);
manager.bake(); manager.bake();
manager.save(); manager.save();
return Component.text("Removed player " + player.getName() + " from group " + group + "!").color(NamedTextColor.GREEN); return Component.text("Removed player " + player.getName() + " from group " + group + "!").color(NamedTextColor.GREEN);
} }
case "permission": case "permission":
if (actionType) { if (actionType) {
manager.insertPermission(rankContext.getContext(), value); manager.insertPermission(rankContext.getState(), value);
manager.bake(); manager.bake();
manager.save(); manager.save();
return Component.text("Added permission " + value + " to group " + group + "!").color(NamedTextColor.GREEN); return Component.text("Added permission " + value + " to group " + group + "!").color(NamedTextColor.GREEN);
} else { } else {
manager.ejectPermission(rankContext.getContext(), value); manager.ejectPermission(rankContext.getState(), value);
manager.bake(); manager.bake();
manager.save(); manager.save();
return Component.text("Removed permission " + value + " from group " + group + "!").color(NamedTextColor.GREEN); return Component.text("Removed permission " + value + " from group " + group + "!").color(NamedTextColor.GREEN);

View File

@ -1,4 +0,0 @@
package mc.unraveled.reforged.command;
public class JailCMD {
}

View File

@ -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 <player> <reason>",
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> <reason>");
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<String> tab(CommandSender sender, String[] args) {
if (args.length == 1) return Utilities.playerCompletions(args[0]);
return super.tab(sender, args);
}
}

View File

@ -1,4 +1,72 @@
package mc.unraveled.reforged.command; 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 = "/<command> <player> <on | off>",
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> <on | off>");
}
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 <player> <on | off>");
}
}
}
@Override
public List<String> 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);
}
} }

View File

@ -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.api.annotations.CommandInfo;
import mc.unraveled.reforged.command.base.AbstractCommandBase;
import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.data.InfractionData;
import mc.unraveled.reforged.data.PlayerData; import mc.unraveled.reforged.data.PlayerData;
import mc.unraveled.reforged.permission.Rank; import mc.unraveled.reforged.permission.Rank;
@ -24,7 +25,7 @@ public class PlayerDataCMD extends AbstractCommandBase {
@Override @Override
public Component cmd(CommandSender sender, String[] args) { public Component cmd(CommandSender sender, String[] args) {
switch (args.length) { switch (args.length) {
case 0: case 0 -> {
if (sender instanceof Player player) { if (sender instanceof Player player) {
PlayerData data = getPlugin().getDataManager().getPlayerData(player.getUniqueId()); PlayerData data = getPlugin().getDataManager().getPlayerData(player.getUniqueId());
@ -46,8 +47,8 @@ public class PlayerDataCMD extends AbstractCommandBase {
return Component.text(sb); return Component.text(sb);
} else return Component.text("This command can only be used by players!"); } else return Component.text("This command can only be used by players!");
}
case 2: case 2 -> {
if (args[1].equalsIgnoreCase("info")) { if (args[1].equalsIgnoreCase("info")) {
Player target = getPlugin().getServer().getPlayer(args[0]); Player target = getPlugin().getServer().getPlayer(args[0]);
if (target == null) return MessageDefaults.MSG_NOT_FOUND; if (target == null) return MessageDefaults.MSG_NOT_FOUND;
@ -73,7 +74,8 @@ public class PlayerDataCMD extends AbstractCommandBase {
} else { } else {
return usage(); return usage();
} }
case 3: }
case 3 -> {
if (args[1].equalsIgnoreCase("reset")) { if (args[1].equalsIgnoreCase("reset")) {
Player target = getPlugin().getServer().getPlayer(args[0]); Player target = getPlugin().getServer().getPlayer(args[0]);
if (target == null) return MessageDefaults.MSG_NOT_FOUND; 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); return Component.text("Invalid data type!").color(NamedTextColor.RED);
} }
} }
case 4: }
case 4 -> {
Player target = getPlugin().getServer().getPlayer(args[0]); Player target = getPlugin().getServer().getPlayer(args[0]);
if (target == null) return MessageDefaults.MSG_NOT_FOUND; if (target == null) return MessageDefaults.MSG_NOT_FOUND;
if (args[1].equalsIgnoreCase("set")) { if (args[1].equalsIgnoreCase("set")) {
switch (args[2]) { switch (args[2]) {
case "rank": case "rank":
@ -183,9 +185,12 @@ public class PlayerDataCMD extends AbstractCommandBase {
} else { } else {
return usage(); return usage();
} }
default: }
default -> {
return usage(); return usage();
}
} }
return null;
} }
private Component usage() { private Component usage() {

View File

@ -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<String> tab(CommandSender sender, String[] args) {
return super.tab(sender, args);
}
}

View File

@ -1,6 +1,5 @@
package mc.unraveled.reforged.command.base; package mc.unraveled.reforged.command.base;
import lombok.Getter;
import mc.unraveled.reforged.api.ICommandBase; import mc.unraveled.reforged.api.ICommandBase;
import mc.unraveled.reforged.permission.TPermission; import mc.unraveled.reforged.permission.TPermission;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
@ -12,7 +11,6 @@ import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -20,7 +18,6 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
public abstract class AbstractCommandBase extends TPermission implements ICommandBase { public abstract class AbstractCommandBase extends TPermission implements ICommandBase {
@Getter
private final Traverse plugin; 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 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. * @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); super(permission, permissionMessage, allowConsole);
this.plugin = plugin; 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 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. * @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); 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 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. * @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) { protected AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission, boolean allowConsole) {
this(plugin, permission, "You do not have permission to use this command!", allowConsole); this(plugin, permission, MessageDefaults.MSG_NO_PERMS.toString(), allowConsole);
} }
/** /**
* @param plugin The plugin that owns this command * @param plugin The plugin that owns this command
* @param permission The permission the user should have to run the command * @param permission The permission the user should have to run the command
*/ */
public AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission) { protected AbstractCommandBase(@NotNull Traverse plugin, @NotNull String permission) {
this(plugin, permission, "You do not have permission to use this command!", true); this(plugin, permission, MessageDefaults.MSG_NO_PERMS.toString(), true);
} }
@Override @Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String lbl, String[] args) { public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String lbl, String[] args) {
if (lbl.equalsIgnoreCase("")) {
return false;
}
if (!hasPermission(sender)) { if (!hasPermission(sender)) {
sender.sendMessage(MessageDefaults.MSG_NO_PERMS); sender.sendMessage(MessageDefaults.MSG_NO_PERMS);
return true; return true;
@ -132,12 +133,8 @@ public abstract class AbstractCommandBase extends TPermission implements IComman
Bukkit.getServer().broadcast(msg(text, color)); Bukkit.getServer().broadcast(msg(text, color));
} }
public void enablePlugin(Plugin plugin) { public Traverse getPlugin() {
Bukkit.getServer().getPluginManager().enablePlugin(plugin); return plugin;
}
public void disablePlugin(Plugin plugin) {
Bukkit.getServer().getPluginManager().disablePlugin(plugin);
} }
protected static class MessageDefaults { 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 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 MUTED = Component.text("You are muted!").color(NamedTextColor.RED);
public static final Component BANNED = Component.text("You are banned!").color(NamedTextColor.RED); public static final Component BANNED = Component.text("You are banned!").color(NamedTextColor.RED);
private MessageDefaults() {
throw new AssertionError();
}
} }
} }

View File

@ -1,22 +1,20 @@
package mc.unraveled.reforged.config; package mc.unraveled.reforged.config;
import lombok.Getter;
import lombok.SneakyThrows;
import mc.unraveled.reforged.api.Baker; import mc.unraveled.reforged.api.Baker;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
import java.io.IOException;
@Getter
public abstract class Yaml extends YamlConfiguration implements Baker { public abstract class Yaml extends YamlConfiguration implements Baker {
private final String fileName; private final String fileName;
private final File dataFolder; private final File dataFolder;
private final Traverse plugin; private final Traverse plugin;
private final File yamlFile; private final File yamlFile;
@Getter
private boolean baked = false; private boolean baked = false;
Yaml(@NotNull Traverse plugin, String fileName, File dataFolder, boolean copyDefaults) { 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); 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. * Makes the file read only after saving to disk.
*/ */
@SneakyThrows
@Override @Override
public void bake() { public void bake() {
if (baked) return; if (baked) return;
super.save(yamlFile); try {
super.save(yamlFile);
} catch (IOException e) {
Bukkit.getLogger().severe(e.getMessage());
}
if (yamlFile.setWritable(false)) { if (yamlFile.setWritable(false)) {
getPlugin().getLogger().info("Baked " + getFileName()); getPlugin().getLogger().info("Baked " + getFileName());
@ -73,17 +94,23 @@ public abstract class Yaml extends YamlConfiguration implements Baker {
} }
} }
@SneakyThrows
public void saveToFile() { public void saveToFile() {
unbake(); unbake();
super.save(yamlFile); try {
super.save(yamlFile);
} catch (IOException e) {
Bukkit.getLogger().severe(e.getMessage());
}
bake(); bake();
} }
@SneakyThrows
public void loadFromFile() { public void loadFromFile() {
unbake(); unbake();
super.load(yamlFile); try {
super.load(yamlFile);
} catch (IOException | InvalidConfigurationException e) {
Bukkit.getLogger().severe(e.getMessage());
}
bake(); bake();
} }
} }

View File

@ -1,8 +1,7 @@
package mc.unraveled.reforged.config; package mc.unraveled.reforged.config;
import lombok.Getter;
import lombok.SneakyThrows;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -11,7 +10,6 @@ import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@Getter
public class YamlManager { public class YamlManager {
private final List<Yaml> configurations = new ArrayList<>(); private final List<Yaml> configurations = new ArrayList<>();
private final Traverse plugin; private final Traverse plugin;
@ -20,6 +18,14 @@ public class YamlManager {
this.plugin = plugin; this.plugin = plugin;
} }
public List<Yaml> getConfigurations() {
return configurations;
}
public Traverse getPlugin() {
return plugin;
}
public Builder bldr() { public Builder bldr() {
return new Builder(plugin); return new Builder(plugin);
} }
@ -32,14 +38,20 @@ public class YamlManager {
configurations.remove(yaml); configurations.remove(yaml);
} }
@SneakyThrows
public void load(@NotNull Yaml yaml) { 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) { 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() { public void loadAll() {

View File

@ -1,11 +1,8 @@
package mc.unraveled.reforged.data; package mc.unraveled.reforged.data;
import lombok.SneakyThrows;
import mc.unraveled.reforged.api.Baker; import mc.unraveled.reforged.api.Baker;
import mc.unraveled.reforged.api.Locker;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import mc.unraveled.reforged.storage.DBUser; import mc.unraveled.reforged.storage.DBUser;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.HashSet; import java.util.HashSet;
@ -13,7 +10,8 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; 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 final Traverse plugin;
private Set<PlayerData> playerDataCache = new HashSet<>(); // Should only be set by the baker. private Set<PlayerData> playerDataCache = new HashSet<>(); // Should only be set by the baker.
private boolean baked = false; // 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) { 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); playerDataCache.remove(data);
} }
public void removePlayerData(UUID uuid) { 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)); playerDataCache.removeIf(data -> data.getUuid().equals(uuid));
} }
public void removePlayerData(String playerName) { 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)); playerDataCache.removeIf(data -> data.getUserName().equals(playerName));
} }
@ -86,31 +84,21 @@ public final class DataManager implements Baker, Locker {
user.close(); user.close();
} }
@SneakyThrows
@Override @Override
public void bake() { public void bake() {
if (baked) return; if (baked) return;
synchronized (lock()) { this.playerDataCache = playerDataCache.stream().collect(Collectors.toUnmodifiableSet());
this.playerDataCache = playerDataCache.stream().collect(Collectors.toUnmodifiableSet());
lock().wait(1000);
}
this.baked = true; this.baked = true;
lock().notify();
} }
@SneakyThrows
@Override @Override
public void unbake() { public void unbake() {
if (!baked) return; if (!baked) return;
synchronized (lock()) { this.playerDataCache = new HashSet<>(playerDataCache);
this.playerDataCache = new HashSet<>(playerDataCache);
lock().wait(1000);
}
this.baked = false; this.baked = false;
lock().notify();
} }
} }

View File

@ -1,7 +1,5 @@
package mc.unraveled.reforged.data; package mc.unraveled.reforged.data;
import lombok.Getter;
import lombok.Setter;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import mc.unraveled.reforged.storage.DBInfraction; import mc.unraveled.reforged.storage.DBInfraction;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -12,29 +10,13 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class InfractionData { public class InfractionData {
private static final Map<OfflinePlayer, InfractionData> playerInfractionDataMap = new HashMap<>() {{ private static final Map<OfflinePlayer, InfractionData> playerInfractionDataMap = new HashMap<>();
DBInfraction infraction = new DBInfraction(JavaPlugin.getPlugin(Traverse.class).getSQLManager().establish());
for (InfractionData data : infraction.getInfractionsList()) {
put(data.getPlayer(), data);
}
}};
@Getter
private final OfflinePlayer player; private final OfflinePlayer player;
@Getter
private int infractions = 0; private int infractions = 0;
@Getter
@Setter
private boolean muted = false; private boolean muted = false;
@Getter
@Setter
private boolean frozen = false; private boolean frozen = false;
@Getter
@Setter
private boolean locked = false; private boolean locked = false;
@Getter
@Setter
private boolean jailed = false; private boolean jailed = false;
public InfractionData(OfflinePlayer player) { public InfractionData(OfflinePlayer player) {
@ -48,6 +30,11 @@ public class InfractionData {
this.frozen = frozen; this.frozen = frozen;
this.locked = locked; this.locked = locked;
this.jailed = jailed; 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) { public static InfractionData getCachedInfractionData(OfflinePlayer player) {
@ -61,6 +48,50 @@ public class InfractionData {
return data; 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() { public void increment() {
infractions++; infractions++;
} }

View File

@ -1,14 +1,22 @@
package mc.unraveled.reforged.data; package mc.unraveled.reforged.data;
import lombok.Data;
import lombok.NoArgsConstructor;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
/** /**
* Login Message Information Bean * Login Message Information Bean
*/ */
@Data
@NoArgsConstructor
public class LoginInfo { public class LoginInfo {
private Component loginMessage; private Component loginMessage;
public LoginInfo() {
this.loginMessage = Component.empty();
}
public Component getLoginMessage() {
return loginMessage;
}
public void setLoginMessage(Component loginMessage) {
this.loginMessage = loginMessage;
}
} }

View File

@ -1,30 +1,27 @@
package mc.unraveled.reforged.data; package mc.unraveled.reforged.data;
import lombok.Getter;
import mc.unraveled.reforged.api.Baker; import mc.unraveled.reforged.api.Baker;
import mc.unraveled.reforged.listening.AbstractListener; import mc.unraveled.reforged.listening.AbstractListener;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import mc.unraveled.reforged.storage.DBUser; import mc.unraveled.reforged.storage.DBUser;
import mc.unraveled.reforged.util.Pair; import mc.unraveled.reforged.util.Pair;
import net.kyori.adventure.text.Component;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Getter
public class LoginManager implements Baker { public class LoginManager implements Baker {
private final Traverse plugin; private final Traverse plugin;
private Set<Pair<OfflinePlayer, LoginInfo>> dataSet = new HashSet<>(); // VALUE ONLY MODIFIED BY BAKER private Set<Pair<OfflinePlayer, LoginInfo>> dataSet = new HashSet<>(); // VALUE ONLY MODIFIED BY BAKER
private boolean baked = false; private boolean baked = false;
public LoginManager(Traverse plugin) { public LoginManager(@NotNull Traverse plugin) {
this.plugin = plugin; this.plugin = plugin;
DBUser user = new DBUser(plugin.getSQLManager().establish()); DBUser user = new DBUser(plugin.getSQLManager().establish());
@ -36,6 +33,18 @@ public class LoginManager implements Baker {
new LoginListener(plugin); new LoginListener(plugin);
} }
public Traverse getPlugin() {
return plugin;
}
public Set<Pair<OfflinePlayer, LoginInfo>> getDataSet() {
return dataSet;
}
public boolean isBaked() {
return baked;
}
public void add(OfflinePlayer player, LoginInfo data) { public void add(OfflinePlayer player, LoginInfo data) {
dataSet.add(new Pair<>(player, data)); dataSet.add(new Pair<>(player, data));
} }

View File

@ -1,14 +1,10 @@
package mc.unraveled.reforged.data; package mc.unraveled.reforged.data;
import lombok.AllArgsConstructor;
import lombok.Data;
import mc.unraveled.reforged.permission.Rank; import mc.unraveled.reforged.permission.Rank;
import java.util.Date; import java.util.Date;
import java.util.UUID; import java.util.UUID;
@Data
@AllArgsConstructor
public class PlayerData { public class PlayerData {
private UUID uuid; private UUID uuid;
private String userName; private String userName;
@ -18,4 +14,79 @@ public class PlayerData {
private Date lastLogin; private Date lastLogin;
private String loginMessage; private String loginMessage;
private InfractionData infractionData; 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;
}
} }

View File

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

View File

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

View File

@ -1,6 +1,5 @@
package mc.unraveled.reforged.economy; package mc.unraveled.reforged.economy;
import lombok.Getter;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.economy.EconomyResponse; import net.milkbowl.vault.economy.EconomyResponse;
@ -9,20 +8,16 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
@Getter
public class EconomyManager { public class EconomyManager {
private final RegisteredServiceProvider<Economy> rsp; private final RegisteredServiceProvider<Economy> rsp;
private final Map<Player, List<EconomyRequest>> requests = new HashMap<>(); // This is NOT persistent. private final Map<UUID, List<EconomyRequest>> requests = new HashMap<>(); // This is NOT persistent.
private final Economy economy; private final Economy economy;
public EconomyManager(@NotNull Traverse plugin) { public EconomyManager(@NotNull Traverse plugin) {
if (plugin.getServer().getPluginManager().getPlugin("Vault") == null) 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); rsp = plugin.getServer().getServicesManager().getRegistration(Economy.class);
@ -31,6 +26,18 @@ public class EconomyManager {
economy = rsp.getProvider(); economy = rsp.getProvider();
} }
public RegisteredServiceProvider<Economy> getRsp() {
return rsp;
}
public Map<UUID, List<EconomyRequest>> getRequests() {
return requests;
}
public Economy getEconomy() {
return economy;
}
public EconomyResponse newAccount(OfflinePlayer player) { public EconomyResponse newAccount(OfflinePlayer player) {
return economy.createBank(player.getName(), 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) { public EconomyRequest request(@NotNull OfflinePlayer from, @NotNull OfflinePlayer to, int amount) {
EconomyRequest request = new EconomyRequest(this, (Player) from, (Player) to, amount); EconomyRequest request = new EconomyRequest(this, (Player) from, (Player) to, amount);
if (requests.containsKey(to)) { if (requests.containsKey(to.getUniqueId())) {
requests.get(to).add(request); requests.get(to.getUniqueId()).add(request);
} else { } else {
requests.put((Player) to, List.of(request)); requests.put(to.getUniqueId(), List.of(request));
} }
return request; return request;

View File

@ -1,18 +1,13 @@
package mc.unraveled.reforged.economy; package mc.unraveled.reforged.economy;
import lombok.Getter;
import lombok.Setter;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.economy.EconomyResponse; import net.milkbowl.vault.economy.EconomyResponse;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class EconomyRequest { public class EconomyRequest {
@Getter
private final Player sender; private final Player sender;
@Getter
private final Player target; private final Player target;
@Getter
private final int amount; private final int amount;
private final EconomyManager economy; private final EconomyManager economy;
@ -23,6 +18,18 @@ public class EconomyRequest {
this.economy = economy; this.economy = economy;
} }
public Player getSender() {
return sender;
}
public Player getTarget() {
return target;
}
public int getAmount() {
return amount;
}
public EconomyResponse accept() { public EconomyResponse accept() {
EconomyResponse r = economy.withdraw(target, amount); EconomyResponse r = economy.withdraw(target, amount);
if (r.transactionSuccess()) { if (r.transactionSuccess()) {
@ -34,7 +41,7 @@ public class EconomyRequest {
sender.sendMessage(Component.text("Your request has been accepted.")); sender.sendMessage(Component.text("Your request has been accepted."));
target.sendMessage(Component.text("You have accepted " + sender.getName() + "'s request.")); 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; return r;
} }
@ -43,6 +50,6 @@ public class EconomyRequest {
sender.sendMessage(Component.text("Your request has been denied.")); sender.sendMessage(Component.text("Your request has been denied."));
target.sendMessage(Component.text("You have denied " + sender.getName() + "'s request.")); target.sendMessage(Component.text("You have denied " + sender.getName() + "'s request."));
economy.getRequests().get(target).remove(this); economy.getRequests().get(target.getUniqueId()).remove(this);
} }
} }

View File

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

View File

@ -1,10 +1,16 @@
package mc.unraveled.reforged.listening; package mc.unraveled.reforged.listening;
import lombok.Data;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@Data
public class AbstractListener implements Listener { public class AbstractListener implements Listener {
private final Traverse plugin; private final Traverse plugin;
public AbstractListener(Traverse plugin) {
this.plugin = plugin;
}
public Traverse getPlugin() {
return plugin;
}
} }

View File

@ -2,6 +2,7 @@ package mc.unraveled.reforged.listening;
import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.data.InfractionData;
import mc.unraveled.reforged.data.PlayerData; import mc.unraveled.reforged.data.PlayerData;
import mc.unraveled.reforged.data.PlayerDataBuilder;
import mc.unraveled.reforged.permission.Rank; import mc.unraveled.reforged.permission.Rank;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -22,14 +23,17 @@ public class PlayerDataListener extends AbstractListener {
PlayerData data = getPlugin().getDataManager().getPlayerData(player.getUniqueId()); PlayerData data = getPlugin().getDataManager().getPlayerData(player.getUniqueId());
if (data == null) { if (data == null) {
data = new PlayerData(player.getUniqueId(), PlayerDataBuilder builder = new PlayerDataBuilder()
player.getName(), .setUuid(player.getUniqueId())
Rank.NON_OP, .setUserName(player.getName())
0L, .setRank(Rank.NON_OP)
0, .setPlaytime(0L)
Date.from(Instant.now()), .setCoins(0)
null, .setLastLogin(Date.from(Instant.now()))
InfractionData.getCachedInfractionData(player)); .setLoginMessage(null)
.setInfractionData(InfractionData.getCachedInfractionData(player))
.compile();
data = new PlayerData(builder);
getPlugin().getDataManager().addPlayerData(data); getPlugin().getDataManager().addPlayerData(data);
} }

View File

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

View File

@ -1,16 +1,15 @@
package mc.unraveled.reforged.permission; package mc.unraveled.reforged.permission;
import lombok.Data;
import mc.unraveled.reforged.api.Baker; import mc.unraveled.reforged.api.Baker;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Data
public class Group implements Baker { public class Group implements Baker {
public static final String BAKED_GROUP = "Cannot modify a baked group.";
private final Rank rank; private final Rank rank;
private Set<String> permissions = new HashSet<>(); private Set<String> permissions = new HashSet<>();
private Set<OfflinePlayer> players = new HashSet<>(); private Set<OfflinePlayer> players = new HashSet<>();
@ -20,23 +19,43 @@ public class Group implements Baker {
this.rank = rank; this.rank = rank;
} }
public Rank getRank() {
return rank;
}
public Set<String> getPermissions() {
return permissions;
}
public Set<OfflinePlayer> getPlayers() {
return players;
}
public boolean isBaked() {
return baked;
}
public void setBaked(boolean baked) {
this.baked = baked;
}
public void insert(String permission) { 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); permissions.add(permission);
} }
public void insert(OfflinePlayer player) { 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); players.add(player);
} }
public void eject(String permission) { 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); permissions.remove(permission);
} }
public void eject(OfflinePlayer player) { 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); players.remove(player);
} }

View File

@ -4,6 +4,7 @@ import mc.unraveled.reforged.util.BasicColors;
import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextColor;
public enum Rank { public enum Rank {
CONSOLE("console", "RCON", BasicColors.PURPLE.getColor(), 8),
EXECUTIVE("executive", "Exec", BasicColors.DARK_RED.getColor(), 7), EXECUTIVE("executive", "Exec", BasicColors.DARK_RED.getColor(), 7),
DEV("developer", "Dev", BasicColors.PURPLE.getColor(), 6), DEV("developer", "Dev", BasicColors.PURPLE.getColor(), 6),
ADMIN("admin", "Admin", BasicColors.GOLD.getColor(), 5), ADMIN("admin", "Admin", BasicColors.GOLD.getColor(), 5),

View File

@ -1,38 +1,38 @@
package mc.unraveled.reforged.permission; package mc.unraveled.reforged.permission;
import lombok.Getter;
import mc.unraveled.reforged.api.Baker; import mc.unraveled.reforged.api.Baker;
import mc.unraveled.reforged.api.Locker;
import mc.unraveled.reforged.plugin.Traverse; import mc.unraveled.reforged.plugin.Traverse;
import mc.unraveled.reforged.storage.DBGroup; import mc.unraveled.reforged.storage.DBGroup;
import mc.unraveled.reforged.util.Tuple; import mc.unraveled.reforged.util.Tuple;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; 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 final Traverse plugin;
private List<Tuple<Rank, List<OfflinePlayer>, List<String>>> rankQueue = new ArrayList<>(); private final List<Tuple<Rank, List<UUID>, List<String>>> rankQueue = new ArrayList<>();
private List<Group> bakedGroups = new ArrayList<>(); private final List<Group> bakedGroups = new ArrayList<>();
private boolean baked = false; private boolean baked = false;
public RankManager(@NotNull Traverse plugin) { public RankManager(@NotNull Traverse plugin) {
this.plugin = plugin; this.plugin = plugin;
lock().notify();
DBGroup groupHandler = new DBGroup(plugin.getSQLManager().establish()); DBGroup groupHandler = new DBGroup(plugin.getSQLManager().establish());
Arrays.stream(Rank.values()).forEach(groupHandler::createTable); Arrays.stream(Rank.values()).forEach(groupHandler::createTable);
Rank[] ranks = Rank.values(); Rank[] ranks = Rank.values();
for (Rank rank : ranks) { for (Rank rank : ranks) {
Tuple<Rank, List<OfflinePlayer>, List<String>> rankTuple; Tuple<Rank, List<UUID>, List<String>> rankTuple;
List<OfflinePlayer> playerList; List<UUID> playerList;
List<String> permissionList; List<String> permissionList;
playerList = groupHandler.getPlayers(rank); playerList = groupHandler.getPlayers(rank);
@ -46,12 +46,28 @@ public class RankManager implements Baker, Locker {
bake(); bake();
} }
public void insert(Rank rank, List<OfflinePlayer> player, List<String> args) { public Traverse getPlugin() {
rankQueue.add(new Tuple<>(rank, player, args)); return plugin;
} }
public void eject(Rank rank, List<OfflinePlayer> player, List<String> args) { public void insert(Rank rank, List<UUID> playerList, List<String> args) {
rankQueue.remove(new Tuple<>(rank, player, args)); rankQueue.add(new Tuple<>(rank, playerList, args));
}
public void eject(Rank rank, List<UUID> playerList, List<String> 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) { public void insertPermission(Rank rank, String permission) {
@ -69,13 +85,13 @@ public class RankManager implements Baker, Locker {
public void insertPlayer(Rank rank, OfflinePlayer player) { public void insertPlayer(Rank rank, OfflinePlayer player) {
rankQueue.stream() rankQueue.stream()
.filter(tuple -> tuple.getFirst().equals(rank)) .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) { public void ejectPlayer(Rank rank, OfflinePlayer player) {
rankQueue.stream() rankQueue.stream()
.filter(tuple -> tuple.getFirst().equals(rank)) .filter(tuple -> tuple.getFirst().equals(rank))
.forEach(tuple -> tuple.getSecond().remove(player)); .forEach(tuple -> tuple.getSecond().remove(player.getUniqueId()));
} }
public void save() { public void save() {
@ -98,36 +114,30 @@ public class RankManager implements Baker, Locker {
public void bake() { public void bake() {
if (baked) return; if (baked) return;
synchronized (lock()) { rankQueue.forEach(tuple -> {
rankQueue.forEach(tuple -> { Rank rank = tuple.getFirst();
Rank rank = tuple.getFirst(); List<UUID> players = tuple.getSecond();
List<OfflinePlayer> players = tuple.getSecond(); List<String> permissions = tuple.getThird();
List<String> permissions = tuple.getThird();
Group group = new Group(rank); Group group = new Group(rank);
for (OfflinePlayer p : players) { for (UUID p : players) {
group.insert(p); group.insert(Bukkit.getOfflinePlayer(p));
} }
for (String arg : permissions) { for (String arg : permissions) {
group.insert(arg); group.insert(arg);
} }
bakedGroups.add(group); bakedGroups.add(group);
}); });
}
baked = true; baked = true;
lock().notify();
} }
@Override @Override
public void unbake() { public void unbake() {
if (!baked) return; if (!baked) return;
synchronized (lock()) { bakedGroups.clear();
bakedGroups.clear();
}
baked = false; baked = false;
lock().notify();
} }
} }

View File

@ -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 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. * @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.permission = "traverse." + permission;
this.permissionMessage = permissionMessage; this.permissionMessage = permissionMessage;
this.allowConsole = allowConsole; this.allowConsole = allowConsole;

View File

@ -1,8 +1,5 @@
package mc.unraveled.reforged.plugin; 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.banning.BanManager;
import mc.unraveled.reforged.command.*; import mc.unraveled.reforged.command.*;
import mc.unraveled.reforged.command.base.CommandLoader; 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.config.YamlManager;
import mc.unraveled.reforged.data.DataManager; import mc.unraveled.reforged.data.DataManager;
import mc.unraveled.reforged.data.LoginManager; import mc.unraveled.reforged.data.LoginManager;
import mc.unraveled.reforged.data.StaffChat;
import mc.unraveled.reforged.economy.EconomyManager; import mc.unraveled.reforged.economy.EconomyManager;
import mc.unraveled.reforged.listening.InfractionListener; 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.permission.RankManager;
import mc.unraveled.reforged.service.base.Scheduling; import mc.unraveled.reforged.service.base.Scheduling;
import mc.unraveled.reforged.service.base.ServicePool; import mc.unraveled.reforged.service.base.ServicePool;
import mc.unraveled.reforged.storage.DBConnectionHandler; import mc.unraveled.reforged.storage.DBConnectionHandler;
import mc.unraveled.reforged.storage.DBProperties; import mc.unraveled.reforged.storage.DBProperties;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; 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. // Secondary variable declaration.
private final String CONFIG_FILE = "config.yml"; private final String CONFIG_FILE = "config.yml";
private final File CONFIG = new File(getDataFolder(), CONFIG_FILE); private final File CONFIG = new File(getDataFolder(), CONFIG_FILE);
// Primary variable declaration. // Primary variable declaration.
@Getter
private DBConnectionHandler SQLManager; private DBConnectionHandler SQLManager;
@Getter
private DataManager dataManager; private DataManager dataManager;
@Getter
private CommandLoader commandLoader; private CommandLoader commandLoader;
@Getter
private BanManager banManager; private BanManager banManager;
@Getter
private RankManager rankManager; private RankManager rankManager;
@Getter
private Scheduling scheduler; private Scheduling scheduler;
@Getter
private ServicePool PIPELINE; private ServicePool PIPELINE;
@Getter
private EconomyManager economyManager; private EconomyManager economyManager;
@Getter
private LoginManager loginManager; private LoginManager loginManager;
@Getter
private YamlManager yamlManager; private YamlManager yamlManager;
@Getter
private Yaml yamlConfig; 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 @Override
@SneakyThrows
public void onEnable() { public void onEnable() {
this.SQLManager = new DBConnectionHandler(new DBProperties("db.properties")); this.SQLManager = new DBConnectionHandler(new DBProperties("db.properties"));
this.dataManager = new DataManager(this);
this.commandLoader = new CommandLoader(this, "TRAVERSE"); this.commandLoader = new CommandLoader(this, "TRAVERSE");
this.dataManager = new DataManager(this);
this.banManager = new BanManager(this); this.banManager = new BanManager(this);
this.rankManager = new RankManager(this); this.rankManager = new RankManager(this);
this.scheduler = new Scheduling(this); this.scheduler = new Scheduling(this);
@ -63,6 +112,7 @@ public final class Traverse extends JavaPlugin implements Locker {
this.economyManager = new EconomyManager(this); this.economyManager = new EconomyManager(this);
this.loginManager = new LoginManager(this); this.loginManager = new LoginManager(this);
this.yamlManager = new YamlManager(this); this.yamlManager = new YamlManager(this);
this.staffChat = new StaffChat(this);
registerCommands(); registerCommands();
registerListeners(); registerListeners();
@ -78,48 +128,55 @@ public final class Traverse extends JavaPlugin implements Locker {
// Plugin shutdown logic // Plugin shutdown logic
} }
@SneakyThrows
public void registerCommands() { public void registerCommands() {
synchronized (lock()) { getCommandLoader().register(
getCommandLoader().register( new BanCMD(this),
new BanCMD(this), new BanInfoCMD(this),
new BankCMD(this), new BankCMD(this),
new EntityPurgeCMD(this), new EntityPurgeCMD(this),
new GroupCMD(this), new GroupCMD(this),
new MuteCMD(this), new KickCMD(this),
new PardonCMD(this), new LockCMD(this),
new TraverseCMD(this), new MuteCMD(this),
new UnmuteCMD(this) new PardonCMD(this),
); new PlayerDataCMD(this),
lock().wait(1000); new StaffChatCMD(this),
} new TraverseCMD(this),
new UnmuteCMD(this)
);
lock().notify();
getCommandLoader().load(); getCommandLoader().load();
} }
public void registerListeners() { 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() { public void registerConfig() {
Yaml yaml; Yaml yaml;
if (CONFIG.createNewFile()) { try {
yaml = getYamlManager().bldr() if (CONFIG.createNewFile()) {
.fileName(CONFIG_FILE) yaml = getYamlManager().bldr()
.dataFolder(getDataFolder()) .fileName(CONFIG_FILE)
.copyDefaults(true) .dataFolder(getDataFolder())
.build(); .copyDefaults(true)
} else { .build();
yaml = getYamlManager().bldr() } else {
.fileName(CONFIG_FILE) yaml = getYamlManager().bldr()
.dataFolder(getDataFolder()) .fileName(CONFIG_FILE)
.copyDefaults(false) .dataFolder(getDataFolder())
.build(); .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(); getYamlConfig().loadFromFile();
} }
} }

View File

@ -1,7 +1,5 @@
package mc.unraveled.reforged.service; package mc.unraveled.reforged.service;
import lombok.Getter;
import lombok.Setter;
import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.data.InfractionData;
import mc.unraveled.reforged.service.base.AbstractService; import mc.unraveled.reforged.service.base.AbstractService;
import mc.unraveled.reforged.service.base.ServicePool; import mc.unraveled.reforged.service.base.ServicePool;
@ -10,13 +8,16 @@ import org.jetbrains.annotations.Nullable;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
public class MuteService extends AbstractService { public class MuteService extends AbstractService {
@Setter
private InfractionData infractionData = null; private InfractionData infractionData = null;
public MuteService(@Nullable ServicePool parentPool, @NotNull String service_name, long delay) { public MuteService(@Nullable ServicePool parentPool, @NotNull String service_name, long delay) {
super(parentPool, service_name, delay); super(parentPool, service_name, delay);
} }
public void setInfractionData(InfractionData infractionData) {
this.infractionData = infractionData;
}
@Override @Override
public int getServiceId() { public int getServiceId() {
return 0; return 0;

View File

@ -48,7 +48,7 @@ public abstract class AbstractService implements IService {
* *
* @param service_name A namespaced key which can be used to identify the service. * @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))), this((new ServicePool("defaultPool" + Scheduling.denom, JavaPlugin.getPlugin(Traverse.class))),
service_name, service_name,
0L, 0L,

View File

@ -1,114 +1,128 @@
package mc.unraveled.reforged.storage; package mc.unraveled.reforged.storage;
import lombok.Getter;
import lombok.SneakyThrows;
import mc.unraveled.reforged.banning.AbstractBan; import mc.unraveled.reforged.banning.AbstractBan;
import mc.unraveled.reforged.banning.SimpleBan; import mc.unraveled.reforged.banning.SimpleBan;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@Getter
public class DBBan { public class DBBan {
@Getter
private Connection connection; private Connection connection;
public DBBan(Connection connection) { public DBBan(Connection connection) {
this.connection = connection; this.connection = connection;
} }
@SneakyThrows
public void createTable() { 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));"); try (PreparedStatement statement = getConnection()
statement.executeUpdate(); .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) { public void insert(@NotNull AbstractBan ban) {
PreparedStatement statement = getConnection().prepareStatement("IF NOT EXISTS (SELECT 1 FROM bans WHERE uuid = ?) " + try (PreparedStatement statement = getConnection()
"BEGIN INSERT INTO bans (uuid, ip, reason, banned_by, banned_at, expires_at, active) VALUES (?, ?, ?, ?, ?, ?, ?) END " + .prepareStatement("INSERT INTO bans (uuid, ip, reason, banned_by, banned_at, expires_at, active) VALUES (?, ?, ?, ?, ?, ?, ?);")) {
"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.getIp());
statement.setString(1, ban.getUuid()); statement.setString(3, ban.getReason());
statement.setString(2, ban.getUuid()); statement.setString(4, ban.getSource());
statement.setString(3, ban.getIp()); statement.setLong(5, ban.getPropagated());
statement.setString(4, ban.getReason()); statement.setLong(6, ban.getExpiry());
statement.setString(5, ban.getSource()); statement.setBoolean(7, ban.isActive());
statement.setLong(6, ban.getPropagated()); statement.executeUpdate();
statement.setLong(7, ban.getExpiry()); } catch (SQLException e) {
statement.setBoolean(8, ban.isActive()); Bukkit.getLogger().severe(e.getMessage());
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();
} }
@SneakyThrows
@Nullable @Nullable
public AbstractBan getBan(@NotNull UUID uuid) { public AbstractBan getBan(@NotNull UUID uuid) {
PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM bans WHERE uuid = ?;"); try (PreparedStatement statement = getConnection()
statement.setString(1, uuid.toString()); .prepareStatement("SELECT * FROM bans WHERE uuid = ?;")) {
ResultSet rs = statement.executeQuery(); statement.setString(1, uuid.toString());
if (rs.next()) { try (ResultSet rs = statement.executeQuery()) {
return new SimpleBan(rs.getString("uuid"), if (rs.next()) {
rs.getString("ip"), return new SimpleBan(rs.getString("uuid"),
rs.getString("reason"), rs.getString("ip"),
rs.getString("banned_by"), rs.getString("reason"),
rs.getLong("banned_at"), rs.getString("banned_by"),
rs.getLong("expires_at"), rs.getLong("banned_at"),
rs.getBoolean("active")); rs.getLong("expires_at"),
rs.getBoolean("active"));
}
}
} catch (SQLException e) {
Bukkit.getLogger().severe(e.getMessage());
} }
return null; return null;
} }
@SneakyThrows
public List<AbstractBan> all() { public List<AbstractBan> all() {
PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM bans;");
ResultSet rs = statement.executeQuery();
List<AbstractBan> bans = new ArrayList<>(); List<AbstractBan> bans = new ArrayList<>();
while (rs.next()) { try (PreparedStatement statement = getConnection()
bans.add(new SimpleBan(rs.getString("uuid"), .prepareStatement("SELECT * FROM bans;")) {
rs.getString("ip"), try (ResultSet rs = statement.executeQuery()) {
rs.getString("reason"), while (rs.next()) {
rs.getString("banned_by"), bans.add(new SimpleBan(rs.getString("uuid"),
rs.getLong("banned_at"), rs.getString("ip"),
rs.getLong("expires_at"), rs.getString("reason"),
rs.getBoolean("active"))); 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; return bans;
} }
@SneakyThrows
public void delete(@NotNull AbstractBan ban) { public void delete(@NotNull AbstractBan ban) {
PreparedStatement statement = getConnection().prepareStatement("DELETE FROM bans WHERE uuid = ?;"); try (PreparedStatement statement = getConnection()
statement.setString(1, ban.getUuid()); .prepareStatement("DELETE FROM bans WHERE uuid = ?;")) {
statement.executeUpdate(); statement.setString(1, ban.getUuid());
statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe(e.getMessage());
}
} }
@SneakyThrows
public void deleteAll() { public void deleteAll() {
PreparedStatement statement = getConnection().prepareStatement("DELETE FROM bans;"); try (PreparedStatement statement = getConnection()
statement.executeUpdate(); .prepareStatement("DELETE FROM bans;")) {
statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe(e.getMessage());
}
} }
@SneakyThrows
public void close() { public void close() {
getConnection().close(); try {
getConnection().close();
} catch (SQLException e) {
Bukkit.getLogger().severe(e.getMessage());
}
this.connection = null; this.connection = null;
} }
public void open(Connection connection) { public void open(Connection connection) {
this.connection = connection; this.connection = connection;
} }
public Connection getConnection() {
return connection;
}
} }

View File

@ -1,31 +1,44 @@
package mc.unraveled.reforged.storage; 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 { public class DBConnectionHandler {
private final DBProperties properties; private final DBProperties properties;
public DBConnectionHandler(DBProperties properties) throws SQLException { public DBConnectionHandler(DBProperties properties) {
this.properties = properties; this.properties = properties;
} }
@SneakyThrows
public Connection establish() { 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() { 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 { public record ContextConnection(Connection connection) implements AutoCloseable {
@SneakyThrows
@Override @Override
public void close() { public void close() {
connection.close(); try {
connection.close();
} catch (SQLException e) {
Bukkit.getLogger().severe("Failed to close connection: " + e.getMessage());
}
} }
} }
} }

View File

@ -1,92 +1,111 @@
package mc.unraveled.reforged.storage; package mc.unraveled.reforged.storage;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import mc.unraveled.reforged.permission.Rank; import mc.unraveled.reforged.permission.Rank;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull;
import org.bukkit.permissions.Permission;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
public class DBGroup { public class DBGroup {
@Getter
private Connection connection; private Connection connection;
public DBGroup(Connection connection) { public DBGroup(Connection connection) {
this.connection = connection; this.connection = connection;
} }
@SneakyThrows
public void createTable(Rank rank) { public void createTable(Rank rank) {
PreparedStatement statement = getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS " + rank.getAttachment().getName() + " (uuid VARCHAR(36), permissions VARCHAR(64));"); try (PreparedStatement statement = getConnection().prepareStatement("CREATE TABLE IF NOT EXISTS " + rank.getAttachment().getName() + " (uuid VARCHAR(36), permissions VARCHAR(64));")) {
statement.execute(); statement.execute();
} catch (SQLException e) {
Bukkit.getLogger().severe("Failed to create table: " + e.getMessage());
}
} }
@SneakyThrows
public void addPermission(Rank rank, String permission) { public void addPermission(Rank rank, String permission) {
PreparedStatement statement = getConnection().prepareStatement("INSERT INTO " + rank.getAttachment().getName() + " (permissions) VALUES (?);"); try (PreparedStatement statement = getConnection().prepareStatement("INSERT INTO " + rank.getAttachment().getName() + " (permissions) VALUES (?);")) {
statement.setString(1, permission); statement.setString(1, permission);
statement.executeUpdate(); statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Failed to add permission: " + e.getMessage());
}
} }
@SneakyThrows
public void removePermission(Rank rank, String permission) { public void removePermission(Rank rank, String permission) {
PreparedStatement statement = getConnection().prepareStatement("DELETE FROM " + rank.getAttachment().getName() + " WHERE permissions = ?;"); try (PreparedStatement statement = getConnection().prepareStatement("DELETE FROM " + rank.getAttachment().getName() + " WHERE permissions = ?;")) {
statement.setString(1, permission); statement.setString(1, permission);
statement.executeUpdate(); statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Failed to remove permission: " + e.getMessage());
}
} }
@SneakyThrows
public List<String> getPermissions(Rank rank) { public List<String> getPermissions(Rank rank) {
List<String> permissions = new ArrayList<>(); List<String> permissions = new ArrayList<>();
PreparedStatement statement = getConnection().prepareStatement("SELECT permissions FROM " + rank.getAttachment().getName() + ";"); try (PreparedStatement statement = getConnection().prepareStatement("SELECT permissions FROM " + rank.getAttachment().getName() + ";")) {
ResultSet rs = statement.executeQuery(); ResultSet rs = statement.executeQuery();
while (rs.next()) { while (rs.next()) {
permissions.add(rs.getString("permissions")); permissions.add(rs.getString("permissions"));
}
} catch (SQLException e) {
Bukkit.getLogger().severe("Failed to get permissions: " + e.getMessage());
} }
return permissions; return permissions;
} }
@SneakyThrows public void addPlayer(@NotNull Rank rank, @NotNull OfflinePlayer player) {
public void addPlayer(Rank rank, OfflinePlayer player) { try (PreparedStatement statement = getConnection().prepareStatement("INSERT INTO " + rank.getAttachment().getName() + " (uuid) VALUES (?);")) {
PreparedStatement statement = getConnection().prepareStatement("INSERT INTO " + rank.getAttachment().getName() + " (uuid) VALUES (?);"); statement.setString(1, player.getUniqueId().toString());
statement.setString(1, player.getUniqueId().toString()); statement.executeUpdate();
statement.executeUpdate(); } catch (SQLException e) {
} Bukkit.getLogger().severe("Failed to add player: " + e.getMessage());
@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<OfflinePlayer> getPlayers(Rank rank) {
List<OfflinePlayer> 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 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<UUID> getPlayers(Rank rank) {
List<UUID> 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; return players;
} }
@SneakyThrows
public void close() { 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) { public void open(Connection connection) {
this.connection = connection; this.connection = connection;
} }
public Connection getConnection() {
return connection;
}
} }

View File

@ -1,6 +1,5 @@
package mc.unraveled.reforged.storage; package mc.unraveled.reforged.storage;
import lombok.SneakyThrows;
import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.data.InfractionData;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -9,96 +8,112 @@ import org.bukkit.entity.Player;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
public class DBInfraction { 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 Connection connection;
private final String INF = "infractions";
public DBInfraction(Connection connection) { public DBInfraction(Connection connection) {
this.connection = connection; this.connection = connection;
} }
@SneakyThrows
public void createTable() { public void createTable() {
PreparedStatement statement = connection.prepareStatement(CREATE_TABLE); 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));";
statement.executeUpdate(); 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) { 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 + SQLConst.BEGIN +
INSERT + INSERT +
SQLConst.END_SPACE + SQLConst.END_SPACE +
SQLConst.ELSE + SQLConst.ELSE +
UPDATE + UPDATE +
SQLConst.END + SQLConst.END +
SQLConst.SEMICOLON); SQLConst.SEMICOLON)) {
statement.setString(1, player.getUniqueId().toString()); statement.setString(1, player.getUniqueId().toString());
statement.setString(2, player.getUniqueId().toString()); statement.setInt(2, data.getInfractions());
statement.setInt(3, data.getInfractions()); statement.setBoolean(3, data.isMuted());
statement.setBoolean(4, data.isMuted()); statement.setBoolean(4, data.isFrozen());
statement.setBoolean(5, data.isFrozen()); statement.setBoolean(5, data.isLocked());
statement.setBoolean(6, data.isLocked()); statement.setBoolean(6, data.isJailed());
statement.setBoolean(7, data.isJailed()); statement.setInt(7, data.getInfractions());
statement.setInt(8, data.getInfractions()); statement.setBoolean(8, data.isMuted());
statement.setBoolean(9, data.isMuted()); statement.setBoolean(9, data.isFrozen());
statement.setBoolean(10, data.isFrozen()); statement.setBoolean(10, data.isLocked());
statement.setBoolean(11, data.isLocked()); statement.setBoolean(11, data.isJailed());
statement.setBoolean(12, data.isJailed()); statement.setString(12, player.getUniqueId().toString());
statement.setString(13, player.getUniqueId().toString()); statement.executeUpdate();
statement.executeUpdate(); } catch (SQLException e) {
Bukkit.getLogger().severe("Error while inserting " + player.getName());
}
} }
@SneakyThrows
public void eject(Player player) { public void eject(Player player) {
PreparedStatement statement = connection.prepareStatement(DELETE); String DELETE = "DELETE FROM infractions WHERE uuid = ?;";
statement.setString(1, player.getUniqueId().toString()); try (PreparedStatement statement = connection.prepareStatement(DELETE)) {
statement.executeUpdate(); statement.setString(1, player.getUniqueId().toString());
statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Error while ejecting " + player.getName());
}
} }
@SneakyThrows
public List<InfractionData> getInfractionsList() { public List<InfractionData> getInfractionsList() {
List<InfractionData> temp = new ArrayList<>(); List<InfractionData> temp = new ArrayList<>();
PreparedStatement statement = connection.prepareStatement(SELECT); String SELECT = "SELECT * FROM infractions;";
ResultSet rs = statement.executeQuery(); try (PreparedStatement statement = connection.prepareStatement(SELECT);
while (rs.next()) { ResultSet rs = statement.executeQuery()) {
OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("uuid"))); while (rs.next()) {
int infractions = rs.getInt("infractions"); OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(rs.getString("uuid")));
boolean muted = rs.getBoolean("muted"); int infractions = rs.getInt(INF);
boolean frozen = rs.getBoolean("frozen"); boolean muted = rs.getBoolean("muted");
boolean locked = rs.getBoolean("locked"); boolean frozen = rs.getBoolean("frozen");
boolean jailed = rs.getBoolean("jailed"); 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; return temp;
} }
@SneakyThrows
public InfractionData getInfraction(String uuid) { public InfractionData getInfraction(String uuid) {
PreparedStatement statement = connection.prepareStatement(SELECT_UUID); String SELECT_UUID = "SELECT * FROM infractions WHERE uuid = ?;";
statement.setString(1, uuid); try (PreparedStatement statement = connection.prepareStatement(SELECT_UUID)) {
ResultSet rs = statement.executeQuery(); statement.setString(1, uuid);
if (rs.next()) { try (ResultSet rs = statement.executeQuery()) {
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")); 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))); return new InfractionData(Bukkit.getOfflinePlayer(UUID.fromString(uuid)));
} }
@SneakyThrows
public void close() { public void close() {
connection.close(); try {
connection.close();
} catch (SQLException e) {
Bukkit.getLogger().severe("Error while closing connection");
}
} }
} }

View File

@ -1,12 +1,11 @@
package mc.unraveled.reforged.storage; package mc.unraveled.reforged.storage;
import lombok.Getter; import org.bukkit.Bukkit;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Properties; import java.util.Properties;
@Getter
public class DBProperties { public class DBProperties {
private final Properties properties; private final Properties properties;
private final String url; private final String url;
@ -20,10 +19,10 @@ public class DBProperties {
public DBProperties(String fileName) { public DBProperties(String fileName) {
properties = new Properties(); properties = new Properties();
try { try (FileInputStream fileInputStream = new FileInputStream(fileName)) {
properties.load(new FileInputStream(fileName)); properties.load(fileInputStream);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); Bukkit.getLogger().severe("Could not load database properties file!");
} }
driver = properties.getProperty("driver"); driver = properties.getProperty("driver");
databaseType = properties.getProperty("databaseType"); databaseType = properties.getProperty("databaseType");
@ -34,4 +33,40 @@ public class DBProperties {
password = properties.getProperty("password"); password = properties.getProperty("password");
url = driver + ":" + databaseType + "://" + host + ":" + port + "/" + databaseFile; 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;
}
} }

View File

@ -1,10 +1,9 @@
package mc.unraveled.reforged.storage; package mc.unraveled.reforged.storage;
import lombok.Getter;
import lombok.SneakyThrows;
import mc.unraveled.reforged.data.InfractionData; import mc.unraveled.reforged.data.InfractionData;
import mc.unraveled.reforged.data.LoginInfo; import mc.unraveled.reforged.data.LoginInfo;
import mc.unraveled.reforged.data.PlayerData; import mc.unraveled.reforged.data.PlayerData;
import mc.unraveled.reforged.data.PlayerDataBuilder;
import mc.unraveled.reforged.permission.Rank; import mc.unraveled.reforged.permission.Rank;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -14,186 +13,228 @@ import org.jetbrains.annotations.NotNull;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
public class DBUser { public class DBUser {
@Getter public static final String LOGIN_MESSAGE = "login_message";
private Connection connection; private final String COIN_LITERAL = "coins";
private final Connection connection;
public DBUser(Connection connection) { public DBUser(Connection connection) {
this.connection = connection; this.connection = connection;
} }
@SneakyThrows
public void createTable() { 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));"); 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(); statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Could not create users table!");
}
} }
@SneakyThrows
public void insert(@NotNull PlayerData playerData) { 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 " + "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.executeUpdate();
statement.setString(2, playerData.getUuid().toString()); } catch (SQLException e) {
statement.setString(3, playerData.getUserName()); Bukkit.getLogger().severe("Could not insert player data into users table!");
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();
} }
@SneakyThrows
public void delete(@NotNull PlayerData playerData) { public void delete(@NotNull PlayerData playerData) {
PreparedStatement statement = getConnection().prepareStatement("DELETE FROM users WHERE uuid = ?;"); try (PreparedStatement statement = getConnection().prepareStatement("DELETE FROM users WHERE uuid = ?;")) {
statement.setString(1, playerData.getUuid().toString()); statement.setString(1, playerData.getUuid().toString());
statement.executeUpdate(); statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Could not delete player data from users table!");
}
} }
@SneakyThrows
public void deleteAll() { public void deleteAll() {
PreparedStatement statement = getConnection().prepareStatement("DELETE FROM users;"); try (PreparedStatement statement = getConnection().prepareStatement("DELETE FROM users;")) {
statement.executeUpdate(); 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) { public void setLastLogin(String uuid, long lastLogin) {
PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET last_login = ? WHERE uuid = ?;"); try (PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET last_login = ? WHERE uuid = ?;")) {
statement.setLong(1, lastLogin); statement.setLong(1, lastLogin);
statement.setString(2, uuid); statement.setString(2, uuid);
statement.executeUpdate(); statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Could not update last login for player " + uuid + "!");
}
} }
@SneakyThrows
public Date getLastLogin(String uuid) { public Date getLastLogin(String uuid) {
PreparedStatement statement = getConnection().prepareStatement("SELECT last_login FROM users WHERE uuid = ?;"); AtomicLong lastLogin = new AtomicLong(0L);
statement.setString(1, uuid);
ResultSet resultSet = statement.executeQuery();
long lastLogin = 0;
while (resultSet.next()) { try (PreparedStatement statement = getConnection().prepareStatement("SELECT last_login FROM users WHERE uuid = ?;")) {
lastLogin = resultSet.getLong("last_login"); 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) { public void setCoins(String uuid, int coins) {
PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET coins = ? WHERE uuid = ?;"); try (PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET coins = ? WHERE uuid = ?;")) {
statement.setInt(1, coins); statement.setInt(1, coins);
statement.setString(2, uuid); statement.setString(2, uuid);
statement.executeUpdate(); statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Could not update coins for player " + uuid + "!");
}
} }
@SneakyThrows
public int getCoins(String uuid) { public int getCoins(String uuid) {
PreparedStatement statement = getConnection().prepareStatement("SELECT coins FROM users WHERE uuid = ?;"); AtomicInteger coins = new AtomicInteger(0);
statement.setString(1, uuid);
ResultSet resultSet = statement.executeQuery();
int coins = 0;
while (resultSet.next()) { try (PreparedStatement statement = getConnection().prepareStatement("SELECT coins FROM users WHERE uuid = ?;")) {
coins = resultSet.getInt("coins"); 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) { public void setRank(String uuid, @NotNull Rank rank) {
PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET rank = ? WHERE uuid = ?;"); try (PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET rank = ? WHERE uuid = ?;")) {
statement.setString(1, rank.name()); statement.setString(1, rank.name());
statement.setString(2, uuid); statement.setString(2, uuid);
statement.executeUpdate(); statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Could not update rank for player " + uuid + "!");
}
} }
@SneakyThrows
public Rank getRank(String uuid) { public Rank getRank(String uuid) {
PreparedStatement statement = getConnection().prepareStatement("SELECT rank FROM users WHERE uuid = ?;"); AtomicReference<Rank> rank = new AtomicReference<>(Rank.NON_OP);
statement.setString(1, uuid);
ResultSet resultSet = statement.executeQuery();
Rank rank = Rank.NON_OP;
while (resultSet.next()) { try (PreparedStatement statement = getConnection().prepareStatement("SELECT rank FROM users WHERE uuid = ?;")) {
rank = Rank.valueOf(resultSet.getString("rank")); 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) { public void setLoginMessage(String uuid, String message) {
PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET login_message = ? WHERE uuid = ?;"); try (PreparedStatement statement = getConnection().prepareStatement("UPDATE users SET login_message = ? WHERE uuid = ?;")) {
statement.setString(1, message); statement.setString(1, message);
statement.setString(2, uuid); statement.setString(2, uuid);
statement.executeUpdate(); statement.executeUpdate();
} catch (SQLException e) {
Bukkit.getLogger().severe("Could not update login message for player " + uuid + "!");
}
} }
@SneakyThrows
public Map<OfflinePlayer, LoginInfo> getLoginMessages() { public Map<OfflinePlayer, LoginInfo> getLoginMessages() {
PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users;");
ResultSet resultSet = statement.executeQuery();
Map<OfflinePlayer, LoginInfo> loginInfoMap = new HashMap<>(); Map<OfflinePlayer, LoginInfo> loginInfoMap = new HashMap<>();
while (resultSet.next()) { try (PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users;")) {
OfflinePlayer player = Bukkit.getPlayer(UUID.fromString(resultSet.getString("uuid"))); try (ResultSet resultSet = statement.executeQuery()) {
LoginInfo loginInfo = new LoginInfo(); while (resultSet.next()) {
loginInfoMap.put(player, loginInfo); 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; return loginInfoMap;
} }
@SneakyThrows
public LoginInfo getLoginInfo(String uuid) { 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(); LoginInfo loginInfo = new LoginInfo();
while (resultSet.next()) { try (PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users WHERE uuid = ?;")) {
Component c = Component.text(resultSet.getString("login_message")); statement.setString(1, uuid);
loginInfo.setLoginMessage(c); 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; return loginInfo;
} }
@SneakyThrows
public List<PlayerData> all() { public List<PlayerData> all() {
PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users;");
ResultSet resultSet = statement.executeQuery();
List<PlayerData> dataList = new ArrayList<>(); List<PlayerData> dataList = new ArrayList<>();
InfractionData data = InfractionData.getCachedInfractionData(Bukkit.getOfflinePlayer(UUID.fromString(resultSet.getString("uuid"))));
while (resultSet.next()) { try (PreparedStatement statement = getConnection().prepareStatement("SELECT * FROM users;")) {
PlayerData playerData = new PlayerData(UUID.fromString(resultSet.getString("uuid")), try (ResultSet resultSet = statement.executeQuery()) {
resultSet.getString("username"), while (resultSet.next()) {
Rank.valueOf(resultSet.getString("rank")), 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();
resultSet.getLong("play_time"), PlayerData playerData = new PlayerData(playerDataBuilder);
resultSet.getInt("coins"), dataList.add(playerData);
new Date(resultSet.getLong("last_login")), }
resultSet.getString("login_message"), }
data); } catch (SQLException e) {
dataList.add(playerData); Bukkit.getLogger().severe("Could not get all player data from users table!");
} }
return dataList; return dataList;
} }
@SneakyThrows
public void close() { public void close() {
getConnection().close(); try {
getConnection().close();
} catch (SQLException e) {
Bukkit.getLogger().severe("Could not close database connection!");
}
}
public Connection getConnection() {
return connection;
} }
} }

View File

@ -15,7 +15,7 @@ public final class SQLConst {
return "IF NOT EXISTS (SELECT * FROM " + v + ") "; return "IF NOT EXISTS (SELECT * FROM " + v + ") ";
} }
public static String IF(String v, String u) { public static String IF(String v, String u, String literal) {
return "IF NOT EXISTS (SELECT * FROM " + v + " WHERE " + u + " = ?) "; return "IF NOT EXISTS (SELECT * FROM " + v + " WHERE " + u + " = " + literal + ") ";
} }
} }

View File

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

View File

@ -1,10 +1,17 @@
package mc.unraveled.reforged.util; package mc.unraveled.reforged.util;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Context<S> { public class Context<S> {
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;
}
} }

View File

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

View File

@ -1,7 +1,7 @@
# The SQL driver to use. # The SQL driver to use.
driver=jdbc driver=jdbc
# The type of database to use. # The type of database to use.
databaseType=postgresql databaseType=mysql
# The database host. # The database host.
host=localhost host=localhost
# The database port. # The database port.