mirror of
https://github.com/Xiao-MoMi/craft-engine.git
synced 2026-01-06 15:52:03 +00:00
加快配置文件读取性能
This commit is contained in:
@@ -365,6 +365,8 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
|
||||
// cache command suggestions
|
||||
cachedSuggestions.add(Suggestion.suggestion(id.toString()));
|
||||
|
||||
// TODO Deprecated 理论支持任意物品类型
|
||||
if (material == Material.TOTEM_OF_UNDYING)
|
||||
cachedTotemSuggestions.add(Suggestion.suggestion(id.toString()));
|
||||
|
||||
@@ -426,6 +428,7 @@ public class BukkitItemManager extends AbstractItemManager<ItemStack> {
|
||||
}
|
||||
|
||||
if (Config.packMinVersion() < 21.39f) {
|
||||
// TODO 手动指定旧版格式
|
||||
List<LegacyOverridesModel> legacyOverridesModels = new ArrayList<>();
|
||||
processModelRecursively(model, new LinkedHashMap<>(), legacyOverridesModels, materialId, customModelData);
|
||||
TreeSet<LegacyOverridesModel> lom = legacyOverrides.computeIfAbsent(materialId, k -> new TreeSet<>());
|
||||
|
||||
@@ -71,10 +71,11 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
private final BiConsumer<Path, Path> eventDispatcher;
|
||||
private final Map<String, Pack> loadedPacks = new HashMap<>();
|
||||
private final Map<String, ConfigParser> sectionParsers = new HashMap<>();
|
||||
private final TreeMap<ConfigParser, List<CachedConfig>> cachedConfigs = new TreeMap<>();
|
||||
protected BiConsumer<Path, Path> zipGenerator;
|
||||
protected ResourcePackHost resourcePackHost;
|
||||
|
||||
private Map<Path, CachedConfigFile> cachedConfigFiles = Collections.emptyMap();
|
||||
|
||||
public AbstractPackManager(CraftEngine plugin, BiConsumer<Path, Path> eventDispatcher) {
|
||||
this.plugin = plugin;
|
||||
this.eventDispatcher = eventDispatcher;
|
||||
@@ -175,7 +176,6 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
@Override
|
||||
public void unload() {
|
||||
this.loadedPacks.clear();
|
||||
this.cachedConfigs.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -408,38 +408,48 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
plugin.saveResource("resources/default/resourcepack/assets/minecraft/textures/gui/sprites/tooltip/topaz_frame.png.mcmeta");
|
||||
}
|
||||
|
||||
private void loadResourceConfigs(Predicate<ConfigParser> predicate) {
|
||||
long o1 = System.nanoTime();
|
||||
private void updateCachedConfigFiles() {
|
||||
Map<Path, CachedConfigFile> previousFiles = this.cachedConfigFiles;
|
||||
this.cachedConfigFiles = new HashMap<>();
|
||||
for (Pack pack : loadedPacks()) {
|
||||
if (!pack.enabled()) continue;
|
||||
Pair<List<Path>, List<Path>> files = FileUtils.getConfigsDeeply(pack.configurationFolder());
|
||||
for (Path path : files.left()) {
|
||||
try (InputStreamReader inputStream = new InputStreamReader(new FileInputStream(path.toFile()), StandardCharsets.UTF_8)) {
|
||||
Yaml yaml = new Yaml(new StringKeyConstructor(new LoaderOptions()));
|
||||
Map<String, Object> data = yaml.load(inputStream);
|
||||
if (data == null) continue;
|
||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||
processConfigEntry(entry, path, pack);
|
||||
List<Path> files = FileUtils.getYmlConfigsDeeply(pack.configurationFolder());
|
||||
for (Path path : files) {
|
||||
CachedConfigFile cachedFile = previousFiles.get(path);
|
||||
try {
|
||||
long lastModifiedTime = Files.getLastModifiedTime(path).toMillis();
|
||||
if (cachedFile != null && cachedFile.lastModified() == lastModifiedTime) {
|
||||
this.cachedConfigFiles.put(path, cachedFile);
|
||||
continue;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn(path, "Error loading config file", e);
|
||||
try (InputStreamReader inputStream = new InputStreamReader(Files.newInputStream(path), StandardCharsets.UTF_8)) {
|
||||
Yaml yaml = new Yaml(new StringKeyConstructor(new LoaderOptions()));
|
||||
Map<String, Object> data = yaml.load(inputStream);
|
||||
this.cachedConfigFiles.put(path, new CachedConfigFile(data, pack, lastModifiedTime));
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn(path, "Error loading config file", e);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
this.plugin.logger().warn(path, "Error reading last modified time", e);
|
||||
}
|
||||
}
|
||||
for (Path path : files.right()) {
|
||||
try (InputStreamReader inputStream = new InputStreamReader(new FileInputStream(path.toFile()), StandardCharsets.UTF_8)) {
|
||||
Map<?, ?> dataRaw = GsonHelper.get().fromJson(JsonParser.parseReader(inputStream).getAsJsonObject(), Map.class);
|
||||
Map<String, Object> data = castToMap(dataRaw, false);
|
||||
for (Map.Entry<String, Object> entry : data.entrySet()) {
|
||||
processConfigEntry(entry, path, pack);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
this.plugin.logger().warn(path, "Error loading config file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadResourceConfigs(Predicate<ConfigParser> predicate) {
|
||||
TreeMap<ConfigParser, List<CachedConfig>> cachedConfigs = new TreeMap<>();
|
||||
long o1 = System.nanoTime();
|
||||
this.updateCachedConfigFiles();
|
||||
for (Map.Entry<Path, CachedConfigFile> fileEntry : this.cachedConfigFiles.entrySet()) {
|
||||
CachedConfigFile cachedFile = fileEntry.getValue();
|
||||
for (Map.Entry<String, Object> entry : cachedFile.config().entrySet()) {
|
||||
processConfigEntry(entry, fileEntry.getKey(), cachedFile.pack(), (p, c) ->
|
||||
cachedConfigs.computeIfAbsent(p, k -> new ArrayList<>()).add(c));
|
||||
}
|
||||
}
|
||||
long o2 = System.nanoTime();
|
||||
this.plugin.logger().info("Loaded packs. Took " + String.format("%.2f", ((o2 - o1) / 1_000_000.0)) + " ms");
|
||||
for (Map.Entry<ConfigParser, List<CachedConfig>> entry : this.cachedConfigs.entrySet()) {
|
||||
for (Map.Entry<ConfigParser, List<CachedConfig>> entry : cachedConfigs.entrySet()) {
|
||||
ConfigParser parser = entry.getKey();
|
||||
long t1 = System.nanoTime();
|
||||
for (CachedConfig cached : entry.getValue()) {
|
||||
@@ -476,17 +486,17 @@ public abstract class AbstractPackManager implements PackManager {
|
||||
long t2 = System.nanoTime();
|
||||
this.plugin.logger().info("Loaded " + parser.sectionId()[0] + " in " + String.format("%.2f", ((t2 - t1) / 1_000_000.0)) + " ms");
|
||||
}
|
||||
this.cachedConfigs.clear();
|
||||
}
|
||||
|
||||
private void processConfigEntry(Map.Entry<String, Object> entry, Path path, Pack pack) {
|
||||
private void processConfigEntry(Map.Entry<String, Object> entry, Path path, Pack pack, BiConsumer<ConfigParser, CachedConfig> callback) {
|
||||
if (entry.getValue() instanceof Map<?,?> typeSections0) {
|
||||
String key = entry.getKey();
|
||||
int hashIndex = key.indexOf('#');
|
||||
String configType = hashIndex != -1 ? key.substring(0, hashIndex) : key;
|
||||
Optional.ofNullable(this.sectionParsers.get(configType))
|
||||
.ifPresent(parser -> this.cachedConfigs.computeIfAbsent(parser, k -> new ArrayList<>())
|
||||
.add(new CachedConfig(key, castToMap(typeSections0, false), path, pack)));
|
||||
.ifPresent(parser -> {
|
||||
callback.accept(parser, new CachedConfig(key, castToMap(typeSections0, false), path, pack));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package net.momirealms.craftengine.core.pack;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class CachedConfigFile {
|
||||
private final Map<String, Object> config;
|
||||
private final long lastModified;
|
||||
private final Pack pack;
|
||||
|
||||
public CachedConfigFile(Map<String, Object> config, Pack pack, long lastModified) {
|
||||
this.config = config;
|
||||
this.lastModified = lastModified;
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
public Pack pack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
public Map<String, Object> config() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public long lastModified() {
|
||||
return lastModified;
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,31 @@ public class FileUtils {
|
||||
Files.createDirectories(Files.exists(path) ? path.toRealPath() : path);
|
||||
}
|
||||
|
||||
public static List<Path> getYmlConfigsDeeply(Path configFolder) {
|
||||
if (!Files.exists(configFolder)) return List.of();
|
||||
List<Path> validYaml = new ArrayList<>();
|
||||
Deque<Path> pathDeque = new ArrayDeque<>();
|
||||
pathDeque.push(configFolder);
|
||||
while (!pathDeque.isEmpty()) {
|
||||
Path path = pathDeque.pop();
|
||||
try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
|
||||
for (Path subPath : stream) {
|
||||
if (Files.isDirectory(subPath)) {
|
||||
pathDeque.push(subPath);
|
||||
} else if (Files.isRegularFile(subPath)) {
|
||||
String pathString = subPath.toString();
|
||||
if (pathString.endsWith(".yml")) {
|
||||
validYaml.add(subPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return validYaml;
|
||||
}
|
||||
|
||||
public static Pair<List<Path>, List<Path>> getConfigsDeeply(Path configFolder) {
|
||||
if (!Files.exists(configFolder)) return Pair.of(List.of(), List.of());
|
||||
List<Path> validYaml = new ArrayList<>();
|
||||
|
||||
@@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Project settings
|
||||
# Rule: [major update].[feature update].[bug fix]
|
||||
project_version=0.0.53.7
|
||||
project_version=0.0.53.8
|
||||
config_version=32
|
||||
lang_version=12
|
||||
project_group=net.momirealms
|
||||
|
||||
Reference in New Issue
Block a user