9
0
mirror of https://github.com/Xiao-MoMi/craft-engine.git synced 2025-12-27 19:09:08 +00:00

优化资源包生成速度

This commit is contained in:
XiaoMoMi
2025-05-16 20:31:57 +08:00
parent 804c8f6c80
commit 1eb64ba0b6
10 changed files with 102 additions and 94 deletions

View File

@@ -96,6 +96,7 @@ tasks {
relocate("org.ahocorasick", "net.momirealms.craftengine.libraries.ahocorasick")
relocate("com.ezylang.evalex", "net.momirealms.craftengine.libraries.evalex")
relocate("com.google.common.jimfs", "net.momirealms.craftengine.libraries.jimfs")
relocate("org.apache.commons.imaging", "net.momirealms.craftengine.libraries.imaging")
}
}

View File

@@ -79,5 +79,6 @@ tasks {
relocate("software.amazon.awssdk", "net.momirealms.craftengine.libraries.awssdk")
relocate("software.amazon.eventstream", "net.momirealms.craftengine.libraries.eventstream")
relocate("com.google.common.jimfs", "net.momirealms.craftengine.libraries.jimfs")
relocate("org.apache.commons.imaging", "net.momirealms.craftengine.libraries.imaging")
}
}

View File

@@ -20,6 +20,7 @@ caffeine=${caffeine_version}
slf4j-api=${slf4j_version}
zstd-jni=${zstd_version}
commons-io=${commons_io_version}
commons-imaging=${commons_imaging_version}
byte-buddy=${byte_buddy_version}
snake-yaml=${snake_yaml_version}
adventure-text-minimessage=${adventure_bundle_version}

View File

@@ -54,7 +54,6 @@ public class ReloadCommand extends BukkitCommandFeature<CommandSender> {
Component.text(reloadResult.asyncTime()),
Component.text(reloadResult.syncTime())
);
});
} catch (Exception e) {
handleFeedback(context, MessageConstants.COMMAND_RELOAD_CONFIG_FAILURE);
@@ -88,6 +87,9 @@ public class ReloadCommand extends BukkitCommandFeature<CommandSender> {
Component.text(reloadResult.syncTime()),
Component.text(packTime)
);
} catch (Exception e) {
handleFeedback(context, MessageConstants.COMMAND_RELOAD_PACK_FAILURE);
plugin().logger().warn("Failed to generate resource pack", e);
} finally {
RELOAD_PACK_FLAG = false;
}

View File

@@ -91,6 +91,7 @@ tasks {
relocate("software.amazon.eventstream", "net.momirealms.craftengine.libraries.eventstream") // awssdk
relocate("com.ezylang.evalex", "net.momirealms.craftengine.libraries.evalex")
relocate("com.google.common.jimfs", "net.momirealms.craftengine.libraries.jimfs")
relocate("org.apache.commons.imaging", "net.momirealms.craftengine.libraries.imaging")
}
}

View File

