2022-04-17 20:43:07 +08:00
|
|
|
package emu.grasscutter.data;
|
|
|
|
|
2022-05-17 18:00:52 +08:00
|
|
|
import java.io.*;
|
2022-06-29 19:53:50 +08:00
|
|
|
import java.lang.reflect.Type;
|
2022-06-14 20:51:13 +08:00
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Path;
|
2022-04-19 11:26:34 +08:00
|
|
|
import java.util.*;
|
2022-04-17 20:43:07 +08:00
|
|
|
import java.util.Map.Entry;
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
2022-06-14 20:51:13 +08:00
|
|
|
import emu.grasscutter.data.binout.*;
|
2022-07-18 18:13:55 +08:00
|
|
|
import emu.grasscutter.game.world.SpawnDataEntry;
|
2022-05-25 14:12:36 +08:00
|
|
|
import emu.grasscutter.scripts.SceneIndexManager;
|
2022-04-19 11:26:34 +08:00
|
|
|
import emu.grasscutter.utils.Utils;
|
2022-06-14 20:51:13 +08:00
|
|
|
import lombok.SneakyThrows;
|
2022-04-17 20:43:07 +08:00
|
|
|
import org.reflections.Reflections;
|
|
|
|
|
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 com.google.gson.reflect.TypeToken;
|
|
|
|
|
|
|
|
import emu.grasscutter.Grasscutter;
|
2022-05-28 19:21:47 +08:00
|
|
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
|
|
|
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
|
|
|
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-05-11 12:30:07 +08:00
|
|
|
import emu.grasscutter.game.world.SpawnDataEntry.*;
|
2022-04-17 20:43:07 +08:00
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
|
|
|
2022-07-20 17:29:51 +08:00
|
|
|
import static emu.grasscutter.config.Configuration.*;
|
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-06-27 00:26:39 +08:00
|
|
|
private static final List<String> loadedResources = new ArrayList<>();
|
2022-05-17 18:00:52 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
public static List<Class<?>> getResourceDefClasses() {
|
|
|
|
Reflections reflections = new Reflections(ResourceLoader.class.getPackage().getName());
|
2022-04-27 12:21:57 +08:00
|
|
|
Set<?> classes = reflections.getSubTypesOf(GameResource.class);
|
2022-04-17 20:43:07 +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-19 11:26:34 +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
|
|
|
|
|
|
|
return classList;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
public static void loadAll() {
|
2022-06-27 00:31:09 +08:00
|
|
|
Grasscutter.getLogger().info(translate("messages.status.resources.loading"));
|
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
// Load ability lists
|
|
|
|
loadAbilityEmbryos();
|
|
|
|
loadOpenConfig();
|
2022-05-08 19:40:01 +08:00
|
|
|
loadAbilityModifiers();
|
2022-04-17 20:43:07 +08:00
|
|
|
// Load resources
|
|
|
|
loadResources();
|
|
|
|
// Process into depots
|
2022-04-27 12:21:57 +08:00
|
|
|
GameDepot.load();
|
2022-05-11 18:56:40 +08:00
|
|
|
// Load spawn data and quests
|
2022-04-25 16:50:58 +08:00
|
|
|
loadSpawnData();
|
2022-05-11 18:56:40 +08:00
|
|
|
loadQuests();
|
2022-04-30 05:29:34 +08:00
|
|
|
// Load scene points - must be done AFTER resources are loaded
|
|
|
|
loadScenePoints();
|
2022-06-14 20:51:13 +08:00
|
|
|
// Load default home layout
|
|
|
|
loadHomeworldDefaultSaveData();
|
2022-05-25 10:44:46 +08:00
|
|
|
loadNpcBornData();
|
2022-06-27 00:31:09 +08:00
|
|
|
|
|
|
|
Grasscutter.getLogger().info(translate("messages.status.resources.finish"));
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
public static void loadResources() {
|
2022-05-17 18:00:52 +08:00
|
|
|
loadResources(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void loadResources(boolean doReload) {
|
2022-04-17 20:43:07 +08:00
|
|
|
for (Class<?> resourceDefinition : getResourceDefClasses()) {
|
|
|
|
ResourceType type = resourceDefinition.getAnnotation(ResourceType.class);
|
|
|
|
|
|
|
|
if (type == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
@SuppressWarnings("rawtypes")
|
2022-04-27 12:21:57 +08:00
|
|
|
Int2ObjectMap map = GameData.getMapByResourceDef(resourceDefinition);
|
2022-04-17 20:43:07 +08:00
|
|
|
|
|
|
|
if (map == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
2022-05-17 18:00:52 +08:00
|
|
|
loadFromResource(resourceDefinition, type, map, doReload);
|
2022-04-17 20:43:07 +08:00
|
|
|
} catch (Exception e) {
|
2022-04-19 11:26:34 +08:00
|
|
|
Grasscutter.getLogger().error("Error loading resource file: " + Arrays.toString(type.name()), e);
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
@SuppressWarnings("rawtypes")
|
2022-05-17 18:00:52 +08:00
|
|
|
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-04-17 20:43:07 +08:00
|
|
|
}
|
|
|
|
}
|
2022-05-17 18:00:52 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
|
|
|
protected static void loadFromResource(Class<?> c, String fileName, Int2ObjectMap map) throws Exception {
|
2022-05-28 19:21:47 +08:00
|
|
|
try (FileReader fileReader = new FileReader(RESOURCE("ExcelBinOutput/" + fileName))) {
|
|
|
|
List list = Grasscutter.getGsonFactory().fromJson(fileReader, TypeToken.getParameterized(Collection.class, c).getType());
|
|
|
|
|
|
|
|
for (Object o : list) {
|
|
|
|
GameResource res = (GameResource) o;
|
|
|
|
res.onLoad();
|
|
|
|
map.put(res.getId(), res);
|
2022-05-17 18:00:52 +08:00
|
|
|
}
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-21 04:45:38 +08:00
|
|
|
private static void loadScenePoints() {
|
|
|
|
Pattern pattern = Pattern.compile("(?<=scene)(.*?)(?=_point.json)");
|
2022-05-11 12:30:07 +08:00
|
|
|
File folder = new File(RESOURCE("BinOutput/Scene/Point"));
|
2022-04-21 10:37:24 +08:00
|
|
|
|
|
|
|
if (!folder.isDirectory() || !folder.exists() || folder.listFiles() == null) {
|
|
|
|
Grasscutter.getLogger().error("Scene point files cannot be found, you cannot use teleport waypoints!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-04-21 04:45:38 +08:00
|
|
|
List<ScenePointEntry> scenePointList = new ArrayList<>();
|
2022-04-27 05:44:30 +08:00
|
|
|
for (File file : Objects.requireNonNull(folder.listFiles())) {
|
2022-05-11 12:30:07 +08:00
|
|
|
ScenePointConfig config; Integer sceneId;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-21 04:45:38 +08:00
|
|
|
Matcher matcher = pattern.matcher(file.getName());
|
|
|
|
if (matcher.find()) {
|
|
|
|
sceneId = Integer.parseInt(matcher.group(1));
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
try (FileReader fileReader = new FileReader(file)) {
|
|
|
|
config = Grasscutter.getGsonFactory().fromJson(fileReader, ScenePointConfig.class);
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (config.points == null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Map.Entry<String, JsonElement> entry : config.points.entrySet()) {
|
|
|
|
PointData pointData = Grasscutter.getGsonFactory().fromJson(entry.getValue(), PointData.class);
|
2022-04-28 23:20:37 +08:00
|
|
|
pointData.setId(Integer.parseInt(entry.getKey()));
|
2022-04-21 04:45:38 +08:00
|
|
|
|
|
|
|
ScenePointEntry sl = new ScenePointEntry(sceneId + "_" + entry.getKey(), pointData);
|
|
|
|
scenePointList.add(sl);
|
2022-04-30 05:29:34 +08:00
|
|
|
GameData.getScenePointIdList().add(pointData.getId());
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-30 05:29:34 +08:00
|
|
|
pointData.updateDailyDungeon();
|
2022-04-21 04:45:38 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (ScenePointEntry entry : scenePointList) {
|
2022-04-27 12:21:57 +08:00
|
|
|
GameData.getScenePointEntries().put(entry.getName(), entry);
|
2022-04-21 04:45:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
private static void loadAbilityEmbryos() {
|
|
|
|
List<AbilityEmbryoEntry> embryoList = null;
|
2022-05-17 18:00:52 +08:00
|
|
|
|
|
|
|
// Read from cached file if exists
|
2022-06-27 00:26:39 +08:00
|
|
|
try (InputStream embryoCache = DataLoader.load("AbilityEmbryos.json", false)) {
|
2022-05-17 18:00:52 +08:00
|
|
|
embryoList = Grasscutter.getGsonFactory().fromJson(new InputStreamReader(embryoCache), TypeToken.getParameterized(Collection.class, AbilityEmbryoEntry.class).getType());
|
2022-06-27 00:26:39 +08:00
|
|
|
} catch (Exception ignored) {}
|
2022-05-17 18:00:52 +08:00
|
|
|
|
|
|
|
if(embryoList == null) {
|
2022-04-17 20:43:07 +08:00
|
|
|
// Load from BinOutput
|
|
|
|
Pattern pattern = Pattern.compile("(?<=ConfigAvatar_)(.*?)(?=.json)");
|
2022-04-27 05:44:30 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
embryoList = new LinkedList<>();
|
2022-05-11 12:30:07 +08:00
|
|
|
File folder = new File(Utils.toFilePath(RESOURCE("BinOutput/Avatar/")));
|
2022-04-19 11:26:34 +08:00
|
|
|
File[] files = folder.listFiles();
|
|
|
|
if(files == null) {
|
|
|
|
Grasscutter.getLogger().error("Error loading ability embryos: no files found in " + folder.getAbsolutePath());
|
|
|
|
return;
|
|
|
|
}
|
2022-04-27 05:44:30 +08:00
|
|
|
|
2022-04-19 11:26:34 +08:00
|
|
|
for (File file : files) {
|
|
|
|
AvatarConfig config;
|
|
|
|
String avatarName;
|
2022-04-27 05:44:30 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
Matcher matcher = pattern.matcher(file.getName());
|
|
|
|
if (matcher.find()) {
|
|
|
|
avatarName = matcher.group(0);
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
2022-04-27 05:44:30 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
try (FileReader fileReader = new FileReader(file)) {
|
|
|
|
config = Grasscutter.getGsonFactory().fromJson(fileReader, AvatarConfig.class);
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
continue;
|
|
|
|
}
|
2022-04-27 05:44:30 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
if (config.abilities == null) {
|
|
|
|
continue;
|
|
|
|
}
|
2022-04-27 05:44:30 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
int s = config.abilities.size();
|
|
|
|
AbilityEmbryoEntry al = new AbilityEmbryoEntry(avatarName, config.abilities.stream().map(Object::toString).toArray(size -> new String[s]));
|
|
|
|
embryoList.add(al);
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-06-16 22:54:53 +08:00
|
|
|
File playerElementsFile = new File(Utils.toFilePath(RESOURCE("BinOutput/AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json")));
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-06-16 22:54:53 +08:00
|
|
|
if (playerElementsFile.exists()) {
|
|
|
|
try (FileReader fileReader = new FileReader(playerElementsFile)) {
|
|
|
|
GameDepot.setPlayerAbilities(Grasscutter.getGsonFactory().fromJson(fileReader, new TypeToken<Map<String, AvatarConfig>>(){}.getType()));
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
if (embryoList == null || embryoList.isEmpty()) {
|
|
|
|
Grasscutter.getLogger().error("No embryos loaded!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (AbilityEmbryoEntry entry : embryoList) {
|
2022-04-27 12:21:57 +08:00
|
|
|
GameData.getAbilityEmbryoInfo().put(entry.getName(), entry);
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
private static void loadAbilityModifiers() {
|
|
|
|
// Load from BinOutput
|
2022-05-11 12:30:07 +08:00
|
|
|
File folder = new File(Utils.toFilePath(RESOURCE("BinOutput/Ability/Temp/AvatarAbilities/")));
|
2022-05-08 19:40:01 +08:00
|
|
|
File[] files = folder.listFiles();
|
|
|
|
if (files == null) {
|
|
|
|
Grasscutter.getLogger().error("Error loading ability modifiers: no files found in " + folder.getAbsolutePath());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (File file : files) {
|
2022-05-11 12:30:07 +08:00
|
|
|
List<AbilityConfigData> abilityConfigList;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
try (FileReader fileReader = new FileReader(file)) {
|
|
|
|
abilityConfigList = Grasscutter.getGsonFactory().fromJson(fileReader, TypeToken.getParameterized(Collection.class, AbilityConfigData.class).getType());
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
continue;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
for (AbilityConfigData data : abilityConfigList) {
|
|
|
|
if (data.Default.modifiers == null || data.Default.modifiers.size() == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
AbilityModifierEntry modifierEntry = new AbilityModifierEntry(data.Default.abilityName);
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
for (Entry<String, AbilityModifier> entry : data.Default.modifiers.entrySet()) {
|
|
|
|
AbilityModifier modifier = entry.getValue();
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
// Stare.
|
|
|
|
if (modifier.onAdded != null) {
|
|
|
|
for (AbilityModifierAction action : modifier.onAdded) {
|
|
|
|
if (action.$type.contains("HealHP")) {
|
|
|
|
action.type = AbilityModifierActionType.HealHP;
|
|
|
|
modifierEntry.getOnAdded().add(action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
if (modifier.onThinkInterval != null) {
|
|
|
|
for (AbilityModifierAction action : modifier.onThinkInterval) {
|
|
|
|
if (action.$type.contains("HealHP")) {
|
|
|
|
action.type = AbilityModifierActionType.HealHP;
|
|
|
|
modifierEntry.getOnThinkInterval().add(action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
if (modifier.onRemoved != null) {
|
|
|
|
for (AbilityModifierAction action : modifier.onRemoved) {
|
|
|
|
if (action.$type.contains("HealHP")) {
|
|
|
|
action.type = AbilityModifierActionType.HealHP;
|
|
|
|
modifierEntry.getOnRemoved().add(action);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-08 19:40:01 +08:00
|
|
|
GameData.getAbilityModifiers().put(modifierEntry.getName(), modifierEntry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-25 16:50:58 +08:00
|
|
|
private static void loadSpawnData() {
|
2022-06-29 19:53:50 +08:00
|
|
|
String[] spawnDataNames = {"Spawns.json", "GadgetSpawns.json"};
|
2022-07-18 18:13:55 +08:00
|
|
|
ArrayList<SpawnGroupEntry> spawnEntryMap = new ArrayList<>();
|
|
|
|
|
|
|
|
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
|
|
|
Type type = TypeToken.getParameterized(Collection.class, SpawnGroupEntry.class).getType();
|
2022-07-20 17:26:02 +08:00
|
|
|
List<SpawnGroupEntry> list = Grasscutter.getGsonFactory().fromJson(reader, type);
|
2022-07-18 18:13:55 +08:00
|
|
|
|
|
|
|
// Add spawns to group if it already exists in our spawn group map
|
|
|
|
spawnEntryMap.addAll(list);
|
|
|
|
} catch (Exception ignored) {}
|
|
|
|
}
|
|
|
|
|
2022-06-29 19:53:50 +08:00
|
|
|
if (spawnEntryMap.isEmpty()) {
|
2022-04-25 16:50:58 +08:00
|
|
|
Grasscutter.getLogger().error("No spawn data loaded!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
if(!areaSort.containsKey(point)) {
|
|
|
|
areaSort.put(point, new ArrayList<>());
|
|
|
|
}
|
|
|
|
areaSort.get(point).add(s);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
GameDepot.addSpawnListById(areaSort);
|
2022-04-25 16:50:58 +08:00
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
private static void loadOpenConfig() {
|
|
|
|
// Read from cached file if exists
|
|
|
|
List<OpenConfigEntry> list = null;
|
2022-05-17 18:00:52 +08:00
|
|
|
|
|
|
|
try(InputStream openConfigCache = DataLoader.load("OpenConfig.json", false)) {
|
|
|
|
list = Grasscutter.getGsonFactory().fromJson(new InputStreamReader(openConfigCache), TypeToken.getParameterized(Collection.class, SpawnGroupEntry.class).getType());
|
|
|
|
} catch (Exception ignored) {}
|
|
|
|
|
|
|
|
if (list == null) {
|
2022-04-17 20:43:07 +08:00
|
|
|
Map<String, OpenConfigEntry> map = new TreeMap<>();
|
|
|
|
java.lang.reflect.Type type = new TypeToken<Map<String, OpenConfigData[]>>() {}.getType();
|
2022-04-20 00:21:14 +08:00
|
|
|
String[] folderNames = {"BinOutput/Talent/EquipTalents/", "BinOutput/Talent/AvatarTalents/"};
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
for (String name : folderNames) {
|
2022-05-11 12:30:07 +08:00
|
|
|
File folder = new File(Utils.toFilePath(RESOURCE(name)));
|
2022-04-19 11:26:34 +08:00
|
|
|
File[] files = folder.listFiles();
|
|
|
|
if(files == null) {
|
|
|
|
Grasscutter.getLogger().error("Error loading open config: no files found in " + folder.getAbsolutePath()); return;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-19 11:26:34 +08:00
|
|
|
for (File file : files) {
|
2022-04-17 20:43:07 +08:00
|
|
|
if (!file.getName().endsWith(".json")) {
|
|
|
|
continue;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-19 11:26:34 +08:00
|
|
|
Map<String, OpenConfigData[]> config;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
try (FileReader fileReader = new FileReader(file)) {
|
|
|
|
config = Grasscutter.getGsonFactory().fromJson(fileReader, type);
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
continue;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
for (Entry<String, OpenConfigData[]> e : config.entrySet()) {
|
2022-05-01 10:34:50 +08:00
|
|
|
OpenConfigEntry entry = new OpenConfigEntry(e.getKey(), e.getValue());
|
2022-04-17 20:43:07 +08:00
|
|
|
map.put(entry.getName(), entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
list = new ArrayList<>(map.values());
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
if (list == null || list.isEmpty()) {
|
|
|
|
Grasscutter.getLogger().error("No openconfig entries loaded!");
|
|
|
|
return;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
for (OpenConfigEntry entry : list) {
|
2022-04-27 12:21:57 +08:00
|
|
|
GameData.getOpenConfigEntries().put(entry.getName(), entry);
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-11 18:56:40 +08:00
|
|
|
private static void loadQuests() {
|
2022-05-11 19:01:38 +08:00
|
|
|
File folder = new File(RESOURCE("BinOutput/Quest/"));
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-11 18:56:40 +08:00
|
|
|
if (!folder.exists()) {
|
|
|
|
return;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-11 18:56:40 +08:00
|
|
|
for (File file : folder.listFiles()) {
|
2022-05-13 18:12:25 +08:00
|
|
|
MainQuestData mainQuest = null;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-11 18:56:40 +08:00
|
|
|
try (FileReader fileReader = new FileReader(file)) {
|
2022-05-13 18:12:25 +08:00
|
|
|
mainQuest = Grasscutter.getGsonFactory().fromJson(fileReader, MainQuestData.class);
|
2022-05-11 18:56:40 +08:00
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
continue;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-13 18:12:25 +08:00
|
|
|
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
|
2022-05-11 18:56:40 +08:00
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
|
|
|
Grasscutter.getLogger().debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
|
2022-05-11 18:56:40 +08:00
|
|
|
}
|
2022-04-27 05:44:30 +08:00
|
|
|
|
2022-06-14 20:51:13 +08:00
|
|
|
@SneakyThrows
|
|
|
|
private static void loadHomeworldDefaultSaveData(){
|
|
|
|
var folder = Files.list(Path.of(RESOURCE("BinOutput/HomeworldDefaultSave"))).toList();
|
|
|
|
var pattern = Pattern.compile("scene(.*)_home_config.json");
|
|
|
|
|
|
|
|
for(var file : folder){
|
|
|
|
var matcher = pattern.matcher(file.getFileName().toString());
|
|
|
|
if(!matcher.find()){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
var sceneId = matcher.group(1);
|
|
|
|
|
|
|
|
var data = Grasscutter.getGsonFactory().fromJson(Files.readString(file), HomeworldDefaultSaveData.class);
|
|
|
|
|
|
|
|
GameData.getHomeworldDefaultSaveData().put(Integer.parseInt(sceneId), data);
|
|
|
|
}
|
|
|
|
|
2022-06-27 00:26:39 +08:00
|
|
|
Grasscutter.getLogger().debug("Loaded " + GameData.getHomeworldDefaultSaveData().size() + " HomeworldDefaultSaveDatas.");
|
2022-06-14 20:51:13 +08:00
|
|
|
}
|
|
|
|
|
2022-05-25 10:44:46 +08:00
|
|
|
@SneakyThrows
|
|
|
|
private static void loadNpcBornData(){
|
|
|
|
var folder = Files.list(Path.of(RESOURCE("BinOutput/Scene/SceneNpcBorn"))).toList();
|
|
|
|
|
|
|
|
for(var file : folder){
|
|
|
|
if(file.toFile().isDirectory()){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
var data = Grasscutter.getGsonFactory().fromJson(Files.readString(file), SceneNpcBornData.class);
|
|
|
|
if(data.getBornPosList() == null || data.getBornPosList().size() == 0){
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-05-25 14:12:36 +08:00
|
|
|
data.setIndex(SceneIndexManager.buildIndex(3, data.getBornPosList(), item -> item.getPos().toPoint()));
|
2022-05-25 10:44:46 +08:00
|
|
|
GameData.getSceneNpcBornData().put(data.getSceneId(), data);
|
|
|
|
}
|
|
|
|
|
2022-06-27 00:26:39 +08:00
|
|
|
Grasscutter.getLogger().debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneNpcBornDatas.");
|
2022-05-25 10:44:46 +08:00
|
|
|
}
|
2022-06-18 14:35:45 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
// BinOutput configs
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-06-16 22:54:53 +08:00
|
|
|
public static class AvatarConfig {
|
|
|
|
@SerializedName(value="abilities", alternate={"targetAbilities"})
|
2022-04-17 20:43:07 +08:00
|
|
|
public ArrayList<AvatarConfigAbility> abilities;
|
2022-06-16 22:54:53 +08:00
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-06-16 22:54:53 +08:00
|
|
|
public static class AvatarConfigAbility {
|
|
|
|
public String abilityName;
|
|
|
|
public String toString() {
|
|
|
|
return abilityName;
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-04-17 20:43:07 +08:00
|
|
|
private static class OpenConfig {
|
|
|
|
public OpenConfigData[] data;
|
|
|
|
}
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-01 10:34:50 +08:00
|
|
|
public static class OpenConfigData {
|
2022-04-17 20:43:07 +08:00
|
|
|
public String $type;
|
|
|
|
public String abilityName;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-29 12:36:56 +08:00
|
|
|
@SerializedName(value="talentIndex", alternate={"OJOFFKLNAHN"})
|
2022-04-17 20:43:07 +08:00
|
|
|
public int talentIndex;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-29 12:36:56 +08:00
|
|
|
@SerializedName(value="skillID", alternate={"overtime"})
|
2022-05-01 10:34:50 +08:00
|
|
|
public int skillID;
|
2022-06-27 00:26:39 +08:00
|
|
|
|
2022-05-29 12:36:56 +08:00
|
|
|
@SerializedName(value="pointDelta", alternate={"IGEBKIHPOIF"})
|
2022-05-01 10:34:50 +08:00
|
|
|
public int pointDelta;
|
2022-04-17 20:43:07 +08:00
|
|
|
}
|
|
|
|
}
|