From 2b185ea7e4a64aff28eac8152b7d3dca1a97e33a Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Thu, 13 Jul 2023 15:42:10 +0800 Subject: Add DungeonRoomsDFU --- .../skyblock/dungeon/secrets/DungeonRoomsDFU.java | 90 ++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java (limited to 'src/test/java') diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java new file mode 100644 index 00000000..305d1efb --- /dev/null +++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java @@ -0,0 +1,90 @@ +package me.xmrvizzy.skyblocker.skyblock.dungeon.secrets; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.zip.InflaterInputStream; + +public class DungeonRoomsDFU { + private static final Logger LOGGER = LoggerFactory.getLogger(DungeonRoomsDFU.class); + private static final String DUNGEONS_DATA_DIR = "/assets/skyblocker/dungeons"; + private static final String DUNGEON_ROOMS_DATA_DIR = DUNGEONS_DATA_DIR + "/dungeonrooms"; + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + private static final HashMap>> ROOMS = new HashMap<>(); + private static JsonObject roomsJson; + private static JsonObject waypointsJson; + + public static void main(String[] args) { + load().join(); + } + + private static CompletableFuture load() { + try { + List> dungeonFutures = new ArrayList<>(); + //noinspection DataFlowIssue + File dungeons = new File(DungeonRoomsDFU.class.getResource(DUNGEON_ROOMS_DATA_DIR).getFile()); + int resourcePathIndex = dungeons.getPath().indexOf(DUNGEON_ROOMS_DATA_DIR); + //noinspection DataFlowIssue + for (File dungeon : dungeons.listFiles()) { + if (!dungeon.isDirectory()) { + continue; + } + File[] roomShapes = dungeon.listFiles(); + if (roomShapes == null) { + LOGGER.error("Failed to load dungeon secrets for dungeon {}", dungeon.getName()); + continue; + } + ROOMS.put(dungeon.getName(), new HashMap<>()); + List> roomShapeFutures = new ArrayList<>(); + for (File roomShape : roomShapes) { + roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> ROOMS.get(dungeon.getName()).put(roomShape.getName(), rooms))); + } + dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getName(), ROOMS.get(dungeon.getName()).size(), ROOMS.get(dungeon.getName()).values().stream().mapToInt(HashMap::size).sum()))); + } + dungeonFutures.add(CompletableFuture.runAsync(() -> { + //noinspection DataFlowIssue + try (BufferedReader roomsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/dungeonrooms.json"))); + BufferedReader waypointsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/secretlocations.json")))) { + roomsJson = GSON.fromJson(roomsReader, JsonObject.class); + waypointsJson = GSON.fromJson(waypointsReader, JsonObject.class); + LOGGER.info("Loaded dungeon secrets json"); + } catch (Exception e) { + LOGGER.error("Failed to load dungeon secrets json", e); + } + })); + return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", ROOMS.size(), ROOMS.values().stream().mapToInt(HashMap::size).sum(), ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); + } catch (Exception e) { + throw new RuntimeException("Failed to load dungeon secrets", e); + } + } + + private static HashMap readRooms(File roomShape, int resourcePathIndex) { + HashMap data = new HashMap<>(); + File[] rooms = roomShape.listFiles(); + if (rooms == null) { + LOGGER.error("Failed to load dungeon secrets room shape {}", roomShape.getName()); + return data; + } + for (File room : rooms) { + String name = room.getName(); + //noinspection DataFlowIssue + try (ObjectInputStream in = new ObjectInputStream(new InflaterInputStream(DungeonRoomsDFU.class.getResourceAsStream(room.getPath().substring(resourcePathIndex))))) { + data.put(name.substring(0, name.length() - 9), (long[]) in.readObject()); + LOGGER.info("Loaded dungeon secrets room {}", name); + } catch (NullPointerException | IOException | ClassNotFoundException e) { + LOGGER.error("Failed to load dungeon secrets room " + name, e); + } + } + LOGGER.info("Loaded dungeon secrets room shape {} with {} rooms", roomShape.getName(), data.size()); + return data; + } +} -- cgit From a5998f09db291a15b7108dec8a66065fbdc40108 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Fri, 14 Jul 2023 13:06:55 +0800 Subject: Add rooms data updating --- .../skyblock/dungeon/secrets/DungeonRoomsDFU.java | 74 ++++++++++++++++++---- 1 file changed, 63 insertions(+), 11 deletions(-) (limited to 'src/test/java') diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java index 305d1efb..25fda2d2 100644 --- a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java +++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java @@ -3,28 +3,36 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon.secrets; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; +import net.minecraft.datafixer.fix.ItemIdFix; +import net.minecraft.datafixer.fix.ItemInstanceTheFlatteningFix; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.zip.InflaterInputStream; +/** + * Utility class to convert the old dungeon rooms data from Dungeon Rooms Mod to a new format. + * The new format is similar to DRM's format, but uses ints instead of longs and a custom numeric block id to store the block states. + * The first byte is the x position, the second byte is the y position, the third byte is the z position, and the fourth byte is the custom numeric block id. + * Use {@link DungeonSecrets#NUMERIC_ID} to get the custom numeric block id of a block. + * Run this manually when updating dungeon rooms data with DRM's data in {@code src/test/resources/assets/skyblocker/dungeons/dungeonrooms}. + */ public class DungeonRoomsDFU { private static final Logger LOGGER = LoggerFactory.getLogger(DungeonRoomsDFU.class); private static final String DUNGEONS_DATA_DIR = "/assets/skyblocker/dungeons"; private static final String DUNGEON_ROOMS_DATA_DIR = DUNGEONS_DATA_DIR + "/dungeonrooms"; private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - private static final HashMap>> ROOMS = new HashMap<>(); + private static final HashMap>> OLD_ROOMS = new HashMap<>(); + private static final HashMap>> ROOMS = new HashMap<>(); private static JsonObject roomsJson; private static JsonObject waypointsJson; public static void main(String[] args) { load().join(); + updateRooms(); } private static CompletableFuture load() { @@ -43,17 +51,16 @@ public class DungeonRoomsDFU { LOGGER.error("Failed to load dungeon secrets for dungeon {}", dungeon.getName()); continue; } - ROOMS.put(dungeon.getName(), new HashMap<>()); + OLD_ROOMS.put(dungeon.getName(), new HashMap<>()); List> roomShapeFutures = new ArrayList<>(); for (File roomShape : roomShapes) { - roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> ROOMS.get(dungeon.getName()).put(roomShape.getName(), rooms))); + roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> OLD_ROOMS.get(dungeon.getName()).put(roomShape.getName(), rooms))); } - dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getName(), ROOMS.get(dungeon.getName()).size(), ROOMS.get(dungeon.getName()).values().stream().mapToInt(HashMap::size).sum()))); + dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getName(), OLD_ROOMS.get(dungeon.getName()).size(), OLD_ROOMS.get(dungeon.getName()).values().stream().mapToInt(HashMap::size).sum()))); } dungeonFutures.add(CompletableFuture.runAsync(() -> { //noinspection DataFlowIssue - try (BufferedReader roomsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/dungeonrooms.json"))); - BufferedReader waypointsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/secretlocations.json")))) { + try (BufferedReader roomsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/dungeonrooms.json"))); BufferedReader waypointsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/secretlocations.json")))) { roomsJson = GSON.fromJson(roomsReader, JsonObject.class); waypointsJson = GSON.fromJson(waypointsReader, JsonObject.class); LOGGER.info("Loaded dungeon secrets json"); @@ -61,7 +68,7 @@ public class DungeonRoomsDFU { LOGGER.error("Failed to load dungeon secrets json", e); } })); - return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", ROOMS.size(), ROOMS.values().stream().mapToInt(HashMap::size).sum(), ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); + return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", OLD_ROOMS.size(), OLD_ROOMS.values().stream().mapToInt(HashMap::size).sum(), OLD_ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); } catch (Exception e) { throw new RuntimeException("Failed to load dungeon secrets", e); } @@ -87,4 +94,49 @@ public class DungeonRoomsDFU { LOGGER.info("Loaded dungeon secrets room shape {} with {} rooms", roomShape.getName(), data.size()); return data; } + + private static void updateRooms() { + for (Map.Entry>> oldDungeon : OLD_ROOMS.entrySet()) { + HashMap> dungeon = new HashMap<>(); + for (Map.Entry> oldRoomShape : oldDungeon.getValue().entrySet()) { + HashMap roomShape = new HashMap<>(); + for (Map.Entry oldRoomEntry : oldRoomShape.getValue().entrySet()) { + roomShape.put(oldRoomEntry.getKey(), updateRoom(oldRoomEntry.getValue())); + } + dungeon.put(oldRoomShape.getKey(), roomShape); + } + ROOMS.put(oldDungeon.getKey(), dungeon); + } + } + + private static int[] updateRoom(long[] oldRoom) { + int[] room = new int[oldRoom.length]; + for (int i = 0; i < oldRoom.length; i++) { + room[i] = updateBlock(oldRoom[i]); + } + return room; + } + + /** + * Updates the block state from Dungeon Rooms Mod's format to the new format explained in {@link DungeonRoomsDFU}. + * + * @param oldBlock the old block state in DRM's format + * @return the new block state in the new format + */ + private static int updateBlock(long oldBlock) { + short x = (short) ((oldBlock >> 48) & 0xFFFF); + short y = (short) ((oldBlock >> 32) & 0xFFFF); + short z = (short) ((oldBlock >> 16) & 0xFFFF); + // Blocks should be within the range 0 to 256, since a dungeon room is at most around 128 blocks long and around 150 blocks tall. + if (x < 0 || x > 0xFF || y < 0 || y > 0xFF || z < 0 || z > 0xFF) { + throw new IllegalArgumentException("Invalid block: " + oldBlock); + } + short oldId = (short) (oldBlock & 0xFFFF); + // Get the new id for the block. + String newId = ItemInstanceTheFlatteningFix.getItem(ItemIdFix.fromId(oldId / 100), oldId % 100); + if (newId == null) { + newId = ItemIdFix.fromId(oldId / 100); + } + return (x << 24) | (y << 16) | (z << 8) | DungeonSecrets.NUMERIC_ID.get(newId); + } } -- cgit From b81cd1254ddc430120c64b1ddcc95e0537f32789 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Fri, 14 Jul 2023 15:58:59 +0800 Subject: Add rooms data saving and update reading to nio --- .../skyblock/dungeon/secrets/DungeonRoomsDFU.java | 137 +++++++++++++-------- 1 file changed, 87 insertions(+), 50 deletions(-) (limited to 'src/test/java') diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java index 25fda2d2..8143b0c4 100644 --- a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java +++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java @@ -9,8 +9,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.*; +import java.net.URL; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.zip.DeflaterOutputStream; import java.util.zip.InflaterInputStream; /** @@ -33,66 +38,67 @@ public class DungeonRoomsDFU { public static void main(String[] args) { load().join(); updateRooms(); + save().join(); } private static CompletableFuture load() { - try { - List> dungeonFutures = new ArrayList<>(); - //noinspection DataFlowIssue - File dungeons = new File(DungeonRoomsDFU.class.getResource(DUNGEON_ROOMS_DATA_DIR).getFile()); - int resourcePathIndex = dungeons.getPath().indexOf(DUNGEON_ROOMS_DATA_DIR); - //noinspection DataFlowIssue - for (File dungeon : dungeons.listFiles()) { - if (!dungeon.isDirectory()) { - continue; - } - File[] roomShapes = dungeon.listFiles(); - if (roomShapes == null) { - LOGGER.error("Failed to load dungeon secrets for dungeon {}", dungeon.getName()); - continue; - } - OLD_ROOMS.put(dungeon.getName(), new HashMap<>()); - List> roomShapeFutures = new ArrayList<>(); - for (File roomShape : roomShapes) { - roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> OLD_ROOMS.get(dungeon.getName()).put(roomShape.getName(), rooms))); + List> dungeonFutures = new ArrayList<>(); + URL dungeonsURL = DungeonRoomsDFU.class.getResource(DUNGEON_ROOMS_DATA_DIR); + if (dungeonsURL == null) { + LOGGER.error("Failed to load dungeon secrets, unable to find dungeon rooms data directory"); + return CompletableFuture.completedFuture(null); + } + Path dungeonsDir = Path.of(dungeonsURL.getPath()); + int resourcePathIndex = dungeonsDir.toString().indexOf(DUNGEON_ROOMS_DATA_DIR); + try (DirectoryStream dungeons = Files.newDirectoryStream(dungeonsDir, Files::isDirectory)) { + for (Path dungeon : dungeons) { + try (DirectoryStream roomShapes = Files.newDirectoryStream(dungeon, Files::isDirectory)) { + List> roomShapeFutures = new ArrayList<>(); + HashMap> roomShapesMap = new HashMap<>(); + for (Path roomShape : roomShapes) { + roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> roomShapesMap.put(roomShape.getFileName().toString(), rooms))); + } + OLD_ROOMS.put(dungeon.getFileName().toString(), roomShapesMap); + dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getFileName(), roomShapesMap.size(), roomShapesMap.values().stream().mapToInt(HashMap::size).sum()))); + } catch (IOException e) { + LOGGER.error("Failed to load dungeon secrets for dungeon " + dungeon.getFileName(), e); } - dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getName(), OLD_ROOMS.get(dungeon.getName()).size(), OLD_ROOMS.get(dungeon.getName()).values().stream().mapToInt(HashMap::size).sum()))); } - dungeonFutures.add(CompletableFuture.runAsync(() -> { - //noinspection DataFlowIssue - try (BufferedReader roomsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/dungeonrooms.json"))); BufferedReader waypointsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/secretlocations.json")))) { - roomsJson = GSON.fromJson(roomsReader, JsonObject.class); - waypointsJson = GSON.fromJson(waypointsReader, JsonObject.class); - LOGGER.info("Loaded dungeon secrets json"); - } catch (Exception e) { - LOGGER.error("Failed to load dungeon secrets json", e); - } - })); - return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", OLD_ROOMS.size(), OLD_ROOMS.values().stream().mapToInt(HashMap::size).sum(), OLD_ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); - } catch (Exception e) { - throw new RuntimeException("Failed to load dungeon secrets", e); + } catch (IOException e) { + LOGGER.error("Failed to load dungeon secrets", e); } + dungeonFutures.add(CompletableFuture.runAsync(() -> { + //noinspection DataFlowIssue + try (BufferedReader roomsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/dungeonrooms.json"))); BufferedReader waypointsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/secretlocations.json")))) { + roomsJson = GSON.fromJson(roomsReader, JsonObject.class); + waypointsJson = GSON.fromJson(waypointsReader, JsonObject.class); + LOGGER.info("Loaded dungeon secrets json"); + } catch (Exception e) { + LOGGER.error("Failed to load dungeon secrets json", e); + } + })); + return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", OLD_ROOMS.size(), OLD_ROOMS.values().stream().mapToInt(HashMap::size).sum(), OLD_ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); } - private static HashMap readRooms(File roomShape, int resourcePathIndex) { - HashMap data = new HashMap<>(); - File[] rooms = roomShape.listFiles(); - if (rooms == null) { - LOGGER.error("Failed to load dungeon secrets room shape {}", roomShape.getName()); - return data; - } - for (File room : rooms) { - String name = room.getName(); - //noinspection DataFlowIssue - try (ObjectInputStream in = new ObjectInputStream(new InflaterInputStream(DungeonRoomsDFU.class.getResourceAsStream(room.getPath().substring(resourcePathIndex))))) { - data.put(name.substring(0, name.length() - 9), (long[]) in.readObject()); - LOGGER.info("Loaded dungeon secrets room {}", name); - } catch (NullPointerException | IOException | ClassNotFoundException e) { - LOGGER.error("Failed to load dungeon secrets room " + name, e); + private static HashMap readRooms(Path roomShape, int resourcePathIndex) { + try (DirectoryStream rooms = Files.newDirectoryStream(roomShape, Files::isRegularFile)) { + HashMap roomsData = new HashMap<>(); + for (Path room : rooms) { + String name = room.getFileName().toString(); + //noinspection DataFlowIssue + try (ObjectInputStream in = new ObjectInputStream(new InflaterInputStream(DungeonRoomsDFU.class.getResourceAsStream(room.toString().substring(resourcePathIndex))))) { + roomsData.put(name.substring(0, name.length() - 9), (long[]) in.readObject()); + LOGGER.info("Loaded dungeon secrets room {}", name); + } catch (NullPointerException | IOException | ClassNotFoundException e) { + LOGGER.error("Failed to load dungeon secrets room " + name, e); + } } + LOGGER.info("Loaded dungeon secrets room shape {} with {} rooms", roomShape.getFileName(), roomsData.size()); + return roomsData; + } catch (IOException e) { + LOGGER.error("Failed to load dungeon secrets room shape " + roomShape.getFileName(), e); } - LOGGER.info("Loaded dungeon secrets room shape {} with {} rooms", roomShape.getName(), data.size()); - return data; + return null; } private static void updateRooms() { @@ -139,4 +145,35 @@ public class DungeonRoomsDFU { } return (x << 24) | (y << 16) | (z << 8) | DungeonSecrets.NUMERIC_ID.get(newId); } + + private static CompletableFuture save() { + List> dungeonFutures = new ArrayList<>(); + for (Map.Entry>> dungeon : ROOMS.entrySet()) { + Path dungeonDir = Path.of("out", "dungeons", dungeon.getKey()); + List> roomShapeFutures = new ArrayList<>(); + for (Map.Entry> roomShape : dungeon.getValue().entrySet()) { + Path roomShapeDir = dungeonDir.resolve(roomShape.getKey()); + roomShapeFutures.add(CompletableFuture.runAsync(() -> saveRooms(roomShapeDir, roomShape))); + } + dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Saved dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getKey(), dungeon.getValue().size(), dungeon.getValue().values().stream().mapToInt(HashMap::size).sum()))); + } + return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Saved dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", ROOMS.size(), ROOMS.values().stream().mapToInt(HashMap::size).sum(), ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); + } + + private static void saveRooms(Path roomShapeDir, Map.Entry> roomShape) { + try { + Files.createDirectories(roomShapeDir); + } catch (IOException e) { + LOGGER.error("Failed to save dungeon secrets: failed to create dungeon secrets room shape directory " + roomShapeDir, e); + } + for (Map.Entry room : roomShape.getValue().entrySet()) { + try (ObjectOutputStream out = new ObjectOutputStream(new DeflaterOutputStream(Files.newOutputStream(roomShapeDir.resolve(room.getKey() + ".skeleton"))))) { + out.writeObject(room.getValue()); + LOGGER.info("Saved dungeon secrets room {}", room.getKey()); + } catch (IOException e) { + LOGGER.error("Failed to save dungeon secrets room " + room.getKey(), e); + } + } + LOGGER.info("Saved dungeon secrets room shape {} with {} rooms", roomShape.getKey(), roomShape.getValue().size()); + } } -- cgit From 611e7710d8cfc5365727f3db532112d7d249752c Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 16 Jul 2023 11:39:59 +0800 Subject: Remove json loading in DungeonRoomsDFU --- .../skyblock/dungeon/secrets/DungeonRoomsDFU.java | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'src/test/java') diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java index 8143b0c4..7e85d721 100644 --- a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java +++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java @@ -1,8 +1,5 @@ package me.xmrvizzy.skyblocker.skyblock.dungeon.secrets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; import net.minecraft.datafixer.fix.ItemIdFix; import net.minecraft.datafixer.fix.ItemInstanceTheFlatteningFix; import org.slf4j.Logger; @@ -29,11 +26,8 @@ public class DungeonRoomsDFU { private static final Logger LOGGER = LoggerFactory.getLogger(DungeonRoomsDFU.class); private static final String DUNGEONS_DATA_DIR = "/assets/skyblocker/dungeons"; private static final String DUNGEON_ROOMS_DATA_DIR = DUNGEONS_DATA_DIR + "/dungeonrooms"; - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); private static final HashMap>> OLD_ROOMS = new HashMap<>(); private static final HashMap>> ROOMS = new HashMap<>(); - private static JsonObject roomsJson; - private static JsonObject waypointsJson; public static void main(String[] args) { load().join(); @@ -67,16 +61,6 @@ public class DungeonRoomsDFU { } catch (IOException e) { LOGGER.error("Failed to load dungeon secrets", e); } - dungeonFutures.add(CompletableFuture.runAsync(() -> { - //noinspection DataFlowIssue - try (BufferedReader roomsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/dungeonrooms.json"))); BufferedReader waypointsReader = new BufferedReader(new InputStreamReader(DungeonRoomsDFU.class.getResourceAsStream(DUNGEONS_DATA_DIR + "/secretlocations.json")))) { - roomsJson = GSON.fromJson(roomsReader, JsonObject.class); - waypointsJson = GSON.fromJson(waypointsReader, JsonObject.class); - LOGGER.info("Loaded dungeon secrets json"); - } catch (Exception e) { - LOGGER.error("Failed to load dungeon secrets json", e); - } - })); return CompletableFuture.allOf(dungeonFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for {} dungeon(s), {} room shapes, and {} rooms total", OLD_ROOMS.size(), OLD_ROOMS.values().stream().mapToInt(HashMap::size).sum(), OLD_ROOMS.values().stream().map(HashMap::values).flatMap(Collection::stream).mapToInt(HashMap::size).sum())); } -- cgit From 2452ce3afafec1f9230a0cbfe384cd97d93e2d72 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 23 Jul 2023 16:14:53 +0800 Subject: Add room matching --- .../skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src/test/java') diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java index 7e85d721..613f642c 100644 --- a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java +++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java @@ -104,6 +104,8 @@ public class DungeonRoomsDFU { for (int i = 0; i < oldRoom.length; i++) { room[i] = updateBlock(oldRoom[i]); } + // Technically not needed, as the long array should be sorted already. + Arrays.sort(room); return room; } @@ -114,9 +116,9 @@ public class DungeonRoomsDFU { * @return the new block state in the new format */ private static int updateBlock(long oldBlock) { - short x = (short) ((oldBlock >> 48) & 0xFFFF); - short y = (short) ((oldBlock >> 32) & 0xFFFF); - short z = (short) ((oldBlock >> 16) & 0xFFFF); + short x = (short) (oldBlock >> 48 & 0xFFFF); + short y = (short) (oldBlock >> 32 & 0xFFFF); + short z = (short) (oldBlock >> 16 & 0xFFFF); // Blocks should be within the range 0 to 256, since a dungeon room is at most around 128 blocks long and around 150 blocks tall. if (x < 0 || x > 0xFF || y < 0 || y > 0xFF || z < 0 || z > 0xFF) { throw new IllegalArgumentException("Invalid block: " + oldBlock); @@ -127,7 +129,7 @@ public class DungeonRoomsDFU { if (newId == null) { newId = ItemIdFix.fromId(oldId / 100); } - return (x << 24) | (y << 16) | (z << 8) | DungeonSecrets.NUMERIC_ID.get(newId); + return x << 24 | y << 16 | z << 8 | DungeonSecrets.NUMERIC_ID.get(newId); } private static CompletableFuture save() { -- cgit From 1f40dff278681277cee7605e0aadd1812577b31a Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Mon, 24 Jul 2023 11:33:16 +0800 Subject: Refactor room matching --- .../xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/test/java') diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java index 613f642c..7260bff8 100644 --- a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java +++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java @@ -129,7 +129,7 @@ public class DungeonRoomsDFU { if (newId == null) { newId = ItemIdFix.fromId(oldId / 100); } - return x << 24 | y << 16 | z << 8 | DungeonSecrets.NUMERIC_ID.get(newId); + return x << 24 | y << 16 | z << 8 | DungeonSecrets.NUMERIC_ID.getByte(newId); } private static CompletableFuture save() { -- cgit From 3cfcfa8f0767563ca6d0e14df90b509bbc6ad812 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:44:30 +0800 Subject: Finish secret found detection --- .../skyblocker/skyblock/dungeon/secrets/RoomTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/RoomTest.java (limited to 'src/test/java') diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/RoomTest.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/RoomTest.java new file mode 100644 index 00000000..b704037c --- /dev/null +++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/RoomTest.java @@ -0,0 +1,13 @@ +package me.xmrvizzy.skyblocker.skyblock.dungeon.secrets; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class RoomTest { + @Test + void onChatMessage() { + Assertions.assertFalse(Room.isAllSecretsFound("§10,000/10,000❤ §a5,000§a❈ Defense §b2,000/2,000✎ Mana §70/1 Secrets")); + Assertions.assertTrue(Room.isAllSecretsFound("§1,000,000/10,000❤ §3+1,000.5 Combat (33.33%) §b4,000/2,000✎ Mana §710/10 Secrets")); + Assertions.assertTrue(Room.isAllSecretsFound("§1,000,000/10,000❤ §b-25 Mana (§6Instant Transmission§b) §b2,000/2,000✎ Mana §710/1 Secrets")); + } +} -- cgit From 6567b0d3819b3e2bbc0b272cbfc2858acc96fb50 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Fri, 18 Aug 2023 14:09:05 +0800 Subject: Migrate dungeon rooms data to resource system --- .../skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/test/java') diff --git a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java index 7260bff8..c103bb3d 100644 --- a/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java +++ b/src/test/java/me/xmrvizzy/skyblocker/skyblock/dungeon/secrets/DungeonRoomsDFU.java @@ -50,9 +50,9 @@ public class DungeonRoomsDFU { List> roomShapeFutures = new ArrayList<>(); HashMap> roomShapesMap = new HashMap<>(); for (Path roomShape : roomShapes) { - roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> roomShapesMap.put(roomShape.getFileName().toString(), rooms))); + roomShapeFutures.add(CompletableFuture.supplyAsync(() -> readRooms(roomShape, resourcePathIndex)).thenAccept(rooms -> roomShapesMap.put(roomShape.getFileName().toString().toLowerCase(), rooms))); } - OLD_ROOMS.put(dungeon.getFileName().toString(), roomShapesMap); + OLD_ROOMS.put(dungeon.getFileName().toString().toLowerCase(), roomShapesMap); dungeonFutures.add(CompletableFuture.allOf(roomShapeFutures.toArray(CompletableFuture[]::new)).thenRun(() -> LOGGER.info("Loaded dungeon secrets for dungeon {} with {} room shapes and {} rooms total", dungeon.getFileName(), roomShapesMap.size(), roomShapesMap.values().stream().mapToInt(HashMap::size).sum()))); } catch (IOException e) { LOGGER.error("Failed to load dungeon secrets for dungeon " + dungeon.getFileName(), e); @@ -71,7 +71,7 @@ public class DungeonRoomsDFU { String name = room.getFileName().toString(); //noinspection DataFlowIssue try (ObjectInputStream in = new ObjectInputStream(new InflaterInputStream(DungeonRoomsDFU.class.getResourceAsStream(room.toString().substring(resourcePathIndex))))) { - roomsData.put(name.substring(0, name.length() - 9), (long[]) in.readObject()); + roomsData.put(name.substring(0, name.length() - 9).toLowerCase(), (long[]) in.readObject()); LOGGER.info("Loaded dungeon secrets room {}", name); } catch (NullPointerException | IOException | ClassNotFoundException e) { LOGGER.error("Failed to load dungeon secrets room " + name, e); -- cgit