2022-04-17 20:43:07 +08:00
|
|
|
package emu.grasscutter.data;
|
|
|
|
|
2022-04-21 04:45:38 +08:00
|
|
|
import com.google.gson.JsonElement;
|
2022-05-29 12:36:56 +08:00
|
|
|
import com.google.gson.annotations.SerializedName;
|
2022-04-17 20:43:07 +08:00
|
|
|
import emu.grasscutter.Grasscutter;
|
2022-07-24 03:59:23 +08:00
|
|
|
import emu.grasscutter.data.binout.*;
|
2022-05-28 19:21:47 +08:00
|
|
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
|
|
|
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
|
2022-04-21 04:45:38 +08:00
|
|
|
import emu.grasscutter.data.common.PointData;
|
|
|
|
import emu.grasscutter.data.common.ScenePointConfig;
|
2022-08-21 14:19:59 +08:00
|
|
|
import emu.grasscutter.game.managers.blossom.BlossomConfig;
|
2022-07-24 03:59:23 +08:00
|
|
|
import emu.grasscutter.game.quest.QuestEncryptionKey;
|
|
|
|
import emu.grasscutter.game.world.SpawnDataEntry;
|
|
|
|
import emu.grasscutter.game.world.SpawnDataEntry.GridBlockId;
|
|
|
|
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
|
|
|
import emu.grasscutter.scripts.SceneIndexManager;
|
2022-08-11 16:24:59 +08:00
|
|
|
import emu.grasscutter.utils.JsonUtils;
|
2022-04-17 20:43:07 +08:00
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
2022-09-23 16:40:46 +08:00
|
|
|
import lombok.val;
|
|
|
|
|
2022-07-24 03:59:23 +08:00
|
|
|
import org.reflections.Reflections;
|
2022-04-17 20:43:07 +08:00
|
|
|
|
2022-07-24 03:59:23 +08:00
|
|
|
import java.io.*;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.regex.Pattern;
|
2022-09-23 16:40:46 +08:00
|
|
|
import java.util.stream.Stream;
|
2022-07-24 03:59:23 +08:00
|
|
|
|
2022-08-09 20:14:44 +08:00
|
|
|
import static emu.grasscutter.config.Configuration.DATA;
|
2022-09-23 16:40:46 +08:00
|
|
|
import static emu.grasscutter.config.Configuration.getResourcePath;
|
2022-06-27 00:31:09 +08:00
|
|
|
import static emu.grasscutter.utils.Language.translate;
|
2022-05-11 12:30:07 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
public class ResourceLoader {
|
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
private static final List<String> loadedResources = new ArrayList<>();
|
2022-05-17 18:00:52 +08:00
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
public static List<Class<?>> getResourceDefClasses() {
|
|
|
|
Reflections reflections = new Reflections(ResourceLoader.class.getPackage().getName());
|
|
|
|
Set<?> classes = reflections.getSubTypesOf(GameResource.class);
|
2022-04-17 20:43:07 +08:00
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
List<Class<?>> classList = new ArrayList<>(classes.size());
|
|
|
|
classes.forEach(o -> {
|
|
|
|
Class<?> c = (Class<?>) o;
|
|
|
|
if (c.getAnnotation(ResourceType.class) != null) {
|
|
|
|
classList.add(c);
|
|
|
|
}
|
|
|
|
});
|
2022-04-17 20:43:07 +08:00
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
classList.sort((a, b) -> b.getAnnotation(ResourceType.class).loadPriority().value() - a.getAnnotation(ResourceType.class).loadPriority().value());
|
2022-04-17 20:43:07 +08:00
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
return classList;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-07-30 19:22:59 +08:00
|
|
|
private static boolean loadedAll = false;
|
2022-07-21 15:21:22 +08:00
|
|
|
public static void loadAll() {
|
2022-07-30 19:22:59 +08:00
|
|
|
if (loadedAll) return;
|
2022-06-27 00:31:09 +08:00
|
|
|
Grasscutter.getLogger().info(translate("messages.status.resources.loading"));
|
|
|
|
|
2022-08-21 19:33:54 +08:00
|
|
|
// Load ability lists
|
|
|
|
loadAbilityEmbryos();
|
|
|
|
loadOpenConfig();
|
|
|
|
loadAbilityModifiers();
|
|
|
|
// Load resources
|
|
|
|
loadResources(true);
|
|
|
|
// Process into depots
|
|
|
|
GameDepot.load();
|
|
|
|
// Load spawn data and quests
|
2022-09-15 10:26:20 +08:00
|
|
|
loadGadgetConfigData();
|
2022-08-21 19:33:54 +08:00
|
|
|
loadSpawnData();
|
|
|
|
loadQuests();
|
2022-07-23 17:28:49 +08:00
|
|
|
loadScriptSceneData();
|
2022-08-21 19:33:54 +08:00
|
|
|
// Load scene points - must be done AFTER resources are loaded
|
|
|
|
loadScenePoints();
|
|
|
|
// Load default home layout
|
|
|
|
loadHomeworldDefaultSaveData();
|
|
|
|
loadNpcBornData();
|
2022-08-21 14:19:59 +08:00
|
|
|
loadBlossomResources();
|
2022-06-27 00:31:09 +08:00
|
|
|
|
|
|
|
Grasscutter.getLogger().info(translate("messages.status.resources.finish"));
|
2022-07-30 19:22:59 +08:00
|
|
|
loadedAll = true;
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void loadResources() {
|
|
|
|
loadResources(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void loadResources(boolean doReload) {
|
|
|
|
for (Class<?> resourceDefinition : getResourceDefClasses()) {
|
|
|
|
ResourceType type = resourceDefinition.getAnnotation(ResourceType.class);
|
|
|
|
|
|
|
|
if (type == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
|
Int2ObjectMap map = GameData.getMapByResourceDef(resourceDefinition);
|
|
|
|
|
|
|
|
if (map == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
loadFromResource(resourceDefinition, type, map, doReload);
|
|
|
|
} catch (Exception e) {
|
2022-09-23 16:40:46 +08:00
|
|
|
Grasscutter.getLogger().error("Error loading resource file: " + Arrays.toString(type.name()), e.getLocalizedMessage());
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("rawtypes")
|
|
|
|
protected static void loadFromResource(Class<?> c, ResourceType type, Int2ObjectMap map, boolean doReload) throws Exception {
|
|
|
|
if (!loadedResources.contains(c.getSimpleName()) || doReload) {
|
|
|
|
for (String name : type.name()) {
|
|
|
|
loadFromResource(c, name, map);
|
|
|
|
}
|
|
|
|
loadedResources.add(c.getSimpleName());
|
2022-06-27 00:26:39 +08:00
|
|
|
Grasscutter.getLogger().debug("Loaded " + map.size() + " " + c.getSimpleName() + "s.");
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
2022-08-09 20:14:44 +08:00
|
|
|
protected static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map) throws Exception {
|
2022-09-23 16:40:46 +08:00
|
|
|
List<T> list = JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c);
|
2022-08-09 20:14:44 +08:00
|
|
|
|
|
|
|
for (T o : list) {
|
|
|
|
GameResource res = (GameResource) o;
|
|
|
|
res.onLoad();
|
|
|
|
map.put(res.getId(), res);
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void loadScenePoints() {
|
2022-09-23 16:40:46 +08:00
|
|
|
val pattern = Pattern.compile("scene([0-9]+)_point\\.json");
|
|
|
|
try {
|
|
|
|
Files.newDirectoryStream(getResourcePath("BinOutput/Scene/Point"), "scene*_point.json").forEach(path -> {
|
|
|
|
val matcher = pattern.matcher(path.getFileName().toString());
|
|
|
|
if (!matcher.find()) return;
|
|
|
|
int sceneId = Integer.parseInt(matcher.group(1));
|
|
|
|
ScenePointConfig config;
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
config = JsonUtils.loadToClass(path, ScenePointConfig.class);
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
return;
|
|
|
|
}
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
if (config.points == null) return;
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
List<Integer> scenePoints = new ArrayList<>();
|
|
|
|
for (Map.Entry<String, JsonElement> entry : config.points.entrySet()) {
|
|
|
|
String key = entry.getKey();
|
|
|
|
String name = sceneId + "_" + key;
|
|
|
|
int id = Integer.parseInt(key);
|
|
|
|
PointData pointData = JsonUtils.decode(entry.getValue(), PointData.class);
|
|
|
|
pointData.setId(id);
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
GameData.getScenePointIdList().add(id);
|
|
|
|
GameData.getScenePointEntries().put(name, new ScenePointEntry(name, pointData));
|
|
|
|
scenePoints.add(id);
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
pointData.updateDailyDungeon();
|
|
|
|
}
|
|
|
|
GameData.getScenePointsPerScene().put(sceneId, scenePoints);
|
|
|
|
});
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Scene point files cannot be found, you cannot use teleport waypoints!");
|
|
|
|
return;
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void loadAbilityEmbryos() {
|
|
|
|
List<AbilityEmbryoEntry> embryoList = null;
|
|
|
|
|
|
|
|
// Read from cached file if exists
|
2022-08-09 20:14:44 +08:00
|
|
|
try {
|
2022-08-11 16:24:59 +08:00
|
|
|
embryoList = JsonUtils.loadToList(DATA("AbilityEmbryos.json"), AbilityEmbryoEntry.class);
|
2022-07-21 15:21:22 +08:00
|
|
|
} catch (Exception ignored) {}
|
|
|
|
|
|
|
|
if (embryoList == null) {
|
|
|
|
// Load from BinOutput
|
2022-09-23 16:40:46 +08:00
|
|
|
val pattern = Pattern.compile("ConfigAvatar_(.+?)\\.json");
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
val l = new ArrayList<AbilityEmbryoEntry>();
|
|
|
|
try {
|
|
|
|
Files.newDirectoryStream(getResourcePath("BinOutput/Avatar/"), "ConfigAvatar_*.json").forEach(path -> {
|
|
|
|
val matcher = pattern.matcher(path.getFileName().toString());
|
|
|
|
if (!matcher.find()) return;
|
|
|
|
String avatarName = matcher.group(1);
|
|
|
|
AvatarConfig config;
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
config = JsonUtils.loadToClass(path, AvatarConfig.class);
|
|
|
|
} catch (Exception e) {
|
|
|
|
Grasscutter.getLogger().error("Error loading player ability embryos:", e);
|
|
|
|
return;
|
|
|
|
}
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
if (config.abilities == null) return;
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
int s = config.abilities.size();
|
|
|
|
AbilityEmbryoEntry al = new AbilityEmbryoEntry(avatarName, config.abilities.stream().map(Object::toString).toArray(size -> new String[s]));
|
|
|
|
l.add(al);
|
|
|
|
});
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Error loading ability embryos: no files found");
|
|
|
|
return;
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
embryoList = l;
|
|
|
|
|
2022-08-09 20:14:44 +08:00
|
|
|
try {
|
2022-09-23 16:40:46 +08:00
|
|
|
GameDepot.setPlayerAbilities(JsonUtils.loadToMap(getResourcePath("BinOutput/AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json"), String.class, AvatarConfig.class));
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Error loading player abilities:", e);
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (embryoList == null || embryoList.isEmpty()) {
|
|
|
|
Grasscutter.getLogger().error("No embryos loaded!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (AbilityEmbryoEntry entry : embryoList) {
|
|
|
|
GameData.getAbilityEmbryoInfo().put(entry.getName(), entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void loadAbilityModifiers() {
|
|
|
|
// Load from BinOutput
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
Files.newDirectoryStream(getResourcePath("BinOutput/Ability/Temp/AvatarAbilities/")).forEach(path -> {
|
|
|
|
List<AbilityConfigData> abilityConfigList;
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
abilityConfigList = JsonUtils.loadToList(path, AbilityConfigData.class);
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Error loading ability modifiers from path " + path.toString() + ": ", e);
|
|
|
|
return;
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
abilityConfigList.forEach(data -> {
|
|
|
|
if (data.Default.modifiers == null || data.Default.modifiers.size() == 0) {
|
|
|
|
return;
|
|
|
|
}
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
String name = data.Default.abilityName;
|
|
|
|
AbilityModifierEntry modifierEntry = new AbilityModifierEntry(name);
|
|
|
|
data.Default.modifiers.forEach((key, modifier) -> {
|
|
|
|
Stream.ofNullable(modifier.onAdded)
|
|
|
|
.flatMap(Stream::of)
|
|
|
|
.filter(action -> action.$type.contains("HealHP"))
|
|
|
|
.forEach(action -> {
|
2022-07-21 15:21:22 +08:00
|
|
|
action.type = AbilityModifierActionType.HealHP;
|
|
|
|
modifierEntry.getOnAdded().add(action);
|
2022-09-23 16:40:46 +08:00
|
|
|
});
|
|
|
|
Stream.ofNullable(modifier.onThinkInterval)
|
|
|
|
.flatMap(Stream::of)
|
|
|
|
.filter(action -> action.$type.contains("HealHP"))
|
|
|
|
.forEach(action -> {
|
2022-07-21 15:21:22 +08:00
|
|
|
action.type = AbilityModifierActionType.HealHP;
|
|
|
|
modifierEntry.getOnThinkInterval().add(action);
|
2022-09-23 16:40:46 +08:00
|
|
|
});
|
|
|
|
Stream.ofNullable(modifier.onRemoved)
|
|
|
|
.flatMap(Stream::of)
|
|
|
|
.filter(action -> action.$type.contains("HealHP"))
|
|
|
|
.forEach(action -> {
|
2022-07-21 15:21:22 +08:00
|
|
|
action.type = AbilityModifierActionType.HealHP;
|
|
|
|
modifierEntry.getOnRemoved().add(action);
|
2022-09-23 16:40:46 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
GameData.getAbilityModifiers().put(name, modifierEntry);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Error loading ability modifiers: ", e);
|
|
|
|
return;
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void loadSpawnData() {
|
|
|
|
String[] spawnDataNames = {"Spawns.json", "GadgetSpawns.json"};
|
|
|
|
ArrayList<SpawnGroupEntry> spawnEntryMap = new ArrayList<>();
|
2022-07-18 18:13:55 +08:00
|
|
|
|
|
|
|
for (String name : spawnDataNames) {
|
|
|
|
// Load spawn entries from file
|
2022-07-20 17:26:02 +08:00
|
|
|
try (InputStreamReader reader = DataLoader.loadReader(name)) {
|
2022-07-18 18:13:55 +08:00
|
|
|
// Add spawns to group if it already exists in our spawn group map
|
2022-08-11 16:24:59 +08:00
|
|
|
spawnEntryMap.addAll(JsonUtils.loadToList(reader, SpawnGroupEntry.class));
|
2022-07-18 18:13:55 +08:00
|
|
|
} catch (Exception ignored) {}
|
|
|
|
}
|
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
if (spawnEntryMap.isEmpty()) {
|
|
|
|
Grasscutter.getLogger().error("No spawn data loaded!");
|
|
|
|
return;
|
|
|
|
}
|
2022-04-25 16:50:58 +08:00
|
|
|
|
2022-07-18 18:13:55 +08:00
|
|
|
HashMap<GridBlockId, ArrayList<SpawnDataEntry>> areaSort = new HashMap<>();
|
|
|
|
//key = sceneId,x,z , value = ArrayList<SpawnDataEntry>
|
|
|
|
for (SpawnGroupEntry entry : spawnEntryMap) {
|
|
|
|
entry.getSpawns().forEach(
|
|
|
|
s -> {
|
|
|
|
s.setGroup(entry);
|
|
|
|
GridBlockId point = s.getBlockId();
|
2022-07-21 15:21:22 +08:00
|
|
|
if (!areaSort.containsKey(point)) {
|
2022-07-18 18:13:55 +08:00
|
|
|
areaSort.put(point, new ArrayList<>());
|
|
|
|
}
|
|
|
|
areaSort.get(point).add(s);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
GameDepot.addSpawnListById(areaSort);
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private static void loadOpenConfig() {
|
|
|
|
// Read from cached file if exists
|
|
|
|
List<OpenConfigEntry> list = null;
|
|
|
|
|
2022-08-09 20:14:44 +08:00
|
|
|
try {
|
2022-08-11 16:24:59 +08:00
|
|
|
list = JsonUtils.loadToList(DATA("OpenConfig.json"), OpenConfigEntry.class);
|
2022-07-21 15:21:22 +08:00
|
|
|
} catch (Exception ignored) {}
|
|
|
|
|
|
|
|
if (list == null) {
|
|
|
|
Map<String, OpenConfigEntry> map = new TreeMap<>();
|
|
|
|
String[] folderNames = {"BinOutput/Talent/EquipTalents/", "BinOutput/Talent/AvatarTalents/"};
|
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
for (String folderName : folderNames) {
|
|
|
|
try {
|
|
|
|
Files.newDirectoryStream(getResourcePath(folderName), "*.json").forEach(path -> {
|
|
|
|
try {
|
|
|
|
JsonUtils.loadToMap(path, String.class, OpenConfigData[].class)
|
|
|
|
.forEach((name, data) -> map.put(name, new OpenConfigEntry(name, data)));
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Error loading open config: no files found in " + folderName);
|
|
|
|
return;
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
list = new ArrayList<>(map.values());
|
|
|
|
}
|
|
|
|
|
|
|
|
if (list == null || list.isEmpty()) {
|
|
|
|
Grasscutter.getLogger().error("No openconfig entries loaded!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (OpenConfigEntry entry : list) {
|
|
|
|
GameData.getOpenConfigEntries().put(entry.getName(), entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void loadQuests() {
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
Files.list(getResourcePath("BinOutput/Quest/")).forEach(path -> {
|
|
|
|
try {
|
|
|
|
val mainQuest = JsonUtils.loadToClass(path, MainQuestData.class);
|
|
|
|
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
|
|
|
|
} catch (IOException e) {
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Quest data missing");
|
2022-07-21 15:21:22 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-08-09 20:14:44 +08:00
|
|
|
try {
|
2022-09-23 16:40:46 +08:00
|
|
|
val questEncryptionMap = GameData.getMainQuestEncryptionMap();
|
2022-08-23 21:59:52 +08:00
|
|
|
String path = "QuestEncryptionKeys.json";
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
JsonUtils.loadToList(getResourcePath(path), QuestEncryptionKey.class).forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
|
|
|
} catch (IOException | NullPointerException ignored) {}
|
|
|
|
try {
|
|
|
|
DataLoader.loadList(path, QuestEncryptionKey.class).forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
|
|
|
} catch (IOException | NullPointerException ignored) {}
|
2022-07-27 02:49:45 +08:00
|
|
|
Grasscutter.getLogger().debug("Loaded {} quest keys.", questEncryptionMap.size());
|
2022-07-24 03:59:23 +08:00
|
|
|
} catch (Exception e) {
|
|
|
|
Grasscutter.getLogger().error("Unable to load quest keys.", e);
|
|
|
|
}
|
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
Grasscutter.getLogger().debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
|
|
|
|
}
|
|
|
|
|
2022-07-23 17:28:49 +08:00
|
|
|
public static void loadScriptSceneData() {
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
Files.list(getResourcePath("ScriptSceneData/")).forEach(path -> {
|
|
|
|
try {
|
|
|
|
GameData.getScriptSceneDataMap().put(path.getFileName().toString(), JsonUtils.loadToClass(path, ScriptSceneData.class));
|
|
|
|
} catch (IOException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Grasscutter.getLogger().debug("Loaded " + GameData.getScriptSceneDataMap().size() + " ScriptSceneDatas.");
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().debug("ScriptSceneData folder missing or empty.");
|
2022-07-23 17:28:49 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-09 20:14:44 +08:00
|
|
|
private static void loadHomeworldDefaultSaveData() {
|
2022-09-23 16:40:46 +08:00
|
|
|
val pattern = Pattern.compile("scene([0-9]+)_home_config\\.json");
|
|
|
|
try {
|
|
|
|
Files.newDirectoryStream(getResourcePath("BinOutput/HomeworldDefaultSave"), "scene*_home_config.json").forEach(path -> {
|
|
|
|
val matcher = pattern.matcher(path.getFileName().toString());
|
|
|
|
if (!matcher.find()) return;
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
val sceneId = Integer.parseInt(matcher.group(1));
|
|
|
|
val data = JsonUtils.loadToClass(path, HomeworldDefaultSaveData.class);
|
|
|
|
GameData.getHomeworldDefaultSaveData().put(sceneId, data);
|
|
|
|
} catch (Exception ignored) {}
|
|
|
|
});
|
|
|
|
Grasscutter.getLogger().debug("Loaded " + GameData.getHomeworldDefaultSaveData().size() + " HomeworldDefaultSaveDatas.");
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Failed to load HomeworldDefaultSave folder.");
|
|
|
|
}
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private static void loadNpcBornData() {
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
Files.newDirectoryStream(getResourcePath("BinOutput/Scene/SceneNpcBorn/"), "*.json").forEach(path -> {
|
|
|
|
try {
|
|
|
|
val data = JsonUtils.loadToClass(path, SceneNpcBornData.class);
|
|
|
|
if (data.getBornPosList() == null || data.getBornPosList().size() == 0) {
|
|
|
|
return;
|
|
|
|
}
|
2022-07-21 15:21:22 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
data.setIndex(SceneIndexManager.buildIndex(3, data.getBornPosList(), item -> item.getPos().toPoint()));
|
|
|
|
GameData.getSceneNpcBornData().put(data.getSceneId(), data);
|
|
|
|
} catch (IOException ignored) {}
|
|
|
|
});
|
|
|
|
Grasscutter.getLogger().debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneNpcBornDatas.");
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Failed to load SceneNpcBorn folder.");
|
|
|
|
}
|
2022-07-21 15:21:22 +08:00
|
|
|
}
|
|
|
|
|
2022-09-15 10:26:20 +08:00
|
|
|
private static void loadGadgetConfigData() {
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
Files.newDirectoryStream(getResourcePath("BinOutput/Gadget/"), "*.json").forEach(path -> {
|
|
|
|
try {
|
|
|
|
GameData.getGadgetConfigData().putAll(JsonUtils.loadToMap(path, String.class, ConfigGadget.class));
|
|
|
|
} catch (Exception e) {
|
|
|
|
Grasscutter.getLogger().error("failed to load ConfigGadget entries for " + path.toString(), e);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
2022-09-15 10:26:20 +08:00
|
|
|
|
2022-09-23 16:40:46 +08:00
|
|
|
Grasscutter.getLogger().debug("Loaded {} ConfigGadget entries.", GameData.getGadgetConfigData().size());
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().error("Failed to load ConfigGadget folder.");
|
|
|
|
}
|
2022-09-15 10:26:20 +08:00
|
|
|
}
|
|
|
|
|
2022-08-21 14:19:59 +08:00
|
|
|
private static void loadBlossomResources() {
|
2022-09-23 16:40:46 +08:00
|
|
|
try {
|
|
|
|
GameDepot.setBlossomConfig(DataLoader.loadClass("BlossomConfig.json", BlossomConfig.class));
|
|
|
|
Grasscutter.getLogger().debug("Loaded BlossomConfig.");
|
|
|
|
} catch (IOException e) {
|
|
|
|
Grasscutter.getLogger().warn("Failed to load BlossomConfig.");
|
|
|
|
}
|
2022-08-21 14:19:59 +08:00
|
|
|
}
|
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
// BinOutput configs
|
|
|
|
|
|
|
|
public static class AvatarConfig {
|
|
|
|
@SerializedName(value="abilities", alternate={"targetAbilities"})
|
|
|
|
public ArrayList<AvatarConfigAbility> abilities;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class AvatarConfigAbility {
|
|
|
|
public String abilityName;
|
|
|
|
public String toString() {
|
|
|
|
return abilityName;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static class OpenConfig {
|
|
|
|
public OpenConfigData[] data;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static class OpenConfigData {
|
|
|
|
public String $type;
|
|
|
|
public String abilityName;
|
|
|
|
|
|
|
|
@SerializedName(value="talentIndex", alternate={"OJOFFKLNAHN"})
|
|
|
|
public int talentIndex;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
@SerializedName(value="skillID", alternate={"overtime"})
|
|
|
|
public int skillID;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-07-21 15:21:22 +08:00
|
|
|
@SerializedName(value="pointDelta", alternate={"IGEBKIHPOIF"})
|
|
|
|
public int pointDelta;
|
|
|
|
}
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|