From 5ce226813f61f44fbf984ce1bdcd3fd8106c1947 Mon Sep 17 00:00:00 2001 From: kuroppoi <68156848+kuroppoi@users.noreply.github.com> Date: Wed, 20 Jul 2022 19:27:09 +0200 Subject: [PATCH] Let's not serialize entire Zone objects to deserialize them as POJOs --- .../java/brainwine/gameserver/zone/Zone.java | 5 ++ .../brainwine/gameserver/zone/ZoneConfig.java | 4 + .../brainwine/gameserver/zone/ZoneData.java | 17 +++-- .../gameserver/zone/ZoneManager.java | 74 ++++++++++--------- 4 files changed, 60 insertions(+), 40 deletions(-) diff --git a/gameserver/src/main/java/brainwine/gameserver/zone/Zone.java b/gameserver/src/main/java/brainwine/gameserver/zone/Zone.java index 5f6e540..69019c2 100644 --- a/gameserver/src/main/java/brainwine/gameserver/zone/Zone.java +++ b/gameserver/src/main/java/brainwine/gameserver/zone/Zone.java @@ -79,6 +79,7 @@ public class Zone { this(documentId, config.getName(), config.getBiome(), config.getWidth(), config.getHeight()); surface = data.getSurface(); sunlight = data.getSunlight(); + pendingSunlight.addAll(data.getPendingSunlight()); chunksExplored = data.getChunksExplored(); } @@ -764,6 +765,10 @@ public class Zone { } } + public Set getPendingSunlight() { + return Collections.unmodifiableSet(pendingSunlight); + } + public void setSunlight(int x, int sunlight) { if(x < 0 || x >= width) { return; diff --git a/gameserver/src/main/java/brainwine/gameserver/zone/ZoneConfig.java b/gameserver/src/main/java/brainwine/gameserver/zone/ZoneConfig.java index 696ddf4..d1eae5e 100644 --- a/gameserver/src/main/java/brainwine/gameserver/zone/ZoneConfig.java +++ b/gameserver/src/main/java/brainwine/gameserver/zone/ZoneConfig.java @@ -12,6 +12,10 @@ public class ZoneConfig { private final int width; private final int height; + public ZoneConfig(Zone zone) { + this(zone.getName(), zone.getBiome(), zone.getWidth(), zone.getHeight()); + } + @ConstructorProperties({"name", "biome", "width", "height"}) public ZoneConfig(String name, Biome biome, int width, int height) { this.name = name; diff --git a/gameserver/src/main/java/brainwine/gameserver/zone/ZoneData.java b/gameserver/src/main/java/brainwine/gameserver/zone/ZoneData.java index 8f4dac6..4800423 100644 --- a/gameserver/src/main/java/brainwine/gameserver/zone/ZoneData.java +++ b/gameserver/src/main/java/brainwine/gameserver/zone/ZoneData.java @@ -1,19 +1,24 @@ package brainwine.gameserver.zone; import java.beans.ConstructorProperties; +import java.util.Collection; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) public class ZoneData { - private int[] surface; - private int[] sunlight; - private int[] pendingSunlight; - private boolean[] chunksExplored; + private final int[] surface; + private final int[] sunlight; + private final Collection pendingSunlight; + private final boolean[] chunksExplored; + + public ZoneData(Zone zone) { + this(zone.getSurface(), zone.getSunlight(), zone.getPendingSunlight(), zone.getChunksExplored()); + } @ConstructorProperties({"surface", "sunlight", "pending_sunlight", "chunks_explored"}) - public ZoneData(int[] surface, int[] sunlight, int[] pendingSunlight, boolean[] chunksExplored) { + public ZoneData(int[] surface, int[] sunlight, Collection pendingSunlight, boolean[] chunksExplored) { this.surface = surface; this.sunlight = sunlight; this.pendingSunlight = pendingSunlight; @@ -28,7 +33,7 @@ public class ZoneData { return sunlight; } - public int[] getPendingSunlight() { + public Collection getPendingSunlight() { return pendingSunlight; } diff --git a/gameserver/src/main/java/brainwine/gameserver/zone/ZoneManager.java b/gameserver/src/main/java/brainwine/gameserver/zone/ZoneManager.java index 105744f..98d901a 100644 --- a/gameserver/src/main/java/brainwine/gameserver/zone/ZoneManager.java +++ b/gameserver/src/main/java/brainwine/gameserver/zone/ZoneManager.java @@ -1,6 +1,7 @@ package brainwine.gameserver.zone; import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; import java.util.Collection; @@ -10,6 +11,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.function.Predicate; +import java.util.zip.DataFormatException; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -66,40 +68,14 @@ public class ZoneManager { private void loadZone(File file) { String id = file.getName(); File dataFile = new File(file, "zone.dat"); - File shapeFile = new File(file, "shape.cmp"); + File legacyDataFile = new File(file, "shape.cmp"); try { ZoneData data = null; - if(shapeFile.exists() && !dataFile.exists()) { - MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(ZipUtils.inflateBytes(Files.readAllBytes(shapeFile.toPath()))); - int[] surface = new int[unpacker.unpackArrayHeader()]; - - for(int i = 0; i < surface.length; i++) { - surface[i] = unpacker.unpackInt(); - } - - int[] sunlight = new int[unpacker.unpackArrayHeader()]; - - for(int i = 0; i < sunlight.length; i++) { - sunlight[i] = unpacker.unpackInt(); - } - - int[] pendingSunlight = new int[unpacker.unpackArrayHeader()]; - - for(int i = 0; i < pendingSunlight.length; i++) { - pendingSunlight[i] = unpacker.unpackInt(); - } - - boolean[] chunksExplored = new boolean[unpacker.unpackArrayHeader()]; - - for(int i = 0; i < pendingSunlight.length; i++) { - chunksExplored[i] = unpacker.unpackBoolean(); - } - - data = new ZoneData(surface, sunlight, pendingSunlight, chunksExplored); - mapper.writeValue(dataFile, data); - shapeFile.delete(); + if(legacyDataFile.exists() && !dataFile.exists()) { + data = convertLegacyDataFile(legacyDataFile, dataFile); + legacyDataFile.delete(); } else { data = mapper.readValue(ZipUtils.inflateBytes(Files.readAllBytes(dataFile.toPath())), ZoneData.class); } @@ -113,6 +89,38 @@ public class ZoneManager { } } + private ZoneData convertLegacyDataFile(File legacyFile, File outputFile) throws IOException, DataFormatException { + MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(ZipUtils.inflateBytes(Files.readAllBytes(legacyFile.toPath()))); + int[] surface = new int[unpacker.unpackArrayHeader()]; + + for(int i = 0; i < surface.length; i++) { + surface[i] = unpacker.unpackInt(); + } + + int[] sunlight = new int[unpacker.unpackArrayHeader()]; + + for(int i = 0; i < sunlight.length; i++) { + sunlight[i] = unpacker.unpackInt(); + } + + List pendingSunlight = new ArrayList<>(); + int pendingSunlightSize = unpacker.unpackArrayHeader(); + + for(int i = 0; i < pendingSunlightSize; i++) { + pendingSunlight.add(unpacker.unpackInt()); + } + + boolean[] chunksExplored = new boolean[unpacker.unpackArrayHeader()]; + + for(int i = 0; i < chunksExplored.length; i++) { + chunksExplored[i] = unpacker.unpackBoolean(); + } + + ZoneData data = new ZoneData(surface, sunlight, pendingSunlight, chunksExplored); + mapper.writeValue(outputFile, data); + return data; + } + public void saveZones() { for(Zone zone : getZones()) { saveZone(zone); @@ -125,11 +133,9 @@ public class ZoneManager { try { zone.saveChunks(); - ZoneConfig config = JsonHelper.readValue(zone, ZoneConfig.class); - ZoneData data = JsonHelper.readValue(zone, ZoneData.class); JsonHelper.writeValue(new File(file, "metablocks.json"), zone.getMetaBlocks()); - JsonHelper.writeValue(new File(file, "config.json"), config); - Files.write(new File(file, "zone.dat").toPath(), ZipUtils.deflateBytes(mapper.writeValueAsBytes(data))); + JsonHelper.writeValue(new File(file, "config.json"), new ZoneConfig(zone)); + Files.write(new File(file, "zone.dat").toPath(), ZipUtils.deflateBytes(mapper.writeValueAsBytes(new ZoneData(zone)))); } catch(Exception e) { logger.error("Zone save failure. id: {}", zone.getDocumentId(), e); }