mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-25 23:07:50 +00:00
Allow loading Resources from zip files
Move Resources loading from String filenames to Paths Add zip support
This commit is contained in:
parent
a90455a7a4
commit
fbc0219cba
@ -45,7 +45,6 @@ import javax.annotation.Nullable;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.DATA;
|
|
||||||
import static emu.grasscutter.config.Configuration.SERVER;
|
import static emu.grasscutter.config.Configuration.SERVER;
|
||||||
import static emu.grasscutter.utils.Language.translate;
|
import static emu.grasscutter.utils.Language.translate;
|
||||||
|
|
||||||
@ -203,7 +202,7 @@ public final class Grasscutter {
|
|||||||
|
|
||||||
// If the file already exists, we attempt to load it.
|
// If the file already exists, we attempt to load it.
|
||||||
try {
|
try {
|
||||||
config = JsonUtils.loadToClass(configFile.getPath(), ConfigContainer.class);
|
config = JsonUtils.loadToClass(configFile.toPath(), ConfigContainer.class);
|
||||||
} catch (Exception exception) {
|
} catch (Exception exception) {
|
||||||
getLogger().error("There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json.");
|
getLogger().error("There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json.");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
|
@ -26,7 +26,7 @@ public class ConfigContainer {
|
|||||||
*/
|
*/
|
||||||
public static void updateConfig() {
|
public static void updateConfig() {
|
||||||
try { // Check if the server is using a legacy config.
|
try { // Check if the server is using a legacy config.
|
||||||
JsonObject configObject = JsonUtils.loadToClass(Grasscutter.configFile.getPath(), JsonObject.class);
|
JsonObject configObject = JsonUtils.loadToClass(Grasscutter.configFile.toPath(), JsonObject.class);
|
||||||
if (!configObject.has("version")) {
|
if (!configObject.has("version")) {
|
||||||
Grasscutter.getLogger().info("Updating legacy ..");
|
Grasscutter.getLogger().info("Updating legacy ..");
|
||||||
Grasscutter.saveConfig(null);
|
Grasscutter.saveConfig(null);
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
package emu.grasscutter.config;
|
package emu.grasscutter.config;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileSystem;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
import static emu.grasscutter.Grasscutter.config;
|
import static emu.grasscutter.Grasscutter.config;
|
||||||
@ -30,6 +38,42 @@ public final class Configuration extends ConfigContainer {
|
|||||||
private static final String PLUGINS_FOLDER = config.folderStructure.plugins;
|
private static final String PLUGINS_FOLDER = config.folderStructure.plugins;
|
||||||
private static final String SCRIPTS_FOLDER = config.folderStructure.scripts;
|
private static final String SCRIPTS_FOLDER = config.folderStructure.scripts;
|
||||||
private static final String PACKETS_FOLDER = config.folderStructure.packets;
|
private static final String PACKETS_FOLDER = config.folderStructure.packets;
|
||||||
|
private static final FileSystem RESOURCES_FILE_SYSTEM; // Not sure about lifetime rules on this one, might be safe to remove
|
||||||
|
private static final Path RESOURCES_PATH;
|
||||||
|
static {
|
||||||
|
FileSystem fs = null;
|
||||||
|
Path path = Path.of(RESOURCES_FOLDER);
|
||||||
|
if (RESOURCES_FOLDER.endsWith(".zip")) { // Would be nice to support .tar.gz too at some point, but it doesn't come for free in Java
|
||||||
|
try {
|
||||||
|
fs = FileSystems.newFileSystem(path);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Grasscutter.getLogger().error("Failed to load resources zip \"" + RESOURCES_FOLDER + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fs != null) {
|
||||||
|
var root = fs.getPath("");
|
||||||
|
try (Stream<Path> pathStream = java.nio.file.Files.find(root, 3, (p, a) -> {
|
||||||
|
var filename = p.getFileName();
|
||||||
|
if (filename == null) return false;
|
||||||
|
return filename.toString().equals("ExcelBinOutput");
|
||||||
|
})) {
|
||||||
|
var excelBinOutput = pathStream.findFirst();
|
||||||
|
if (excelBinOutput.isPresent()) {
|
||||||
|
path = excelBinOutput.get().getParent();
|
||||||
|
if (path == null)
|
||||||
|
path = root;
|
||||||
|
Grasscutter.getLogger().debug("Resources will be loaded from \"" + RESOURCES_FOLDER + "/" + path.toString() + "\"");
|
||||||
|
} else {
|
||||||
|
Grasscutter.getLogger().error("Failed to find ExcelBinOutput in resources zip \"" + RESOURCES_FOLDER + "\"");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
Grasscutter.getLogger().error("Failed to scan resources zip \"" + RESOURCES_FOLDER + "\"");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RESOURCES_FILE_SYSTEM = fs;
|
||||||
|
RESOURCES_PATH = path;
|
||||||
|
};
|
||||||
|
|
||||||
public static final Server SERVER = config.server;
|
public static final Server SERVER = config.server;
|
||||||
public static final Database DATABASE = config.databaseInfo;
|
public static final Database DATABASE = config.databaseInfo;
|
||||||
@ -54,11 +98,15 @@ public final class Configuration extends ConfigContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String DATA(String path) {
|
public static String DATA(String path) {
|
||||||
return Paths.get(DATA_FOLDER, path).toString();
|
return Path.of(DATA_FOLDER, path).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Path getResourcePath(String path) {
|
||||||
|
return RESOURCES_PATH.resolve(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String RESOURCE(String path) {
|
public static String RESOURCE(String path) {
|
||||||
return Paths.get(RESOURCES_FOLDER, path).toString();
|
return getResourcePath(path).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String PLUGIN() {
|
public static String PLUGIN() {
|
||||||
@ -66,15 +114,15 @@ public final class Configuration extends ConfigContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String PLUGIN(String path) {
|
public static String PLUGIN(String path) {
|
||||||
return Paths.get(PLUGINS_FOLDER, path).toString();
|
return Path.of(PLUGINS_FOLDER, path).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String SCRIPT(String path) {
|
public static String SCRIPT(String path) {
|
||||||
return Paths.get(SCRIPTS_FOLDER, path).toString();
|
return Path.of(SCRIPTS_FOLDER, path).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String PACKET(String path) {
|
public static String PACKET(String path) {
|
||||||
return Paths.get(PACKETS_FOLDER, path).toString();
|
return Path.of(PACKETS_FOLDER, path).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,7 +5,6 @@ import com.google.gson.annotations.SerializedName;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.binout.*;
|
import emu.grasscutter.data.binout.*;
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityConfigData;
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierActionType;
|
||||||
import emu.grasscutter.data.common.PointData;
|
import emu.grasscutter.data.common.PointData;
|
||||||
import emu.grasscutter.data.common.ScenePointConfig;
|
import emu.grasscutter.data.common.ScenePointConfig;
|
||||||
@ -16,21 +15,19 @@ import emu.grasscutter.game.world.SpawnDataEntry.GridBlockId;
|
|||||||
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
import emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry;
|
||||||
import emu.grasscutter.scripts.SceneIndexManager;
|
import emu.grasscutter.scripts.SceneIndexManager;
|
||||||
import emu.grasscutter.utils.JsonUtils;
|
import emu.grasscutter.utils.JsonUtils;
|
||||||
import emu.grasscutter.utils.Utils;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import lombok.SneakyThrows;
|
import lombok.val;
|
||||||
|
|
||||||
import org.reflections.Reflections;
|
import org.reflections.Reflections;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.DATA;
|
import static emu.grasscutter.config.Configuration.DATA;
|
||||||
import static emu.grasscutter.config.Configuration.RESOURCE;
|
import static emu.grasscutter.config.Configuration.getResourcePath;
|
||||||
import static emu.grasscutter.utils.Language.translate;
|
import static emu.grasscutter.utils.Language.translate;
|
||||||
|
|
||||||
public class ResourceLoader {
|
public class ResourceLoader {
|
||||||
@ -105,7 +102,7 @@ public class ResourceLoader {
|
|||||||
try {
|
try {
|
||||||
loadFromResource(resourceDefinition, type, map, doReload);
|
loadFromResource(resourceDefinition, type, map, doReload);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Grasscutter.getLogger().error("Error loading resource file: " + Arrays.toString(type.name()), e);
|
Grasscutter.getLogger().error("Error loading resource file: " + Arrays.toString(type.name()), e.getLocalizedMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,7 +120,7 @@ public class ResourceLoader {
|
|||||||
|
|
||||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
protected static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map) throws Exception {
|
protected static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map) throws Exception {
|
||||||
List<T> list = JsonUtils.loadToList(RESOURCE("ExcelBinOutput/" + fileName), c);
|
List<T> list = JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c);
|
||||||
|
|
||||||
for (T o : list) {
|
for (T o : list) {
|
||||||
GameResource res = (GameResource) o;
|
GameResource res = (GameResource) o;
|
||||||
@ -133,51 +130,43 @@ public class ResourceLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void loadScenePoints() {
|
private static void loadScenePoints() {
|
||||||
Pattern pattern = Pattern.compile("(?<=scene)(.*?)(?=_point.json)");
|
val pattern = Pattern.compile("scene([0-9]+)_point\\.json");
|
||||||
File folder = new File(RESOURCE("BinOutput/Scene/Point"));
|
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;
|
||||||
|
|
||||||
if (!folder.isDirectory() || !folder.exists() || folder.listFiles() == null) {
|
try {
|
||||||
|
config = JsonUtils.loadToClass(path, ScenePointConfig.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.points == null) return;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
GameData.getScenePointIdList().add(id);
|
||||||
|
GameData.getScenePointEntries().put(name, new ScenePointEntry(name, pointData));
|
||||||
|
scenePoints.add(id);
|
||||||
|
|
||||||
|
pointData.updateDailyDungeon();
|
||||||
|
}
|
||||||
|
GameData.getScenePointsPerScene().put(sceneId, scenePoints);
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
Grasscutter.getLogger().error("Scene point files cannot be found, you cannot use teleport waypoints!");
|
Grasscutter.getLogger().error("Scene point files cannot be found, you cannot use teleport waypoints!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (File file : Objects.requireNonNull(folder.listFiles())) {
|
|
||||||
ScenePointConfig config;
|
|
||||||
Integer sceneId;
|
|
||||||
|
|
||||||
Matcher matcher = pattern.matcher(file.getName());
|
|
||||||
if (matcher.find()) {
|
|
||||||
sceneId = Integer.parseInt(matcher.group(1));
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
config = JsonUtils.loadToClass(file.getPath(), ScenePointConfig.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.points == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Integer> scenePoints = new ArrayList<>();
|
|
||||||
for (Map.Entry<String, JsonElement> entry : config.points.entrySet()) {
|
|
||||||
int id = Integer.parseInt(entry.getKey());
|
|
||||||
String name = sceneId + "_" + entry.getKey();
|
|
||||||
PointData pointData = JsonUtils.decode(entry.getValue(), PointData.class);
|
|
||||||
pointData.setId(id);
|
|
||||||
|
|
||||||
GameData.getScenePointIdList().add(id);
|
|
||||||
GameData.getScenePointEntries().put(name, new ScenePointEntry(name, pointData));
|
|
||||||
scenePoints.add(id);
|
|
||||||
|
|
||||||
pointData.updateDailyDungeon();
|
|
||||||
}
|
|
||||||
GameData.getScenePointsPerScene().put(sceneId, scenePoints);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadAbilityEmbryos() {
|
private static void loadAbilityEmbryos() {
|
||||||
@ -190,47 +179,40 @@ public class ResourceLoader {
|
|||||||
|
|
||||||
if (embryoList == null) {
|
if (embryoList == null) {
|
||||||
// Load from BinOutput
|
// Load from BinOutput
|
||||||
Pattern pattern = Pattern.compile("(?<=ConfigAvatar_)(.*?)(?=.json)");
|
val pattern = Pattern.compile("ConfigAvatar_(.+?)\\.json");
|
||||||
|
|
||||||
embryoList = new ArrayList<>();
|
val l = new ArrayList<AbilityEmbryoEntry>();
|
||||||
File folder = new File(Utils.toFilePath(RESOURCE("BinOutput/Avatar/")));
|
try {
|
||||||
File[] files = folder.listFiles();
|
Files.newDirectoryStream(getResourcePath("BinOutput/Avatar/"), "ConfigAvatar_*.json").forEach(path -> {
|
||||||
if (files == null) {
|
val matcher = pattern.matcher(path.getFileName().toString());
|
||||||
Grasscutter.getLogger().error("Error loading ability embryos: no files found in " + folder.getAbsolutePath());
|
if (!matcher.find()) return;
|
||||||
|
String avatarName = matcher.group(1);
|
||||||
|
AvatarConfig config;
|
||||||
|
|
||||||
|
try {
|
||||||
|
config = JsonUtils.loadToClass(path, AvatarConfig.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Grasscutter.getLogger().error("Error loading player ability embryos:", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.abilities == null) return;
|
||||||
|
|
||||||
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (File file : files) {
|
embryoList = l;
|
||||||
AvatarConfig config;
|
|
||||||
String avatarName;
|
|
||||||
|
|
||||||
Matcher matcher = pattern.matcher(file.getName());
|
|
||||||
if (matcher.find()) {
|
|
||||||
avatarName = matcher.group(0);
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
config = JsonUtils.loadToClass(file.getPath(), AvatarConfig.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.abilities == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int s = config.abilities.size();
|
|
||||||
AbilityEmbryoEntry al = new AbilityEmbryoEntry(avatarName, config.abilities.stream().map(Object::toString).toArray(size -> new String[s]));
|
|
||||||
embryoList.add(al);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
GameDepot.setPlayerAbilities(JsonUtils.loadToMap(RESOURCE("BinOutput/AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json"), String.class, AvatarConfig.class));
|
GameDepot.setPlayerAbilities(JsonUtils.loadToMap(getResourcePath("BinOutput/AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json"), String.class, AvatarConfig.class));
|
||||||
} catch (Exception e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
Grasscutter.getLogger().error("Error loading player abilities:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,64 +228,54 @@ public class ResourceLoader {
|
|||||||
|
|
||||||
private static void loadAbilityModifiers() {
|
private static void loadAbilityModifiers() {
|
||||||
// Load from BinOutput
|
// Load from BinOutput
|
||||||
File folder = new File(Utils.toFilePath(RESOURCE("BinOutput/Ability/Temp/AvatarAbilities/")));
|
try {
|
||||||
File[] files = folder.listFiles();
|
Files.newDirectoryStream(getResourcePath("BinOutput/Ability/Temp/AvatarAbilities/")).forEach(path -> {
|
||||||
if (files == null) {
|
List<AbilityConfigData> abilityConfigList;
|
||||||
Grasscutter.getLogger().error("Error loading ability modifiers: no files found in " + folder.getAbsolutePath());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (File file : files) {
|
try {
|
||||||
List<AbilityConfigData> abilityConfigList;
|
abilityConfigList = JsonUtils.loadToList(path, AbilityConfigData.class);
|
||||||
|
} catch (IOException e) {
|
||||||
try {
|
Grasscutter.getLogger().error("Error loading ability modifiers from path " + path.toString() + ": ", e);
|
||||||
abilityConfigList = JsonUtils.loadToList(file.getPath(), AbilityConfigData.class);
|
return;
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (AbilityConfigData data : abilityConfigList) {
|
|
||||||
if (data.Default.modifiers == null || data.Default.modifiers.size() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AbilityModifierEntry modifierEntry = new AbilityModifierEntry(data.Default.abilityName);
|
abilityConfigList.forEach(data -> {
|
||||||
|
if (data.Default.modifiers == null || data.Default.modifiers.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (Entry<String, AbilityModifier> entry : data.Default.modifiers.entrySet()) {
|
String name = data.Default.abilityName;
|
||||||
AbilityModifier modifier = entry.getValue();
|
AbilityModifierEntry modifierEntry = new AbilityModifierEntry(name);
|
||||||
|
data.Default.modifiers.forEach((key, modifier) -> {
|
||||||
// Stare.
|
Stream.ofNullable(modifier.onAdded)
|
||||||
if (modifier.onAdded != null) {
|
.flatMap(Stream::of)
|
||||||
for (AbilityModifierAction action : modifier.onAdded) {
|
.filter(action -> action.$type.contains("HealHP"))
|
||||||
if (action.$type.contains("HealHP")) {
|
.forEach(action -> {
|
||||||
action.type = AbilityModifierActionType.HealHP;
|
action.type = AbilityModifierActionType.HealHP;
|
||||||
modifierEntry.getOnAdded().add(action);
|
modifierEntry.getOnAdded().add(action);
|
||||||
}
|
});
|
||||||
}
|
Stream.ofNullable(modifier.onThinkInterval)
|
||||||
}
|
.flatMap(Stream::of)
|
||||||
|
.filter(action -> action.$type.contains("HealHP"))
|
||||||
if (modifier.onThinkInterval != null) {
|
.forEach(action -> {
|
||||||
for (AbilityModifierAction action : modifier.onThinkInterval) {
|
|
||||||
if (action.$type.contains("HealHP")) {
|
|
||||||
action.type = AbilityModifierActionType.HealHP;
|
action.type = AbilityModifierActionType.HealHP;
|
||||||
modifierEntry.getOnThinkInterval().add(action);
|
modifierEntry.getOnThinkInterval().add(action);
|
||||||
}
|
});
|
||||||
}
|
Stream.ofNullable(modifier.onRemoved)
|
||||||
}
|
.flatMap(Stream::of)
|
||||||
|
.filter(action -> action.$type.contains("HealHP"))
|
||||||
if (modifier.onRemoved != null) {
|
.forEach(action -> {
|
||||||
for (AbilityModifierAction action : modifier.onRemoved) {
|
|
||||||
if (action.$type.contains("HealHP")) {
|
|
||||||
action.type = AbilityModifierActionType.HealHP;
|
action.type = AbilityModifierActionType.HealHP;
|
||||||
modifierEntry.getOnRemoved().add(action);
|
modifierEntry.getOnRemoved().add(action);
|
||||||
}
|
});
|
||||||
}
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GameData.getAbilityModifiers().put(modifierEntry.getName(), modifierEntry);
|
GameData.getAbilityModifiers().put(name, modifierEntry);
|
||||||
}
|
});
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
Grasscutter.getLogger().error("Error loading ability modifiers: ", e);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,30 +325,20 @@ public class ResourceLoader {
|
|||||||
Map<String, OpenConfigEntry> map = new TreeMap<>();
|
Map<String, OpenConfigEntry> map = new TreeMap<>();
|
||||||
String[] folderNames = {"BinOutput/Talent/EquipTalents/", "BinOutput/Talent/AvatarTalents/"};
|
String[] folderNames = {"BinOutput/Talent/EquipTalents/", "BinOutput/Talent/AvatarTalents/"};
|
||||||
|
|
||||||
for (String name : folderNames) {
|
for (String folderName : folderNames) {
|
||||||
File folder = new File(Utils.toFilePath(RESOURCE(name)));
|
try {
|
||||||
File[] files = folder.listFiles();
|
Files.newDirectoryStream(getResourcePath(folderName), "*.json").forEach(path -> {
|
||||||
if (files == null) {
|
try {
|
||||||
Grasscutter.getLogger().error("Error loading open config: no files found in " + folder.getAbsolutePath()); return;
|
JsonUtils.loadToMap(path, String.class, OpenConfigData[].class)
|
||||||
}
|
.forEach((name, data) -> map.put(name, new OpenConfigEntry(name, data)));
|
||||||
|
} catch (Exception e) {
|
||||||
for (File file : files) {
|
e.printStackTrace();
|
||||||
if (!file.getName().endsWith(".json")) {
|
return;
|
||||||
continue;
|
}
|
||||||
}
|
});
|
||||||
Map<String, OpenConfigData[]> config;
|
} catch (IOException e) {
|
||||||
|
Grasscutter.getLogger().error("Error loading open config: no files found in " + folderName);
|
||||||
try {
|
return;
|
||||||
config = JsonUtils.loadToMap(file.getPath(), String.class, OpenConfigData[].class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Entry<String, OpenConfigData[]> e : config.entrySet()) {
|
|
||||||
OpenConfigEntry entry = new OpenConfigEntry(e.getKey(), e.getValue());
|
|
||||||
map.put(entry.getName(), entry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -394,37 +356,29 @@ public class ResourceLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void loadQuests() {
|
private static void loadQuests() {
|
||||||
File folder = new File(RESOURCE("BinOutput/Quest/"));
|
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) {
|
||||||
|
|
||||||
if (!folder.exists()) {
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
Grasscutter.getLogger().error("Quest data missing");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (File file : folder.listFiles()) {
|
|
||||||
MainQuestData mainQuest = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
mainQuest = JsonUtils.loadToClass(file.getPath(), MainQuestData.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
List<QuestEncryptionKey> keys;
|
val questEncryptionMap = GameData.getMainQuestEncryptionMap();
|
||||||
Int2ObjectMap<QuestEncryptionKey> questEncryptionMap = GameData.getMainQuestEncryptionMap();
|
|
||||||
String path = "QuestEncryptionKeys.json";
|
String path = "QuestEncryptionKeys.json";
|
||||||
if (Utils.fileExists(RESOURCE(path))) {
|
try {
|
||||||
keys = JsonUtils.loadToList(RESOURCE(path), QuestEncryptionKey.class);
|
JsonUtils.loadToList(getResourcePath(path), QuestEncryptionKey.class).forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
||||||
keys.forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
} catch (IOException | NullPointerException ignored) {}
|
||||||
}
|
try {
|
||||||
if (Utils.fileExists(DATA(path))) {
|
DataLoader.loadList(path, QuestEncryptionKey.class).forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
||||||
keys = DataLoader.loadList(path, QuestEncryptionKey.class);
|
} catch (IOException | NullPointerException ignored) {}
|
||||||
keys.forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
|
||||||
}
|
|
||||||
Grasscutter.getLogger().debug("Loaded {} quest keys.", questEncryptionMap.size());
|
Grasscutter.getLogger().debug("Loaded {} quest keys.", questEncryptionMap.size());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Grasscutter.getLogger().error("Unable to load quest keys.", e);
|
Grasscutter.getLogger().error("Unable to load quest keys.", e);
|
||||||
@ -434,95 +388,84 @@ public class ResourceLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void loadScriptSceneData() {
|
public static void loadScriptSceneData() {
|
||||||
File folder = new File(RESOURCE("ScriptSceneData/"));
|
try {
|
||||||
|
Files.list(getResourcePath("ScriptSceneData/")).forEach(path -> {
|
||||||
if (!folder.exists()) {
|
try {
|
||||||
return;
|
GameData.getScriptSceneDataMap().put(path.getFileName().toString(), JsonUtils.loadToClass(path, ScriptSceneData.class));
|
||||||
}
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
for (File file : folder.listFiles()) {
|
|
||||||
ScriptSceneData sceneData;
|
|
||||||
try {
|
|
||||||
sceneData = JsonUtils.loadToClass(file.getPath(), ScriptSceneData.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameData.getScriptSceneDataMap().put(file.getName(), sceneData);
|
|
||||||
}
|
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Loaded " + GameData.getScriptSceneDataMap().size() + " ScriptSceneDatas.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
private static void loadHomeworldDefaultSaveData() {
|
|
||||||
var pattern = Pattern.compile("scene(.*)_home_config.json");
|
|
||||||
Files.list(Path.of(RESOURCE("BinOutput/HomeworldDefaultSave"))).forEach(file -> {
|
|
||||||
String filename = file.getFileName().toString();
|
|
||||||
var matcher = pattern.matcher(filename);
|
|
||||||
if (!matcher.find()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
var sceneId = Integer.parseInt(matcher.group(1));
|
|
||||||
var data = JsonUtils.loadToClass(file.toString(), HomeworldDefaultSaveData.class);
|
|
||||||
GameData.getHomeworldDefaultSaveData().put(sceneId, data);
|
|
||||||
} catch (Exception ignored) {}
|
|
||||||
});
|
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Loaded " + GameData.getHomeworldDefaultSaveData().size() + " HomeworldDefaultSaveDatas.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
private static void loadNpcBornData() {
|
|
||||||
Files.list(Path.of(RESOURCE("BinOutput/Scene/SceneNpcBorn"))).forEach(file -> {
|
|
||||||
if (file.toFile().isDirectory()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
var data = JsonUtils.loadToClass(file.toString(), SceneNpcBornData.class);
|
|
||||||
if (data.getBornPosList() == null || data.getBornPosList().size() == 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
data.setIndex(SceneIndexManager.buildIndex(3, data.getBornPosList(), item -> item.getPos().toPoint()));
|
Grasscutter.getLogger().debug("Loaded " + GameData.getScriptSceneDataMap().size() + " ScriptSceneDatas.");
|
||||||
GameData.getSceneNpcBornData().put(data.getSceneId(), data);
|
} catch (IOException e) {
|
||||||
} catch (Exception ignored) {}
|
Grasscutter.getLogger().debug("ScriptSceneData folder missing or empty.");
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
Grasscutter.getLogger().debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneNpcBornDatas.");
|
}
|
||||||
|
|
||||||
|
private static void loadHomeworldDefaultSaveData() {
|
||||||
|
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;
|
||||||
|
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loadNpcBornData() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
private static void loadGadgetConfigData() {
|
private static void loadGadgetConfigData() {
|
||||||
Files.list(Path.of(RESOURCE("BinOutput/Gadget/"))).forEach(filePath -> {
|
try {
|
||||||
var file = filePath.toFile();
|
Files.newDirectoryStream(getResourcePath("BinOutput/Gadget/"), "*.json").forEach(path -> {
|
||||||
if (file.isDirectory() || !file.getName().endsWith("json")) {
|
try {
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Map<String, ConfigGadget> config;
|
Grasscutter.getLogger().debug("Loaded {} ConfigGadget entries.", GameData.getGadgetConfigData().size());
|
||||||
|
} catch (IOException e) {
|
||||||
try {
|
Grasscutter.getLogger().error("Failed to load ConfigGadget folder.");
|
||||||
config = JsonUtils.loadToMap(filePath.toString(), String.class, ConfigGadget.class);
|
}
|
||||||
} catch (Exception e) {
|
|
||||||
Grasscutter.getLogger().error("failed to load ConfigGadget entries for "+filePath, e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Entry<String, ConfigGadget> e : config.entrySet()) {
|
|
||||||
GameData.getGadgetConfigData().put(e.getKey(), e.getValue());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Grasscutter.getLogger().debug("Loaded {} ConfigGadget entries.", GameData.getGadgetConfigData().size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
|
||||||
private static void loadBlossomResources() {
|
private static void loadBlossomResources() {
|
||||||
GameDepot.setBlossomConfig(DataLoader.loadClass("BlossomConfig.json", BlossomConfig.class));
|
try {
|
||||||
Grasscutter.getLogger().debug("Loaded BlossomConfig.");
|
GameDepot.setBlossomConfig(DataLoader.loadClass("BlossomConfig.json", BlossomConfig.class));
|
||||||
|
Grasscutter.getLogger().debug("Loaded BlossomConfig.");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Grasscutter.getLogger().warn("Failed to load BlossomConfig.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// BinOutput configs
|
// BinOutput configs
|
||||||
|
@ -2,9 +2,11 @@ package emu.grasscutter.tools;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -215,11 +217,15 @@ public final class Tools {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> getAvailableLanguage() {
|
public static List<String> getAvailableLanguage() {
|
||||||
File textMapFolder = new File(RESOURCE("TextMap"));
|
|
||||||
List<String> availableLangList = new ArrayList<>();
|
List<String> availableLangList = new ArrayList<>();
|
||||||
for (String textMapFileName : Objects.requireNonNull(textMapFolder.list((dir, name) -> name.startsWith("TextMap") && name.endsWith(".json")))) {
|
try {
|
||||||
availableLangList.add(textMapFileName.replace("TextMap", "").replace(".json", "").toLowerCase());
|
Files.newDirectoryStream(getResourcePath("TextMap"), "TextMap*.json").forEach(path -> {
|
||||||
} return availableLangList;
|
availableLangList.add(path.getFileName().toString().replace("TextMap", "").replace(".json", "").toLowerCase());
|
||||||
|
});
|
||||||
|
} catch (IOException e) {
|
||||||
|
Grasscutter.getLogger().error("Failed to get available languages:", e);
|
||||||
|
}
|
||||||
|
return availableLangList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated(forRemoval = true, since = "1.2.3")
|
@Deprecated(forRemoval = true, since = "1.2.3")
|
||||||
|
@ -9,7 +9,6 @@ import java.net.URI;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -17,7 +16,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public final class FileUtils {
|
public final class FileUtils {
|
||||||
public static void write(String dest, byte[] bytes) {
|
public static void write(String dest, byte[] bytes) {
|
||||||
Path path = Paths.get(dest);
|
Path path = Path.of(dest);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Files.write(path, bytes);
|
Files.write(path, bytes);
|
||||||
@ -27,7 +26,7 @@ public final class FileUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] read(String dest) {
|
public static byte[] read(String dest) {
|
||||||
return read(Paths.get(dest));
|
return read(Path.of(dest));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] read(Path path) {
|
public static byte[] read(Path path) {
|
||||||
|
@ -3,7 +3,10 @@ package emu.grasscutter.utils;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -32,36 +35,57 @@ public final class JsonUtils {
|
|||||||
return gson.fromJson(jsonElement, classType);
|
return gson.fromJson(jsonElement, classType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T loadToClass(InputStreamReader fileReader, Class<T> classType) throws IOException {
|
public static <T> T loadToClass(Reader fileReader, Class<T> classType) throws IOException {
|
||||||
return gson.fromJson(fileReader, classType);
|
return gson.fromJson(fileReader, classType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static <T> T loadToClass(String filename, Class<T> classType) throws IOException {
|
public static <T> T loadToClass(String filename, Class<T> classType) throws IOException {
|
||||||
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) {
|
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) {
|
||||||
return loadToClass(fileReader, classType);
|
return loadToClass(fileReader, classType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> List<T> loadToList(InputStreamReader fileReader, Class<T> classType) throws IOException {
|
public static <T> T loadToClass(Path filename, Class<T> classType) throws IOException {
|
||||||
|
try (var fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) {
|
||||||
|
return loadToClass(fileReader, classType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> List<T> loadToList(Reader fileReader, Class<T> classType) throws IOException {
|
||||||
return gson.fromJson(fileReader, TypeToken.getParameterized(List.class, classType).getType());
|
return gson.fromJson(fileReader, TypeToken.getParameterized(List.class, classType).getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static <T> List<T> loadToList(String filename, Class<T> classType) throws IOException {
|
public static <T> List<T> loadToList(String filename, Class<T> classType) throws IOException {
|
||||||
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) {
|
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) {
|
||||||
return loadToList(fileReader, classType);
|
return loadToList(fileReader, classType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T1,T2> Map<T1,T2> loadToMap(InputStreamReader fileReader, Class<T1> keyType, Class<T2> valueType) throws IOException {
|
public static <T> List<T> loadToList(Path filename, Class<T> classType) throws IOException {
|
||||||
|
try (var fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) {
|
||||||
|
return loadToList(fileReader, classType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T1,T2> Map<T1,T2> loadToMap(Reader fileReader, Class<T1> keyType, Class<T2> valueType) throws IOException {
|
||||||
return gson.fromJson(fileReader, TypeToken.getParameterized(Map.class, keyType, valueType).getType());
|
return gson.fromJson(fileReader, TypeToken.getParameterized(Map.class, keyType, valueType).getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static <T1,T2> Map<T1,T2> loadToMap(String filename, Class<T1> keyType, Class<T2> valueType) throws IOException {
|
public static <T1,T2> Map<T1,T2> loadToMap(String filename, Class<T1> keyType, Class<T2> valueType) throws IOException {
|
||||||
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) {
|
try (InputStreamReader fileReader = new InputStreamReader(new FileInputStream(Utils.toFilePath(filename)), StandardCharsets.UTF_8)) {
|
||||||
return loadToMap(fileReader, keyType, valueType);
|
return loadToMap(fileReader, keyType, valueType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T1,T2> Map<T1,T2> loadToMap(Path filename, Class<T1> keyType, Class<T2> valueType) throws IOException {
|
||||||
|
try (var fileReader = Files.newBufferedReader(filename, StandardCharsets.UTF_8)) {
|
||||||
|
return loadToMap(fileReader, keyType, valueType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely JSON decodes a given string.
|
* Safely JSON decodes a given string.
|
||||||
* @param jsonData The JSON-encoded data.
|
* @param jsonData The JSON-encoded data.
|
||||||
|
@ -325,7 +325,7 @@ public final class Language {
|
|||||||
|
|
||||||
private static Int2ObjectMap<String> loadTextMapFile(String language, IntSet nameHashes) {
|
private static Int2ObjectMap<String> loadTextMapFile(String language, IntSet nameHashes) {
|
||||||
Int2ObjectMap<String> output = new Int2ObjectOpenHashMap<>();
|
Int2ObjectMap<String> output = new Int2ObjectOpenHashMap<>();
|
||||||
try (BufferedReader file = new BufferedReader(new FileReader(Utils.toFilePath(RESOURCE("TextMap/TextMap"+language+".json")), StandardCharsets.UTF_8))) {
|
try (BufferedReader file = Files.newBufferedReader(getResourcePath("TextMap/TextMap"+language+".json"), StandardCharsets.UTF_8)) {
|
||||||
Matcher matcher = textMapKeyValueRegex.matcher("");
|
Matcher matcher = textMapKeyValueRegex.matcher("");
|
||||||
return new Int2ObjectOpenHashMap<>(
|
return new Int2ObjectOpenHashMap<>(
|
||||||
file.lines()
|
file.lines()
|
||||||
@ -406,7 +406,7 @@ public final class Language {
|
|||||||
try {
|
try {
|
||||||
long cacheModified = Files.getLastModifiedTime(TEXTMAP_CACHE_PATH).toMillis();
|
long cacheModified = Files.getLastModifiedTime(TEXTMAP_CACHE_PATH).toMillis();
|
||||||
|
|
||||||
long textmapsModified = Files.list(Path.of(RESOURCE("TextMap")))
|
long textmapsModified = Files.list(getResourcePath("TextMap"))
|
||||||
.filter(path -> path.toString().endsWith(".json"))
|
.filter(path -> path.toString().endsWith(".json"))
|
||||||
.map(path -> {
|
.map(path -> {
|
||||||
try {
|
try {
|
||||||
|
@ -22,6 +22,7 @@ import org.slf4j.Logger;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static emu.grasscutter.config.Configuration.getResourcePath;
|
||||||
import static emu.grasscutter.utils.Language.translate;
|
import static emu.grasscutter.utils.Language.translate;
|
||||||
|
|
||||||
@SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"})
|
@SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"})
|
||||||
@ -169,19 +170,18 @@ public final class Utils {
|
|||||||
Logger logger = Grasscutter.getLogger();
|
Logger logger = Grasscutter.getLogger();
|
||||||
boolean exit = false;
|
boolean exit = false;
|
||||||
|
|
||||||
String resourcesFolder = config.folderStructure.resources;
|
|
||||||
String dataFolder = config.folderStructure.data;
|
String dataFolder = config.folderStructure.data;
|
||||||
|
|
||||||
// Check for resources folder.
|
// Check for resources folder.
|
||||||
if (!fileExists(resourcesFolder)) {
|
if (!Files.exists(getResourcePath(""))) {
|
||||||
logger.info(translate("messages.status.create_resources"));
|
logger.info(translate("messages.status.create_resources"));
|
||||||
logger.info(translate("messages.status.resources_error"));
|
logger.info(translate("messages.status.resources_error"));
|
||||||
createFolder(resourcesFolder); exit = true;
|
createFolder(config.folderStructure.resources); exit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for BinOutput + ExcelBinOutput.
|
// Check for BinOutput + ExcelBinOutput.
|
||||||
if (!fileExists(resourcesFolder + "BinOutput") ||
|
if (!Files.exists(getResourcePath("BinOutput")) ||
|
||||||
!fileExists(resourcesFolder + "ExcelBinOutput")) {
|
!Files.exists(getResourcePath("ExcelBinOutput"))) {
|
||||||
logger.info(translate("messages.status.resources_error"));
|
logger.info(translate("messages.status.resources_error"));
|
||||||
exit = true;
|
exit = true;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user