@@ -19,6 +19,7 @@ import net.momirealms.craftengine.core.pack.model.LegacyOverridesModel;
import net.momirealms.craftengine.core.pack.model.generation.ModelGeneration;
import net.momirealms.craftengine.core.pack.model.generation.ModelGenerator;
import net.momirealms.craftengine.core.pack.obfuscation.ObfA;
import net.momirealms.craftengine.core.pack.obfuscation.ObfH;
import net.momirealms.craftengine.core.plugin.CraftEngine;
import net.momirealms.craftengine.core.plugin.config.Config;
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
@@ -46,7 +47,6 @@ import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Stream;
import static net.momirealms.craftengine.core.util.MiscUtils.castToMap;
@@ -145,7 +145,6 @@ public abstract class AbstractPackManager implements PackManager {
@Override
public void load() {
initFileSystemProvider();
List<Map<?, ?>> list = Config.instance().settings().getMapList("resource-pack.delivery.hosting");
if (list == null || list.isEmpty()) {
this.resourcePackHost = NoneHost.INSTANCE;
@@ -187,12 +186,13 @@ public abstract class AbstractPackManager implements PackManager {
if (magicClazz != null) {
int fileCount = ObfA.VALUES[1] - ObfA.VALUES[17];
Constructor<?> magicConstructor = ReflectionUtils.getConstructor(magicClazz, fileCount);
assert magicConstructor != null;
// magicConstructor.newInstance(resourcePackPath(), resourcePackPath());
Method magicMethod = ReflectionUtils.getMethod(magicClazz, void.class);
assert magicMethod != null;
this.zipGenerator = (p1, p2) -> {
try {
assert magicConstructor != null;
Object magicObject = magicConstructor.newInstance(p1, p2);
assert magicMethod != null;
magicMethod.invoke(magicObject);
} catch (Exception e) {
this.plugin.logger().warn("Failed to generate zip files", e);
@@ -427,6 +427,7 @@ public abstract class AbstractPackManager implements PackManager {
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);
if (data == null) continue;
this.cachedConfigFiles.put(path, new CachedConfigFile(data, pack, lastModifiedTime));
} catch (Exception e) {
this.plugin.logger().warn(path, "Error loading config file", e);
@@ -502,91 +503,92 @@ public abstract class AbstractPackManager implements PackManager {
}
}
private static void initFileSystemProvider() {
String osName = System.getProperty("os.name").toLowerCase();
String providerClass = null;
if (osName.contains("win")) {
providerClass = "sun.nio.fs.WindowsFileSystemProvider";
} else if (osName.contains("nix") || osName.contains("nux") || osName.contains("aix")) {
providerClass = "sun.nio.fs.LinuxFileSystemProvider";
} else if (osName.contains("mac")) {
providerClass = "sun.nio.fs.MacOSXFileSystemProvider";
}
if (providerClass != null) {
try {
System.setProperty("java.nio.file.spi.DefaultFileSystemProvider", providerClass);
} catch (Exception ignored) {}
}
}
// private static void initFileSystemProvider() {
// String osName = System.getProperty("os.name").toLowerCase();
// String providerClass = null;
// if (osName.contains("win")) {
// providerClass = "sun.nio.fs.WindowsFileSystemProvider";
// } else if (osName.contains("nix") || osName.contains("nux") || osName.contains("aix")) {
// providerClass = "sun.nio.fs.LinuxFileSystemProvider";
// } else if (osName.contains("mac")) {
// providerClass = "sun.nio.fs.MacOSXFileSystemProvider";
// }
// if (providerClass != null) {
// try {
// System.setProperty("java.nio.file.spi.DefaultFileSystemProvider", providerClass);
// } catch (Exception ignored) {}
// }
// }
//
// private static void deleteDirectory(Path folder) throws IOException {
// if (!Files.exists(folder)) return;
// try (Stream<Path> walk = Files.walk(folder)) {
// walk.sorted(Comparator.reverseOrder())
// .parallel()
// .forEach(path -> {
// try {
// Files.delete(path);
// } catch (IOException ignored) {}
// });
// }
// }
private void updateAssetsCache(List<Path> folders) {
private static void deleteDirectory(Path folder) throws IOException {
if (!Files.exists(folder)) return;
try (Stream<Path> walk = Files.walk(folder)) {
walk.sorted(Comparator.reverseOrder())
.parallel()
.forEach(path -> {
try {
Files.delete(path);
} catch (IOException ignored) {}
});
}
}
@Override
public void generateResourcePack() {
public void generateResourcePack() throws IOException {
this.plugin.logger().info("Generating resource pack...");
long start = System.currentTimeMillis();
// get the target location
try (FileSystem fs = Jimfs.newFileSystem(Configuration.forCurrentPlatform())) {
// firstly merge existing folders
try {
Path generatedPackPath = fs.getPath("resource_pack");
List<Path> folders = new ArrayList<>();
folders.addAll(loadedPacks().stream().filter(Pack::enabled).map(Pack::resourcePackFolder).toList());
folders.addAll(Config.foldersToMerge().stream().map(it -> plugin.dataFolderPath().getParent().resolve(it)).filter(Files::exists).toList());
List<Pair<Path, List<Path>>> duplicated = mergeFolder(folders, fs);
if (!duplicated.isEmpty()) {
plugin.logger().severe(AdventureHelper.miniMessage().stripTags(TranslationManager.instance().miniMessageTranslation("warning.config.pack.duplicated_files")));
int x = 1;
for (Pair<Path, List<Path>> path : duplicated) {
this.plugin.logger().warn("[ " + (x++) + " ] " + path.left());
for (int i = 0, size = path.right().size(); i < size; i++) {
if (i == size - 1) {
this.plugin.logger().info("" + path.right().get(i).toAbsolutePath());
} else {
this.plugin.logger().info("" + path.right().get(i).toAbsolutePath());
}
Path generatedPackPath = fs.getPath("resource_pack");
List<Path> folders = new ArrayList<>();
folders.addAll(loadedPacks().stream().filter(Pack::enabled).map(Pack::resourcePackFolder).toList());
folders.addAll(Config.foldersToMerge().stream().map(it -> plugin.dataFolderPath().getParent().resolve(it)).filter(Files::exists).toList());
List<Pair<Path, List<Path>>> duplicated = mergeFolder(folders, fs);
if (!duplicated.isEmpty()) {
plugin.logger().severe(AdventureHelper.miniMessage().stripTags(TranslationManager.instance().miniMessageTranslation("warning.config.pack.duplicated_files")));
int x = 1;
for (Pair<Path, List<Path>> path : duplicated) {
this.plugin.logger().warn("[ " + (x++) + " ] " + path.left());
for (int i = 0, size = path.right().size(); i < size; i++) {
if (i == size - 1) {
this.plugin.logger().info("" + path.right().get(i).toAbsolutePath());
} else {
this.plugin.logger().info("" + path.right().get(i).toAbsolutePath());
}
}
}
this.generateFonts(generatedPackPath);
this.generateItemModels(generatedPackPath, this.plugin.itemManager());
this.generateItemModels(generatedPackPath, this.plugin.blockManager());
this.generateBlockOverrides(generatedPackPath);
this.generateLegacyItemOverrides(generatedPackPath);
this.generateModernItemOverrides(generatedPackPath);
this.generateModernItemModels1_21_2(generatedPackPath);
this.generateModernItemModels1_21_4(generatedPackPath);
this.generateOverrideSounds(generatedPackPath);
this.generateCustomSounds(generatedPackPath);
this.generateClientLang(generatedPackPath);
this.generateEquipments(generatedPackPath);
this.generateParticle(generatedPackPath);
Path zipFile = resourcePackPath();
try {
this.zipGenerator.accept(generatedPackPath, zipFile);
} catch (Exception e) {
this.plugin.logger().severe("Error zipping resource pack", e);
}
long end = System.currentTimeMillis();
this.plugin.logger().info("Finished generating resource pack in " + (end - start) + "ms");
this.eventDispatcher.accept(generatedPackPath, zipFile);
} catch (Exception e) {
this.plugin.logger().severe("Error merging resource pack", e);
}
} catch (IOException e) {
throw new RuntimeException(e);
this.generateFonts(generatedPackPath);
this.generateItemModels(generatedPackPath, this.plugin.itemManager());
this.generateItemModels(generatedPackPath, this.plugin.blockManager());
this.generateBlockOverrides(generatedPackPath);
this.generateLegacyItemOverrides(generatedPackPath);
this.generateModernItemOverrides(generatedPackPath);
this.generateModernItemModels1_21_2(generatedPackPath);
this.generateModernItemModels1_21_4(generatedPackPath);
this.generateOverrideSounds(generatedPackPath);
this.generateCustomSounds(generatedPackPath);
this.generateClientLang(generatedPackPath);
this.generateEquipments(generatedPackPath);
this.generateParticle(generatedPackPath);
Path zipFile = fs.getPath("resource_pack.zip");
try {
this.zipGenerator.accept(generatedPackPath, zipFile);
} catch (Exception e) {
this.plugin.logger().severe("Error zipping resource pack", e);
}
Files.write(resourcePackPath(), Files.readAllBytes(zipFile));
long end = System.currentTimeMillis();
this.plugin.logger().info("Finished generating resource pack in " + (end - start) + "ms");
this.eventDispatcher.accept(generatedPackPath, resourcePackPath());
}
}
@@ -728,7 +730,6 @@ public abstract class AbstractPackManager implements PackManager {
.resolve("assets")
.resolve(entry.getKey())
.resolve("sounds.json");
JsonObject soundJson;
if (Files.exists(soundPath)) {
try (BufferedReader reader = Files.newBufferedReader(soundPath)) {
@@ -740,18 +741,15 @@ public abstract class AbstractPackManager implements PackManager {
} else {
soundJson = new JsonObject();
}
for (SoundEvent soundEvent : entry.getValue()) {
soundJson.add(soundEvent.id().value(), soundEvent.get());
}
try {
Files.createDirectories(soundPath.getParent());
} catch (IOException e) {
plugin.logger().severe("Error creating " + soundPath.toAbsolutePath());
return;
}
try (BufferedWriter writer = Files.newBufferedWriter(soundPath)) {
GsonHelper.get().toJson(soundJson, writer);
} catch (IOException e) {
@@ -805,14 +803,12 @@ public abstract class AbstractPackManager implements PackManager {
plugin.logger().warn("Cannot find " + originalKey.value() + " in sound template");
}
}
try {
Files.createDirectories(soundPath.getParent());
} catch (IOException e) {
plugin.logger().severe("Error creating " + soundPath.toAbsolutePath());
return;
}
try (BufferedWriter writer = Files.newBufferedWriter(soundPath)) {
GsonHelper.get().toJson(soundJson, writer);
} catch (IOException e) {
@@ -1161,16 +1157,11 @@ public abstract class AbstractPackManager implements PackManager {
providers.add(image.get());
}
try {
Files.writeString(fontPath, fontJson.toString().replace("\\\\u", "\\u"));
try (BufferedWriter writer = Files.newBufferedWriter(fontPath)) {
GsonHelper.get().toJson(fontJson, writer);
} catch (IOException e) {
throw new RuntimeException(e);
this.plugin.logger().warn("Failed to save font for " + namespacedKey, e);
}
// try (FileWriter fileWriter = new FileWriter(fontPath.toFile())) {
// fileWriter.write(fontJson.toString().replace("\\\\u", "\\u"));
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
}
if (Config.resourcePack$overrideUniform()) {

View File

@@ -6,6 +6,7 @@ import net.momirealms.craftengine.core.plugin.Manageable;
import net.momirealms.craftengine.core.plugin.config.ConfigParser;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
@@ -32,7 +33,7 @@ public interface PackManager extends Manageable {
}
}
void generateResourcePack();
void generateResourcePack() throws IOException;
Path resourcePackPath();

View File

@@ -310,7 +310,8 @@ public abstract class CraftEngine implements Plugin {
Dependencies.AHO_CORASICK,
Dependencies.LZ4,
Dependencies.EVALEX,
Dependencies.JIMFS
Dependencies.JIMFS,
Dependencies.COMMONS_IMAGING
);
}

View File

@@ -288,6 +288,14 @@ public class Dependencies {
List.of(Relocation.of("jimfs", "com{}google{}common{}jimfs"))
);
public static final Dependency COMMONS_IMAGING = new Dependency(
"commons-imaging",
"org{}apache{}commons",
"commons-imaging",
"commons-imaging",
List.of(Relocation.of("imaging", "org{}apache{}commons{}imaging"))
);
public static final Dependency AMAZON_AWSSDK_S3 = new Dependency(
"amazon-sdk-s3",
"software{}amazon{}awssdk",

View File

@@ -39,8 +39,9 @@ lz4_version=1.8.0
geantyref_version=1.3.16
zstd_version=1.5.7-2
commons_io_version=2.18.0
commons_imaging_version=1.0.0-alpha6
sparrow_nbt_version=0.7.3
sparrow_util_version=0.42
sparrow_util_version=0.45
fastutil_version=8.5.15
netty_version=4.1.119.Final
joml_version=1.10.8