diff --git a/bukkit/pom.xml b/bukkit/pom.xml index cca49154..9db25c6b 100644 --- a/bukkit/pom.xml +++ b/bukkit/pom.xml @@ -136,6 +136,13 @@ 2.6.1 provided + + + com.zaxxer + HikariCP + 2.7.6 + provided + diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSchedulerAdapter.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSchedulerAdapter.java index 7e7985f7..8b1cb40c 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSchedulerAdapter.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitSchedulerAdapter.java @@ -29,7 +29,7 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import me.lucko.luckperms.common.plugin.SchedulerAdapter; import me.lucko.luckperms.common.plugin.SchedulerTask; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitTask; @@ -105,7 +105,7 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter { @Override public void shutdown() { - SafeIterator.iterate(this.tasks, SchedulerTask::cancel); + SafeIteration.iterate(this.tasks, SchedulerTask::cancel); // wait for executor this.asyncFallback.shutdown(); diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationBPermissions.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationBPermissions.java index 1c421458..45ed1ef1 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationBPermissions.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationBPermissions.java @@ -46,7 +46,7 @@ import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; @@ -124,14 +124,14 @@ public class MigrationBPermissions extends SubCommand { // Migrate one world at a time. log.log("Starting world migration."); - SafeIterator.iterate(worldManager.getAllWorlds(), world -> { + SafeIteration.iterate(worldManager.getAllWorlds(), world -> { log.log("Migrating world: " + world.getName()); // Migrate all groups log.log("Starting group migration in world " + world.getName() + "."); AtomicInteger groupCount = new AtomicInteger(0); - SafeIterator.iterate(world.getAll(CalculableType.GROUP), group -> { + SafeIteration.iterate(world.getAll(CalculableType.GROUP), group -> { String groupName = MigrationUtils.standardizeName(group.getName()); if (group.getName().equalsIgnoreCase(world.getDefaultGroup())) { groupName = NodeFactory.DEFAULT_GROUP_NAME; @@ -153,7 +153,7 @@ public class MigrationBPermissions extends SubCommand { // Migrate all users log.log("Starting user migration in world " + world.getName() + "."); AtomicInteger userCount = new AtomicInteger(0); - SafeIterator.iterate(world.getAll(CalculableType.USER), user -> { + SafeIteration.iterate(world.getAll(CalculableType.USER), user -> { // There is no mention of UUIDs in the API. I assume that name = uuid. idk? UUID uuid = BukkitMigrationUtils.lookupUuid(log, user.getName()); if (uuid == null) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationGroupManager.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationGroupManager.java index 30515a38..023c32ee 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationGroupManager.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationGroupManager.java @@ -41,7 +41,7 @@ import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import org.anjocaido.groupmanager.GlobalGroups; import org.anjocaido.groupmanager.GroupManager; @@ -93,7 +93,7 @@ public class MigrationGroupManager extends SubCommand { GlobalGroups gg = GroupManager.getGlobalGroups(); AtomicInteger globalGroupCount = new AtomicInteger(0); - SafeIterator.iterate(gg.getGroupList(), g -> { + SafeIteration.iterate(gg.getGroupList(), g -> { String groupName = MigrationUtils.standardizeName(g.getName()); Group group = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join(); @@ -120,13 +120,13 @@ public class MigrationGroupManager extends SubCommand { // Collect data for all users and groups. log.log("Collecting user and group data."); - SafeIterator.iterate(worlds, String::toLowerCase, world -> { + SafeIteration.iterate(worlds, String::toLowerCase, world -> { log.log("Querying world " + world); WorldDataHolder wdh = wh.getWorldData(world); AtomicInteger groupWorldCount = new AtomicInteger(0); - SafeIterator.iterate(wdh.getGroupList(), group -> { + SafeIteration.iterate(wdh.getGroupList(), group -> { String groupName = MigrationUtils.standardizeName(group.getName()); groups.putIfAbsent(groupName, new HashSet<>()); @@ -160,7 +160,7 @@ public class MigrationGroupManager extends SubCommand { log.log("Migrated " + groupWorldCount.get() + " groups in world " + world); AtomicInteger userWorldCount = new AtomicInteger(0); - SafeIterator.iterate(wdh.getUserList(), user -> { + SafeIteration.iterate(wdh.getUserList(), user -> { UUID uuid = BukkitMigrationUtils.lookupUuid(log, user.getUUID()); if (uuid == null) { return; @@ -210,7 +210,7 @@ public class MigrationGroupManager extends SubCommand { log.log("Starting group migration."); AtomicInteger groupCount = new AtomicInteger(0); - SafeIterator.iterate(groups.entrySet(), e -> { + SafeIteration.iterate(groups.entrySet(), e -> { Group group = plugin.getStorage().createAndLoadGroup(e.getKey(), CreationCause.INTERNAL).join(); for (Node node : e.getValue()) { @@ -224,7 +224,7 @@ public class MigrationGroupManager extends SubCommand { log.log("Starting user migration."); AtomicInteger userCount = new AtomicInteger(0); - SafeIterator.iterate(users.entrySet(), e -> { + SafeIteration.iterate(users.entrySet(), e -> { User user = plugin.getStorage().loadUser(e.getKey(), null).join(); for (Node node : e.getValue()) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsBukkit.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsBukkit.java index bca686db..ee25dfc9 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsBukkit.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsBukkit.java @@ -42,7 +42,7 @@ import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; @@ -79,7 +79,7 @@ public class MigrationPermissionsBukkit extends SubCommand { ConfigurationSection groupsSection = config.getConfigurationSection("groups"); - SafeIterator.iterate(groupsSection.getKeys(false), key -> { + SafeIteration.iterate(groupsSection.getKeys(false), key -> { final String groupName = MigrationUtils.standardizeName(key); Group lpGroup = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join(); @@ -99,7 +99,7 @@ public class MigrationPermissionsBukkit extends SubCommand { ConfigurationSection usersSection = config.getConfigurationSection("users"); - SafeIterator.iterate(usersSection.getKeys(false), key -> { + SafeIteration.iterate(usersSection.getKeys(false), key -> { UUID uuid = BukkitMigrationUtils.lookupUuid(log, key); if (uuid == null) { return; diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsEx.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsEx.java index a0ce44c2..f43d6683 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsEx.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPermissionsEx.java @@ -43,7 +43,7 @@ import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import org.bukkit.Bukkit; @@ -117,7 +117,7 @@ public class MigrationPermissionsEx extends SubCommand { log.log("Starting group migration."); AtomicInteger groupCount = new AtomicInteger(0); Set ladders = new HashSet<>(); - SafeIterator.iterate(manager.getGroupList(), group -> { + SafeIteration.iterate(manager.getGroupList(), group -> { int groupWeight = maxWeight - group.getRank(); final String groupName = MigrationUtils.standardizeName(group.getName()); @@ -161,7 +161,7 @@ public class MigrationPermissionsEx extends SubCommand { // Increment the max weight from the group migrations. All user meta should override. int userWeight = maxWeight + 5; - SafeIterator.iterate(manager.getUsers(), user -> { + SafeIteration.iterate(manager.getUsers(), user -> { UUID u = BukkitMigrationUtils.lookupUuid(log, user.getIdentifier()); if (u == null) { return; diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPowerfulPerms.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPowerfulPerms.java index 09edb74a..2fdc38d1 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPowerfulPerms.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationPowerfulPerms.java @@ -31,6 +31,7 @@ import com.github.gustav9797.PowerfulPermsAPI.Permission; import com.github.gustav9797.PowerfulPermsAPI.PermissionManager; import com.github.gustav9797.PowerfulPermsAPI.PowerfulPermsPlugin; import com.google.common.collect.ImmutableSet; +import com.zaxxer.hikari.HikariDataSource; import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.event.cause.CreationCause; @@ -47,9 +48,8 @@ import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.storage.StorageType; -import me.lucko.luckperms.common.utils.HikariSupplier; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import org.bukkit.Bukkit; @@ -57,6 +57,7 @@ import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; +import java.sql.SQLException; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -158,7 +159,7 @@ public class MigrationPowerfulPerms extends SubCommand { // Groups first. log.log("Starting group migration."); AtomicInteger groupCount = new AtomicInteger(0); - SafeIterator.iterate(groups, g -> { + SafeIteration.iterate(groups, g -> { maxWeight.set(Math.max(maxWeight.get(), g.getRank())); String groupName = MigrationUtils.standardizeName(g.getName()); @@ -218,7 +219,7 @@ public class MigrationPowerfulPerms extends SubCommand { maxWeight.addAndGet(5); // Migrate all users and their groups - SafeIterator.iterate(uuids, uuid -> { + SafeIteration.iterate(uuids, uuid -> { // Create a LuckPerms user for the UUID User user = plugin.getStorage().loadUser(uuid, null).join(); @@ -340,4 +341,47 @@ public class MigrationPowerfulPerms extends SubCommand { throw new RuntimeException(e); } } + + /** + * A simple hikari wrapper + */ + public static final class HikariSupplier implements AutoCloseable { + + private final String address; + private final String database; + private final String username; + private final String password; + + private HikariDataSource hikari; + + public HikariSupplier(String address, String database, String username, String password) { + this.address = address; + this.database = database; + this.username = username; + this.password = password; + } + + public void setup(String poolName) { + this.hikari = new HikariDataSource(); + this.hikari.setPoolName(poolName); + this.hikari.setMaximumPoolSize(2); + this.hikari.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource"); + this.hikari.addDataSourceProperty("serverName", this.address.split(":")[0]); + this.hikari.addDataSourceProperty("port", this.address.split(":")[1]); + this.hikari.addDataSourceProperty("databaseName", this.database); + this.hikari.addDataSourceProperty("user", this.username); + this.hikari.addDataSourceProperty("password", this.password); + } + + @Override + public void close() { + this.hikari.close(); + } + + public Connection getConnection() throws SQLException { + return this.hikari.getConnection(); + } + } + + } diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationZPermissions.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationZPermissions.java index eb7776c1..d0eeaf7f 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationZPermissions.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/migration/MigrationZPermissions.java @@ -43,7 +43,7 @@ import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import org.bukkit.Bukkit; import org.tyrannyofheaven.bukkit.zPermissions.ZPermissionsService; @@ -104,7 +104,7 @@ public class MigrationZPermissions extends SubCommand { AtomicInteger groupCount = new AtomicInteger(0); AtomicInteger maxWeight = new AtomicInteger(0); - SafeIterator.iterate(internalService.getEntities(true), entity -> { + SafeIteration.iterate(internalService.getEntities(true), entity -> { String groupName = MigrationUtils.standardizeName(entity.getDisplayName()); Group group = plugin.getStorage().createAndLoadGroup(groupName, CreationCause.INTERNAL).join(); @@ -138,7 +138,7 @@ public class MigrationZPermissions extends SubCommand { // Migrate all tracks log.log("Starting track migration."); AtomicInteger trackCount = new AtomicInteger(0); - SafeIterator.iterate(service.getAllTracks(), t -> { + SafeIteration.iterate(service.getAllTracks(), t -> { String trackName = MigrationUtils.standardizeName(t); Track track = plugin.getStorage().createAndLoadTrack(trackName, CreationCause.INTERNAL).join(); track.setGroups(service.getTrackGroups(t)); @@ -156,7 +156,7 @@ public class MigrationZPermissions extends SubCommand { Set usersToMigrate = new HashSet<>(userParents.keySet()); usersToMigrate.addAll(service.getAllPlayersUUID()); - SafeIterator.iterate(usersToMigrate, u -> { + SafeIteration.iterate(usersToMigrate, u -> { PermissionEntity entity = internalService.getEntity(null, u, false); String username = null; diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSchedulerAdapter.java b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSchedulerAdapter.java index 96277a3c..1ed2b2b5 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSchedulerAdapter.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeSchedulerAdapter.java @@ -27,7 +27,7 @@ package me.lucko.luckperms.bungee; import me.lucko.luckperms.common.plugin.SchedulerAdapter; import me.lucko.luckperms.common.plugin.SchedulerTask; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import net.md_5.bungee.api.scheduler.ScheduledTask; import net.md_5.bungee.api.scheduler.TaskScheduler; @@ -109,7 +109,7 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter { @Override public void shutdown() { - SafeIterator.iterate(this.tasks, SchedulerTask::cancel); + SafeIteration.iterate(this.tasks, SchedulerTask::cancel); } private static final class BungeeSchedulerTask implements SchedulerTask { diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/migration/MigrationBungeePerms.java b/bungee/src/main/java/me/lucko/luckperms/bungee/migration/MigrationBungeePerms.java index 3370cf15..12bac34c 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/migration/MigrationBungeePerms.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/migration/MigrationBungeePerms.java @@ -38,7 +38,7 @@ import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import net.alpenblock.bungeeperms.BungeePerms; import net.alpenblock.bungeeperms.Group; @@ -82,7 +82,7 @@ public class MigrationBungeePerms extends SubCommand { // Migrate all groups. log.log("Starting group migration."); AtomicInteger groupCount = new AtomicInteger(0); - SafeIterator.iterate(groups, g -> { + SafeIteration.iterate(groups, g -> { int groupWeight = maxWeight - g.getRank(); // Make a LuckPerms group for the one being migrated @@ -104,7 +104,7 @@ public class MigrationBungeePerms extends SubCommand { // Increment the max weight from the group migrations. All user meta should override. int userWeight = maxWeight + 5; - SafeIterator.iterate(bp.getPermissionsManager().getBackEnd().loadUsers(), u -> { + SafeIteration.iterate(bp.getPermissionsManager().getBackEnd().loadUsers(), u -> { if (u.getUUID() == null) { log.logErr("Could not parse UUID for user: " + u.getName()); return; diff --git a/common/src/main/java/me/lucko/luckperms/common/actionlog/Log.java b/common/src/main/java/me/lucko/luckperms/common/actionlog/Log.java index 22d68095..1519a956 100644 --- a/common/src/main/java/me/lucko/luckperms/common/actionlog/Log.java +++ b/common/src/main/java/me/lucko/luckperms/common/actionlog/Log.java @@ -38,11 +38,19 @@ import java.util.UUID; import java.util.stream.Collectors; public class Log { + private static Log empty = null; public static Builder builder() { return new Builder(); } + public synchronized static Log empty() { + if (empty == null) { + empty = builder().build(); + } + return empty; + } + private static SortedMap getPage(Set set, int pageNo, int entries) { if (pageNo < 1) { throw new IllegalArgumentException("pageNo cannot be less than 1: " + pageNo); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/other/HolderEditor.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/other/HolderEditor.java index 75df6789..acb660ab 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/other/HolderEditor.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/generic/other/HolderEditor.java @@ -40,7 +40,7 @@ import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.webeditor.WebEditorUtils; +import me.lucko.luckperms.common.webeditor.WebEditor; import net.kyori.text.Component; import net.kyori.text.TextComponent; @@ -66,10 +66,10 @@ public class HolderEditor extends SubCommand { Message.EDITOR_START.send(sender); // form the payload data - JsonObject payload = WebEditorUtils.formPayload(Collections.singletonList(holder), sender, label, plugin); + JsonObject payload = WebEditor.formPayload(Collections.singletonList(holder), sender, label, plugin); // upload the payload data to gist - String gistId = WebEditorUtils.postToGist(new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(payload)); + String gistId = WebEditor.postToGist(new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(payload)); if (gistId == null) { Message.EDITOR_UPLOAD_FAILURE.send(sender); return CommandResult.STATE_ERROR; diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/ApplyEditsCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/ApplyEditsCommand.java index 6d036e18..0ad19c7a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/ApplyEditsCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/ApplyEditsCommand.java @@ -47,7 +47,7 @@ import me.lucko.luckperms.common.node.NodeModel; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.DateUtil; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.webeditor.WebEditorUtils; +import me.lucko.luckperms.common.webeditor.WebEditor; import java.util.HashSet; import java.util.List; @@ -69,7 +69,7 @@ public class ApplyEditsCommand extends SingleCommand { return CommandResult.INVALID_ARGS; } - JsonObject data = WebEditorUtils.getDataFromGist(code); + JsonObject data = WebEditor.getDataFromGist(code); if (data == null) { Message.APPLY_EDITS_UNABLE_TO_READ.send(sender, code); return CommandResult.FAILURE; @@ -94,7 +94,7 @@ public class ApplyEditsCommand extends SingleCommand { } String who = data.get("who").getAsString(); - PermissionHolder holder = WebEditorUtils.getHolderFromIdentifier(plugin, sender, who); + PermissionHolder holder = WebEditor.getHolderFromIdentifier(plugin, sender, who); if (holder == null) { // the #getHolderFromIdentifier method will send the error message onto the sender return false; @@ -105,7 +105,7 @@ public class ApplyEditsCommand extends SingleCommand { return false; } - Set nodes = WebEditorUtils.deserializePermissions(data.getAsJsonArray("nodes")); + Set nodes = WebEditor.deserializePermissions(data.getAsJsonArray("nodes")); Set before = new HashSet<>(holder.getEnduringNodes().values()); Set after = nodes.stream().map(NodeModel::toNode).collect(Collectors.toSet()); diff --git a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/EditorCommand.java b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/EditorCommand.java index edf184f8..3cade9a3 100644 --- a/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/EditorCommand.java +++ b/common/src/main/java/me/lucko/luckperms/common/commands/impl/misc/EditorCommand.java @@ -41,7 +41,7 @@ import me.lucko.luckperms.common.locale.Message; import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.webeditor.WebEditorUtils; +import me.lucko.luckperms.common.webeditor.WebEditor; import net.kyori.text.Component; import net.kyori.text.TextComponent; @@ -92,10 +92,10 @@ public class EditorCommand extends SingleCommand { Message.EDITOR_START.send(sender); // form the payload data - JsonObject payload = WebEditorUtils.formPayload(holders, sender, label, plugin); + JsonObject payload = WebEditor.formPayload(holders, sender, label, plugin); // upload the payload data to gist - String gistId = WebEditorUtils.postToGist(new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(payload)); + String gistId = WebEditor.postToGist(new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create().toJson(payload)); if (gistId == null) { Message.EDITOR_UPLOAD_FAILURE.send(sender); return CommandResult.STATE_ERROR; diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java b/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java new file mode 100644 index 00000000..4a943638 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/node/ForwardingNode.java @@ -0,0 +1,250 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.node; + +import me.lucko.luckperms.api.Node; +import me.lucko.luckperms.api.Tristate; +import me.lucko.luckperms.api.context.ContextSet; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import javax.annotation.Nonnull; + +public abstract class ForwardingNode implements Node { + + protected abstract Node delegate(); + + @Override + public int hashCode() { + return delegate().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return this == obj || delegate().equals(obj); + } + + @Nonnull + @Override + public String getPermission() { + return delegate().getPermission(); + } + + @Nonnull + @Override + public Boolean getValue() { + return delegate().getValue(); + } + + @Override + public boolean getValuePrimitive() { + return delegate().getValuePrimitive(); + } + + @Nonnull + @Override + public Tristate getTristate() { + return delegate().getTristate(); + } + + @Override + public boolean isNegated() { + return delegate().isNegated(); + } + + @Override + public boolean isOverride() { + return delegate().isOverride(); + } + + @Nonnull + @Override + public Optional getServer() { + return delegate().getServer(); + } + + @Nonnull + @Override + public Optional getWorld() { + return delegate().getWorld(); + } + + @Override + public boolean isServerSpecific() { + return delegate().isServerSpecific(); + } + + @Override + public boolean isWorldSpecific() { + return delegate().isWorldSpecific(); + } + + @Override + public boolean appliesGlobally() { + return delegate().appliesGlobally(); + } + + @Override + public boolean hasSpecificContext() { + return delegate().hasSpecificContext(); + } + + @Override + public boolean shouldApplyWithContext(@Nonnull ContextSet context) { + return delegate().shouldApplyWithContext(context); + } + + @Nonnull + @Override + public List resolveShorthand() { + return delegate().resolveShorthand(); + } + + @Override + public boolean isTemporary() { + return delegate().isTemporary(); + } + + @Override + public boolean isPermanent() { + return delegate().isPermanent(); + } + + @Override + public long getExpiryUnixTime() throws IllegalStateException { + return delegate().getExpiryUnixTime(); + } + + @Nonnull + @Override + public Date getExpiry() throws IllegalStateException { + return delegate().getExpiry(); + } + + @Override + public long getSecondsTilExpiry() throws IllegalStateException { + return delegate().getSecondsTilExpiry(); + } + + @Override + public boolean hasExpired() { + return delegate().hasExpired(); + } + + @Nonnull + @Override + public ContextSet getContexts() { + return delegate().getContexts(); + } + + @Nonnull + @Override + public ContextSet getFullContexts() { + return delegate().getFullContexts(); + } + + @Override + public boolean isGroupNode() { + return delegate().isGroupNode(); + } + + @Nonnull + @Override + public String getGroupName() throws IllegalStateException { + return delegate().getGroupName(); + } + + @Override + public boolean isWildcard() { + return delegate().isWildcard(); + } + + @Override + public int getWildcardLevel() throws IllegalStateException { + return delegate().getWildcardLevel(); + } + + @Override + public boolean isMeta() { + return delegate().isMeta(); + } + + @Nonnull + @Override + public Map.Entry getMeta() throws IllegalStateException { + return delegate().getMeta(); + } + + @Override + public boolean isPrefix() { + return delegate().isPrefix(); + } + + @Nonnull + @Override + public Map.Entry getPrefix() throws IllegalStateException { + return delegate().getPrefix(); + } + + @Override + public boolean isSuffix() { + return delegate().isSuffix(); + } + + @Nonnull + @Override + public Map.Entry getSuffix() throws IllegalStateException { + return delegate().getSuffix(); + } + + @Override + public boolean equalsIgnoringValue(@Nonnull Node other) { + return delegate().equalsIgnoringValue(other); + } + + @Override + public boolean almostEquals(@Nonnull Node other) { + return delegate().almostEquals(other); + } + + @Override + public boolean equalsIgnoringValueOrTemp(@Nonnull Node other) { + return delegate().equalsIgnoringValueOrTemp(other); + } + + @Override + public String getKey() { + return delegate().getKey(); + } + + @Override + public Boolean setValue(Boolean value) { + return delegate().setValue(value); + } +} diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableLocalizedNode.java b/common/src/main/java/me/lucko/luckperms/common/node/ImmutableLocalizedNode.java index 80839c7d..0e474b8c 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableLocalizedNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/ImmutableLocalizedNode.java @@ -27,21 +27,15 @@ package me.lucko.luckperms.common.node; import me.lucko.luckperms.api.LocalizedNode; import me.lucko.luckperms.api.Node; -import me.lucko.luckperms.api.Tristate; -import me.lucko.luckperms.api.context.ContextSet; -import java.util.Date; -import java.util.List; -import java.util.Map; import java.util.Objects; -import java.util.Optional; import javax.annotation.Nonnull; /** * Holds a Node and where it was inherited from. All calls are passed onto the contained Node instance. */ -public final class ImmutableLocalizedNode implements LocalizedNode { +public final class ImmutableLocalizedNode extends ForwardingNode implements LocalizedNode { public static ImmutableLocalizedNode of(Node node, String location) { Objects.requireNonNull(node, "node"); Objects.requireNonNull(location, "location"); @@ -57,13 +51,8 @@ public final class ImmutableLocalizedNode implements LocalizedNode { } @Override - public int hashCode() { - return this.node.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return this == obj || this.node.equals(obj); + protected Node delegate() { + return this.node; } @Nonnull @@ -78,204 +67,6 @@ public final class ImmutableLocalizedNode implements LocalizedNode { return this.location; } - @Nonnull - @Override - public Optional getServer() { - return this.node.getServer(); - } - - @Override - public boolean getValuePrimitive() { - return this.node.getValuePrimitive(); - } - - @Override - public String getKey() { - return this.node.getKey(); - } - - @Nonnull - @Override - public Map.Entry getMeta() throws IllegalStateException { - return this.node.getMeta(); - } - - @Override - public boolean isServerSpecific() { - return this.node.isServerSpecific(); - } - - @Nonnull - @Override - public Tristate getTristate() { - return this.node.getTristate(); - } - - @Override - public boolean hasExpired() { - return this.node.hasExpired(); - } - - @Override - public boolean isWildcard() { - return this.node.isWildcard(); - } - - @Override - public boolean equalsIgnoringValueOrTemp(@Nonnull Node other) { - return this.node.equalsIgnoringValueOrTemp(other); - } - - @Nonnull - @Override - public List resolveShorthand() { - return this.node.resolveShorthand(); - } - - @Override - public boolean almostEquals(@Nonnull Node other) { - return this.node.almostEquals(other); - } - - @Nonnull - @Override - public ContextSet getFullContexts() { - return this.node.getFullContexts(); - } - - @Override - public long getSecondsTilExpiry() throws IllegalStateException { - return this.node.getSecondsTilExpiry(); - } - - @Nonnull - @Override - public String getPermission() { - return this.node.getPermission(); - } - - @Nonnull - @Override - public Map.Entry getSuffix() throws IllegalStateException { - return this.node.getSuffix(); - } - - @Override - public boolean isWorldSpecific() { - return this.node.isWorldSpecific(); - } - - @Override - public boolean equalsIgnoringValue(@Nonnull Node other) { - return this.node.equalsIgnoringValue(other); - } - - @Override - public long getExpiryUnixTime() throws IllegalStateException { - return this.node.getExpiryUnixTime(); - } - - @Override - public boolean isGroupNode() { - return this.node.isGroupNode(); - } - - @Override - public Boolean setValue(Boolean value) { - return this.node.setValue(value); - } - - @Override - public boolean isPrefix() { - return this.node.isPrefix(); - } - - @Nonnull - @Override - public String getGroupName() throws IllegalStateException { - return this.node.getGroupName(); - } - - @Nonnull - @Override - public Date getExpiry() throws IllegalStateException { - return this.node.getExpiry(); - } - - @Override - public boolean isNegated() { - return this.node.isNegated(); - } - - @Override - public boolean hasSpecificContext() { - return this.node.hasSpecificContext(); - } - - @Override - public int getWildcardLevel() throws IllegalStateException { - return this.node.getWildcardLevel(); - } - - @Override - public boolean isTemporary() { - return this.node.isTemporary(); - } - - @Nonnull - @Override - public Map.Entry getPrefix() throws IllegalStateException { - return this.node.getPrefix(); - } - - @Override - public boolean isMeta() { - return this.node.isMeta(); - } - - @Override - public boolean isPermanent() { - return this.node.isPermanent(); - } - - @Nonnull - @Override - public Optional getWorld() { - return this.node.getWorld(); - } - - @Nonnull - @Override - public Boolean getValue() { - return this.node.getValue(); - } - - @Override - public boolean isOverride() { - return this.node.isOverride(); - } - - @Override - public boolean isSuffix() { - return this.node.isSuffix(); - } - - @Nonnull - @Override - public ContextSet getContexts() { - return this.node.getContexts(); - } - - @Override - public boolean appliesGlobally() { - return this.node.appliesGlobally(); - } - - @Override - public boolean shouldApplyWithContext(@Nonnull ContextSet context) { - return this.node.shouldApplyWithContext(context); - } - @Override public String toString() { return "ImmutableLocalizedNode(node=" + this.getNode() + ", location=" + this.getLocation() + ")"; diff --git a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableTransientNode.java b/common/src/main/java/me/lucko/luckperms/common/node/ImmutableTransientNode.java index 7678a3d5..7ecf493b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/node/ImmutableTransientNode.java +++ b/common/src/main/java/me/lucko/luckperms/common/node/ImmutableTransientNode.java @@ -26,21 +26,13 @@ package me.lucko.luckperms.common.node; import me.lucko.luckperms.api.Node; -import me.lucko.luckperms.api.Tristate; -import me.lucko.luckperms.api.context.ContextSet; -import java.util.Date; -import java.util.List; -import java.util.Map; import java.util.Objects; -import java.util.Optional; - -import javax.annotation.Nonnull; /** * Holds a Node and plus an owning object. All calls are passed onto the contained Node instance. */ -public final class ImmutableTransientNode implements Node { +public final class ImmutableTransientNode extends ForwardingNode implements Node { public static ImmutableTransientNode of(Node node, O owner) { Objects.requireNonNull(node, "node"); Objects.requireNonNull(owner, "owner"); @@ -56,13 +48,8 @@ public final class ImmutableTransientNode implements Node { } @Override - public int hashCode() { - return this.node.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return this == obj || this.node.equals(obj); + protected Node delegate() { + return this.node; } public Node getNode() { @@ -73,204 +60,6 @@ public final class ImmutableTransientNode implements Node { return this.owner; } - @Nonnull - @Override - public Optional getServer() { - return this.node.getServer(); - } - - @Override - public boolean getValuePrimitive() { - return this.node.getValuePrimitive(); - } - - @Override - public String getKey() { - return this.node.getKey(); - } - - @Nonnull - @Override - public Map.Entry getMeta() throws IllegalStateException { - return this.node.getMeta(); - } - - @Override - public boolean isServerSpecific() { - return this.node.isServerSpecific(); - } - - @Nonnull - @Override - public Tristate getTristate() { - return this.node.getTristate(); - } - - @Override - public boolean hasExpired() { - return this.node.hasExpired(); - } - - @Override - public boolean isWildcard() { - return this.node.isWildcard(); - } - - @Override - public boolean equalsIgnoringValueOrTemp(@Nonnull Node other) { - return this.node.equalsIgnoringValueOrTemp(other); - } - - @Nonnull - @Override - public List resolveShorthand() { - return this.node.resolveShorthand(); - } - - @Override - public boolean almostEquals(@Nonnull Node other) { - return this.node.almostEquals(other); - } - - @Nonnull - @Override - public ContextSet getFullContexts() { - return this.node.getFullContexts(); - } - - @Override - public long getSecondsTilExpiry() throws IllegalStateException { - return this.node.getSecondsTilExpiry(); - } - - @Nonnull - @Override - public String getPermission() { - return this.node.getPermission(); - } - - @Nonnull - @Override - public Map.Entry getSuffix() throws IllegalStateException { - return this.node.getSuffix(); - } - - @Override - public boolean isWorldSpecific() { - return this.node.isWorldSpecific(); - } - - @Override - public boolean equalsIgnoringValue(@Nonnull Node other) { - return this.node.equalsIgnoringValue(other); - } - - @Override - public long getExpiryUnixTime() throws IllegalStateException { - return this.node.getExpiryUnixTime(); - } - - @Override - public boolean isGroupNode() { - return this.node.isGroupNode(); - } - - @Override - public Boolean setValue(Boolean value) { - return this.node.setValue(value); - } - - @Override - public boolean isPrefix() { - return this.node.isPrefix(); - } - - @Nonnull - @Override - public String getGroupName() throws IllegalStateException { - return this.node.getGroupName(); - } - - @Nonnull - @Override - public Date getExpiry() throws IllegalStateException { - return this.node.getExpiry(); - } - - @Override - public boolean isNegated() { - return this.node.isNegated(); - } - - @Override - public boolean hasSpecificContext() { - return this.node.hasSpecificContext(); - } - - @Override - public int getWildcardLevel() throws IllegalStateException { - return this.node.getWildcardLevel(); - } - - @Override - public boolean isTemporary() { - return this.node.isTemporary(); - } - - @Nonnull - @Override - public Map.Entry getPrefix() throws IllegalStateException { - return this.node.getPrefix(); - } - - @Override - public boolean isMeta() { - return this.node.isMeta(); - } - - @Override - public boolean isPermanent() { - return this.node.isPermanent(); - } - - @Nonnull - @Override - public Optional getWorld() { - return this.node.getWorld(); - } - - @Nonnull - @Override - public Boolean getValue() { - return this.node.getValue(); - } - - @Override - public boolean isOverride() { - return this.node.isOverride(); - } - - @Override - public boolean isSuffix() { - return this.node.isSuffix(); - } - - @Nonnull - @Override - public ContextSet getContexts() { - return this.node.getContexts(); - } - - @Override - public boolean appliesGlobally() { - return this.node.appliesGlobally(); - } - - @Override - public boolean shouldApplyWithContext(@Nonnull ContextSet context) { - return this.node.shouldApplyWithContext(context); - } - @Override public String toString() { return "ImmutableTransientNode(node=" + this.getNode() + ", owner=" + this.getOwner() + ")"; diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/AbstractStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/AbstractStorage.java index 450ecaa5..a393e392 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/AbstractStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/AbstractStorage.java @@ -53,13 +53,15 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; /** - * Converts a {@link AbstractDao} to use {@link CompletableFuture}s + * Implements {@link Storage} using an {@link AbstractDao}. */ public class AbstractStorage implements Storage { public static Storage create(LuckPermsPlugin plugin, AbstractDao backing) { - BufferedOutputStorage bufferedDs = BufferedOutputStorage.wrap(PhasedStorage.wrap(new AbstractStorage(plugin, backing)), 250L); - plugin.getScheduler().asyncRepeating(bufferedDs, 2L); - return bufferedDs; + Storage base = new AbstractStorage(plugin, backing); + Storage phased = PhasedStorage.wrap(base); + BufferedOutputStorage buffered = BufferedOutputStorage.wrap(phased, 250L); + plugin.getScheduler().asyncRepeating(buffered, 2L); + return buffered; } private final LuckPermsPlugin plugin; diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/ConfigurateDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/ConfigurateDao.java index d2c71031..0cfebd0a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/ConfigurateDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/ConfigurateDao.java @@ -33,7 +33,6 @@ import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.common.actionlog.Log; import me.lucko.luckperms.common.bulkupdate.BulkUpdate; -import me.lucko.luckperms.common.commands.CommandManager; import me.lucko.luckperms.common.contexts.ContextSetConfigurateSerializer; import me.lucko.luckperms.common.managers.group.GroupManager; import me.lucko.luckperms.common.managers.track.TrackManager; @@ -46,8 +45,6 @@ import me.lucko.luckperms.common.node.NodeModel; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.references.UserIdentifier; import me.lucko.luckperms.common.storage.dao.AbstractDao; -import me.lucko.luckperms.common.storage.dao.legacy.LegacyJsonMigration; -import me.lucko.luckperms.common.storage.dao.legacy.LegacyYamlMigration; import me.lucko.luckperms.common.utils.ImmutableCollectors; import me.lucko.luckperms.common.utils.Uuids; @@ -64,7 +61,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Date; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; @@ -73,18 +69,11 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.logging.FileHandler; -import java.util.logging.Formatter; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; import java.util.stream.Collectors; public abstract class ConfigurateDao extends AbstractDao { - private static final String LOG_FORMAT = "%s(%s): [%s] %s(%s) --> %s"; - - private final Logger actionLogger = Logger.getLogger("luckperms_actions"); private final FileUuidCache uuidCache = new FileUuidCache(); + private final FileActionLogger actionLogger = new FileActionLogger(); private final String fileExtension; private final String dataFolderName; @@ -169,132 +158,59 @@ public abstract class ConfigurateDao extends AbstractDao { @Override public void init() { try { - setupFiles(); + File data = FileUtils.mkdirs(new File(this.plugin.getDataDirectory(), this.dataFolderName)); + + this.usersDirectory = FileUtils.mkdir(new File(data, "users")); + this.groupsDirectory = FileUtils.mkdir(new File(data, "groups")); + this.tracksDirectory = FileUtils.mkdir(new File(data, "tracks")); + this.uuidDataFile = FileUtils.createNewFile(new File(data, "uuidcache.txt")); + this.actionLogFile = FileUtils.createNewFile(new File(data, "actions.log")); + + // Listen for file changes. + this.plugin.getFileWatcher().ifPresent(watcher -> { + watcher.subscribe("user", this.usersDirectory.toPath(), s -> { + if (!s.endsWith(this.fileExtension)) { + return; + } + + String user = s.substring(0, s.length() - this.fileExtension.length()); + UUID uuid = Uuids.parseNullable(user); + if (uuid == null) { + return; + } + + User u = this.plugin.getUserManager().getIfLoaded(uuid); + if (u != null) { + this.plugin.getLog().info("[FileWatcher] Refreshing user " + u.getFriendlyName()); + this.plugin.getStorage().loadUser(uuid, null); + } + }); + watcher.subscribe("group", this.groupsDirectory.toPath(), s -> { + if (!s.endsWith(this.fileExtension)) { + return; + } + + String groupName = s.substring(0, s.length() - this.fileExtension.length()); + this.plugin.getLog().info("[FileWatcher] Refreshing group " + groupName); + this.plugin.getUpdateTaskBuffer().request(); + }); + watcher.subscribe("track", this.tracksDirectory.toPath(), s -> { + if (!s.endsWith(this.fileExtension)) { + return; + } + + String trackName = s.substring(0, s.length() - this.fileExtension.length()); + this.plugin.getLog().info("[FileWatcher] Refreshing track " + trackName); + this.plugin.getStorage().loadAllTracks(); + }); + }); } catch (IOException e) { e.printStackTrace(); return; } this.uuidCache.load(this.uuidDataFile); - - try { - FileHandler fh = new FileHandler(this.actionLogFile.getAbsolutePath(), 0, 1, true); - fh.setFormatter(new Formatter() { - @Override - public String format(LogRecord record) { - return new Date(record.getMillis()).toString() + ": " + record.getMessage() + "\n"; - } - }); - this.actionLogger.addHandler(fh); - this.actionLogger.setUseParentHandlers(false); - this.actionLogger.setLevel(Level.ALL); - this.actionLogger.setFilter(record -> true); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private static void mkdir(File file) throws IOException { - if (file.exists()) { - return; - } - if (!file.mkdir()) { - throw new IOException("Unable to create directory - " + file.getPath()); - } - } - - private static void mkdirs(File file) throws IOException { - if (file.exists()) { - return; - } - if (!file.mkdirs()) { - throw new IOException("Unable to create directory - " + file.getPath()); - } - } - - private void setupFiles() throws IOException { - File data = new File(this.plugin.getDataDirectory(), this.dataFolderName); - - // Try to perform schema migration - File oldData = new File(this.plugin.getDataDirectory(), "data"); - - if (!data.exists() && oldData.exists()) { - mkdirs(data); - - this.plugin.getLog().severe("===== Legacy Schema Migration ====="); - this.plugin.getLog().severe("Starting migration from legacy schema. This could take a while...."); - this.plugin.getLog().severe("Please do not stop your server while the migration takes place."); - - if (this instanceof YamlDao) { - try { - new LegacyYamlMigration(this.plugin, (YamlDao) this, oldData, data).run(); - } catch (Exception e) { - e.printStackTrace(); - } - } else if (this instanceof JsonDao) { - try { - new LegacyJsonMigration(this.plugin, (JsonDao) this, oldData, data).run(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } else { - mkdirs(data); - } - - this.usersDirectory = new File(data, "users"); - mkdir(this.usersDirectory); - - this.groupsDirectory = new File(data, "groups"); - mkdir(this.groupsDirectory); - - this.tracksDirectory = new File(data, "tracks"); - mkdir(this.tracksDirectory); - - this.uuidDataFile = new File(data, "uuidcache.txt"); - this.uuidDataFile.createNewFile(); - - this.actionLogFile = new File(data, "actions.log"); - this.actionLogFile.createNewFile(); - - // Listen for file changes. - this.plugin.getFileWatcher().ifPresent(watcher -> { - watcher.subscribe("user", this.usersDirectory.toPath(), s -> { - if (!s.endsWith(this.fileExtension)) { - return; - } - - String user = s.substring(0, s.length() - this.fileExtension.length()); - UUID uuid = Uuids.parseNullable(user); - if (uuid == null) { - return; - } - - User u = this.plugin.getUserManager().getIfLoaded(uuid); - if (u != null) { - this.plugin.getLog().info("[FileWatcher] Refreshing user " + u.getFriendlyName()); - this.plugin.getStorage().loadUser(uuid, null); - } - }); - watcher.subscribe("group", this.groupsDirectory.toPath(), s -> { - if (!s.endsWith(this.fileExtension)) { - return; - } - - String groupName = s.substring(0, s.length() - this.fileExtension.length()); - this.plugin.getLog().info("[FileWatcher] Refreshing group " + groupName); - this.plugin.getUpdateTaskBuffer().request(); - }); - watcher.subscribe("track", this.tracksDirectory.toPath(), s -> { - if (!s.endsWith(this.fileExtension)) { - return; - } - - String trackName = s.substring(0, s.length() - this.fileExtension.length()); - this.plugin.getLog().info("[FileWatcher] Refreshing track " + trackName); - this.plugin.getStorage().loadAllTracks(); - }); - }); + this.actionLogger.init(this.actionLogFile); } @Override @@ -304,20 +220,14 @@ public abstract class ConfigurateDao extends AbstractDao { @Override public void logAction(LogEntry entry) { - this.actionLogger.info(String.format(LOG_FORMAT, - (entry.getActor().equals(CommandManager.CONSOLE_UUID) ? "" : entry.getActor() + " "), - entry.getActorName(), - Character.toString(entry.getType().getCode()), - entry.getActed().map(e -> e.toString() + " ").orElse(""), - entry.getActedName(), - entry.getAction()) - ); + this.actionLogger.logAction(entry); } @Override public Log getLog() { - // Flatfile doesn't support viewing log data from in-game. You can just read the file in a text editor. - return Log.builder().build(); + // File based daos don't support viewing log data from in-game. + // You can just read the file in a text editor. + return Log.empty(); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileActionLogger.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileActionLogger.java new file mode 100644 index 00000000..f4fb8664 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileActionLogger.java @@ -0,0 +1,72 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.storage.dao.file; + +import me.lucko.luckperms.api.LogEntry; +import me.lucko.luckperms.common.commands.CommandManager; + +import java.io.File; +import java.util.Date; +import java.util.logging.FileHandler; +import java.util.logging.Formatter; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +public class FileActionLogger { + private static final String LOG_FORMAT = "%s(%s): [%s] %s(%s) --> %s"; + private final Logger actionLogger = Logger.getLogger("luckperms_actions"); + + public void init(File file) { + try { + FileHandler fh = new FileHandler(file.getAbsolutePath(), 0, 1, true); + fh.setFormatter(new Formatter() { + @Override + public String format(LogRecord record) { + return new Date(record.getMillis()).toString() + ": " + record.getMessage() + "\n"; + } + }); + this.actionLogger.addHandler(fh); + this.actionLogger.setUseParentHandlers(false); + this.actionLogger.setLevel(Level.ALL); + this.actionLogger.setFilter(record -> true); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void logAction(LogEntry entry) { + this.actionLogger.info(String.format(LOG_FORMAT, + (entry.getActor().equals(CommandManager.CONSOLE_UUID) ? "" : entry.getActor() + " "), + entry.getActorName(), + Character.toString(entry.getType().getCode()), + entry.getActed().map(e -> e.toString() + " ").orElse(""), + entry.getActedName(), + entry.getAction()) + ); + } + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileUtils.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileUtils.java new file mode 100644 index 00000000..6e176e28 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/FileUtils.java @@ -0,0 +1,65 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * Copyright (c) contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.lucko.luckperms.common.storage.dao.file; + +import java.io.File; +import java.io.IOException; + +public final class FileUtils { + + public static File mkdir(File file) throws IOException { + if (file.exists()) { + return file; + } + if (!file.mkdir()) { + throw new IOException("Unable to create directory - " + file.getPath()); + } + return file; + } + + public static File mkdirs(File file) throws IOException { + if (file.exists()) { + return file; + } + if (!file.mkdirs()) { + throw new IOException("Unable to create directory - " + file.getPath()); + } + return file; + } + + public static File createNewFile(File file) throws IOException { + if (file.exists()) { + return file; + } + if (!file.createNewFile()) { + throw new IOException("Unable to create file - " + file.getPath()); + } + return file; + } + + private FileUtils() {} + +} diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/HoconDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/HoconDao.java index 4228a62d..cd40452b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/HoconDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/HoconDao.java @@ -36,7 +36,6 @@ import java.nio.file.Files; import java.nio.file.Path; public class HoconDao extends ConfigurateDao { - public HoconDao(LuckPermsPlugin plugin, String dataFolderName) { super(plugin, "HOCON", ".conf", dataFolderName); } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/JsonDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/JsonDao.java index d09f7497..ce8af824 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/JsonDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/JsonDao.java @@ -36,7 +36,6 @@ import java.nio.file.Files; import java.nio.file.Path; public class JsonDao extends ConfigurateDao { - public JsonDao(LuckPermsPlugin plugin, String dataFolderName) { super(plugin, "JSON", ".json", dataFolderName); } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/YamlDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/YamlDao.java index ee59d619..fe299805 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/YamlDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/YamlDao.java @@ -38,7 +38,6 @@ import java.nio.file.Files; import java.nio.file.Path; public class YamlDao extends ConfigurateDao { - public YamlDao(LuckPermsPlugin plugin, String dataFolderName) { super(plugin, "YAML", ".yml", dataFolderName); } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacyJsonMigration.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacyJsonMigration.java deleted file mode 100644 index 36a6c732..00000000 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacyJsonMigration.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.lucko.luckperms.common.storage.dao.legacy; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; - -import me.lucko.luckperms.common.contexts.ContextSetJsonSerializer; -import me.lucko.luckperms.common.node.LegacyNodeFactory; -import me.lucko.luckperms.common.node.NodeModel; -import me.lucko.luckperms.common.plugin.LuckPermsPlugin; -import me.lucko.luckperms.common.storage.dao.file.JsonDao; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.HashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -@SuppressWarnings("unchecked") -public class LegacyJsonMigration implements Runnable { - private final Gson gson = new GsonBuilder().setPrettyPrinting().create(); - - private final LuckPermsPlugin plugin; - private final JsonDao backing; - private final File oldDataFolder; - private final File newDataFolder; - - public LegacyJsonMigration(LuckPermsPlugin plugin, JsonDao backing, File oldDataFolder, File newDataFolder) { - this.plugin = plugin; - this.backing = backing; - this.oldDataFolder = oldDataFolder; - this.newDataFolder = newDataFolder; - } - - private void writeElementToFile(File file, JsonElement element) { - try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) { - this.gson.toJson(element, writer); - writer.flush(); - } catch (Throwable t) { - this.plugin.getLog().warn("Exception whilst writing to file: " + file.getAbsolutePath()); - t.printStackTrace(); - } - } - - private JsonObject readObjectFromFile(File file) { - try (BufferedReader reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) { - return this.gson.fromJson(reader, JsonObject.class); - } catch (Throwable t) { - this.plugin.getLog().warn("Exception whilst reading from file: " + file.getAbsolutePath()); - t.printStackTrace(); - return null; - } - } - - @Override - public void run() { - this.plugin.getLog().warn("Moving existing files to their new location."); - relocateFile(this.oldDataFolder, this.newDataFolder, "actions.log"); - relocateFile(this.oldDataFolder, this.newDataFolder, "uuidcache.txt"); - relocateFile(this.oldDataFolder, this.newDataFolder, "tracks"); - - this.plugin.getLog().warn("Migrating group files"); - File oldGroupsDir = new File(this.oldDataFolder, "groups"); - if (oldGroupsDir.exists() && oldGroupsDir.isDirectory()) { - File newGroupsDir = new File(this.newDataFolder, "groups"); - newGroupsDir.mkdir(); - - File[] toMigrate = oldGroupsDir.listFiles((dir, name) -> name.endsWith(this.backing.getFileExtension())); - if (toMigrate != null) { - for (File oldFile : toMigrate) { - try { - File replacementFile = new File(newGroupsDir, oldFile.getName()); - - JsonObject values = readObjectFromFile(oldFile); - - Map perms = new HashMap<>(); - String name = values.get("name").getAsString(); - JsonObject permsSection = values.get("perms").getAsJsonObject(); - for (Map.Entry e : permsSection.entrySet()) { - perms.put(e.getKey(), e.getValue().getAsBoolean()); - } - - - Set nodes = perms.entrySet().stream() - .map(e -> LegacyNodeFactory.fromLegacyString(e.getKey(), e.getValue())) - .map(NodeModel::fromNode) - .collect(Collectors.toCollection(LinkedHashSet::new)); - - if (!replacementFile.exists()) { - try { - replacementFile.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - JsonObject data = new JsonObject(); - data.addProperty("name", name); - data.add("permissions", serializePermissions(nodes)); - writeElementToFile(replacementFile, data); - - oldFile.delete(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - - this.plugin.getLog().warn("Migrated group files, now migrating user files."); - - File oldUsersDir = new File(this.oldDataFolder, "users"); - if (oldUsersDir.exists() && oldUsersDir.isDirectory()) { - File newUsersDir = new File(this.newDataFolder, "users"); - newUsersDir.mkdir(); - - File[] toMigrate = oldUsersDir.listFiles((dir, name) -> name.endsWith(this.backing.getFileExtension())); - if (toMigrate != null) { - for (File oldFile : toMigrate) { - try { - File replacementFile = new File(newUsersDir, oldFile.getName()); - - JsonObject values = readObjectFromFile(oldFile); - - Map perms = new HashMap<>(); - String uuid = values.get("uuid").getAsString(); - String name = values.get("name").getAsString(); - String primaryGroup = values.get("primaryGroup").getAsString(); - JsonObject permsSection = values.get("perms").getAsJsonObject(); - for (Map.Entry e : permsSection.entrySet()) { - perms.put(e.getKey(), e.getValue().getAsBoolean()); - } - - Set nodes = perms.entrySet().stream() - .map(e -> LegacyNodeFactory.fromLegacyString(e.getKey(), e.getValue())) - .map(NodeModel::fromNode) - .collect(Collectors.toCollection(LinkedHashSet::new)); - - if (!replacementFile.exists()) { - try { - replacementFile.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - JsonObject data = new JsonObject(); - data.addProperty("uuid", uuid); - data.addProperty("name", name); - data.addProperty("primaryGroup", primaryGroup); - data.add("permissions", serializePermissions(nodes)); - writeElementToFile(replacementFile, data); - - oldFile.delete(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - this.plugin.getLog().warn("Migrated user files."); - - // rename the old data file - this.oldDataFolder.renameTo(new File(this.oldDataFolder.getParent(), "old-data-backup")); - - this.plugin.getLog().warn("Legacy schema migration complete."); - } - - private static void relocateFile(File dirFrom, File dirTo, String fileName) { - File file = new File(dirFrom, fileName); - if (file.exists()) { - try { - Files.move(file.toPath(), new File(dirTo, fileName).toPath()); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private static JsonArray serializePermissions(Set nodes) { - JsonArray arr = new JsonArray(); - - for (NodeModel node : nodes) { - // just a raw, default node. - boolean single = node.getValue() && - node.getServer().equalsIgnoreCase("global") && - node.getWorld().equalsIgnoreCase("global") && - node.getExpiry() == 0L && - node.getContexts().isEmpty(); - - // just add a string to the list. - if (single) { - arr.add(new JsonPrimitive(node.getPermission())); - continue; - } - - JsonObject attributes = new JsonObject(); - attributes.addProperty("value", node.getValue()); - - if (!node.getServer().equals("global")) { - attributes.addProperty("server", node.getServer()); - } - - if (!node.getWorld().equals("global")) { - attributes.addProperty("world", node.getWorld()); - } - - if (node.getExpiry() != 0L) { - attributes.addProperty("expiry", node.getExpiry()); - } - - if (!node.getContexts().isEmpty()) { - attributes.add("context", ContextSetJsonSerializer.serializeContextSet(node.getContexts())); - } - - JsonObject perm = new JsonObject(); - perm.add(node.getPermission(), attributes); - arr.add(perm); - } - - return arr; - } -} diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacySqlMigration.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacySqlMigration.java deleted file mode 100644 index 69bedcfc..00000000 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacySqlMigration.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.lucko.luckperms.common.storage.dao.legacy; - -import com.google.common.collect.Lists; -import com.google.gson.reflect.TypeToken; - -import me.lucko.luckperms.common.contexts.ContextSetJsonSerializer; -import me.lucko.luckperms.common.node.LegacyNodeFactory; -import me.lucko.luckperms.common.node.NodeFactory; -import me.lucko.luckperms.common.node.NodeModel; -import me.lucko.luckperms.common.storage.dao.sql.SqlDao; - -import java.lang.reflect.Type; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -public class LegacySqlMigration implements Runnable { - private static final Type NODE_MAP_TYPE = new TypeToken>() {}.getType(); - private final SqlDao backing; - - public LegacySqlMigration(SqlDao backing) { - this.backing = backing; - } - - @Override - public void run() { - this.backing.getPlugin().getLog().warn("Collecting UUID data from the old tables."); - - Map uuidData = new HashMap<>(); - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement("SELECT uuid, name FROM lp_uuid")) { - try (ResultSet rs = ps.executeQuery()) { - while (rs.next()) { - try { - uuidData.put(UUID.fromString(rs.getString("uuid")), rs.getString("name")); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } - } - } - } - } catch (SQLException e) { - e.printStackTrace(); - } - - this.backing.getPlugin().getLog().warn("Found " + uuidData.size() + " uuid data entries. Copying to new tables..."); - - List> uuidEntries = new ArrayList<>(uuidData.entrySet()); - List>> partitionedUuidEntries = Lists.partition(uuidEntries, 100); - - for (List> l : partitionedUuidEntries) { - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("INSERT INTO {prefix}players VALUES(?, ?, ?)"))) { - for (Map.Entry e : l) { - ps.setString(1, e.getKey().toString()); - ps.setString(2, e.getValue().toLowerCase()); - ps.setString(3, NodeFactory.DEFAULT_GROUP_NAME); - ps.addBatch(); - } - ps.executeBatch(); - } - } catch (SQLException e) { - e.printStackTrace(); - } - } - - uuidData.clear(); - uuidEntries.clear(); - partitionedUuidEntries.clear(); - - this.backing.getPlugin().getLog().warn("Migrated all uuid data."); - this.backing.getPlugin().getLog().warn("Starting user data migration."); - - Set users = new HashSet<>(); - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement("SELECT uuid FROM lp_users")) { - try (ResultSet rs = ps.executeQuery()) { - while (rs.next()) { - try { - users.add(UUID.fromString(rs.getString("uuid"))); - } catch (IllegalArgumentException e) { - e.printStackTrace(); - } - } - } - } - } catch (SQLException e) { - e.printStackTrace(); - } - - this.backing.getPlugin().getLog().warn("Found " + users.size() + " user data entries. Copying to new tables..."); - - AtomicInteger userCounter = new AtomicInteger(0); - for (UUID uuid : users) { - String permsJson = null; - String primaryGroup = null; - - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement("SELECT primary_group, perms FROM lp_users WHERE uuid=?")) { - ps.setString(1, uuid.toString()); - try (ResultSet rs = ps.executeQuery()) { - if (rs.next()) { - permsJson = rs.getString("perms"); - primaryGroup = rs.getString("primary_group"); - } - } - } - } catch (SQLException e) { - e.printStackTrace(); - } - - if (permsJson == null || primaryGroup == null) { - new Throwable().printStackTrace(); - continue; - } - - Map convertedPerms = this.backing.getGson().fromJson(permsJson, NODE_MAP_TYPE); - if (convertedPerms == null) { - new Throwable().printStackTrace(); - continue; - } - - Set nodes = convertedPerms.entrySet().stream() - .map(e -> LegacyNodeFactory.fromLegacyString(e.getKey(), e.getValue())) - .map(NodeModel::fromNode) - .collect(Collectors.toSet()); - - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("INSERT INTO {prefix}user_permissions(uuid, permission, value, server, world, expiry, contexts) VALUES(?, ?, ?, ?, ?, ?, ?)"))) { - for (NodeModel nd : nodes) { - ps.setString(1, uuid.toString()); - ps.setString(2, nd.getPermission()); - ps.setBoolean(3, nd.getValue()); - ps.setString(4, nd.getServer()); - ps.setString(5, nd.getWorld()); - ps.setLong(6, nd.getExpiry()); - ps.setString(7, this.backing.getGson().toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts()))); - ps.addBatch(); - } - ps.executeBatch(); - } - } catch (SQLException e) { - e.printStackTrace(); - } - - if (!primaryGroup.equalsIgnoreCase(NodeFactory.DEFAULT_GROUP_NAME)) { - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("UPDATE {prefix}players SET primary_group=? WHERE uuid=?"))) { - ps.setString(1, primaryGroup); - ps.setString(2, uuid.toString()); - ps.execute(); - } - } catch (SQLException e) { - e.printStackTrace(); - } - } - - int i = userCounter.incrementAndGet(); - if (i % 100 == 0) { - this.backing.getPlugin().getLog().warn("Migrated " + i + " users so far..."); - } - } - - users.clear(); - - this.backing.getPlugin().getLog().warn("Migrated all user data."); - this.backing.getPlugin().getLog().warn("Starting group data migration."); - - Map groupData = new HashMap<>(); - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement("SELECT name, perms FROM lp_groups")) { - try (ResultSet rs = ps.executeQuery()) { - while (rs.next()) { - groupData.put(rs.getString("name"), rs.getString("perms")); - } - } - } - } catch (SQLException e) { - e.printStackTrace(); - } - - this.backing.getPlugin().getLog().warn("Found " + groupData.size() + " group data entries. Copying to new tables..."); - for (Map.Entry e : groupData.entrySet()) { - String name = e.getKey(); - String permsJson = e.getValue(); - - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("INSERT INTO {prefix}groups VALUES(?)"))) { - ps.setString(1, name); - ps.execute(); - } - } catch (SQLException ex) { - ex.printStackTrace(); - } - - Map convertedPerms = this.backing.getGson().fromJson(permsJson, NODE_MAP_TYPE); - if (convertedPerms == null) { - new Throwable().printStackTrace(); - continue; - } - - Set nodes = convertedPerms.entrySet().stream() - .map(ent -> LegacyNodeFactory.fromLegacyString(ent.getKey(), ent.getValue())) - .map(NodeModel::fromNode) - .collect(Collectors.toSet()); - - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("INSERT INTO {prefix}group_permissions(name, permission, value, server, world, expiry, contexts) VALUES(?, ?, ?, ?, ?, ?, ?)"))) { - for (NodeModel nd : nodes) { - ps.setString(1, name); - ps.setString(2, nd.getPermission()); - ps.setBoolean(3, nd.getValue()); - ps.setString(4, nd.getServer()); - ps.setString(5, nd.getWorld()); - ps.setLong(6, nd.getExpiry()); - ps.setString(7, this.backing.getGson().toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts()))); - ps.addBatch(); - } - ps.executeBatch(); - } - } catch (SQLException ex) { - ex.printStackTrace(); - } - } - - groupData.clear(); - this.backing.getPlugin().getLog().warn("Migrated all group data."); - - this.backing.getPlugin().getLog().warn("Renaming action and track tables."); - try (Connection c = this.backing.getProvider().getConnection()) { - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("DROP TABLE {prefix}actions"))) { - ps.execute(); - } - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("ALTER TABLE lp_actions RENAME TO {prefix}actions"))) { - ps.execute(); - } - - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("DROP TABLE {prefix}tracks"))) { - ps.execute(); - } - try (PreparedStatement ps = c.prepareStatement(this.backing.getPrefix().apply("ALTER TABLE lp_tracks RENAME TO {prefix}tracks"))) { - ps.execute(); - } - } catch (SQLException ex) { - ex.printStackTrace(); - } - - this.backing.getPlugin().getLog().warn("Legacy schema migration complete."); - } -} diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacyYamlMigration.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacyYamlMigration.java deleted file mode 100644 index dda1accf..00000000 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/legacy/LegacyYamlMigration.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.lucko.luckperms.common.storage.dao.legacy; - -import me.lucko.luckperms.common.node.LegacyNodeFactory; -import me.lucko.luckperms.common.node.NodeModel; -import me.lucko.luckperms.common.plugin.LuckPermsPlugin; -import me.lucko.luckperms.common.storage.dao.file.YamlDao; - -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.Yaml; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - -@SuppressWarnings("unchecked") -public class LegacyYamlMigration implements Runnable { - private final LuckPermsPlugin plugin; - private final YamlDao backing; - private final File oldDataFolder; - private final File newDataFolder; - - private final Yaml yaml = getYaml(); - - private static Yaml getYaml() { - DumperOptions options = new DumperOptions(); - options.setAllowUnicode(true); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - return new Yaml(options); - } - - public LegacyYamlMigration(LuckPermsPlugin plugin, YamlDao backing, File oldDataFolder, File newDataFolder) { - this.plugin = plugin; - this.backing = backing; - this.oldDataFolder = oldDataFolder; - this.newDataFolder = newDataFolder; - } - - public void writeMapToFile(File file, Map values) { - try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) { - this.yaml.dump(values, writer); - writer.flush(); - } catch (Throwable t) { - this.plugin.getLog().warn("Exception whilst writing to file: " + file.getAbsolutePath()); - t.printStackTrace(); - } - } - - public Map readMapFromFile(File file) { - try (BufferedReader reader = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) { - return (Map) this.yaml.load(reader); - } catch (Throwable t) { - this.plugin.getLog().warn("Exception whilst reading from file: " + file.getAbsolutePath()); - t.printStackTrace(); - return null; - } - } - - @Override - public void run() { - this.plugin.getLog().warn("Moving existing files to their new location."); - relocateFile(this.oldDataFolder, this.newDataFolder, "actions.log"); - relocateFile(this.oldDataFolder, this.newDataFolder, "uuidcache.txt"); - relocateFile(this.oldDataFolder, this.newDataFolder, "tracks"); - - this.plugin.getLog().warn("Migrating group files"); - File oldGroupsDir = new File(this.oldDataFolder, "groups"); - if (oldGroupsDir.exists() && oldGroupsDir.isDirectory()) { - File newGroupsDir = new File(this.newDataFolder, "groups"); - newGroupsDir.mkdir(); - - File[] toMigrate = oldGroupsDir.listFiles((dir, name) -> name.endsWith(this.backing.getFileExtension())); - if (toMigrate != null) { - for (File oldFile : toMigrate) { - try { - File replacementFile = new File(newGroupsDir, oldFile.getName()); - - Map data = readMapFromFile(oldFile); - - String name = (String) data.get("name"); - Map perms = new HashMap<>((Map) data.get("perms")); - - Set nodes = perms.entrySet().stream() - .map(e -> LegacyNodeFactory.fromLegacyString(e.getKey(), e.getValue())) - .map(NodeModel::fromNode) - .collect(Collectors.toCollection(LinkedHashSet::new)); - - if (!replacementFile.exists()) { - try { - replacementFile.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - Map values = new LinkedHashMap<>(); - values.put("name", name); - values.put("permissions", serializePermissions(nodes)); - writeMapToFile(replacementFile, values); - - oldFile.delete(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - - this.plugin.getLog().warn("Migrated group files, now migrating user files."); - - File oldUsersDir = new File(this.oldDataFolder, "users"); - if (oldUsersDir.exists() && oldUsersDir.isDirectory()) { - File newUsersDir = new File(this.newDataFolder, "users"); - newUsersDir.mkdir(); - - File[] toMigrate = oldUsersDir.listFiles((dir, name) -> name.endsWith(this.backing.getFileExtension())); - if (toMigrate != null) { - for (File oldFile : toMigrate) { - try { - File replacementFile = new File(newUsersDir, oldFile.getName()); - - Map data = readMapFromFile(oldFile); - - String uuid = (String) data.get("uuid"); - String name = (String) data.get("name"); - String primaryGroup = (String) data.get("primary-group"); - Map perms = new HashMap<>((Map) data.get("perms")); - - Set nodes = perms.entrySet().stream() - .map(e -> LegacyNodeFactory.fromLegacyString(e.getKey(), e.getValue())) - .map(NodeModel::fromNode) - .collect(Collectors.toCollection(LinkedHashSet::new)); - - if (!replacementFile.exists()) { - try { - replacementFile.createNewFile(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - Map values = new LinkedHashMap<>(); - values.put("uuid", uuid); - values.put("name", name); - values.put("primary-group", primaryGroup); - values.put("permissions", serializePermissions(nodes)); - writeMapToFile(replacementFile, values); - - oldFile.delete(); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - this.plugin.getLog().warn("Migrated user files."); - - // rename the old data file - this.oldDataFolder.renameTo(new File(this.oldDataFolder.getParent(), "old-data-backup")); - - this.plugin.getLog().warn("Legacy schema migration complete."); - } - - private static void relocateFile(File dirFrom, File dirTo, String fileName) { - File file = new File(dirFrom, fileName); - if (file.exists()) { - try { - Files.move(file.toPath(), new File(dirTo, fileName).toPath()); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - private static List serializePermissions(Set nodes) { - List data = new ArrayList<>(); - - for (NodeModel node : nodes) { - // just a raw, default node. - boolean single = node.getValue() && - node.getServer().equalsIgnoreCase("global") && - node.getWorld().equalsIgnoreCase("global") && - node.getExpiry() == 0L && - node.getContexts().isEmpty(); - - // just add a string to the list. - if (single) { - data.add(node.getPermission()); - continue; - } - - // otherwise, this node has some other special context which needs to be saved. - // we serialize this way so it gets represented nicely in YAML. - - // create a map of node attributes - Map attributes = new LinkedHashMap<>(); - attributes.put("value", node.getValue()); - - if (!node.getServer().equals("global")) { - attributes.put("server", node.getServer()); - } - - if (!node.getWorld().equals("global")) { - attributes.put("world", node.getWorld()); - } - - if (node.getExpiry() != 0L) { - attributes.put("expiry", node.getExpiry()); - } - - if (!node.getContexts().isEmpty()) { - Map context = new HashMap<>(); - Map> map = node.getContexts().toMultimap().asMap(); - - for (Map.Entry> e : map.entrySet()) { - List vals = new ArrayList<>(e.getValue()); - int size = vals.size(); - - if (size == 1) { - context.put(e.getKey(), vals.get(0)); - } else if (size > 1) { - context.put(e.getKey(), vals); - } - } - - attributes.put("context", context); - } - - // create a new map to represent this entry in the list - // the map will only contain one entry. (the permission --> attributes) - Map perm = new HashMap<>(); - - // add the node to the map - perm.put(node.getPermission(), attributes); - - // add the map to the object list, and continue - data.add(perm); - } - - return data; - } -} diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/sql/SqlDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/sql/SqlDao.java index 58efa1e8..52b4594f 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/sql/SqlDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/sql/SqlDao.java @@ -47,7 +47,6 @@ import me.lucko.luckperms.common.node.NodeModel; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.references.UserIdentifier; import me.lucko.luckperms.common.storage.dao.AbstractDao; -import me.lucko.luckperms.common.storage.dao.legacy.LegacySqlMigration; import me.lucko.luckperms.common.storage.dao.sql.connection.AbstractConnectionFactory; import me.lucko.luckperms.common.storage.dao.sql.connection.file.SQLiteConnectionFactory; import me.lucko.luckperms.common.storage.dao.sql.connection.hikari.PostgreConnectionFactory; @@ -115,11 +114,8 @@ public class SqlDao extends AbstractDao { private static final String ACTION_INSERT = "INSERT INTO {prefix}actions(time, actor_uuid, actor_name, type, acted_uuid, acted_name, action) VALUES(?, ?, ?, ?, ?, ?, ?)"; private static final String ACTION_SELECT_ALL = "SELECT * FROM {prefix}actions"; - private final Gson gson; - private final AbstractConnectionFactory provider; - private final Function prefix; public SqlDao(LuckPermsPlugin plugin, AbstractConnectionFactory provider, String prefix) { @@ -133,10 +129,6 @@ public class SqlDao extends AbstractDao { return this.gson; } - public AbstractConnectionFactory getProvider() { - return this.provider; - } - public Function getPrefix() { return this.prefix; } @@ -193,15 +185,6 @@ public class SqlDao extends AbstractDao { } } } - - // Try migration from legacy backing - if (tableExists("lp_users")) { - this.plugin.getLog().severe("===== Legacy Schema Migration ====="); - this.plugin.getLog().severe("Starting migration from legacy schema. This could take a while...."); - this.plugin.getLog().severe("Please do not stop your server while the migration takes place."); - - new LegacySqlMigration(this).run(); - } } // migrations diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/provider/StorageProviders.java b/common/src/main/java/me/lucko/luckperms/common/storage/provider/StorageProviders.java index a058228a..d1aa449b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/provider/StorageProviders.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/provider/StorageProviders.java @@ -25,6 +25,9 @@ package me.lucko.luckperms.common.storage.provider; +/** + * Hook to allow external code to provide a storage dao + */ public final class StorageProviders { private static StorageProvider provider = null; diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/wrappings/BufferedOutputStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/wrappings/BufferedOutputStorage.java index 82b459c9..2836831a 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/wrappings/BufferedOutputStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/wrappings/BufferedOutputStorage.java @@ -46,6 +46,9 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; +/** + * A storage wrapping that passes save tasks through a buffer + */ public class BufferedOutputStorage implements Storage, Runnable { public static BufferedOutputStorage wrap(Storage storage, long flushTime) { return new BufferedOutputStorage(storage, flushTime); diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/wrappings/PhasedStorage.java b/common/src/main/java/me/lucko/luckperms/common/storage/wrappings/PhasedStorage.java index 1eb845c2..fabe37ef 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/wrappings/PhasedStorage.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/wrappings/PhasedStorage.java @@ -49,7 +49,8 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** - * A Datastore wrapping that ensures all tasks are completed before {@link Storage#shutdown()} is called. + * A storage wrapping that ensures all tasks are completed before + * {@link Storage#shutdown()} is called. */ public class PhasedStorage implements Storage { public static PhasedStorage wrap(Storage storage) { diff --git a/common/src/main/java/me/lucko/luckperms/common/utils/HikariSupplier.java b/common/src/main/java/me/lucko/luckperms/common/utils/HikariSupplier.java deleted file mode 100644 index ae2c9699..00000000 --- a/common/src/main/java/me/lucko/luckperms/common/utils/HikariSupplier.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This file is part of LuckPerms, licensed under the MIT License. - * - * Copyright (c) lucko (Luck) - * Copyright (c) contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package me.lucko.luckperms.common.utils; - -import com.zaxxer.hikari.HikariDataSource; - -import java.sql.Connection; -import java.sql.SQLException; - -/** - * A simple hikari wrapper - */ -public class HikariSupplier implements AutoCloseable { - - private final String address; - private final String database; - private final String username; - private final String password; - - private HikariDataSource hikari; - - public HikariSupplier(String address, String database, String username, String password) { - this.address = address; - this.database = database; - this.username = username; - this.password = password; - } - - public void setup(String poolName) { - this.hikari = new HikariDataSource(); - this.hikari.setPoolName(poolName); - this.hikari.setMaximumPoolSize(2); - this.hikari.setDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlDataSource"); - this.hikari.addDataSourceProperty("serverName", this.address.split(":")[0]); - this.hikari.addDataSourceProperty("port", this.address.split(":")[1]); - this.hikari.addDataSourceProperty("databaseName", this.database); - this.hikari.addDataSourceProperty("user", this.username); - this.hikari.addDataSourceProperty("password", this.password); - } - - @Override - public void close() { - this.hikari.close(); - } - - public Connection getConnection() throws SQLException { - return this.hikari.getConnection(); - } -} diff --git a/common/src/main/java/me/lucko/luckperms/common/utils/SafeIterator.java b/common/src/main/java/me/lucko/luckperms/common/utils/SafeIteration.java similarity index 97% rename from common/src/main/java/me/lucko/luckperms/common/utils/SafeIterator.java rename to common/src/main/java/me/lucko/luckperms/common/utils/SafeIteration.java index 2a4c8818..1a62f113 100644 --- a/common/src/main/java/me/lucko/luckperms/common/utils/SafeIterator.java +++ b/common/src/main/java/me/lucko/luckperms/common/utils/SafeIteration.java @@ -28,7 +28,7 @@ package me.lucko.luckperms.common.utils; import java.util.function.Consumer; import java.util.function.Function; -public final class SafeIterator { +public final class SafeIteration { public static void iterate(Iterable iterable, Consumer action) { for (I i : iterable) { @@ -70,6 +70,6 @@ public final class SafeIterator { } } - private SafeIterator() {} + private SafeIteration() {} } diff --git a/common/src/main/java/me/lucko/luckperms/common/utils/Scripting.java b/common/src/main/java/me/lucko/luckperms/common/utils/Scripting.java index dddfbb52..96b63633 100644 --- a/common/src/main/java/me/lucko/luckperms/common/utils/Scripting.java +++ b/common/src/main/java/me/lucko/luckperms/common/utils/Scripting.java @@ -29,17 +29,17 @@ import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; /** - * Nashorn provider utility + * Provides a nashorn script engine (lazily) */ public final class Scripting { - private static ScriptEngine SCRIPT_ENGINE = null; + private static ScriptEngine engine = null; // Lazily load public static synchronized ScriptEngine getScriptEngine() { - if (SCRIPT_ENGINE == null) { - SCRIPT_ENGINE = new ScriptEngineManager(null).getEngineByName("nashorn"); + if (engine == null) { + engine = new ScriptEngineManager(null).getEngineByName("nashorn"); } - return SCRIPT_ENGINE; + return engine; } private Scripting() {} diff --git a/common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditorUtils.java b/common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditor.java similarity index 97% rename from common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditorUtils.java rename to common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditor.java index 8d6fa2d3..f45a7435 100644 --- a/common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditorUtils.java +++ b/common/src/main/java/me/lucko/luckperms/common/webeditor/WebEditor.java @@ -63,7 +63,7 @@ import java.util.stream.Stream; /** * Utility methods for interacting with the LuckPerms web permission editor. */ -public final class WebEditorUtils { +public final class WebEditor { private static final Gson GSON = new Gson(); private static final String FILE_NAME = "luckperms-data.json"; @@ -80,7 +80,7 @@ public final class WebEditorUtils { } // attach the holders permissions - payload.add("nodes", WebEditorUtils.serializePermissions(holder.getEnduringNodes().values().stream().map(NodeModel::fromNode))); + payload.add("nodes", serializePermissions(holder.getEnduringNodes().values().stream().map(NodeModel::fromNode))); } public static JsonObject formPayload(List holders, Sender sender, String cmdLabel, LuckPermsPlugin plugin) { @@ -206,7 +206,7 @@ public final class WebEditorUtils { } } - public static JsonArray serializePermissions(Stream nodes) { + private static JsonArray serializePermissions(Stream nodes) { JsonArray arr = new JsonArray(); nodes.forEach(node -> { JsonObject attributes = new JsonObject(); @@ -275,6 +275,6 @@ public final class WebEditorUtils { return nodes; } - private WebEditorUtils() {} + private WebEditor() {} } diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSchedulerAdapter.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSchedulerAdapter.java index b59c9150..96d09e6c 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSchedulerAdapter.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeSchedulerAdapter.java @@ -27,7 +27,7 @@ package me.lucko.luckperms.sponge; import me.lucko.luckperms.common.plugin.SchedulerAdapter; import me.lucko.luckperms.common.plugin.SchedulerTask; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import org.spongepowered.api.scheduler.Scheduler; import org.spongepowered.api.scheduler.Task; @@ -122,7 +122,7 @@ public class SpongeSchedulerAdapter implements SchedulerAdapter { @Override public void shutdown() { - SafeIterator.iterate(this.tasks, SchedulerTask::cancel); + SafeIteration.iterate(this.tasks, SchedulerTask::cancel); } private static final class SpongeSchedulerTask implements SchedulerTask { diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionManager.java b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionManager.java index 5d5114a2..c6dd8a73 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionManager.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionManager.java @@ -38,7 +38,7 @@ import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import me.lucko.luckperms.common.utils.Uuids; import me.lucko.luckperms.sponge.LPSpongePlugin; import me.lucko.luckperms.sponge.service.LuckPermsService; @@ -91,7 +91,7 @@ public class MigrationPermissionManager extends SubCommand { // Migrate defaults log.log("Migrating default subjects."); - SafeIterator.iterate(pmService.getKnownSubjects().values(), collection -> { + SafeIteration.iterate(pmService.getKnownSubjects().values(), collection -> { migrateSubjectData( collection.getDefaults().getSubjectData(), lpService.getCollection("defaults").loadSubject(collection.getIdentifier()).join().sponge().getSubjectData() @@ -102,7 +102,7 @@ public class MigrationPermissionManager extends SubCommand { // Migrate groups log.log("Starting group migration."); AtomicInteger groupCount = new AtomicInteger(0); - SafeIterator.iterate(pmService.getGroupSubjects().getAllSubjects(), pmGroup -> { + SafeIteration.iterate(pmService.getGroupSubjects().getAllSubjects(), pmGroup -> { String pmName = MigrationUtils.standardizeName(pmGroup.getIdentifier()); // Make a LuckPerms group for the one being migrated @@ -117,7 +117,7 @@ public class MigrationPermissionManager extends SubCommand { // Migrate users log.log("Starting user migration."); AtomicInteger userCount = new AtomicInteger(0); - SafeIterator.iterate(pmService.getUserSubjects().getAllSubjects(), pmUser -> { + SafeIteration.iterate(pmService.getUserSubjects().getAllSubjects(), pmUser -> { UUID uuid = Uuids.parseNullable(pmUser.getIdentifier()); if (uuid == null) { log.logErr("Could not parse UUID for user: " + pmUser.getIdentifier()); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionsEx.java b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionsEx.java index bcbb02e5..b1cf471e 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionsEx.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/migration/MigrationPermissionsEx.java @@ -39,7 +39,7 @@ import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.User; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.utils.Predicates; -import me.lucko.luckperms.common.utils.SafeIterator; +import me.lucko.luckperms.common.utils.SafeIteration; import me.lucko.luckperms.common.utils.Uuids; import me.lucko.luckperms.sponge.LPSpongePlugin; import me.lucko.luckperms.sponge.service.LuckPermsService; @@ -88,7 +88,7 @@ public class MigrationPermissionsEx extends SubCommand { // Migrate defaults log.log("Migrating default subjects."); - SafeIterator.iterate(pexService.getKnownSubjects().values(), collection -> { + SafeIteration.iterate(pexService.getKnownSubjects().values(), collection -> { migrateSubjectData( collection.getDefaults().getSubjectData(), lpService.getCollection("defaults").loadSubject(collection.getIdentifier()).join().sponge().getSubjectData() @@ -113,7 +113,7 @@ public class MigrationPermissionsEx extends SubCommand { // Migrate groups log.log("Starting group migration."); AtomicInteger groupCount = new AtomicInteger(0); - SafeIterator.iterate(pexService.getGroupSubjects().getAllSubjects(), pexGroup -> { + SafeIteration.iterate(pexService.getGroupSubjects().getAllSubjects(), pexGroup -> { String pexName = MigrationUtils.standardizeName(pexGroup.getIdentifier()); Optional rankString = pexGroup.getOption("rank"); @@ -151,7 +151,7 @@ public class MigrationPermissionsEx extends SubCommand { // Migrate tracks log.log("Starting track migration."); - SafeIterator.iterate(tracks.entrySet(), e -> { + SafeIteration.iterate(tracks.entrySet(), e -> { Track track = plugin.getStorage().createAndLoadTrack(e.getKey(), CreationCause.INTERNAL).join(); for (String groupName : e.getValue().values()) { Group group = plugin.getGroupManager().getIfLoaded(groupName); @@ -169,7 +169,7 @@ public class MigrationPermissionsEx extends SubCommand { // Increment the max weight from the group migrations. All user meta should override. int userWeight = maxWeight + 5; - SafeIterator.iterate(pexService.getUserSubjects().getAllSubjects(), pexUser -> { + SafeIteration.iterate(pexService.getUserSubjects().getAllSubjects(), pexUser -> { UUID uuid = Uuids.parseNullable(pexUser.getIdentifier()); if (uuid == null) { log.logErr("Could not parse UUID for user: " + pexUser.getIdentifier());