mirror of
https://github.com/Shiewk/SModeration.git
synced 2026-04-28 05:54:16 +02:00
Add gzip-compressed saving and loading system
This commit is contained in:
@@ -8,24 +8,31 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.kyori.adventure.text.TextComponent;
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
|
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
import static org.bukkit.Bukkit.getPluginManager;
|
import static org.bukkit.Bukkit.getPluginManager;
|
||||||
|
|
||||||
public final class SModeration extends JavaPlugin {
|
public final class SModeration extends JavaPlugin {
|
||||||
|
|
||||||
public static final PunishmentContainer container = new PunishmentContainer();
|
public static final PunishmentContainer container = new PunishmentContainer();
|
||||||
|
public static ComponentLogger LOGGER = null;
|
||||||
public static SModeration PLUGIN = null;
|
public static SModeration PLUGIN = null;
|
||||||
|
public static File SAVE_FILE = null;
|
||||||
|
|
||||||
public static final TextColor PRIMARY_COLOR = TextColor.color(212, 0, 255);
|
public static final TextColor PRIMARY_COLOR = TextColor.color(212, 0, 255);
|
||||||
public static final TextColor SECONDARY_COLOR = TextColor.color(52, 143, 255);
|
public static final TextColor SECONDARY_COLOR = TextColor.color(52, 143, 255);
|
||||||
public static final TextColor INACTIVE_COLOR = NamedTextColor.GRAY;
|
public static final TextColor INACTIVE_COLOR = NamedTextColor.GRAY;
|
||||||
public static final TextComponent CHAT_PREFIX = Component.text("SM \u00BB ").color(SECONDARY_COLOR);
|
public static final TextComponent CHAT_PREFIX = Component.text("SM \u00BB ").color(PRIMARY_COLOR);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
|
LOGGER = getComponentLogger();
|
||||||
PLUGIN = this;
|
PLUGIN = this;
|
||||||
|
SAVE_FILE = new File(this.getDataFolder().getAbsolutePath() + "/container.gz");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -67,5 +74,12 @@ public final class SModeration extends JavaPlugin {
|
|||||||
assert unban != null;
|
assert unban != null;
|
||||||
unban.setExecutor(new UnbanCommand());
|
unban.setExecutor(new UnbanCommand());
|
||||||
unban.setTabCompleter(new UnbanCommand());
|
unban.setTabCompleter(new UnbanCommand());
|
||||||
|
|
||||||
|
container.load(SAVE_FILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
SModeration.container.save(SModeration.SAVE_FILE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.bukkit.event.EventHandler;
|
|||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerLoginEvent;
|
import org.bukkit.event.player.PlayerLoginEvent;
|
||||||
|
import org.bukkit.event.world.WorldSaveEvent;
|
||||||
|
|
||||||
import static de.shiewk.smoderation.SModeration.CHAT_PREFIX;
|
import static de.shiewk.smoderation.SModeration.CHAT_PREFIX;
|
||||||
|
|
||||||
@@ -59,4 +60,11 @@ public class PunishmentListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onWorldSave(WorldSaveEvent event){
|
||||||
|
if (event.getWorld().equals(Bukkit.getServer().getWorlds().get(0))){
|
||||||
|
SModeration.container.save(SModeration.SAVE_FILE);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,10 @@ import net.kyori.adventure.text.Component;
|
|||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.io.EOFException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static de.shiewk.smoderation.SModeration.*;
|
import static de.shiewk.smoderation.SModeration.*;
|
||||||
@@ -25,12 +28,41 @@ public class Punishment {
|
|||||||
private UUID undoneBy;
|
private UUID undoneBy;
|
||||||
|
|
||||||
public Punishment(PunishmentType type, long time, long until, UUID by, UUID to, String reason) {
|
public Punishment(PunishmentType type, long time, long until, UUID by, UUID to, String reason) {
|
||||||
|
this(type, time, until, by, to, reason, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Punishment(PunishmentType type, long time, long until, UUID by, UUID to, String reason, UUID undoneBy) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
this.until = until;
|
this.until = until;
|
||||||
this.by = by;
|
this.by = by;
|
||||||
this.to = to;
|
this.to = to;
|
||||||
this.reason = reason;
|
this.reason = reason;
|
||||||
|
this.undoneBy = undoneBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Punishment load(InputStream in) throws IOException {
|
||||||
|
PunishmentType type = PunishmentType.values()[ByteUtil.bytesToInt(readStreamInternal(in, 4))];
|
||||||
|
long time = ByteUtil.bytesToLong(readStreamInternal(in, 8));
|
||||||
|
long until = ByteUtil.bytesToLong(readStreamInternal(in, 8));
|
||||||
|
UUID by = ByteUtil.bytesToUuid(readStreamInternal(in, 16));
|
||||||
|
UUID to = ByteUtil.bytesToUuid(readStreamInternal(in, 16));
|
||||||
|
int reasonLen = ByteUtil.bytesToInt(readStreamInternal(in, 4));
|
||||||
|
String reason = new String(readStreamInternal(in, reasonLen));
|
||||||
|
UUID undoneBy = null;
|
||||||
|
boolean undone = in.read() == 1;
|
||||||
|
if (undone){
|
||||||
|
undoneBy = ByteUtil.bytesToUuid(readStreamInternal(in, 16));
|
||||||
|
}
|
||||||
|
return new Punishment(type, time, until, by, to, reason, undoneBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean wasUndone(){
|
public boolean wasUndone(){
|
||||||
@@ -66,21 +98,19 @@ public class Punishment {
|
|||||||
|
|
||||||
private static final int BUFFER_LENGTH = 56;
|
private static final int BUFFER_LENGTH = 56;
|
||||||
|
|
||||||
public byte[] toBytes(){
|
public void writeBytes(OutputStream stream) throws IOException {
|
||||||
|
stream.write(ByteUtil.intToBytes(type.ordinal()));
|
||||||
|
stream.write(ByteUtil.longToBytes(time));
|
||||||
|
stream.write(ByteUtil.longToBytes(until));
|
||||||
|
stream.write(ByteUtil.uuidToBytes(by));
|
||||||
|
stream.write(ByteUtil.uuidToBytes(to));
|
||||||
final byte[] reasonBytes = reason.getBytes();
|
final byte[] reasonBytes = reason.getBytes();
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_LENGTH + reasonBytes.length + (undoneBy != null ? 17 : 1));
|
stream.write(ByteUtil.intToBytes(reasonBytes.length));
|
||||||
buffer.putInt(0, type.ordinal());
|
stream.write(reasonBytes);
|
||||||
buffer.putLong(4, time);
|
stream.write(wasUndone() ? 1 : 0);
|
||||||
buffer.putLong(12, until);
|
if (wasUndone()){
|
||||||
buffer.put(20, ByteUtil.uuidToBytes(by));
|
stream.write(ByteUtil.uuidToBytes(undoneBy));
|
||||||
buffer.put(36, ByteUtil.uuidToBytes(to));
|
|
||||||
buffer.putInt(40, reason.length());
|
|
||||||
buffer.put(44, reasonBytes);
|
|
||||||
buffer.put(44+reasonBytes.length, undoneBy != null ? (byte) 1 : (byte) 0);
|
|
||||||
if (undoneBy != null){
|
|
||||||
buffer.put(44+reasonBytes.length+1, ByteUtil.uuidToBytes(undoneBy));
|
|
||||||
}
|
}
|
||||||
return buffer.array();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Component undoMessage(){
|
private Component undoMessage(){
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
package de.shiewk.smoderation.storage;
|
package de.shiewk.smoderation.storage;
|
||||||
|
|
||||||
|
import de.shiewk.smoderation.SModeration;
|
||||||
import de.shiewk.smoderation.punishments.Punishment;
|
import de.shiewk.smoderation.punishments.Punishment;
|
||||||
|
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
public class PunishmentContainer {
|
public class PunishmentContainer {
|
||||||
|
|
||||||
@@ -68,4 +73,54 @@ public class PunishmentContainer {
|
|||||||
public ArrayList<Punishment> copy() {
|
public ArrayList<Punishment> copy() {
|
||||||
return new ArrayList<>(punishments);
|
return new ArrayList<>(punishments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void load(File file){
|
||||||
|
final ComponentLogger logger = SModeration.LOGGER;
|
||||||
|
try {
|
||||||
|
logger.info("Loading from {}", file.getPath());
|
||||||
|
if (!file.isFile()){
|
||||||
|
logger.warn("The file does not exist.");
|
||||||
|
} else {
|
||||||
|
try (FileInputStream fin = new FileInputStream(file)){
|
||||||
|
GZIPInputStream gzin = new GZIPInputStream(fin);
|
||||||
|
while (gzin.available() > 0){
|
||||||
|
add(Punishment.load(gzin));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.info("Successfully loaded {} items.", punishments.size());
|
||||||
|
}
|
||||||
|
} catch (EOFException e) {
|
||||||
|
logger.error("The file was not correctly saved, {} items could be recovered!", this.punishments.size());
|
||||||
|
} catch (IOException e){
|
||||||
|
logger.error("An error occurred while loading: {}", e.toString());
|
||||||
|
for (StackTraceElement stackTraceElement : e.getStackTrace()) {
|
||||||
|
logger.error(stackTraceElement.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(File file) {
|
||||||
|
final ComponentLogger logger = SModeration.LOGGER;
|
||||||
|
try {
|
||||||
|
logger.info("Saving to {}", file.getPath());
|
||||||
|
if (!file.isFile()){
|
||||||
|
file.mkdirs();
|
||||||
|
file.delete();
|
||||||
|
file.createNewFile();
|
||||||
|
}
|
||||||
|
try (FileOutputStream outputStream = new FileOutputStream(file)) {
|
||||||
|
GZIPOutputStream gzout = new GZIPOutputStream(outputStream);
|
||||||
|
for (Punishment punishment : copy()) {
|
||||||
|
punishment.writeBytes(gzout);
|
||||||
|
}
|
||||||
|
gzout.close();
|
||||||
|
}
|
||||||
|
logger.info("Successfully saved.");
|
||||||
|
} catch (IOException e){
|
||||||
|
logger.error("An error occurred while saving: {}", e.toString());
|
||||||
|
for (StackTraceElement stackTraceElement : e.getStackTrace()) {
|
||||||
|
logger.error(stackTraceElement.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,4 +42,19 @@ public abstract class ByteUtil {
|
|||||||
long m = bytesToLong(new byte[]{ i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7] });
|
long m = bytesToLong(new byte[]{ i[0], i[1], i[2], i[3], i[4], i[5], i[6], i[7] });
|
||||||
return new UUID(m, l);
|
return new UUID(m, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int bytesToInt(byte[] bytes) {
|
||||||
|
if (bytes.length != 4){
|
||||||
|
throw new IllegalArgumentException("length must be 4");
|
||||||
|
}
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(4);
|
||||||
|
buffer.put(0, bytes);
|
||||||
|
return buffer.getInt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] intToBytes(int value) {
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(4);
|
||||||
|
buffer.putInt(value);
|
||||||
|
return buffer.array();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user