diff --git a/common/src/main/java/org/ayamemc/ayame/client/resource/AyameModelResource.java b/common/src/main/java/org/ayamemc/ayame/client/resource/AyameModelResource.java deleted file mode 100644 index 993eeb0..0000000 --- a/common/src/main/java/org/ayamemc/ayame/client/resource/AyameModelResource.java +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Custom player model mod. Powered by GeckoLib. - * Copyright (C) 2024 CrystalNeko, HappyRespawnanchor, pertaz(Icon Designer) - * - * This file is part of Ayame. - * - * Ayame is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Ayame is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Ayame. If not, see . - */ - -package org.ayamemc.ayame.client.resource; - -import com.mojang.blaze3d.platform.NativeImage; -import net.minecraft.client.renderer.texture.DynamicTexture; -import net.minecraft.resources.ResourceLocation; -import org.ayamemc.ayame.client.IAyameClientEvents; -import org.ayamemc.ayame.model.AyameModelType; -import org.ayamemc.ayame.model.DefaultAyameModelType; -import org.ayamemc.ayame.model.IndexData; -import org.ayamemc.ayame.util.FileUtil; -import org.ayamemc.ayame.util.JsonInterpreter; -import org.ayamemc.ayame.util.ZipFileManager; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; - -import static org.ayamemc.ayame.Ayame.LOGGER; -import static org.ayamemc.ayame.util.FormatUtil.cv; -import static org.ayamemc.ayame.util.ResourceLocationHelper.withAyameNamespace; - -public class AyameModelResource implements IModelResource { - private final ZipFileManager content; - private final IndexData index; - - /** - * @param content 模型内容 - */ - public AyameModelResource(ZipFileManager content) throws IOException { - if (content == null) { - throw new RuntimeException("Model File Content is null"); - } - this.content = content; - this.index = createIndexData(); - IAyameClientEvents.Instance.INSTANCE.ModelResource_onResourceCreate(this); - } - - private IndexData createIndexData() throws IOException { - return IndexData.Builder.create().parseJson(JsonInterpreter.of(content.readFileContent("index.json"))).build(); - } - - public IndexData.ModelMetaData getMetaData() { - return index.metaData(); - } - - public String getType() { - return IndexData.ModelMetaData.DefaultModelTypes.AYAME; - } - - - public ModelDataResource getDefault() { - try { - if (FileUtil.inputStreamToString(content.readFileContent("index.json")).equalsIgnoreCase("")) { - throw new RuntimeException("Model File index is null"); - } - return ModelDataResource.Builder.create().getDefaultFromZip(content).build(); - } catch (IOException e) { - LOGGER.error("Error when loading default model:", e); - return null; - } - } - - public List getPresets() { - List res = new ArrayList<>(); - for (IndexData.ModelData data : index.presets()) { - try { - res.add(ModelDataResource.Builder.create().getPresetFromZip(data.name(), content).build()); - } catch (IOException e) { - LOGGER.error("Error when loading preset model:", e); - } - } - return res; - } - - - /** - * 模型数据资源,对应{@link IndexData.ModelData} - * - * @param mainName 主模型名称 - * @param name 当前模型名称 - * @param model - * @param texture - * @param animation - */ - public record ModelDataResource(String mainName, String name, JsonInterpreter model, DynamicTexture texture, - JsonInterpreter animation) { - /** - * 使用这个metadata 创建一个{@link DefaultAyameModelType} - * - * @param metaData - * @return - */ - public AyameModelType getOrCreateResource(IndexData.ModelMetaData metaData) { - return ModelResourceWriterUtil.addModelResource(this).setMetaData(metaData).build(); - } - - public ResourceLocation createModelResourceLocation() { - return withAyameNamespace("geo/ayame/" + cv(mainName) + "/" + cv(name) + ".json"); - } - - public ResourceLocation createTextureResourceLocation() { - return withAyameNamespace("textures/ayame/" + cv(mainName) + "/" + cv(name) + ".png"); - } - - public ResourceLocation createAnimationResourceLocation() { - return withAyameNamespace("animations/ayame/" + cv(mainName) + "/" + cv(name) + ".json"); - } - - public static class Builder { - private JsonInterpreter model; - private DynamicTexture texture; - private JsonInterpreter animation; - private String mainName; - private String name; - - public static Builder create() { - return new Builder(); - } - - public Builder getPresetFromZip(String presetName, ZipFileManager zip) throws IOException { - IndexData index = IndexData.Builder.create().parseJson(JsonInterpreter.of(zip.readFileContent("index.json"))).build(); - AtomicReference data = new AtomicReference<>(); - Arrays.asList(index.presets()).forEach(d -> { - if (d.name().equals(presetName)) { - data.set(d); - } - }); - this.model = JsonInterpreter.of(zip.readFileContent(data.get().model())); - this.texture = new DynamicTexture(NativeImage.read(zip.readFileContent(data.get().texture()))); - this.animation = JsonInterpreter.of(zip.readFileContent(data.get().animation())); - this.mainName = index.metaData().name(); - this.name = data.get().name(); - return this; - } - - public Builder getDefaultFromZip(ZipFileManager zip) throws IOException { - IndexData index = IndexData.Builder.create().parseJson(JsonInterpreter.of(zip.readFileContent("index.json"))).build(); - IndexData.ModelData data = index.defaultModel(); - this.model = JsonInterpreter.of(zip.readFileContent(data.model())); - this.texture = new DynamicTexture(NativeImage.read(zip.readFileContent(data.texture()))); - this.animation = JsonInterpreter.of(zip.readFileContent(data.animation())); - this.mainName = index.metaData().name(); - this.name = data.name(); - return this; - } - - public Builder model(JsonInterpreter model) { - this.model = model; - return this; - } - - public Builder texture(DynamicTexture texture) { - this.texture = texture; - return this; - } - - public Builder animation(JsonInterpreter animation) { - this.animation = animation; - return this; - } - - public Builder mainName(String mainName) { - this.mainName = mainName; - return this; - } - - public Builder name(String name) { - this.name = name; - return this; - } - - public ModelDataResource build() { - return new ModelDataResource(mainName, name, model, texture, animation); - } - } - } -} diff --git a/common/src/main/java/org/ayamemc/ayame/util/ZipFileManager.java b/common/src/main/java/org/ayamemc/ayame/util/ZipFileManager.java deleted file mode 100644 index 6811f41..0000000 --- a/common/src/main/java/org/ayamemc/ayame/util/ZipFileManager.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Custom player model mod. Powered by GeckoLib. - * Copyright (C) 2024 CrystalNeko, HappyRespawnanchor, pertaz(Icon Designer) - * - * This file is part of Ayame. - * - * Ayame is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Ayame is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with Ayame. If not, see . - */ - -package org.ayamemc.ayame.util; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.file.Path; -import java.util.*; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import static org.ayamemc.ayame.Ayame.LOGGER; - -public class ZipFileManager { - - private Map fileContents = new HashMap<>(); - - public ZipFileManager(Path path) { - loadZipFile(path); - } - - /** - * 读取ZIP文件,并将内容存储到Map中。 - * - * @param path ZIP文件的路径 - */ - private void loadZipFile(Path path) { - try (ZipFile zipFile = new ZipFile(path.toFile())) { - Enumeration entries = zipFile.entries(); - - while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); - - if (!entry.isDirectory()) { // 忽略目录 - InputStream is = zipFile.getInputStream(entry); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int len; - - while ((len = is.read(buffer)) != -1) { - baos.write(buffer, 0, len); - } - - // 将内容转换为字节数组输入流并存储在 Map 中 - InputStream contentStream = new ByteArrayInputStream(baos.toByteArray()); - fileContents.put(entry.getName(), contentStream); - } - } - } catch (IOException e) { - LOGGER.error(e.getMessage(), e); - } - } - - /** - * 获取ZIP文件中的所有文件。 - * - * @return 所有文件的名称与内容映射 - */ - public Map getAllFiles() { - return fileContents; - } - - /** - * 获取指定目录及其子目录下的所有文件。 - * - * @param dir 目录名称 - * @return 文件名称与内容映射 - */ - public Map getFilesInDir(String dir) { - Map filesInDir = new HashMap<>(); - for (Map.Entry entry : fileContents.entrySet()) { - if (entry.getKey().startsWith(dir + "/")) { - filesInDir.put(entry.getKey(), entry.getValue()); - } - } - return filesInDir; - } - - /** - * 获取指定目录下的所有文件,不包括子目录。 - * - * @param dir 目录名称 - * @return 文件名称与内容映射 - */ - public Map getFilesInDirWithoutSubdirs(String dir) { - Map filesInDir = new HashMap<>(); - for (Map.Entry entry : fileContents.entrySet()) { - if (entry.getKey().startsWith(dir) && !entry.getKey().contains("/")) { - filesInDir.put(entry.getKey(), entry.getValue()); - } - } - return filesInDir; - } - - /** - * 获取ZIP文件中的所有目录路径。 - * - * @return 目录路径列表 - */ - public List getDirs() { - List dirs = new ArrayList<>(); - for (String key : fileContents.keySet()) { - String[] parts = key.split("/"); - if (parts.length > 1) { - StringBuilder dirPath = new StringBuilder(); - for (int i = 0; i < parts.length - 1; i++) { - dirPath.append(parts[i]).append("/"); - if (!dirs.contains(dirPath.toString())) { - dirs.add(dirPath.toString()); - } - } - } - } - return dirs; - } - - /** - * 获取指定目录下的所有子目录。 - * - * @param dir 目录名称 - * @return 子目录路径列表 - */ - public List getDirsInDir(String dir) { - List dirsInDir = new ArrayList<>(); - for (String key : fileContents.keySet()) { - if (key.startsWith(dir + "/")) { - String subKey = key.substring(dir.length() + 1); - String[] parts = subKey.split("/"); - if (parts.length > 1) { - StringBuilder dirPath = new StringBuilder(dir).append("/"); - for (int i = 0; i < parts.length - 1; i++) { - dirPath.append(parts[i]).append("/"); - if (!dirsInDir.contains(dirPath.toString())) { - dirsInDir.add(dirPath.toString()); - } - } - } - } - } - return dirsInDir; - } - - /** - * 读取ZIP文件中的特定文件,并返回其内容的InputStream。 - * - * @param fileName 文件名称 - * @return 文件内容的InputStream - * @throws IOException 如果读取失败 - */ - public InputStream readFileContent(String fileName) throws IOException { - InputStream contentStream = fileContents.get(fileName); - - if (contentStream == null) { - throw new IOException("File not found: " + fileName); - } - - return contentStream; - } -} -