diff --git a/Core/src/main/java/com/plotsquared/core/backup/Backup.java b/Core/src/main/java/com/plotsquared/core/backup/Backup.java index bd7d4f227..92bebd348 100644 --- a/Core/src/main/java/com/plotsquared/core/backup/Backup.java +++ b/Core/src/main/java/com/plotsquared/core/backup/Backup.java @@ -18,6 +18,8 @@ */ package com.plotsquared.core.backup; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.checkerframework.checker.nullness.qual.Nullable; import java.io.IOException; @@ -30,12 +32,14 @@ import java.nio.file.Path; */ public class Backup { + private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Backup.class.getSimpleName()); + private final BackupProfile owner; private final long creationTime; @Nullable private final Path file; - Backup(final BackupProfile owner, final long creationTime, final Path file) { + Backup(final BackupProfile owner, final long creationTime, @Nullable final Path file) { this.owner = owner; this.creationTime = creationTime; this.file = file; @@ -49,7 +53,7 @@ public class Backup { try { Files.deleteIfExists(file); } catch (final IOException e) { - e.printStackTrace(); + LOGGER.error("Error deleting back at {}", file, e); } } } diff --git a/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java b/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java index 1725f5dc6..ce3658df4 100644 --- a/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java +++ b/Core/src/main/java/com/plotsquared/core/backup/PlayerBackupProfile.java @@ -21,14 +21,15 @@ package com.plotsquared.core.backup; import com.google.inject.Inject; import com.google.inject.assistedinject.Assisted; import com.plotsquared.core.configuration.caption.TranslatableCaption; -import com.plotsquared.core.player.ConsolePlayer; +import com.plotsquared.core.exception.PlotSquaredException; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.schematic.Schematic; import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; -import net.kyori.adventure.text.minimessage.MiniMessage; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -51,7 +52,7 @@ import java.util.concurrent.CompletableFuture; */ public class PlayerBackupProfile implements BackupProfile { - static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build(); + private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + PlayerBackupProfile.class.getSimpleName()); private final UUID owner; private final Plot plot; @@ -87,7 +88,7 @@ public class PlayerBackupProfile implements BackupProfile { Files.createDirectory(path); } } catch (final Exception e) { - e.printStackTrace(); + LOGGER.error("Error resolving {} from {}", child, parent, e); } return path; } @@ -104,7 +105,7 @@ public class PlayerBackupProfile implements BackupProfile { try { Files.createDirectories(path); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error creating directory {}", path, e); return Collections.emptyList(); } } @@ -117,11 +118,11 @@ public class PlayerBackupProfile implements BackupProfile { backups.add( new Backup(this, basicFileAttributes.creationTime().toMillis(), file)); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error getting attributes for file {} to create backup", file, e); } }); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error walking files from {}", path, e); } backups.sort(Comparator.comparingLong(Backup::getCreationTime).reversed()); return (this.backupCache = backups); @@ -133,7 +134,7 @@ public class PlayerBackupProfile implements BackupProfile { public void destroy() { this.listBackups().whenCompleteAsync((backups, error) -> { if (error != null) { - error.printStackTrace(); + LOGGER.error("Error while listing backups", error); } backups.forEach(Backup::delete); this.backupCache = null; @@ -141,10 +142,12 @@ public class PlayerBackupProfile implements BackupProfile { } public @NonNull Path getBackupDirectory() { - return resolve(resolve( - resolve(backupManager.getBackupPath(), Objects.requireNonNull(plot.getArea().toString(), "plot area id")), - Objects.requireNonNull(plot.getId().toDashSeparatedString(), "plot id") - ), Objects.requireNonNull(owner.toString(), "owner")); + return resolve( + resolve( + resolve(backupManager.getBackupPath(), Objects.requireNonNull(plot.getArea().toString(), "plot area id")), + Objects.requireNonNull(plot.getId().toDashSeparatedString(), "plot id") + ), Objects.requireNonNull(owner.toString(), "owner") + ); } @Override @@ -156,7 +159,8 @@ public class PlayerBackupProfile implements BackupProfile { backups.get(backups.size() - 1).delete(); } final List plots = Collections.singletonList(plot); - final boolean result = this.schematicHandler.exportAll(plots, getBackupDirectory().toFile(), + final boolean result = this.schematicHandler.exportAll( + plots, getBackupDirectory().toFile(), "%world%-%id%-" + System.currentTimeMillis(), () -> future.complete(new Backup(this, System.currentTimeMillis(), null)) ); @@ -180,7 +184,7 @@ public class PlayerBackupProfile implements BackupProfile { try { schematic = this.schematicHandler.getSchematic(backup.getFile().toFile()); } catch (SchematicHandler.UnsupportedFormatException e) { - e.printStackTrace(); + LOGGER.error("Unsupported format for backup {}", backup.getFile(), e); } if (schematic == null) { future.completeExceptionally(new IllegalArgumentException( @@ -200,10 +204,9 @@ public class PlayerBackupProfile implements BackupProfile { if (value) { future.complete(null); } else { - future.completeExceptionally(new RuntimeException(MINI_MESSAGE.escapeTags( + future.completeExceptionally(new PlotSquaredException( TranslatableCaption - .of("schematics.schematic_paste_failed") - .getComponent(ConsolePlayer.getConsole())))); + .of("schematics.schematic_paste_failed"))); } } } diff --git a/Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java b/Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java index f9f670532..b38697c75 100644 --- a/Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java +++ b/Core/src/main/java/com/plotsquared/core/backup/SimpleBackupManager.java @@ -32,6 +32,8 @@ import com.plotsquared.core.util.task.TaskManager; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -47,6 +49,7 @@ import java.util.concurrent.TimeUnit; @Singleton public class SimpleBackupManager implements BackupManager { + private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + SimpleBackupManager.class.getSimpleName()); private final Path backupPath; private final boolean automaticBackup; private final int backupLimit; @@ -112,7 +115,12 @@ public class SimpleBackupManager implements BackupManager { TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage()))) ); } - throwable.printStackTrace(); + LOGGER.error( + "Error creating backup for plot {};{} and player {}", + plot.getArea(), + plot.getId(), + player == null ? "null" : player.getName(), throwable + ); } else { if (player != null) { player.sendMessage(TranslatableCaption.of("backups.backup_automatic_finished")); @@ -128,6 +136,7 @@ public class SimpleBackupManager implements BackupManager { return this.automaticBackup; } + @NonNull public Path getBackupPath() { return this.backupPath; } diff --git a/Core/src/main/java/com/plotsquared/core/command/Backup.java b/Core/src/main/java/com/plotsquared/core/command/Backup.java index 3ccbb3f98..745c08cb7 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Backup.java +++ b/Core/src/main/java/com/plotsquared/core/command/Backup.java @@ -23,15 +23,20 @@ import com.plotsquared.core.backup.BackupManager; import com.plotsquared.core.backup.BackupProfile; import com.plotsquared.core.backup.NullBackupProfile; import com.plotsquared.core.backup.PlayerBackupProfile; +import com.plotsquared.core.configuration.caption.Caption; import com.plotsquared.core.configuration.caption.TranslatableCaption; +import com.plotsquared.core.exception.PlotSquaredException; import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal3; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.checkerframework.checker.nullness.qual.NonNull; import java.nio.file.Files; @@ -57,6 +62,8 @@ import java.util.stream.Stream; permission = "plots.backup") public final class Backup extends Command { + private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Backup.class.getSimpleName()); + private final BackupManager backupManager; @Inject @@ -326,20 +333,43 @@ public final class Backup extends Command { if (backupProfile instanceof NullBackupProfile) { player.sendMessage( TranslatableCaption.of("backups.backup_impossible"), - TagResolver.resolver("plot", Tag.inserting( - TranslatableCaption.of("generic.generic_other").toComponent(player) - )) + TagResolver.resolver( + "plot", Tag.inserting( + TranslatableCaption.of("generic.generic_other").toComponent(player) + ) + ) ); } else { backupProfile.listBackups().whenComplete((backups, throwable) -> { if (throwable != null) { + Component reason; + if (throwable instanceof PlotSquaredException pe) { + reason = pe.getCaption().toComponent(player); + } else { + reason = Component.text(throwable.getMessage()); + } player.sendMessage( TranslatableCaption.of("backups.backup_load_failure"), - TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage()))) + TagResolver.resolver("reason", Tag.inserting(reason)) + ); + LOGGER.error("Error loading player ({}) backup", player.getName(), throwable); + return; + } + if (number < 1 || number > backups.size()) { + player.sendMessage( + TranslatableCaption.of("backups.backup_impossible"), + TagResolver.resolver( + "plot", + Tag.inserting(TranslatableCaption + .of("generic.generic_invalid_choice") + .toComponent(player)) + ) ); - throwable.printStackTrace(); } else { - if (number < 1 || number > backups.size()) { + final com.plotsquared.core.backup.Backup backup = + backups.get(number - 1); + if (backup == null || backup.getFile() == null || !Files + .exists(backup.getFile())) { player.sendMessage( TranslatableCaption.of("backups.backup_impossible"), TagResolver.resolver( @@ -350,37 +380,23 @@ public final class Backup extends Command { ) ); } else { - final com.plotsquared.core.backup.Backup backup = - backups.get(number - 1); - if (backup == null || backup.getFile() == null || !Files - .exists(backup.getFile())) { - player.sendMessage( - TranslatableCaption.of("backups.backup_impossible"), - TagResolver.resolver( - "plot", - Tag.inserting(TranslatableCaption - .of("generic.generic_invalid_choice") - .toComponent(player)) - ) - ); - } else { - CmdConfirm.addPending(player, "/plot backup load " + number, - () -> backupProfile.restoreBackup(backup, player) - .whenComplete((n, error) -> { - if (error != null) { - player.sendMessage( - TranslatableCaption.of("backups.backup_load_failure"), - TagResolver.resolver( - "reason", - Tag.inserting(Component.text(error.getMessage())) - ) - ); - } else { - player.sendMessage(TranslatableCaption.of("backups.backup_load_success")); - } - }) - ); - } + CmdConfirm.addPending( + player, "/plot backup load " + number, + () -> backupProfile.restoreBackup(backup, player) + .whenComplete((n, error) -> { + if (error != null) { + player.sendMessage( + TranslatableCaption.of("backups.backup_load_failure"), + TagResolver.resolver( + "reason", + Tag.inserting(Component.text(error.getMessage())) + ) + ); + } else { + player.sendMessage(TranslatableCaption.of("backups.backup_load_success")); + } + }) + ); } } }); diff --git a/Core/src/main/java/com/plotsquared/core/exception/PlotSquaredException.java b/Core/src/main/java/com/plotsquared/core/exception/PlotSquaredException.java new file mode 100644 index 000000000..49744bd0f --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/exception/PlotSquaredException.java @@ -0,0 +1,44 @@ +package com.plotsquared.core.exception; + +import com.plotsquared.core.configuration.caption.Caption; +import com.plotsquared.core.configuration.caption.LocaleHolder; + +/** + * Internal use only. Used to allow adventure captions to be used in an exception + * + * @since TODO + */ +public final class PlotSquaredException extends RuntimeException { + + private final Caption caption; + + /** + * Create a new instance with the given caption + * + * @param caption caption + */ + public PlotSquaredException(Caption caption) { + this.caption = caption; + } + + /** + * Create a new instance with the given caption and cause + * + * @param caption caption + * @param cause cause + */ + public PlotSquaredException(Caption caption, Exception cause) { + super(cause); + this.caption = caption; + } + + @Override + public String getMessage() { + return caption.getComponent(LocaleHolder.console()); + } + + public Caption getCaption() { + return caption; + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java index 93e885608..ef3e8775c 100644 --- a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java +++ b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java @@ -135,6 +135,7 @@ public abstract class SchematicHandler { } final String filename; final String website; + final @Nullable UUID finalUuid = uuid; if (uuid == null) { uuid = UUID.randomUUID(); website = Settings.Web.URL + "upload.php?" + uuid; @@ -144,10 +145,11 @@ public abstract class SchematicHandler { filename = file + '.' + extension; } final URL url; + String uri = Settings.Web.URL + "?key=" + uuid + "&type=" + extension; try { - url = URI.create(Settings.Web.URL + "?key=" + uuid + "&type=" + extension).toURL(); + url = URI.create(uri).toURL(); } catch (MalformedURLException e) { - e.printStackTrace(); + LOGGER.error("Malformed URI `{}`", uri, e); whenDone.run(); return; } @@ -193,7 +195,7 @@ public abstract class SchematicHandler { } TaskManager.runTask(whenDone); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error while uploading schematic for UUID {}", finalUuid, e); TaskManager.runTask(whenDone); } }); @@ -388,8 +390,14 @@ public abstract class SchematicHandler { } queue.enqueue(); } catch (Exception e) { - e.printStackTrace(); TaskManager.runTask(whenDone); + LOGGER.error( + "Error pasting schematic to plot {};{} for player {}", + plot.getArea(), + plot.getId(), + actor == null ? "null" : actor.getName(), + e + ); } } @@ -456,7 +464,7 @@ public abstract class SchematicHandler { Clipboard clip = reader.read(); return new Schematic(clip); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error reading schematic from file {}", file.getAbsolutePath(), e); } } else { throw new UnsupportedFormatException("This schematic format is not recognised or supported."); @@ -470,7 +478,7 @@ public abstract class SchematicHandler { InputStream inputStream = Channels.newInputStream(readableByteChannel); return getSchematic(inputStream); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error reading schematic from {}", url, e); } return null; } @@ -486,7 +494,7 @@ public abstract class SchematicHandler { Clipboard clip = schematicReader.read(); return new Schematic(clip); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error reading schematic", e); } } return null; @@ -515,7 +523,7 @@ public abstract class SchematicHandler { } return schematics; } catch (JsonParseException | IOException e) { - e.printStackTrace(); + LOGGER.error("Error retrieving saves for UUID {}", uuid, e); } return null; } @@ -532,7 +540,7 @@ public abstract class SchematicHandler { try (NBTOutputStream nos = new NBTOutputStream(new GZIPOutputStream(output, true))) { nos.writeNamedTag("Schematic", tag); } catch (IOException e1) { - e1.printStackTrace(); + LOGGER.error("Error uploading schematic for UUID {}", uuid, e1); } } }, whenDone); @@ -556,9 +564,9 @@ public abstract class SchematicHandler { nbtStream.writeNamedTag("Schematic", tag); } } catch (FileNotFoundException e) { - e.printStackTrace(); + LOGGER.error("Error saving schematic at {}", path, e); } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error saving schematic at {}", path, e); return false; } return true; @@ -581,7 +589,7 @@ public abstract class SchematicHandler { schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray())); schematic.put("BlockEntities", new ListTag(CompoundTag.class, tileEntities)); - if (biomeBuffer.size() == 0 || biomePalette.size() == 0) { + if (biomeBuffer.size() == 0 || biomePalette.isEmpty()) { return; } @@ -733,10 +741,7 @@ public abstract class SchematicHandler { } BaseBlock block = aabb.getWorld().getFullBlock(point); if (block.getNbtData() != null) { - Map values = new HashMap<>(); - for (Map.Entry entry : block.getNbtData().getValue().entrySet()) { - values.put(entry.getKey(), entry.getValue()); - } + Map values = new HashMap<>(block.getNbtData().getValue()); // Positions are kept in NBT, we don't want that. values.remove("x");