From 1c4d263dd25478df6a7a633532c351cf6a4fbcca Mon Sep 17 00:00:00 2001 From: AnimeGitB Date: Thu, 24 Nov 2022 23:09:55 +1030 Subject: [PATCH] Add Data TSJ loading, replace and update Banners --- .../java/emu/grasscutter/data/DataLoader.java | 13 +++ .../emu/grasscutter/data/ResourceLoader.java | 4 +- .../grasscutter/game/gacha/GachaBanner.java | 2 +- .../grasscutter/game/gacha/GachaSystem.java | 2 +- .../java/emu/grasscutter/utils/FileUtils.java | 25 ++++-- .../java/emu/grasscutter/utils/TsvUtils.java | 4 +- src/main/resources/defaults/data/Banners.json | 83 ------------------- src/main/resources/defaults/data/Banners.tsj | 6 ++ 8 files changed, 43 insertions(+), 96 deletions(-) delete mode 100644 src/main/resources/defaults/data/Banners.json create mode 100644 src/main/resources/defaults/data/Banners.tsj diff --git a/src/main/java/emu/grasscutter/data/DataLoader.java b/src/main/java/emu/grasscutter/data/DataLoader.java index 9b19336bf..f40337dce 100644 --- a/src/main/java/emu/grasscutter/data/DataLoader.java +++ b/src/main/java/emu/grasscutter/data/DataLoader.java @@ -5,6 +5,8 @@ import emu.grasscutter.server.http.handlers.GachaHandler; import emu.grasscutter.tools.Tools; import emu.grasscutter.utils.FileUtils; import emu.grasscutter.utils.JsonUtils; +import emu.grasscutter.utils.TsvUtils; +import lombok.val; import java.io.FileNotFoundException; import java.io.IOException; @@ -88,6 +90,17 @@ public class DataLoader { } } + public static List loadTableToList(String resourcePath, Class classType) throws IOException { + val path = FileUtils.getDataPathTsjJsonTsv(resourcePath); + Grasscutter.getLogger().info("Loading data table from: "+path); + return switch (FileUtils.getFileExtension(path)) { + case "json" -> JsonUtils.loadToList(path, classType); + case "tsj" -> TsvUtils.loadTsjToListSetField(path, classType); + case "tsv" -> TsvUtils.loadTsvToListSetField(path, classType); + default -> null; + }; + } + public static void checkAllFiles() { try { List filenames = FileUtils.getPathsFromResource("/defaults/data/"); diff --git a/src/main/java/emu/grasscutter/data/ResourceLoader.java b/src/main/java/emu/grasscutter/data/ResourceLoader.java index b2f52d030..6c392cfdc 100644 --- a/src/main/java/emu/grasscutter/data/ResourceLoader.java +++ b/src/main/java/emu/grasscutter/data/ResourceLoader.java @@ -152,8 +152,8 @@ public class ResourceLoader { protected static void loadFromResource(Class c, Path filename, Int2ObjectMap map) throws Exception { val results = switch (FileUtils.getFileExtension(filename)) { case "json" -> JsonUtils.loadToList(filename, c); - case "tsj" -> TsvUtils.loadTsjToListSetField(c, filename); - case "tsv" -> TsvUtils.loadTsvToListSetField(c, filename); + case "tsj" -> TsvUtils.loadTsjToListSetField(filename, c); + case "tsv" -> TsvUtils.loadTsvToListSetField(filename, c); default -> null; }; if (results == null) return; diff --git a/src/main/java/emu/grasscutter/game/gacha/GachaBanner.java b/src/main/java/emu/grasscutter/game/gacha/GachaBanner.java index 7afb82cf0..a9c6502d3 100644 --- a/src/main/java/emu/grasscutter/game/gacha/GachaBanner.java +++ b/src/main/java/emu/grasscutter/game/gacha/GachaBanner.java @@ -27,7 +27,7 @@ public class GachaBanner { private int[] rateUpItems4 = {}; private int[] rateUpItems5 = {}; @Getter private int[] fallbackItems3 = {11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304}; - @Getter private int[] fallbackItems4Pool1 = {1014, 1020, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064}; + @Getter private int[] fallbackItems4Pool1 = {1014, 1020, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1059, 1064, 1065, 1067, 1068, 1072}; @Getter private int[] fallbackItems4Pool2 = {11401, 11402, 11403, 11405, 12401, 12402, 12403, 12405, 13401, 13407, 14401, 14402, 14403, 14409, 15401, 15402, 15403, 15405}; @Getter private int[] fallbackItems5Pool1 = {1003, 1016, 1042, 1035, 1041}; @Getter private int[] fallbackItems5Pool2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502}; diff --git a/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java b/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java index a71caf875..f775570ab 100644 --- a/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java +++ b/src/main/java/emu/grasscutter/game/gacha/GachaSystem.java @@ -70,7 +70,7 @@ public class GachaSystem extends BaseGameSystem { public synchronized void load() { getGachaBanners().clear(); try { - List banners = DataLoader.loadList("Banners.json", GachaBanner.class); + List banners = DataLoader.loadTableToList("Banners", GachaBanner.class); if (banners.size() > 0) { for (GachaBanner banner : banners) { banner.onLoad(); diff --git a/src/main/java/emu/grasscutter/utils/FileUtils.java b/src/main/java/emu/grasscutter/utils/FileUtils.java index 574bfd6cb..40b12af21 100644 --- a/src/main/java/emu/grasscutter/utils/FileUtils.java +++ b/src/main/java/emu/grasscutter/utils/FileUtils.java @@ -88,6 +88,19 @@ public final class FileUtils { : Path.of(scripts); }; + private static final String[] TSJ_JSON_TSV = {"tsj", "json", "tsv"}; + private static final Path[] DATA_PATHS = {DATA_USER_PATH, DATA_DEFAULT_PATH}; + public static Path getDataPathTsjJsonTsv(String filename) { + val name = getFilenameWithoutExtension(filename); + for (val data_path : DATA_PATHS) { + for (val ext : TSJ_JSON_TSV) { + val path = data_path.resolve(name + "." + ext); + if (Files.exists(path)) return path; + } + } + return DATA_USER_PATH.resolve(name + ".tsj"); // Maybe they want to write to a new file + } + public static Path getDataPath(String path) { Path userPath = DATA_USER_PATH.resolve(path); if (Files.exists(userPath)) return userPath; @@ -121,13 +134,11 @@ public final class FileUtils { // If none exist, return the TSJ path, in case it wants to create a file public static Path getTsjJsonTsv(Path root, String filename) { val name = getFilenameWithoutExtension(filename); - val tsj = root.resolve(name + ".tsj"); - if (Files.exists(tsj)) return tsj; - val json = root.resolve(name + ".json"); - if (Files.exists(json)) return json; - val tsv = root.resolve(name + ".tsv"); - if (Files.exists(tsv)) return tsv; - return tsj; + for (val ext : TSJ_JSON_TSV) { + val path = root.resolve(name + "." + ext); + if (Files.exists(path)) return path; + } + return root.resolve(name + ".tsj"); } public static Path getScriptPath(String path) { diff --git a/src/main/java/emu/grasscutter/utils/TsvUtils.java b/src/main/java/emu/grasscutter/utils/TsvUtils.java index 32e316154..2e8f422bc 100644 --- a/src/main/java/emu/grasscutter/utils/TsvUtils.java +++ b/src/main/java/emu/grasscutter/utils/TsvUtils.java @@ -402,7 +402,7 @@ public class TsvUtils { // Arrays are represented as arrayName.0, arrayName.1, etc. columns. // Maps/POJOs are represented as objName.fieldOneName, objName.fieldTwoName, etc. columns. // This is currently about 25x as slow as TSJ and Gson parsers, likely due to the tree spam. - public static List loadTsvToListSetField(Class classType, Path filename) { + public static List loadTsvToListSetField(Path filename, Class classType) { try (val fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) { // val fieldMap = getClassFieldMap(classType); // val constructor = classType.getDeclaredConstructor(); @@ -453,7 +453,7 @@ public class TsvUtils { // This uses a hybrid format where columns can hold JSON-encoded values. // I'll term it TSJ (tab-separated JSON) for now, it has convenient properties. - public static List loadTsjToListSetField(Class classType, Path filename) { + public static List loadTsjToListSetField(Path filename, Class classType) { try (val fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) { val fieldMap = getClassFieldMap(classType); val constructor = classType.getDeclaredConstructor(); diff --git a/src/main/resources/defaults/data/Banners.json b/src/main/resources/defaults/data/Banners.json deleted file mode 100644 index 32c26e826..000000000 --- a/src/main/resources/defaults/data/Banners.json +++ /dev/null @@ -1,83 +0,0 @@ -[ - { - "comment": "Beginner's Banner. Do not change for no reason.", - "gachaType": 100, - "scheduleId": 803, - "bannerType": "EVENT", - "prefabPath": "GachaShowPanel_A016", - "titlePath": "UI_GACHA_SHOW_PANEL_A016_TITLE", - "costItemId": 224, - "costItemAmount10": 8, - "gachaTimesLimit": 20, - "beginTime": 0, - "endTime": 1924992000, - "sortId": 9999, - "rateUpItems5": [], - "rateUpItems4": [1034] - }, - { - "comment": "Standard", - "gachaType": 200, - "scheduleId": 893, - "bannerType": "STANDARD", - "prefabPath": "GachaShowPanel_A022", - "titlePath": "UI_GACHA_SHOW_PANEL_A022_TITLE", - "costItemId": 224, - "beginTime": 0, - "endTime": 1924992000, - "sortId": 1000, - "fallbackItems4Pool1": [1006, 1014, 1015, 1020, 1021, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1064], - "weights5": [[1,75], [73,150], [90,10000]] - }, - { - "comment": "Character Event Banner 1", - "gachaType": 301, - "scheduleId": 903, - "bannerType": "EVENT", - "prefabPath": "GachaShowPanel_A103", - "titlePath": "UI_GACHA_SHOW_PANEL_A081_TITLE", - "costItemId": 223, - "beginTime": 0, - "endTime": 1924992000, - "sortId": 9998, - "rateUpItems4": [1032, 1020, 1034], - "rateUpItems5": [1073], - "fallbackItems5Pool2": [], - "weights5": [[1,80], [73,80], [90,10000]] - }, - { - "comment": "Character Event Banner 2", - "gachaType": 400, - "scheduleId": 923, - "bannerType": "EVENT", - "prefabPath": "GachaShowPanel_A104", - "titlePath": "UI_GACHA_SHOW_PANEL_A049_TITLE", - "costItemId": 223, - "beginTime": 0, - "endTime": 1924992000, - "sortId": 9998, - "rateUpItems4": [1032, 1020, 1034], - "rateUpItems5": [1049], - "fallbackItems5Pool2": [], - "weights5": [[1,80], [73,80], [90,10000]] - }, - { - "comment": "Weapon Event Banner", - "gachaType": 302, - "scheduleId": 913, - "bannerType": "WEAPON", - "prefabPath": "GachaShowPanel_A105", - "titlePath": "UI_GACHA_SHOW_PANEL_A021_TITLE", - "costItemId": 223, - "beginTime": 0, - "endTime": 1924992000, - "sortId": 9997, - "rateUpItems4":[15405, 11402, 13407, 14402, 12403], - "rateUpItems5": [14511, 15509], - "fallbackItems5Pool1": [], - "weights4": [[1,600], [7,600], [8,6600], [10,12600]], - "weights5": [[1,100], [62,100], [73,7800], [80,10000]], - "eventChance4": 75, - "eventChance5": 75 - } -] diff --git a/src/main/resources/defaults/data/Banners.tsj b/src/main/resources/defaults/data/Banners.tsj new file mode 100644 index 000000000..a619c2473 --- /dev/null +++ b/src/main/resources/defaults/data/Banners.tsj @@ -0,0 +1,6 @@ +comment gachaType scheduleId bannerType prefabPath titlePath costItemId beginTime endTime sortId rateUpItems5 rateUpItems4 weights5 weights4 fallbackItems5Pool2 fallbackItems5Pool1 fallbackItems4Pool1 eventChance4 eventChance5 costItemAmount10 gachaTimesLimit +Beginner's Banner. Do not change for no reason. 100 803 EVENT GachaShowPanel_A016 UI_GACHA_SHOW_PANEL_A016_TITLE 224 1924992000 9999 [1034] 8 20 +Standard 200 893 STANDARD GachaShowPanel_A022 UI_GACHA_SHOW_PANEL_A022_TITLE 224 1924992000 1000 [[1, 75], [73, 150], [90, 10000]] [1006, 1014, 1015, 1020, 1021, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053, 1055, 1056, 1059, 1064, 1065, 1067, 1068, 1072] +Character Event Banner 1 301 903 EVENT GachaShowPanel_A106 UI_GACHA_SHOW_PANEL_A071_TITLE 223 1924992000 9998 [1058] [1050, 1059, 1074] [[1, 80], [73, 80], [90, 10000]] [] +Character Event Banner 2 400 923 EVENT GachaShowPanel_A107 UI_GACHA_SHOW_PANEL_A037_TITLE 223 1924992000 9998 [1033] [1050, 1059, 1074] [[1, 80], [73, 80], [90, 10000]] [] +Weapon Event Banner 302 913 WEAPON GachaShowPanel_A108 UI_GACHA_SHOW_PANEL_A021_TITLE 223 1924992000 9997 [14509, 15507] [11401, 12402, 13401, 14401, 15402] [[1, 100], [62, 100], [73, 7800], [80, 10000]] [[1, 600], [7, 600], [8, 6600], [10, 12600]] [] 75 75