diff --git a/README.md b/README.md index 7739715d8..e48ff293f 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ A permissions implementation for Bukkit/Spigot, BungeeCord and Sponge. * **Vault Support** - hooks into Vault to integrate with other plugins * **Developer API** - easily integrate LuckPerms into your own projects * **Advanced action logging** - keep track of permission changes over time +* **Easily switch between storage systems** - export a log file from one datastore and import it into another * **Easy and simple setup and configuration using commands** - no editing yml files, yuck * **Negated permissions and groups** - define special rules for certain users/groups * **Regex permissions** - define special permissions using regex @@ -188,6 +189,7 @@ Additionally, you can use wildcards to grant users access to a selection of comm * /perms sync - luckperms.sync * /perms info - luckperms.info * /perms debug - luckperms.debug +* /perms import - luckperms.import * /perms creategroup \ - luckperms.creategroup * /perms deletegroup \ - luckperms.deletegroup * /perms listgroups - luckperms.listgroups @@ -243,6 +245,7 @@ Additionally, you can use wildcards to grant users access to a selection of comm * /perms log recent [user] [page] - luckperms.log.recent * /perms log search \ [page] - luckperms.log.search * /perms log notify [on|off] - luckperms.log.notify +* /perms log export \ - luckperms.log.export * /perms log userhistory \ [page] - luckperms.log.userhistory * /perms log grouphistory \ [page] - luckperms.log.grouphistory * /perms log trackhistory \ [page] - luckperms.log.trackhistory diff --git a/api/src/main/java/me/lucko/luckperms/api/LogEntry.java b/api/src/main/java/me/lucko/luckperms/api/LogEntry.java index 691dc660c..e37187583 100644 --- a/api/src/main/java/me/lucko/luckperms/api/LogEntry.java +++ b/api/src/main/java/me/lucko/luckperms/api/LogEntry.java @@ -74,7 +74,7 @@ public class LogEntry implements Comparable { @Override public int compareTo(LogEntry o) { - return Long.compare(timestamp, o.getTimestamp()); + return equals(o) ? 0 : (Long.compare(timestamp, o.getTimestamp()) == 0 ? 1 : Long.compare(timestamp, o.getTimestamp())); } public boolean matchesSearch(String query) { diff --git a/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java b/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java index 65a6ff687..3307b0bcd 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java +++ b/bukkit/src/main/java/me/lucko/luckperms/LPBukkitPlugin.java @@ -31,6 +31,7 @@ import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.core.LPConfiguration; import me.lucko.luckperms.core.UuidCache; +import me.lucko.luckperms.data.Importer; import me.lucko.luckperms.groups.GroupManager; import me.lucko.luckperms.runnables.UpdateTask; import me.lucko.luckperms.storage.Datastore; @@ -61,6 +62,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { private Datastore datastore; private UuidCache uuidCache; private Logger log; + private Importer importer; @Override public void onEnable() { @@ -105,6 +107,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { userManager = new BukkitUserManager(this); groupManager = new GroupManager(this); trackManager = new TrackManager(); + importer = new Importer(commandManager); // Run update task to refresh any online users getLog().info("Scheduling Update Task to refresh any online users."); @@ -169,6 +172,11 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin { return getDescription().getVersion(); } + @Override + public File getMainDir() { + return getDataFolder(); + } + @Override public Message getPlayerStatus(UUID uuid) { return getServer().getPlayer(getUuidCache().getExternalUUID(uuid)) != null ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE; diff --git a/bukkit/src/main/resources/plugin.yml b/bukkit/src/main/resources/plugin.yml index 9197974d6..28c801781 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/bukkit/src/main/resources/plugin.yml @@ -15,6 +15,7 @@ permissions: luckperms.sync: true luckperms.info: true luckperms.debug: true + luckperms.import: true luckperms.creategroup: true luckperms.deletegroup: true luckperms.listgroups: true diff --git a/bungee/src/main/java/me/lucko/luckperms/LPBungeePlugin.java b/bungee/src/main/java/me/lucko/luckperms/LPBungeePlugin.java index f0b8e181b..bc87db16a 100644 --- a/bungee/src/main/java/me/lucko/luckperms/LPBungeePlugin.java +++ b/bungee/src/main/java/me/lucko/luckperms/LPBungeePlugin.java @@ -30,6 +30,7 @@ import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.core.LPConfiguration; import me.lucko.luckperms.core.UuidCache; +import me.lucko.luckperms.data.Importer; import me.lucko.luckperms.groups.GroupManager; import me.lucko.luckperms.runnables.UpdateTask; import me.lucko.luckperms.storage.Datastore; @@ -42,6 +43,7 @@ import me.lucko.luckperms.utils.LogFactory; import net.md_5.bungee.api.connection.ProxiedPlayer; import net.md_5.bungee.api.plugin.Plugin; +import java.io.File; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -56,6 +58,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { private Datastore datastore; private UuidCache uuidCache; private Logger log; + private Importer importer; @Override public void onEnable() { @@ -69,7 +72,8 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { // register commands getLog().info("Registering commands..."); - getProxy().getPluginManager().registerCommand(this, new BungeeCommand(new CommandManager(this))); + CommandManager commandManager = new CommandManager(this); + getProxy().getPluginManager().registerCommand(this, new BungeeCommand(commandManager)); // disable the default Bungee /perms command so it gets handled by the Bukkit plugin getProxy().getDisabledCommands().add("perms"); @@ -95,6 +99,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { userManager = new BungeeUserManager(this); groupManager = new GroupManager(this); trackManager = new TrackManager(); + importer = new Importer(commandManager); // Run update task to refresh any online users getLog().info("Scheduling Update Task to refresh any online users."); @@ -132,6 +137,11 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin { return getDescription().getVersion(); } + @Override + public File getMainDir() { + return getDataFolder(); + } + @Override public Message getPlayerStatus(UUID uuid) { return getProxy().getPlayer(getUuidCache().getExternalUUID(uuid)) != null ? Message.PLAYER_ONLINE : Message.PLAYER_OFFLINE; diff --git a/common/src/main/java/me/lucko/luckperms/LuckPermsPlugin.java b/common/src/main/java/me/lucko/luckperms/LuckPermsPlugin.java index 982eb7391..43e8d5a4d 100644 --- a/common/src/main/java/me/lucko/luckperms/LuckPermsPlugin.java +++ b/common/src/main/java/me/lucko/luckperms/LuckPermsPlugin.java @@ -27,11 +27,13 @@ import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.core.LPConfiguration; import me.lucko.luckperms.core.UuidCache; +import me.lucko.luckperms.data.Importer; import me.lucko.luckperms.groups.GroupManager; import me.lucko.luckperms.storage.Datastore; import me.lucko.luckperms.tracks.TrackManager; import me.lucko.luckperms.users.UserManager; +import java.io.File; import java.util.List; import java.util.Set; import java.util.UUID; @@ -89,6 +91,16 @@ public interface LuckPermsPlugin { */ String getVersion(); + /** + * @return the main plugin directory + */ + File getMainDir(); + + /** + * @return the importer instance for the platform + */ + Importer getImporter(); + /** * Returns a colored string indicating the status of a player * @param uuid The player's uuid diff --git a/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java b/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java index 7c1447c52..38a6208d5 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java +++ b/common/src/main/java/me/lucko/luckperms/commands/CommandManager.java @@ -33,6 +33,7 @@ import me.lucko.luckperms.commands.group.GroupMainCommand; import me.lucko.luckperms.commands.group.ListGroups; import me.lucko.luckperms.commands.log.LogMainCommand; import me.lucko.luckperms.commands.misc.DebugCommand; +import me.lucko.luckperms.commands.misc.ImportCommand; import me.lucko.luckperms.commands.misc.InfoCommand; import me.lucko.luckperms.commands.misc.SyncCommand; import me.lucko.luckperms.commands.track.CreateTrack; @@ -61,6 +62,7 @@ public class CommandManager { .add(new SyncCommand()) .add(new InfoCommand()) .add(new DebugCommand()) + .add(new ImportCommand()) .add(new CreateGroup()) .add(new DeleteGroup()) .add(new ListGroups()) diff --git a/common/src/main/java/me/lucko/luckperms/commands/SubCommand.java b/common/src/main/java/me/lucko/luckperms/commands/SubCommand.java index aeb328826..28808049c 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/SubCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/SubCommand.java @@ -147,36 +147,30 @@ public abstract class SubCommand { protected static void save(User user, Sender sender, LuckPermsPlugin plugin) { user.refreshPermissions(); - plugin.getDatastore().saveUser(user, success -> { - if (success) { - Message.USER_SAVE_SUCCESS.send(sender); - } else { - Message.USER_SAVE_ERROR.send(sender); - } - }); + if (plugin.getDatastore().saveUser(user)) { + Message.USER_SAVE_SUCCESS.send(sender); + } else { + Message.USER_SAVE_ERROR.send(sender); + } } protected static void save(Group group, Sender sender, LuckPermsPlugin plugin) { - plugin.getDatastore().saveGroup(group, success -> { - if (success) { - Message.GROUP_SAVE_SUCCESS.send(sender); - } else { - Message.GROUP_SAVE_ERROR.send(sender); - } + if (plugin.getDatastore().saveGroup(group)) { + Message.GROUP_SAVE_SUCCESS.send(sender); + } else { + Message.GROUP_SAVE_ERROR.send(sender); + } - plugin.runUpdateTask(); - }); + plugin.runUpdateTask(); } protected static void save(Track track, Sender sender, LuckPermsPlugin plugin) { - plugin.getDatastore().saveTrack(track, success -> { - if (success) { - Message.TRACK_SAVE_SUCCESS.send(sender); - } else { - Message.TRACK_SAVE_ERROR.send(sender); - } + if (plugin.getDatastore().saveTrack(track)) { + Message.TRACK_SAVE_SUCCESS.send(sender); + } else { + Message.TRACK_SAVE_ERROR.send(sender); + } - plugin.runUpdateTask(); - }); + plugin.runUpdateTask(); } } diff --git a/common/src/main/java/me/lucko/luckperms/commands/log/LogMainCommand.java b/common/src/main/java/me/lucko/luckperms/commands/log/LogMainCommand.java index 89bb7324e..d5e972463 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/log/LogMainCommand.java +++ b/common/src/main/java/me/lucko/luckperms/commands/log/LogMainCommand.java @@ -42,7 +42,7 @@ public class LogMainCommand extends MainCommand { .add(new LogRecent()) .add(new LogSearch()) .add(new LogNotify()) - // .add(new LogExport()) + .add(new LogExport()) .add(new LogUserHistory()) .add(new LogGroupHistory()) .add(new LogTrackHistory()) diff --git a/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogExport.java b/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogExport.java index 0abd2f271..0407d856b 100644 --- a/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogExport.java +++ b/common/src/main/java/me/lucko/luckperms/commands/log/subcommands/LogExport.java @@ -23,13 +23,20 @@ package me.lucko.luckperms.commands.log.subcommands; import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.api.LogEntry; import me.lucko.luckperms.commands.CommandResult; import me.lucko.luckperms.commands.Predicate; import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.commands.SubCommand; +import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.data.Log; +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.ArrayList; import java.util.List; public class LogExport extends SubCommand { @@ -39,7 +46,83 @@ public class LogExport extends SubCommand { @Override public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Log log, List args, String label) { - // TODO: implement this - return CommandResult.SUCCESS; + File f = new File(plugin.getMainDir(), args.get(0)); + if (f.exists()) { + Message.LOG_EXPORT_ALREADY_EXISTS.send(sender, f.getAbsolutePath()); + return CommandResult.INVALID_ARGS; + } + + if (log.getContent().isEmpty()) { + Message.LOG_EXPORT_EMPTY.send(sender); + return CommandResult.STATE_ERROR; + } + + try { + f.createNewFile(); + } catch (IOException e) { + Message.LOG_EXPORT_FAILURE.send(sender); + e.printStackTrace(); + return CommandResult.FAILURE; + } + + if (!Files.isWritable(f.toPath())) { + Message.LOG_EXPORT_NOT_WRITABLE.send(sender, f.getAbsolutePath()); + return CommandResult.FAILURE; + } + + List data = new ArrayList<>(); + + StringBuilder b = new StringBuilder(); + for (LogEntry e : log.getContent()) { + b.setLength(0); + b.append("/luckperms "); + + if (e.getType() == 'U') { + b.append("user ").append(e.getActed().toString()).append(" ").append(e.getAction()); + } + + group: + if (e.getType() == 'G') { + if (e.getAction().equalsIgnoreCase("create")) { + b.append("creategroup ").append(e.getActedName()); + break group; + } + + if (e.getAction().equalsIgnoreCase("delete")) { + b.append("deletegroup ").append(e.getActedName()); + break group; + } + + b.append("group ").append(e.getActedName()).append(" ").append(e.getAction()); + } + + track: + if (e.getType() == 'T') { + if (e.getAction().equalsIgnoreCase("create")) { + b.append("createtrack ").append(e.getActedName()); + break track; + } + + if (e.getAction().equalsIgnoreCase("delete")) { + b.append("deletetrack ").append(e.getActedName()); + break track; + } + + b.append("track ").append(e.getActedName()).append(" ").append(e.getAction());; + } + + data.add(b.toString()); + } + + + try { + Files.write(f.toPath(), data, Charset.defaultCharset()); + Message.LOG_EXPORT_SUCCESS.send(sender, f.getAbsolutePath()); + return CommandResult.SUCCESS; + } catch (IOException e) { + e.printStackTrace(); + Message.LOG_EXPORT_FAILURE.send(sender); + return CommandResult.FAILURE; + } } } diff --git a/common/src/main/java/me/lucko/luckperms/commands/misc/ImportCommand.java b/common/src/main/java/me/lucko/luckperms/commands/misc/ImportCommand.java new file mode 100644 index 000000000..fd3ac5993 --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/commands/misc/ImportCommand.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016 Lucko (Luck) + * + * 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.commands.misc; + +import me.lucko.luckperms.LuckPermsPlugin; +import me.lucko.luckperms.commands.CommandResult; +import me.lucko.luckperms.commands.Sender; +import me.lucko.luckperms.commands.SingleMainCommand; +import me.lucko.luckperms.constants.Message; +import me.lucko.luckperms.constants.Permission; +import me.lucko.luckperms.data.Importer; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.List; + +public class ImportCommand extends SingleMainCommand { + public ImportCommand() { + super("Import", "/%s import ", 1, Permission.IMPORT); + } + + @Override + protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List args, String label) { + if (args.size() == 0) { + sendUsage(sender, label); + return CommandResult.INVALID_ARGS; + } + + Importer importer = plugin.getImporter(); + + File f = new File(plugin.getMainDir(), args.get(0)); + if (!f.exists()) { + Message.IMPORT_LOG_DOESNT_EXIST.send(sender, f.getAbsolutePath()); + return CommandResult.INVALID_ARGS; + } + + if (!Files.isReadable(f.toPath())) { + Message.IMPORT_LOG_NOT_READABLE.send(sender, f.getAbsolutePath()); + return CommandResult.FAILURE; + } + + List commands; + + try { + commands = Files.readAllLines(f.toPath(), Charset.defaultCharset()); + } catch (IOException e) { + e.printStackTrace(); + Message.IMPORT_LOG_FAILURE.send(sender); + return CommandResult.FAILURE; + } + + if (!importer.startRun()) { + Message.IMPORT_ALREADY_RUNNING.send(sender); + return CommandResult.STATE_ERROR; + } + + // Run the importer in its own thread. + plugin.doAsync(() -> importer.start(sender, commands)); + return CommandResult.SUCCESS; + } +} diff --git a/common/src/main/java/me/lucko/luckperms/constants/Message.java b/common/src/main/java/me/lucko/luckperms/constants/Message.java index e5859f388..ff6b37e56 100644 --- a/common/src/main/java/me/lucko/luckperms/constants/Message.java +++ b/common/src/main/java/me/lucko/luckperms/constants/Message.java @@ -270,22 +270,34 @@ public enum Message { LOG_HISTORY_GROUP_HEADER("&aShowing history for group &b%s &a(page &f%s&a of &f%s&a)", true), LOG_HISTORY_TRACK_HEADER("&aShowing history for track &b%s &a(page &f%s&a of &f%s&a)", true), - IMPORT_PROGRESS("&e(Import) &d-> &6%s% complete &7- &e%s&6/&e%s &6operations complete with &c%s &6errors.", true), - IMPORT_PROGRESS_SIN("&e(Import) &d-> &6%s% complete &7- &e%s&6/&e%s &6operations complete with &c%s &6error.", true), + LOG_EXPORT_ALREADY_EXISTS("Error: File %s already exists.", true), + LOG_EXPORT_NOT_WRITABLE("Error: File %s is not writable.", true), + LOG_EXPORT_EMPTY("The log is empty and therefore cannot be exported.", true), + LOG_EXPORT_FAILURE("An unexpected error occured whilst writing to the file.", true), + LOG_EXPORT_SUCCESS("&aSuccessfully exported the log to &b%s&a.", true), + + IMPORT_ALREADY_RUNNING("Another import process is already running. Please wait for it to finish and try again.", true), + IMPORT_LOG_DOESNT_EXIST("Error: File %s does not exist.", true), + IMPORT_LOG_NOT_READABLE("Error: File %s is not readable.", true), + IMPORT_LOG_FAILURE("An unexpected error occured whilst reading from the log file.", true), + + IMPORT_PROGRESS("&e(Import) &d-> &f%s &6percent complete &7- &e%s&6/&e%s &6operations complete with &c%s &6errors.", true), + IMPORT_PROGRESS_SIN("&e(Import) &d-> &f%s &6percent complete &7- &e%s&6/&e%s &6operations complete with &c%s &6error.", true), IMPORT_START("&e(Import) &d-> &6Starting import process.", true), IMPORT_END_COMPLETE("&e(Import) &a&lCOMPLETED &7- took &e%s &7seconds - &7No errors.", true), IMPORT_END_COMPLETE_ERR("&e(Import) &a&lCOMPLETED &7- took &e%s &7seconds - &c%s errors.", true), IMPORT_END_COMPLETE_ERR_SIN("&e(Import) &a&lCOMPLETED &7- took &e%s &7seconds - &c%s error.", true), IMPORT_END_ERROR_HEADER( - PREFIX + "&e(Import) &7-----> &6Showing Error #&e%s &7<-----" + "\n" + + PREFIX + "&e(Import) &7------------> &6Showing Error #&e%s &7<------------" + "\n" + PREFIX + "&e(Import) &6Whilst executing: &fCommand #%s" + "\n" + - PREFIX + "&e(Import) &6Output:s", + PREFIX + "&e(Import) &6Type: &f%s" + "\n" + + PREFIX + "&e(Import) &6Output:", false ), - IMPORT_END_ERROR_CONTENT("&e(Import) &7-> &c%s", true), - IMPORT_END_ERROR_FOOTER("&e(Import) &7<---------------------------->", true); + IMPORT_END_ERROR_CONTENT("&e(Import) &d-> &c%s", true), + IMPORT_END_ERROR_FOOTER("&e(Import) &7<------------------------------------------>", true); private String message; private boolean showPrefix; diff --git a/common/src/main/java/me/lucko/luckperms/constants/Permission.java b/common/src/main/java/me/lucko/luckperms/constants/Permission.java index 24619e211..6921476fe 100644 --- a/common/src/main/java/me/lucko/luckperms/constants/Permission.java +++ b/common/src/main/java/me/lucko/luckperms/constants/Permission.java @@ -32,6 +32,7 @@ public enum Permission { SYNC("sync", null), INFO("info", null), DEBUG("debug", null), + IMPORT("import", null), CREATE_GROUP("creategroup", null), DELETE_GROUP("deletegroup", null), diff --git a/common/src/main/java/me/lucko/luckperms/data/Importer.java b/common/src/main/java/me/lucko/luckperms/data/Importer.java index 4d6d22d79..f5ec21c7f 100644 --- a/common/src/main/java/me/lucko/luckperms/data/Importer.java +++ b/common/src/main/java/me/lucko/luckperms/data/Importer.java @@ -41,13 +41,10 @@ import java.util.stream.Collectors; * Executes a list of commands sequentially in a single thread. */ @RequiredArgsConstructor -public class Importer { // TODO: implement this - - @Getter - private boolean running = false; - +public class Importer { private final CommandManager commandManager; + private boolean running = false; private Sender executor = null; private List commands = null; private Map cmdResult = null; @@ -55,16 +52,22 @@ public class Importer { // TODO: implement this private long lastMsg = 0; private int executing = -1; - public synchronized void start(Sender executor, List commands) { - if (isRunning()) { - throw new IllegalStateException("Import already running."); + public synchronized boolean startRun() { + if (running) { + return false; } running = true; + return true; + + } + + public void start(Sender executor, List commands) { this.executor = executor; this.commands = commands.stream() .map(s -> s.startsWith("/") ? s.substring(1) : s) - .map(s -> s.startsWith("perms ") ? s.substring(5) : s) + .map(s -> s.startsWith("perms ") ? s.substring(6) : s) + .map(s -> s.startsWith("luckperms ") ? s.substring(10) : s) .collect(Collectors.toList()); cmdResult = new HashMap<>(); @@ -127,7 +130,7 @@ public class Importer { // TODO: implement this int errIndex = 1; for (Map.Entry e : cmdResult.entrySet()) { if (e.getValue().getResult() != null && !e.getValue().getResult().booleanValue()) { - Message.IMPORT_END_ERROR_HEADER.send(executor, errIndex, e.getKey()); + Message.IMPORT_END_ERROR_HEADER.send(executor, errIndex, e.getKey(), e.getValue().getResult().toString()); for (String s : e.getValue().getOutput()) { Message.IMPORT_END_ERROR_CONTENT.send(executor, s); } @@ -140,7 +143,7 @@ public class Importer { // TODO: implement this } private void sendProgress(int executing) { - int percent = (executing / commands.size()) * 100; + int percent = (executing * 100) / commands.size(); int errors = 0; for (Map.Entry e : cmdResult.entrySet()) { diff --git a/common/src/main/java/me/lucko/luckperms/data/LogEntry.java b/common/src/main/java/me/lucko/luckperms/data/LogEntry.java index 5c635b5ac..7f1733dfa 100644 --- a/common/src/main/java/me/lucko/luckperms/data/LogEntry.java +++ b/common/src/main/java/me/lucko/luckperms/data/LogEntry.java @@ -23,7 +23,6 @@ package me.lucko.luckperms.data; import me.lucko.luckperms.LuckPermsPlugin; -import me.lucko.luckperms.api.data.Callback; import me.lucko.luckperms.commands.Sender; import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; @@ -42,7 +41,7 @@ public class LogEntry extends me.lucko.luckperms.api.LogEntry { } public void submit(LuckPermsPlugin plugin) { - plugin.getDatastore().logAction(this, Callback.empty()); + plugin.getDatastore().logAction(this); final String msg = super.getFormatted(); diff --git a/common/src/main/java/me/lucko/luckperms/storage/methods/MySQLDatastore.java b/common/src/main/java/me/lucko/luckperms/storage/methods/MySQLDatastore.java index 37bc18fb9..cc0ea80e1 100644 --- a/common/src/main/java/me/lucko/luckperms/storage/methods/MySQLDatastore.java +++ b/common/src/main/java/me/lucko/luckperms/storage/methods/MySQLDatastore.java @@ -38,7 +38,7 @@ public class MySQLDatastore extends SQLDatastore { private static final String CREATETABLE_USERS = "CREATE TABLE IF NOT EXISTS `lp_users` (`uuid` VARCHAR(36) NOT NULL, `name` VARCHAR(16) NOT NULL, `primary_group` VARCHAR(36) NOT NULL, `perms` TEXT NOT NULL, PRIMARY KEY (`uuid`)) DEFAULT CHARSET=utf8;"; private static final String CREATETABLE_GROUPS = "CREATE TABLE IF NOT EXISTS `lp_groups` (`name` VARCHAR(36) NOT NULL, `perms` TEXT NULL, PRIMARY KEY (`name`)) DEFAULT CHARSET=utf8;"; private static final String CREATETABLE_TRACKS = "CREATE TABLE IF NOT EXISTS `lp_tracks` (`name` VARCHAR(36) NOT NULL, `groups` TEXT NULL, PRIMARY KEY (`name`)) DEFAULT CHARSET=utf8;"; - private static final String CREATETABLE_ACTION = "CREATE TABLE IF NOT EXISTS `lp_actions` (`id` INT AUTO_INCREMENT NOT NULL, `time` BIG INT NOT NULL, `actor_uuid` VARCHAR(36) NOT NULL, `actor_name` VARCHAR(16) NOT NULL, `type` CHAR(1) NOT NULL, `acted_uuid` VARCHAR(36) NOT NULL, `acted_name` VARCHAR(36) NOT NULL, `action` VARCHAR(256) NOT NULL, PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;"; + private static final String CREATETABLE_ACTION = "CREATE TABLE IF NOT EXISTS `lp_actions` (`id` INT AUTO_INCREMENT NOT NULL, `time` BIGINT NOT NULL, `actor_uuid` VARCHAR(36) NOT NULL, `actor_name` VARCHAR(16) NOT NULL, `type` CHAR(1) NOT NULL, `acted_uuid` VARCHAR(36) NOT NULL, `acted_name` VARCHAR(36) NOT NULL, `action` VARCHAR(256) NOT NULL, PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;"; private final MySQLConfiguration configuration; private HikariDataSource hikari; diff --git a/sponge/src/main/java/me/lucko/luckperms/LPSpongePlugin.java b/sponge/src/main/java/me/lucko/luckperms/LPSpongePlugin.java index 2caf98d5c..779e49fb2 100644 --- a/sponge/src/main/java/me/lucko/luckperms/LPSpongePlugin.java +++ b/sponge/src/main/java/me/lucko/luckperms/LPSpongePlugin.java @@ -31,6 +31,7 @@ import me.lucko.luckperms.constants.Message; import me.lucko.luckperms.constants.Permission; import me.lucko.luckperms.core.LPConfiguration; import me.lucko.luckperms.core.UuidCache; +import me.lucko.luckperms.data.Importer; import me.lucko.luckperms.groups.GroupManager; import me.lucko.luckperms.runnables.UpdateTask; import me.lucko.luckperms.storage.Datastore; @@ -87,6 +88,7 @@ public class LPSpongePlugin implements LuckPermsPlugin { private Datastore datastore; private UuidCache uuidCache; private me.lucko.luckperms.api.Logger log; + private Importer importer; @Listener public void onEnable(GamePreInitializationEvent event) { @@ -101,7 +103,8 @@ public class LPSpongePlugin implements LuckPermsPlugin { // register commands getLog().info("Registering commands..."); CommandManager cmdService = Sponge.getCommandManager(); - cmdService.register(this, new SpongeCommand(this), "luckperms", "perms", "lp", "permissions", "p", "perm"); + SpongeCommand commandManager = new SpongeCommand(this); + cmdService.register(this, commandManager, "luckperms", "perms", "lp", "permissions", "p", "perm"); getLog().info("Detecting storage method..."); final String storageMethod = configuration.getStorageMethod(); @@ -110,13 +113,13 @@ public class LPSpongePlugin implements LuckPermsPlugin { datastore = new MySQLDatastore(this, configuration.getDatabaseValues()); } else if (storageMethod.equalsIgnoreCase("sqlite")) { getLog().info("Using SQLite as storage method."); - datastore = new SQLiteDatastore(this, new File(getStorageDir(), "luckperms.sqlite")); + datastore = new SQLiteDatastore(this, new File(getMainDir(), "luckperms.sqlite")); } else if (storageMethod.equalsIgnoreCase("flatfile")) { getLog().info("Using Flatfile (JSON) as storage method."); - datastore = new FlatfileDatastore(this, getStorageDir()); + datastore = new FlatfileDatastore(this, getMainDir()); } else { getLog().severe("Storage method '" + storageMethod + "' was not recognised. Using SQLite as fallback."); - datastore = new SQLiteDatastore(this, new File(getStorageDir(), "luckperms.sqlite")); + datastore = new SQLiteDatastore(this, new File(getMainDir(), "luckperms.sqlite")); } getLog().info("Initialising datastore..."); @@ -127,6 +130,7 @@ public class LPSpongePlugin implements LuckPermsPlugin { userManager = new SpongeUserManager(this); groupManager = new GroupManager(this); trackManager = new TrackManager(); + importer = new Importer(commandManager); // Run update task to refresh any online users getLog().info("Scheduling Update Task to refresh any online users."); @@ -184,7 +188,8 @@ public class LPSpongePlugin implements LuckPermsPlugin { } @SuppressWarnings("ResultOfMethodCallIgnored") - private File getStorageDir() { + @Override + public File getMainDir() { File base = configDir.toFile().getParentFile().getParentFile(); File luckPermsDir = new File(base, "luckperms"); luckPermsDir.mkdirs();