mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-12-01 18:36:49 +00:00
Add Data TSJ loading, replace and update Banners
This commit is contained in:
parent
35962542af
commit
1c4d263dd2
@ -5,6 +5,8 @@ import emu.grasscutter.server.http.handlers.GachaHandler;
|
|||||||
import emu.grasscutter.tools.Tools;
|
import emu.grasscutter.tools.Tools;
|
||||||
import emu.grasscutter.utils.FileUtils;
|
import emu.grasscutter.utils.FileUtils;
|
||||||
import emu.grasscutter.utils.JsonUtils;
|
import emu.grasscutter.utils.JsonUtils;
|
||||||
|
import emu.grasscutter.utils.TsvUtils;
|
||||||
|
import lombok.val;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -88,6 +90,17 @@ public class DataLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> loadTableToList(String resourcePath, Class<T> 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() {
|
public static void checkAllFiles() {
|
||||||
try {
|
try {
|
||||||
List<Path> filenames = FileUtils.getPathsFromResource("/defaults/data/");
|
List<Path> filenames = FileUtils.getPathsFromResource("/defaults/data/");
|
||||||
|
@ -152,8 +152,8 @@ public class ResourceLoader {
|
|||||||
protected static <T> void loadFromResource(Class<T> c, Path filename, Int2ObjectMap map) throws Exception {
|
protected static <T> void loadFromResource(Class<T> c, Path filename, Int2ObjectMap map) throws Exception {
|
||||||
val results = switch (FileUtils.getFileExtension(filename)) {
|
val results = switch (FileUtils.getFileExtension(filename)) {
|
||||||
case "json" -> JsonUtils.loadToList(filename, c);
|
case "json" -> JsonUtils.loadToList(filename, c);
|
||||||
case "tsj" -> TsvUtils.loadTsjToListSetField(c, filename);
|
case "tsj" -> TsvUtils.loadTsjToListSetField(filename, c);
|
||||||
case "tsv" -> TsvUtils.loadTsvToListSetField(c, filename);
|
case "tsv" -> TsvUtils.loadTsvToListSetField(filename, c);
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
if (results == null) return;
|
if (results == null) return;
|
||||||
|
@ -27,7 +27,7 @@ public class GachaBanner {
|
|||||||
private int[] rateUpItems4 = {};
|
private int[] rateUpItems4 = {};
|
||||||
private int[] rateUpItems5 = {};
|
private int[] rateUpItems5 = {};
|
||||||
@Getter private int[] fallbackItems3 = {11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304};
|
@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[] 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[] fallbackItems5Pool1 = {1003, 1016, 1042, 1035, 1041};
|
||||||
@Getter private int[] fallbackItems5Pool2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502};
|
@Getter private int[] fallbackItems5Pool2 = {11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502};
|
||||||
|
@ -70,7 +70,7 @@ public class GachaSystem extends BaseGameSystem {
|
|||||||
public synchronized void load() {
|
public synchronized void load() {
|
||||||
getGachaBanners().clear();
|
getGachaBanners().clear();
|
||||||
try {
|
try {
|
||||||
List<GachaBanner> banners = DataLoader.loadList("Banners.json", GachaBanner.class);
|
List<GachaBanner> banners = DataLoader.loadTableToList("Banners", GachaBanner.class);
|
||||||
if (banners.size() > 0) {
|
if (banners.size() > 0) {
|
||||||
for (GachaBanner banner : banners) {
|
for (GachaBanner banner : banners) {
|
||||||
banner.onLoad();
|
banner.onLoad();
|
||||||
|
@ -88,6 +88,19 @@ public final class FileUtils {
|
|||||||
: Path.of(scripts);
|
: 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) {
|
public static Path getDataPath(String path) {
|
||||||
Path userPath = DATA_USER_PATH.resolve(path);
|
Path userPath = DATA_USER_PATH.resolve(path);
|
||||||
if (Files.exists(userPath)) return userPath;
|
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
|
// If none exist, return the TSJ path, in case it wants to create a file
|
||||||
public static Path getTsjJsonTsv(Path root, String filename) {
|
public static Path getTsjJsonTsv(Path root, String filename) {
|
||||||
val name = getFilenameWithoutExtension(filename);
|
val name = getFilenameWithoutExtension(filename);
|
||||||
val tsj = root.resolve(name + ".tsj");
|
for (val ext : TSJ_JSON_TSV) {
|
||||||
if (Files.exists(tsj)) return tsj;
|
val path = root.resolve(name + "." + ext);
|
||||||
val json = root.resolve(name + ".json");
|
if (Files.exists(path)) return path;
|
||||||
if (Files.exists(json)) return json;
|
}
|
||||||
val tsv = root.resolve(name + ".tsv");
|
return root.resolve(name + ".tsj");
|
||||||
if (Files.exists(tsv)) return tsv;
|
|
||||||
return tsj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Path getScriptPath(String path) {
|
public static Path getScriptPath(String path) {
|
||||||
|
@ -402,7 +402,7 @@ public class TsvUtils {
|
|||||||
// Arrays are represented as arrayName.0, arrayName.1, etc. columns.
|
// Arrays are represented as arrayName.0, arrayName.1, etc. columns.
|
||||||
// Maps/POJOs are represented as objName.fieldOneName, objName.fieldTwoName, 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.
|
// This is currently about 25x as slow as TSJ and Gson parsers, likely due to the tree spam.
|
||||||
public static <T> List<T> loadTsvToListSetField(Class<T> classType, Path filename) {
|
public static <T> List<T> loadTsvToListSetField(Path filename, Class<T> classType) {
|
||||||
try (val fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) {
|
try (val fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) {
|
||||||
// val fieldMap = getClassFieldMap(classType);
|
// val fieldMap = getClassFieldMap(classType);
|
||||||
// val constructor = classType.getDeclaredConstructor();
|
// val constructor = classType.getDeclaredConstructor();
|
||||||
@ -453,7 +453,7 @@ public class TsvUtils {
|
|||||||
|
|
||||||
// This uses a hybrid format where columns can hold JSON-encoded values.
|
// 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.
|
// I'll term it TSJ (tab-separated JSON) for now, it has convenient properties.
|
||||||
public static <T> List<T> loadTsjToListSetField(Class<T> classType, Path filename) {
|
public static <T> List<T> loadTsjToListSetField(Path filename, Class<T> classType) {
|
||||||
try (val fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) {
|
try (val fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) {
|
||||||
val fieldMap = getClassFieldMap(classType);
|
val fieldMap = getClassFieldMap(classType);
|
||||||
val constructor = classType.getDeclaredConstructor();
|
val constructor = classType.getDeclaredConstructor();
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
]
|
|
6
src/main/resources/defaults/data/Banners.tsj
Normal file
6
src/main/resources/defaults/data/Banners.tsj
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user