diff --git a/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java b/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java index 2de25b8..69a6fcd 100644 --- a/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java +++ b/src/main/java/de/shiewk/smoderation/paper/SModerationPaper.java @@ -10,6 +10,7 @@ import de.shiewk.smoderation.paper.punishments.Kick; import de.shiewk.smoderation.paper.punishments.Mute; import de.shiewk.smoderation.paper.punishments.PunishmentManager; import de.shiewk.smoderation.paper.translation.TranslatorManager; +import de.shiewk.smoderation.paper.util.SModLegacy; import de.shiewk.smoderation.paper.util.SchedulerUtil; import io.papermc.paper.command.brigadier.Commands; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; @@ -79,6 +80,12 @@ public final class SModerationPaper extends JavaPlugin { this.punishmentManager.registerType("mute", new Mute.Factory()); this.punishmentManager.registerType("ban", new Ban.Factory()); this.punishmentManager.registerType("kick", new Kick.Factory()); + + SModLegacy.migrateV1PunishmentsFile( + this.punishmentManager, + getDataPath().resolve("container.gz"), + getDataPath().resolve("v1-backup.gz") + ); } public boolean isFeatureEnabled(String feature){ diff --git a/src/main/java/de/shiewk/smoderation/paper/punishments/PunishmentManager.java b/src/main/java/de/shiewk/smoderation/paper/punishments/PunishmentManager.java index 781182f..cd5ee7d 100644 --- a/src/main/java/de/shiewk/smoderation/paper/punishments/PunishmentManager.java +++ b/src/main/java/de/shiewk/smoderation/paper/punishments/PunishmentManager.java @@ -115,7 +115,7 @@ public final class PunishmentManager { return List.copyOf(typeRegistry.keySet()); } - private void appendToSave(Punishment punishment) throws IOException { + public void appendToSave(Punishment punishment) throws IOException { synchronized (ioLock) { Path file = getTargetFile(punishment.getTargetID()); if (!Files.exists(file)) { diff --git a/src/main/java/de/shiewk/smoderation/paper/util/SModLegacy.java b/src/main/java/de/shiewk/smoderation/paper/util/SModLegacy.java index 8e0ffd8..c67477c 100644 --- a/src/main/java/de/shiewk/smoderation/paper/util/SModLegacy.java +++ b/src/main/java/de/shiewk/smoderation/paper/util/SModLegacy.java @@ -1,7 +1,18 @@ package de.shiewk.smoderation.paper.util; +import de.shiewk.smoderation.paper.punishments.*; + +import java.io.EOFException; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.UUID; +import java.util.zip.GZIPInputStream; + +import static de.shiewk.smoderation.paper.SModerationPaper.LOGGER; public final class SModLegacy { private SModLegacy() {} @@ -54,4 +65,76 @@ public final class SModLegacy { return buffer.array(); } + private static byte[] readStreamInternal(InputStream stream, int len) throws IOException { + final byte[] bytes = stream.readNBytes(len); + if (bytes.length != len){ + throw new EOFException("Stream has ended before enough bytes were read"); + } + return bytes; + } + + public static void migrateV1PunishmentsFile(PunishmentManager manager, Path path, Path copy) { + int count = 0; + try { + if (Files.isRegularFile(path)) { + LOGGER.info("Migrating V1 punishment file: {}", path); + try (InputStream in = new FileInputStream(path.toFile()); + GZIPInputStream gzin = new GZIPInputStream(in)){ + while (gzin.available() > 0){ + int type = bytesToInt(readStreamInternal(gzin, 4)); + long time = bytesToLong(readStreamInternal(gzin, 8)); + long until = bytesToLong(readStreamInternal(gzin, 8)); + UUID by = bytesToUuid(readStreamInternal(gzin, 16)); + UUID to = bytesToUuid(readStreamInternal(gzin, 16)); + int reasonLen = bytesToInt(readStreamInternal(gzin, 4)); + String reason = new String(readStreamInternal(gzin, reasonLen)); + UUID canceller = null; + boolean cancelled = gzin.read() == 1; + if (cancelled){ + canceller = bytesToUuid(readStreamInternal(gzin, 16)); + } + // Type 0: mute; 1: kick; 2: ban + Punishment p = switch (type){ + case 0 -> new Mute( + Punishment.generateUUID(), + time, + by, + to, + reason, + until - time, + canceller + ); + case 1 -> new Kick( + Punishment.generateUUID(), + time, + by, + to, + reason + ); + case 2 -> new Ban( + Punishment.generateUUID(), + time, + by, + to, + reason, + until - time, + canceller + ); + default -> throw new IllegalArgumentException("Invalid legacy type for punishment: " + type); + }; + count++; + manager.appendToSave(p); + LOGGER.info("Migrated: {}", p); + } + } + LOGGER.info("Successfully loaded {} items.", count); + Files.move(path, copy); + } + } catch (EOFException e) { + LOGGER.error("The file was not correctly saved, {} items could be recovered!", count); + } catch (IOException e){ + LOGGER.error("An error occurred while loading", e); + throw new RuntimeException(e); + } + } }