Add import/export support
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -147,36 +147,30 @@ public abstract class SubCommand<T> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class LogMainCommand extends MainCommand<Log> {
|
||||
.add(new LogRecent())
|
||||
.add(new LogSearch())
|
||||
.add(new LogNotify())
|
||||
// .add(new LogExport())
|
||||
.add(new LogExport())
|
||||
.add(new LogUserHistory())
|
||||
.add(new LogGroupHistory())
|
||||
.add(new LogTrackHistory())
|
||||
|
||||
@@ -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<Log> {
|
||||
@@ -39,7 +46,83 @@ public class LogExport extends SubCommand<Log> {
|
||||
|
||||
@Override
|
||||
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Log log, List<String> 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<String> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* 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 <file>", 1, Permission.IMPORT);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> 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<String> 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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<String> commands = null;
|
||||
private Map<Integer, Result> 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<String> 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<String> 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<Integer, Result> 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<Integer, Result> e : cmdResult.entrySet()) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user