diff --git a/libs/OpenMC.jar b/libs/OpenMC.jar index 1ebfe43..84c45a1 100644 Binary files a/libs/OpenMC.jar and b/libs/OpenMC.jar differ diff --git a/src/main/java/fr/openmc/riftengine/core/RiftLog.java b/src/main/java/fr/openmc/riftengine/core/RiftLog.java new file mode 100644 index 0000000..af7cb33 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/RiftLog.java @@ -0,0 +1,63 @@ +package fr.openmc.riftengine.core; + +import fr.openmc.core.bootstrap.integration.OMCLogger; + +public enum RiftLog { + RIFT_DISABLE("RiftEngine désactivé", LogType.INFO), + RIFT_PACK_INFO("Pack chargé avec succès (pack={})", LogType.INFO), + REGISTRY_LOADED("Registre {} chargé pendant le runtime", LogType.SUCCESS), + REGISTRY_DISABLE("Registre {} stoppé", LogType.SUCCESS), + + IMAGE_NOT_FOUND("Image introuvable pour {} dans le path {} (skip)", LogType.ERROR), + ERROR_READING("Erreur de lecture pour {} (skip) : ", LogType.ERROR), + ICON_TYPE_NOT_RECOGNIZED("Icon type {} : n'est pas reconnu", LogType.ERROR), + DETECTED_AS_MENU_GUI("Glyph {} detécté comme MENU_GUI, il ne sera donc pas en glyph, vu que les menus sont géré autrement", LogType.WARN), + ICON_SKIPPED("Image manquante pour {} emoji(s)/icon(s) sur {}.", LogType.INFO), + DETECTED_AS("{} ({}x{}) détecté comme {}", LogType.INFO), + SYMBOL_KEY_NOT_FOUND("Clé {} introuvable dans {}.", LogType.WARN), + NUMBER_GLYPH_REGISTERED("{}/{} glyphs enregistré", LogType.INFO), + + ITEM_NOT_RESOURCE("Item {} : n'a pas de best resources", LogType.WARN), + RESOURCE_NOT_FOUND("Item {} : a aucune resource", LogType.WARN) + ; + + public static void logBanner(String pluginVersion, String server, String javaVersion) { + OMCLogger.info("\u001B[1;35m██████╗ ██╗███████╗████████╗ \u001B[0;95mRIFT v{}\u001B[0m", pluginVersion); + OMCLogger.info("\u001B[1;35m██╔══██╗██║██╔════╝╚══██╔══╝ \u001B[0;90mPaper {}\u001B[0m", server); + OMCLogger.info("\u001B[1;95m██████╔╝██║█████╗ ██║ \u001B[0;90mJava {}\u001B[0m", javaVersion); + OMCLogger.info("\u001B[1;95m██╔══██╗██║██╔══╝ ██║ \u001B[0m"); + OMCLogger.info("\u001B[1;35m██║ ██║██║██║ ██║ \u001B[0m"); + OMCLogger.info("\u001B[1;95m╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ \u001B[0m"); + OMCLogger.info(""); + } + + private enum LogType { + WARN, + ERROR, + DEBUG, + INFO, + SUCCESS + } + + private final String message; + private final LogType type; + + RiftLog(String message, LogType type) { + this.message = message; + this.type = type; + } + + public void send(Object... args) { + if (type == LogType.WARN) { + OMCLogger.warnFormatted(message, args); + } else if (type == LogType.ERROR) { + OMCLogger.errorFormatted(message, args); + } else if (type == LogType.DEBUG) { + OMCLogger.debug(message, args); + } else if (type == LogType.INFO) { + OMCLogger.infoFormatted(message, args); + } else if (type == LogType.SUCCESS) { + OMCLogger.successFormatted(message, args); + } + } +} diff --git a/src/main/java/fr/openmc/riftengine/core/RiftPlugin.java b/src/main/java/fr/openmc/riftengine/core/RiftPlugin.java index cc2dd3b..cc369fe 100644 --- a/src/main/java/fr/openmc/riftengine/core/RiftPlugin.java +++ b/src/main/java/fr/openmc/riftengine/core/RiftPlugin.java @@ -8,7 +8,9 @@ import fr.openmc.riftengine.core.registry.glyphs.GlyphsRegistry; import lombok.Getter; import lombok.Setter; +import org.bukkit.Bukkit; import org.bukkit.event.Listener; +import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.geysermc.event.Event; import org.geysermc.geyser.api.GeyserApi; @@ -24,6 +26,7 @@ import java.util.List; import java.util.function.Consumer; +// todo: clean les writer et tt qui néccesite du Yml a adapter au max avec nos YmlUtils dans le plugin OpenMC public class RiftPlugin extends JavaPlugin implements EventRegistrar { @Getter private static RiftPlugin instance; @@ -46,6 +49,8 @@ public class RiftPlugin extends JavaPlugin implements EventRegistrar { @Override public void onEnable() { instance = this; + logLoadMessage(this); + try { riftConfig = new RiftConfig(this, this.getConfig()); } catch (IOException e) { @@ -71,16 +76,14 @@ public void onEnable() { } GlyphsRegistry glyphsRegistry = RiftRegistry.GLYPHS; - OMCLogger.info("RiftEngine activé!"); - OMCLogger.infoFormatted(glyphsRegistry.size() + "/" + glyphsRegistry.maxSize() + " glyphs enregistré"); - OMCLogger.infoFormatted("Glyphs : " + glyphsRegistry.values()); + RiftLog.NUMBER_GLYPH_REGISTERED.send(glyphsRegistry.size(), glyphsRegistry.maxSize()); } @Override public void onDisable() { RiftRegistry.stopAll(); - OMCLogger.info("RiftEngine désactivé!"); + RiftLog.RIFT_DISABLE.send(); } public void updateBedrockResourcePack() { @@ -95,13 +98,11 @@ public void updateBedrockResourcePack() { public void onLoadResourcePacks(SessionLoadResourcePacksEvent event) { ResourcePack pack = RiftPlugin.getResourcePack(); - OMCLogger.infoFormatted("RiftEngine pack = " + pack); - if (pack == null) return; event.register(pack, PriorityOption.HIGHEST); - OMCLogger.successFormatted("RiftEngine: pack enregistré !"); + RiftLog.RIFT_PACK_INFO.send(pack); } public void registerListener(Listener... listeners) { @@ -112,4 +113,38 @@ public void registerListener(Listener... listeners) { public void registerEvent(Class listenerClass, Consumer handler) { GeyserApi.api().eventBus().subscribe(this, listenerClass, handler); } + + public static void logLoadMessage(RiftPlugin plugin) { + RiftLog.logBanner( + plugin.getPluginMeta().getVersion(), + Bukkit.getName() + " " + Bukkit.getVersion(), + System.getProperty("java.version") + ); + + for (String dependency : plugin.getPluginMeta().getPluginDependencies()) { + logPluginStatus(dependency, false); + } + + for (String dependency : plugin.getPluginMeta().getPluginSoftDependencies()) { + logPluginStatus(dependency, true); + } + } + + /** + * Log l'état d'une dépendance (requise ou optionnelle). + * + * @param name Nom du plugin dépendance + * @param optional True si la dépendance est optionnelle + */ + private static void logPluginStatus(String name, boolean optional) { + Plugin plugin = Bukkit.getPluginManager().getPlugin(name); + boolean enabled = plugin != null && plugin.isEnabled(); + + String icon = enabled ? "✔" : "✘"; + String color = enabled ? "\u001B[32m" : "\u001B[31m"; + String version = enabled ? " v" + plugin.getPluginMeta().getVersion() : ""; + String label = optional ? " (facultatif)" : ""; + + OMCLogger.info(" {}{} {}{}{}\u001B[0m", color, icon, name, version, label); + } } diff --git a/src/main/java/fr/openmc/riftengine/core/RiftRegistry.java b/src/main/java/fr/openmc/riftengine/core/RiftRegistry.java index 550ad10..440fce8 100644 --- a/src/main/java/fr/openmc/riftengine/core/RiftRegistry.java +++ b/src/main/java/fr/openmc/riftengine/core/RiftRegistry.java @@ -1,11 +1,11 @@ package fr.openmc.riftengine.core; -import fr.openmc.core.bootstrap.integration.OMCLogger; import fr.openmc.core.bootstrap.registries.LifecycleRegistry; import fr.openmc.core.bootstrap.registries.RegistryContext; import fr.openmc.core.bootstrap.registries.RegistryLoadingType; import fr.openmc.riftengine.core.registry.glyphs.GlyphsRegistry; +import fr.openmc.riftengine.core.registry.resolver.ResolverRegistry; import java.util.ArrayList; import java.util.Arrays; @@ -14,12 +14,16 @@ public final class RiftRegistry { // * Registre globaux public static GlyphsRegistry GLYPHS; + public static ResolverRegistry RESOLVERS; private static final List LOADED = new ArrayList<>(); private static final List ALL = List.of( new RegistryContext( () -> GLYPHS = new GlyphsRegistry(), + RegistryLoadingType.RUNTIME), + new RegistryContext( + () -> RESOLVERS = new ResolverRegistry(), RegistryLoadingType.RUNTIME) ); @@ -32,14 +36,15 @@ public static void initAll() { LifecycleRegistry r = load(ctx); r.init(); - OMCLogger.successFormatted("Registre {} chargé pendant le runtime", r.getClass().getSimpleName()); + + RiftLog.REGISTRY_LOADED.send(r.getClass().getSimpleName()); } } public static void stopAll() { for (LifecycleRegistry r : LOADED) { r.stop(); - OMCLogger.successFormatted("Registre {} stoppé", r.getClass().getSimpleName()); + RiftLog.REGISTRY_DISABLE.send(r.getClass().getSimpleName()); } LOADED.clear(); } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/ConverterManager.java b/src/main/java/fr/openmc/riftengine/core/converter/ConverterManager.java index 39140ce..6cd001f 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/ConverterManager.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/ConverterManager.java @@ -7,7 +7,10 @@ import fr.openmc.riftengine.api.scanner.items.ItemEntry; import fr.openmc.riftengine.core.RiftConfig; import fr.openmc.riftengine.core.RiftPlugin; +import fr.openmc.riftengine.core.RiftRegistry; import fr.openmc.riftengine.core.converter.writers.PackWriter; +import fr.openmc.riftengine.core.converter.writers.blocks.BlocksMappingWriter; +import fr.openmc.riftengine.core.converter.writers.blocks.TerrainTextureJsonWriter; import fr.openmc.riftengine.core.converter.writers.glyph.font.FontWriter; import fr.openmc.riftengine.core.converter.writers.glyph.icons.IconsWriter; import fr.openmc.riftengine.core.converter.writers.glyph.icons.SymbolWriter; @@ -19,6 +22,7 @@ import fr.openmc.riftengine.core.converter.writers.manifest.PackIdentity; import fr.openmc.riftengine.core.converter.writers.translations.TranslationInjector; import fr.openmc.riftengine.core.converter.writers.ui.ScoreboardUiWriter; +import fr.openmc.riftengine.core.resolvers.items.ItemResourceResolver; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; @@ -27,13 +31,11 @@ import java.util.ArrayList; import java.util.List; -// todo: faire un converter manager clean, avec des systemes de step, (surtout du coté logger aussi) public class ConverterManager { private final RiftPlugin plugin; private final List writers = new ArrayList<>(); - private final PackIdentity identity; public ConverterManager(RiftPlugin plugin) { this.plugin = plugin; @@ -41,28 +43,38 @@ public ConverterManager(RiftPlugin plugin) { Path itemsAdderContents = getItemsAdderContents(plugin); try { - identity = PackIdentity.loadOrCreate(plugin); + PackIdentity identity = PackIdentity.loadOrCreate(plugin); List items = OMCRegistry.SCANNERS.ITEMS.scan(itemsAdderContents); - writers.addAll(List.of( - new IconWriter(), - new ManifestWriter(identity), + ItemResourceResolver resolver = RiftRegistry.RESOLVERS.ITEM_RESOURCE_RESOLVER; - new TranslationInjector(), - new FontWriter(), - new ScoreboardUiWriter(config.isHideScoreboardNumberBedrock()), + register("Icônes", new IconWriter()); + register("Manifest", new ManifestWriter(identity)); + register("Traductions", new TranslationInjector()); + register("Polices", new FontWriter()); - new IconsWriter(itemsAdderContents), - new SymbolWriter(), + register("Scoreboard", + new ScoreboardUiWriter(config.isHideScoreboardNumberBedrock())); + + register("Icônes ItemsAdder", new IconsWriter(itemsAdderContents)); + register("Mappings des symboles", new SymbolWriter()); + + register("Textures des items", new ItemsTextureJsonWriter(items, resolver)); + register("Fichiers de textures", new ItemsTextureWriter(items, resolver)); + register("Mappings des items", new ItemsMappingWriter(items, resolver)); + + register("Textures des blocs", + new TerrainTextureJsonWriter(identity, items, resolver)); + register("Mappings des blocs", new BlocksMappingWriter(items, resolver)); - new ItemsTextureJsonWriter(items), - new ItemsTextureWriter(items), - new ItemsMappingWriter(items) - )); } catch (Exception e) { throw new RuntimeException("Erreur lors d'initialisation du ConverterManager", e); } } + private void register(String name, PackWriter writer) { + writers.add(new RegisteredPackWriter(name, writer)); + } + /** * Prends un pack java et le convertit en pack bedrock */ diff --git a/src/main/java/fr/openmc/riftengine/core/converter/RegisteredPackWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/RegisteredPackWriter.java new file mode 100644 index 0000000..14c689c --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/converter/RegisteredPackWriter.java @@ -0,0 +1,34 @@ +package fr.openmc.riftengine.core.converter; + +import fr.openmc.core.bootstrap.integration.OMCLogger; +import fr.openmc.core.utils.text.DateUtils; +import fr.openmc.riftengine.core.converter.writers.PackWriter; + +import java.nio.file.Path; +import java.time.LocalDateTime; + +public class RegisteredPackWriter implements PackWriter { + private final String name; + private final PackWriter wrapped; + + public RegisteredPackWriter(String name, PackWriter wrapped) { + this.name = name; + this.wrapped = wrapped; + } + + @Override + public void write(Path bedrockRootPath, Path javaRootPath) throws Exception { + LocalDateTime start = DateUtils.getLocalDateTime(); + OMCLogger.infoFormatted("Conversion : " + name); + + try { + wrapped.write(bedrockRootPath, javaRootPath); + + long elapsed = -DateUtils.getDelayBetweenNowMillis(start); + OMCLogger.successFormatted(name + " terminé en " + elapsed + " ms"); + } catch (Exception e) { + OMCLogger.warnFormatted("Échec de " + name + " : " + e.getMessage(), e); + throw e; + } + } +} diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/PackWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/PackWriter.java index 952f76f..09195d1 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/PackWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/PackWriter.java @@ -1,8 +1,34 @@ package fr.openmc.riftengine.core.converter.writers; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonObject; + import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; public interface PackWriter { + Gson GSON = new GsonBuilder() + .setPrettyPrinting() + .disableHtmlEscaping() // fix des = qui était en caractere unicode + .create(); + void write(Path bedrockRootPath, Path javaRootPath) throws Exception; + + default void writeJsonFile(Path outputFile, JsonObject root) throws IOException { + this.writeFile(outputFile, GSON.toJson(root)); + } + + default void writeFile(Path outputFile, String content) throws IOException { + Files.createDirectories(outputFile.getParent()); + Files.writeString(outputFile, content, StandardCharsets.UTF_8); + } + + default void copyFile(Path toCopy, Path where) throws IOException { + Files.createDirectories(where.getParent()); + Files.copy(toCopy, where, StandardCopyOption.REPLACE_EXISTING); + } } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/blocks/BlocksMappingWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/blocks/BlocksMappingWriter.java new file mode 100644 index 0000000..deae140 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/blocks/BlocksMappingWriter.java @@ -0,0 +1,106 @@ +package fr.openmc.riftengine.core.converter.writers.blocks; + +import com.google.gson.JsonObject; +import fr.openmc.riftengine.api.scanner.blocks.BlockStateScanner; +import fr.openmc.riftengine.api.scanner.items.ItemEntry; +import fr.openmc.riftengine.api.scanner.items.entry.behaviours.IABehaviour; +import fr.openmc.riftengine.api.scanner.items.entry.behaviours.block.BlocksBehaviour; +import fr.openmc.riftengine.core.RiftPlugin; +import fr.openmc.riftengine.core.converter.writers.PackWriter; +import fr.openmc.riftengine.core.resolvers.items.ItemResourceResolver; +import fr.openmc.riftengine.core.resolvers.items.ResolvedItemResource; +import fr.openmc.riftengine.core.utils.IdentifierUtils; +import fr.openmc.riftengine.core.utils.PathUtils; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class BlocksMappingWriter implements PackWriter { + private final List items; + private final ItemResourceResolver resolver; + private static final String OUTPUT_FILE = "custom_mappings/ia-blocks-injected.json"; + + public BlocksMappingWriter(List items, ItemResourceResolver resolver) { + this.items = items; + this.resolver = resolver; + } + + @Override + public void write(Path bedrockRootPath, Path javaRootPath) throws Exception { + JsonObject root = new JsonObject(); + root.addProperty("format_version", 1); + + Map blockStatesByBlock = new HashMap<>(); + + for (ItemEntry item : items) { + IABehaviour behaviour = item.getBehaviour(); + if (!behaviour.isBlock()) continue; + if (!(behaviour instanceof BlocksBehaviour blockBehaviour)) continue; + + List resources = resolver.resolve(javaRootPath, item); + + BlockStateScanner.CustomBlockState state = blockBehaviour.blockState(); + + JsonObject def = new JsonObject(); + def.addProperty("name", item.getKey()); + def.addProperty("geometry", "minecraft:geometry.full_block"); + def.add("material_instances", createMaterialInstance(resources)); + + blockStatesByBlock.computeIfAbsent(state.javaBlock(), _ -> new JsonObject()) + .add(state.state(), def); + } + + JsonObject blocksSetter = new JsonObject(); + blockStatesByBlock.forEach((javaBlock, overrides) -> { + JsonObject def = new JsonObject(); + def.addProperty("name", IdentifierUtils.removeNamespace(javaBlock)); + def.addProperty("only_override_states", true); + def.add("state_overrides", overrides); + blocksSetter.add(javaBlock, def); + }); + root.add("blocks", blocksSetter); + + Path outputFile = PathUtils + .getGeyserPath(RiftPlugin.getInstance().getDataPath()) + .resolve(OUTPUT_FILE); + + Files.deleteIfExists(outputFile); + this.writeJsonFile(outputFile, root); + } + + private JsonObject createMaterialInstance(List faceResources) { + JsonObject materialInstance = new JsonObject(); + + ResolvedItemResource fallback = faceResources.stream() + .filter(resourceFace -> !resourceFace.state().equals("all")) + .findFirst() + .orElse(null); + + if (fallback == null) return materialInstance; + + materialInstance.add("*", materialObj(fallback.bedrockIdentifier())); + + faceResources.forEach(face -> { + switch (face.state()) { + case "side" -> List.of("north", "south", "east", "west") + .forEach(f -> materialInstance.add(f, materialObj(face.bedrockIdWithState(f)))); + case "up", "down", "north", "south", "east", "west" -> materialInstance.add(face.state(), materialObj(face.bedrockIdentifier())); + default -> {} + } + }); + + return materialInstance; + } + + private JsonObject materialObj(String texture) { + JsonObject m = new JsonObject(); + m.addProperty("texture", texture); + m.addProperty("render_method", "alpha_test"); + m.addProperty("face_dimming", true); + m.addProperty("ambient_occlusion", true); + return m; + } +} \ No newline at end of file diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/blocks/TerrainTextureJsonWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/blocks/TerrainTextureJsonWriter.java new file mode 100644 index 0000000..056b8c8 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/blocks/TerrainTextureJsonWriter.java @@ -0,0 +1,57 @@ +package fr.openmc.riftengine.core.converter.writers.blocks; + +import com.google.gson.JsonObject; +import fr.openmc.riftengine.api.scanner.items.ItemEntry; +import fr.openmc.riftengine.api.scanner.items.entry.behaviours.IABehaviour; +import fr.openmc.riftengine.core.converter.writers.PackWriter; +import fr.openmc.riftengine.core.converter.writers.manifest.PackIdentity; +import fr.openmc.riftengine.core.resolvers.items.ItemResourceResolver; +import fr.openmc.riftengine.core.resolvers.items.ResolvedItemResource; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.List; + +/** + * Ecrit le terrain_texture.json qui sert grosso modo a relier les textures aux items (une ref = une resource) + */ +public class TerrainTextureJsonWriter implements PackWriter { + private final PackIdentity packIdentity; + private final List items; + private final ItemResourceResolver resolver; + private static final String OUTPUT_FILE = "textures/terrain_texture.json"; + + public TerrainTextureJsonWriter(PackIdentity packIdentity, List items, ItemResourceResolver resolver) { + this.packIdentity = packIdentity; + this.items = items; + this.resolver = resolver; + } + + @Override + public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { + JsonObject root = new JsonObject(); + JsonObject textureData = new JsonObject(); + + for (ItemEntry itemEntry : items) { + IABehaviour behaviour = itemEntry.getBehaviour(); + if (!behaviour.isBlock()) continue; + + List resolvedItemResources = resolver.resolve(javaRootPath, itemEntry); + + for (ResolvedItemResource resource : resolvedItemResources) { + JsonObject itemData = new JsonObject(); + itemData.addProperty("textures", resource.bedrockTexturePath()); + textureData.add(resource.bedrockIdentifier(), itemData); + } + } + + root.addProperty("resource_pack_name", packIdentity.getPackName()); + root.addProperty("texture_name", "atlas.terrain"); + root.addProperty("padding", 8); + root.addProperty("num_mip_levels", 4); + root.add("texture_data", textureData); + + Path outputFile = bedrockRootPath.resolve(OUTPUT_FILE); + this.writeJsonFile(outputFile, root); + } +} diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/font/FontWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/font/FontWriter.java index d61bb87..4e21cec 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/font/FontWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/font/FontWriter.java @@ -15,7 +15,6 @@ import java.io.Reader; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.util.List; /** @@ -81,8 +80,7 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { String fileName = "glyph_" + page + ".png"; Path glyphPath = bedrockRootPath.resolve("font").resolve(fileName); - Files.createDirectories(glyphPath.getParent()); - Files.copy(fontPng.toPath(), glyphPath, StandardCopyOption.REPLACE_EXISTING); + this.copyFile(fontPng.toPath(), glyphPath); } } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/IconsTypeConfig.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/IconsTypeConfig.java index 7396d40..034f744 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/IconsTypeConfig.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/IconsTypeConfig.java @@ -1,6 +1,6 @@ package fr.openmc.riftengine.core.converter.writers.glyph.icons; -import fr.openmc.core.bootstrap.integration.OMCLogger; +import fr.openmc.riftengine.core.RiftLog; import org.yaml.snakeyaml.Yaml; import java.io.IOException; @@ -38,7 +38,7 @@ public static IconsTypeConfig load(Path configPath) throws IOException { try { overrides.put(namespacedId, IconsType.valueOf(typeName.trim().toUpperCase())); } catch (IllegalArgumentException e) { - OMCLogger.errorFormatted("Type inconnu pour " + namespacedId + " : " + typeName + " (skip)"); + RiftLog.ICON_TYPE_NOT_RECOGNIZED.send(namespacedId, typeName); } } } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/IconsWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/IconsWriter.java index 2a5e844..b864955 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/IconsWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/IconsWriter.java @@ -1,9 +1,9 @@ package fr.openmc.riftengine.core.converter.writers.glyph.icons; import fr.openmc.core.OMCRegistry; -import fr.openmc.core.bootstrap.integration.OMCLogger; import fr.openmc.riftengine.api.scanner.icons.IconEntry; import fr.openmc.riftengine.api.scanner.icons.IconScanner; +import fr.openmc.riftengine.core.RiftLog; import fr.openmc.riftengine.core.RiftPlugin; import fr.openmc.riftengine.core.RiftRegistry; import fr.openmc.riftengine.core.converter.writers.PackWriter; @@ -51,7 +51,7 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { Path imagePath = entry.path().apply(javaRootPath); if (!Files.exists(imagePath)) { - OMCLogger.errorFormatted("Image introuvable pour " + entry.namespacedId() + " dans le path " + imagePath + " (skip)"); + RiftLog.IMAGE_NOT_FOUND.send(entry.namespacedId(), imagePath); skipped++; continue; } @@ -60,13 +60,13 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { try { image = ImageIO.read(imagePath.toFile()); } catch (IOException e) { - OMCLogger.errorFormatted("Erreur de lecture pour " + entry.namespacedId() + " (skip) : " + e.getMessage()); + RiftLog.ERROR_READING.send(entry.namespacedId()); skipped++; continue; } if (image == null) { - OMCLogger.errorFormatted("Image non lisible pour " + entry.namespacedId() + " (skip)"); + RiftLog.ERROR_READING.send(entry.namespacedId()); skipped++; continue; } @@ -77,7 +77,7 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { } if (type.equals(IconsType.MENU_GUI)) { - OMCLogger.warnFormatted("Glyph " + entry.namespacedId() + " detécté comme MENU_GUI, il ne sera donc pas en glyph, vu que les menus sont géré autrement"); + RiftLog.DETECTED_AS_MENU_GUI.send(entry.namespacedId()); continue; } @@ -85,7 +85,7 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { } if (skipped > 0) { - OMCLogger.errorFormatted("Image manquante pour " + skipped + " emoji(s)/icon(s) sur " + entries.size() + "."); + RiftLog.ICON_SKIPPED.send(skipped, entries.size()); } if (resolved.isEmpty()) return; @@ -134,9 +134,7 @@ private void writePage(Path bedrockRootPath, Dimension size, List int col = i % GlyphsRegistry.GRID_SIZE; IconsType type = resolvedEmoji.type(); - OMCLogger.infoFormatted(resolvedEmoji.entry().namespacedId() + " (" - + resolvedEmoji.image().getWidth() + "x" + resolvedEmoji.image().getHeight() - + ") détecté comme " + type); + RiftLog.DETECTED_AS.send(resolvedEmoji.entry().namespacedId(), resolvedEmoji.image().getWidth(), resolvedEmoji.image().getHeight(), type); Rectangle placement = centerImage(resolvedEmoji.image(), cellWidth, cellHeight, resolvedEmoji.entry(), type); imageEditable.drawImage( diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/SymbolWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/SymbolWriter.java index aed89ea..0ef3826 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/SymbolWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/icons/SymbolWriter.java @@ -1,7 +1,7 @@ package fr.openmc.riftengine.core.converter.writers.glyph.icons; -import fr.openmc.core.bootstrap.integration.OMCLogger; import fr.openmc.core.utils.YmlUtils; +import fr.openmc.riftengine.core.RiftLog; import fr.openmc.riftengine.core.RiftPlugin; import fr.openmc.riftengine.core.RiftRegistry; import fr.openmc.riftengine.core.converter.writers.PackWriter; @@ -50,7 +50,7 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { for (IconGlyph icon : icons) { Object entryObj = fontImagesMap.get(icon.getIcon().key()); if (!(entryObj instanceof Map entryMapRaw)) { - OMCLogger.warnFormatted("Clé " + icon.getIcon().key() + " introuvable dans " + ymlFile + "."); + RiftLog.SYMBOL_KEY_NOT_FOUND.send(icon.getIcon().key(), ymlFile); continue; } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsMappingWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsMappingWriter.java index f98b6dc..8354be5 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsMappingWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsMappingWriter.java @@ -1,17 +1,15 @@ package fr.openmc.riftengine.core.converter.writers.items; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import fr.openmc.core.bootstrap.integration.OMCLogger; import fr.openmc.riftengine.api.scanner.items.ItemEntry; import fr.openmc.riftengine.core.RiftPlugin; import fr.openmc.riftengine.core.converter.writers.PackWriter; +import fr.openmc.riftengine.core.resolvers.items.ItemResourceResolver; +import fr.openmc.riftengine.core.resolvers.items.ResolvedItemResource; import fr.openmc.riftengine.core.utils.PathUtils; import org.bukkit.Material; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; @@ -19,12 +17,13 @@ import java.util.Map; public class ItemsMappingWriter implements PackWriter { - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - private final List items; + private final ItemResourceResolver resolver; + private static final String OUTPUT_FILE = "custom_mappings/ia-items-injected.json"; - public ItemsMappingWriter(List items) { + public ItemsMappingWriter(List items, ItemResourceResolver resolver) { this.items = items; + this.resolver = resolver; } @Override @@ -35,23 +34,24 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws Exception { Map byMaterial = new HashMap<>(); for (ItemEntry item : items) { - Map resources = item.getBestResourcesId(); + List resources = resolver.resolve(javaRootPath, item); - if (resources == null) continue; + JsonArray definitions = byMaterial.computeIfAbsent( + item.getMaterial().getKey().asString(), + _ -> new JsonArray() + ); if (resources.size() == 1) { // * Gestion des items a une texture - byMaterial.computeIfAbsent(item.getMaterial().getKey().asString(), _ -> new JsonArray()) - .add(handleUniqueTexture(item)); - } else { + definitions.add(handleUniqueTexture(item, resources.getFirst())); + } else if (resources.size() > 1) { // * Gestion des items a plusieurs textures JsonObject def = new JsonObject(); def.addProperty("type", "group"); - def.addProperty("model", item.getNamespace() + ":ia_auto/" + item.getKey()); - def.add("definitions", handleMultipleTexture(item)); + def.addProperty("model", resources.getFirst().modelResourceId()); + def.add("definitions", handleMultipleTexture(item, resources)); - byMaterial.computeIfAbsent(item.getMaterial().getKey().asString(), _ -> new JsonArray()) - .add(def); + definitions.add(def); } } @@ -60,66 +60,55 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws Exception { root.add("items", itemsSetter); Path outputFile = PathUtils.getGeyserPath(RiftPlugin.getInstance().getDataPath()) - .resolve("custom_mappings").resolve("ia-injected.json"); - Files.createDirectories(outputFile.getParent()); - Files.writeString(outputFile, GSON.toJson(root), StandardCharsets.UTF_8); + .resolve(OUTPUT_FILE); + Files.deleteIfExists(outputFile); + this.writeJsonFile(outputFile, root); } - private JsonObject handleUniqueTexture(ItemEntry item) { + private JsonObject handleUniqueTexture(ItemEntry item, ResolvedItemResource resource) { JsonObject def = new JsonObject(); if (item.getCustomModelData() != null) { def.addProperty("type", "legacy"); def.addProperty("custom_model_data", item.getCustomModelData()); } else { def.addProperty("type", "definition"); - def.addProperty("model", item.getNamespace() + ":ia_auto/" + item.getKey()); + def.addProperty("model", resource.modelResourceId()); } - def.addProperty("bedrock_identifier", item.namespacedId()); + def.addProperty("bedrock_identifier", resource.bedrockIdentifier()); - JsonObject options = new JsonObject(); - options.addProperty("icon", item.namespacedId()); - def.add("bedrock_options", options); + if (item.getBehaviour().isItem()) { + JsonObject options = new JsonObject(); + options.addProperty("icon", resource.bedrockIdentifier()); + def.add("bedrock_options", options); + } return def; } - private JsonArray handleMultipleTexture(ItemEntry item) { + private JsonArray handleMultipleTexture(ItemEntry item, List resources) { JsonArray definitionsArray = new JsonArray(); - Map bestResources = item.getBestResourcesId(); - if (bestResources == null) { - OMCLogger.warn("Item {} : n'a pas de best resources", item.namespacedId()); - return definitionsArray; - } - - for (var entry : bestResources.entrySet()) { - String stateResource = entry.getKey(); - + for (ResolvedItemResource resource : resources) { JsonObject defObject = new JsonObject(); - String namespaceId = item.namespacedId(); - - if (!stateResource.equals("normal")) - namespaceId += "_" + stateResource; - - defObject.addProperty("bedrock_identifier", namespaceId); + defObject.addProperty("bedrock_identifier", resource.bedrockIdentifier()); JsonObject options = new JsonObject(); - options.addProperty("icon", namespaceId); + options.addProperty("icon", resource.bedrockIdentifier()); options.addProperty("display_handheld", true); // y'a 5 types de conditions (broken, damaged, custom_model_data, has_component, fishing_rod_cast), // note pour plus tard si ajout elytra - if (!stateResource.equals("normal") && item.getMaterial().equals(Material.FISHING_ROD)) { + if (!resource.state().equals(ItemEntry.DEFAULT_STATE) && item.getMaterial().equals(Material.FISHING_ROD)) { options.addProperty("display_handheld", true); + JsonObject predicate = new JsonObject(); predicate.addProperty("type", "condition"); predicate.addProperty("property", "fishing_rod_cast"); defObject.add("predicate", predicate); } - defObject.add("bedrock_options", options); definitionsArray.add(defObject); diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsTextureJsonWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsTextureJsonWriter.java index 232ab8a..1ff34c9 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsTextureJsonWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsTextureJsonWriter.java @@ -1,116 +1,48 @@ package fr.openmc.riftengine.core.converter.writers.items; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; -import fr.openmc.core.bootstrap.integration.OMCLogger; import fr.openmc.riftengine.api.scanner.items.ItemEntry; import fr.openmc.riftengine.core.converter.writers.PackWriter; -import fr.openmc.riftengine.core.utils.IdentifierUtils; -import fr.openmc.riftengine.core.utils.PathUtils; +import fr.openmc.riftengine.core.resolvers.items.ItemResourceResolver; +import fr.openmc.riftengine.core.resolvers.items.ResolvedItemResource; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.nio.file.Path; import java.util.List; -import java.util.Map; /** * Ecrit le item_texture.json qui sert grosso modo a relier les textures aux items (une ref = une resource) */ public class ItemsTextureJsonWriter implements PackWriter { private final List items; + private final ItemResourceResolver resolver; + private static final String OUTPUT_FILE = "textures/item_texture.json"; - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - public ItemsTextureJsonWriter(List items) { + public ItemsTextureJsonWriter(List items, ItemResourceResolver resolver) { this.items = items; + this.resolver = resolver; } @Override public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { JsonObject root = new JsonObject(); - JsonObject textureData = new JsonObject(); for (ItemEntry itemEntry : items) { - Map bestResources = itemEntry.getBestResourcesId(); - if (bestResources == null) { - OMCLogger.warn("Item {} : n'a pas de best resources", itemEntry.namespacedId()); - continue; - } - - for (var entry : bestResources.entrySet()) { - String[] textureDataStr = getTextureData(itemEntry, entry.getKey(), entry.getValue(), javaRootPath); - - if (textureDataStr == null) { - OMCLogger.warn("Item {} : textureDataStr n'a pas de contenu", itemEntry.namespacedId()); - continue; - } + List resolvedItemResources = resolver.resolve(javaRootPath, itemEntry); + for (ResolvedItemResource resource : resolvedItemResources) { JsonObject itemData = new JsonObject(); - itemData.addProperty("textures", textureDataStr[1]); - textureData.add(textureDataStr[0], itemData); + itemData.addProperty("textures", resource.bedrockTexturePath()); + textureData.add(resource.bedrockIdentifier(), itemData); } } root.addProperty("texture_name", "atlas.items"); root.add("texture_data", textureData); - Path outputFile = bedrockRootPath.resolve("textures").resolve("item_texture.json"); - Files.createDirectories(outputFile.getParent()); - Files.writeString(outputFile, GSON.toJson(root), StandardCharsets.UTF_8); - } - - /** - * Retourne les id du namespace et de la resource - * (en fonction de si y'a des textures multiples ect fishing rod) - * Note a moi meme: - * - le state normal est skip, a ma vue c'est le state par défaut - */ - public String[] getTextureData(ItemEntry itemEntry, String stateResource, String resourceId, Path javaRootPath) { - String texture = null; - String namespace = itemEntry.namespacedId(); - - if (resourceId.isEmpty()) { - texture = "textures/items/" + itemEntry.getMaterial().name().toLowerCase();; - } else if (resourceId.startsWith("minecraft:")) { - String path = IdentifierUtils.normalizeId(resourceId).split(":", 2)[1]; - texture = IdentifierUtils.toBedrockTexturePath("textures/" + path); - } else { - Map resources = itemEntry.getResourcePath().apply(javaRootPath); - if (resources == null) { - OMCLogger.warn("Item {} : impossible de déterminer la texture", itemEntry.namespacedId()); - return null; - } - - if (resources.isEmpty()) { - OMCLogger.warn("Item {} : impossible de déterminer la texture", itemEntry.namespacedId()); - return null; - } - - Path resourcePath; - if (resources.size() > 1) { - resourcePath = resources.get(stateResource); - if (!stateResource.equals("normal")) - namespace = itemEntry.namespacedId() + "_" + stateResource; - } else { - resourcePath = resources.values().stream().findFirst().get(); - } - - Path reducedPath = PathUtils.getPathFromRoot(resourcePath, "textures"); - if (reducedPath != null) { - texture = IdentifierUtils.toBedrockTexturePath(reducedPath.toString()) - .replaceFirst("\\.[^/.]+$", ""); - } - } - - if (texture == null) { - OMCLogger.warn("Item {} : impossible de déterminer la texture", itemEntry.namespacedId()); - return null; - } - - return new String[] {namespace, texture}; + Path outputFile = bedrockRootPath.resolve(OUTPUT_FILE); + this.writeJsonFile(outputFile, root); } } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsTextureWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsTextureWriter.java index edbdf4b..cd9dffa 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsTextureWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/items/ItemsTextureWriter.java @@ -1,67 +1,34 @@ package fr.openmc.riftengine.core.converter.writers.items; -import fr.openmc.core.bootstrap.integration.OMCLogger; import fr.openmc.riftengine.api.scanner.items.ItemEntry; import fr.openmc.riftengine.core.converter.writers.PackWriter; +import fr.openmc.riftengine.core.resolvers.items.ItemResourceResolver; +import fr.openmc.riftengine.core.resolvers.items.ResolvedItemResource; import fr.openmc.riftengine.core.utils.IdentifierUtils; -import fr.openmc.riftengine.core.utils.PathUtils; import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardCopyOption; import java.util.List; -import java.util.Map; public class ItemsTextureWriter implements PackWriter { private final List items; + private final ItemResourceResolver resolver; - public ItemsTextureWriter(List items) { + public ItemsTextureWriter(List items, ItemResourceResolver resolver) { this.items = items; + this.resolver = resolver; } @Override public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { for (ItemEntry itemEntry : items) { - Map bestResources = itemEntry.getBestResourcesId(); - if (bestResources == null) { - OMCLogger.warn("Item {} : n'a pas de best resources", itemEntry.namespacedId()); - continue; - } - - for (var entry : bestResources.entrySet()) { - String stateResource = entry.getKey(); - String resourceId = entry.getValue(); - - if (resourceId.isEmpty()) { - OMCLogger.warn("Item {} a pas de resource id", itemEntry.namespacedId()); - continue; - } - - if (resourceId.split(":")[0].equals("minecraft")) continue; - - Map resources = itemEntry.getResourcePath().apply(javaRootPath); - if (resources == null) { - OMCLogger.warn("Item {} a aucune resource (Model ou texture)", itemEntry.namespacedId()); - continue; - } - - Path resourcePath = resources.get(stateResource); - if (resourcePath == null) { - OMCLogger.warn("Item {} a aucune resource (Model ou texture)", itemEntry.namespacedId()); - continue; - } + List resources = resolver.resolve(javaRootPath, itemEntry); - Path reducedPath = PathUtils.getPathFromRoot(resourcePath, "textures"); - if (reducedPath == null) { - OMCLogger.warn("Item {} a un Path impossible a réduire {}", itemEntry.namespacedId(), resourcePath.toString()); - continue; - } + for (ResolvedItemResource resource : resources) { + if (resource.isVanilla()) continue; - Path outputFile = bedrockRootPath.resolve( - IdentifierUtils.toBedrockTexturePath(reducedPath.toString())); - Files.createDirectories(outputFile.getParent()); - Files.copy(resourcePath, outputFile, StandardCopyOption.REPLACE_EXISTING); + Path outputFile = bedrockRootPath.resolve(IdentifierUtils.toBedrockTexturePath(resource.bedrockTexturePath())); + this.copyFile(resource.sourcePath(), outputFile); } } } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/IconWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/IconWriter.java index 8ba6ddb..2f26dd5 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/IconWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/IconWriter.java @@ -9,12 +9,14 @@ import java.nio.file.StandardCopyOption; public class IconWriter implements PackWriter { + private static final String OUTPUT_FILE = "pack_icon.png"; + @Override public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { try (InputStream is = getClass().getResourceAsStream("/pack_icon.png")) { if (is == null) throw new IOException("Resource introuvable : pack_icon.png"); - Files.copy(is, bedrockRootPath.resolve("pack_icon.png"), StandardCopyOption.REPLACE_EXISTING); + Files.copy(is, bedrockRootPath.resolve(OUTPUT_FILE), StandardCopyOption.REPLACE_EXISTING); } } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/ManifestWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/ManifestWriter.java index 8d6c8a1..01324b9 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/ManifestWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/ManifestWriter.java @@ -3,12 +3,10 @@ import fr.openmc.riftengine.core.converter.writers.PackWriter; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.nio.file.Path; public class ManifestWriter implements PackWriter { - + private static final String OUTPUT_FILE = "manifest.json"; private final PackIdentity identity; public ManifestWriter(PackIdentity identity) { @@ -17,13 +15,13 @@ public ManifestWriter(PackIdentity identity) { @Override public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { - int[] v = identity.version(); + int[] v = identity.getVersion(); String versionJson = "[" + v[0] + ", " + v[1] + ", " + v[2] + "]"; String manifest = """ { "format_version": 2, "header": { - "name": "RiftPack", + "name": "%s", "description": "Généré par RiftEngine à partir de celui de Java", "uuid": "%s", "version": %s, @@ -37,9 +35,8 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { } ] } - """.formatted(identity.headerUuid(), versionJson, identity.moduleUuid(), versionJson); - - Files.writeString(bedrockRootPath.resolve("manifest.json"), manifest, StandardCharsets.UTF_8); + """.formatted(identity.getPackName(), identity.getHeaderUuid(), versionJson, identity.getModuleUuid(), versionJson); + this.writeFile(bedrockRootPath.resolve(OUTPUT_FILE), manifest); } } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/PackIdentity.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/PackIdentity.java index 6736c72..ff4871b 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/PackIdentity.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/manifest/PackIdentity.java @@ -1,5 +1,6 @@ package fr.openmc.riftengine.core.converter.writers.manifest; +import lombok.Getter; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.java.JavaPlugin; @@ -9,32 +10,24 @@ import static fr.openmc.riftengine.core.RiftPlugin.RP_VERSION; +@Getter public class PackIdentity { + private static final String FILE_NAME = "pack-identity.yml"; + private final String packName; private final UUID headerUuid; private final UUID moduleUuid; private final int[] version; // * [major, minor, patch] - private PackIdentity(UUID headerUuid, UUID moduleUuid, int[] version) { + private PackIdentity(String packName, UUID headerUuid, UUID moduleUuid, int[] version) { + this.packName = packName; this.headerUuid = headerUuid; this.moduleUuid = moduleUuid; this.version = version; } - public UUID headerUuid() { - return headerUuid; - } - - public UUID moduleUuid() { - return moduleUuid; - } - - public int[] version() { - return version; - } - public static PackIdentity loadOrCreate(JavaPlugin plugin) throws IOException { - File file = new File(plugin.getDataFolder(), "pack-identity.yml"); + File file = new File(plugin.getDataFolder(), FILE_NAME); YamlConfiguration config = YamlConfiguration.loadConfiguration(file); if (!config.contains("header-uuid")) { @@ -56,6 +49,7 @@ public static PackIdentity loadOrCreate(JavaPlugin plugin) throws IOException { config.save(file); return new PackIdentity( + "RiftPack", UUID.fromString(config.getString("header-uuid")), UUID.fromString(config.getString("module-uuid")), new int[]{major, minor, patch} diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/ui/ScoreboardUiWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/ui/ScoreboardUiWriter.java index 2059f49..71b3186 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/ui/ScoreboardUiWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/ui/ScoreboardUiWriter.java @@ -1,20 +1,15 @@ package fr.openmc.riftengine.core.converter.writers.ui; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.google.gson.JsonObject; import fr.openmc.riftengine.core.converter.writers.PackWriter; import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.nio.file.Path; public class ScoreboardUiWriter implements PackWriter { + private static final String OUTPUT_FILE = "ui/scoreboards.json"; private final boolean hideScoreboardNumberBedrock; - private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); - public ScoreboardUiWriter(boolean hideScoreboardNumberBedrock) { this.hideScoreboardNumberBedrock = hideScoreboardNumberBedrock; } @@ -29,8 +24,7 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { visible.addProperty("visible", false); root.add("scoreboard_sidebar_score", visible); - Path outputFile = bedrockRootPath.resolve("ui").resolve("scoreboards.json"); - Files.createDirectories(outputFile.getParent()); - Files.writeString(outputFile, GSON.toJson(root), StandardCharsets.UTF_8); + Path outputFile = bedrockRootPath.resolve(OUTPUT_FILE); + this.writeJsonFile(outputFile, root); } } diff --git a/src/main/java/fr/openmc/riftengine/core/registry/resolver/AbstractResolver.java b/src/main/java/fr/openmc/riftengine/core/registry/resolver/AbstractResolver.java new file mode 100644 index 0000000..f787605 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/registry/resolver/AbstractResolver.java @@ -0,0 +1,7 @@ +package fr.openmc.riftengine.core.registry.resolver; + +import java.nio.file.Path; + +public abstract class AbstractResolver { + public abstract O resolve(Path javaRootPath, I input); +} diff --git a/src/main/java/fr/openmc/riftengine/core/registry/resolver/ResolverRegistry.java b/src/main/java/fr/openmc/riftengine/core/registry/resolver/ResolverRegistry.java new file mode 100644 index 0000000..9fe82af --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/registry/resolver/ResolverRegistry.java @@ -0,0 +1,16 @@ +package fr.openmc.riftengine.core.registry.resolver; + +import fr.openmc.core.bootstrap.registries.KeyedRegistry; +import fr.openmc.core.bootstrap.registries.Registry; +import fr.openmc.riftengine.core.resolvers.items.ItemResourceResolver; + +public class ResolverRegistry extends Registry> + implements KeyedRegistry> { + + public final ItemResourceResolver ITEM_RESOURCE_RESOLVER = register(new ItemResourceResolver()); + + @Override + public String key(AbstractResolver resolver) { + return resolver.getClass().getSimpleName(); + } +} \ No newline at end of file diff --git a/src/main/java/fr/openmc/riftengine/core/resolvers/items/ItemResourceResolver.java b/src/main/java/fr/openmc/riftengine/core/resolvers/items/ItemResourceResolver.java new file mode 100644 index 0000000..c6138a9 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/resolvers/items/ItemResourceResolver.java @@ -0,0 +1,73 @@ +package fr.openmc.riftengine.core.resolvers.items; + +import fr.openmc.riftengine.api.scanner.items.ItemEntry; +import fr.openmc.riftengine.core.RiftLog; +import fr.openmc.riftengine.core.registry.resolver.AbstractResolver; +import fr.openmc.riftengine.core.utils.IdentifierUtils; +import fr.openmc.riftengine.core.utils.PathUtils; + +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class ItemResourceResolver extends AbstractResolver> { + + @Override + public List resolve(Path javaRootPath, ItemEntry item) { + Map resources = item.getBestResourcesId(); + + if (resources == null || resources.isEmpty()) { + RiftLog.ITEM_NOT_RESOURCE.send(item.namespacedId()); + return List.of(); + } + + Map bedrockTexturePaths = item.getResourcePath().apply(javaRootPath); + + List resolved = new ArrayList<>(); + for (Map.Entry entry : resources.entrySet()) { + String state = entry.getKey(); + String resourceId = entry.getValue(); + Path bedrockTexturePath = bedrockTexturePaths.get(state); + String bedrockIdentifier = state.equals(ItemEntry.DEFAULT_STATE) ? item.getKey() : item.getKey() + "_" + state; + String bedrockTextureValue = null; + String modelResourceId = item.getNamespace() + ":ia_auto/" + item.getKey(); + + if (resourceId.isEmpty()) { + String folder = item.getBehaviour().isItem() ? "items" : "blocks"; + bedrockTextureValue = "textures/" + folder + "/" + item.getMaterial().name().toLowerCase(); + } else if (resourceId.startsWith("minecraft:")) { + String path = IdentifierUtils.normalizeId(resourceId).split(":", 2)[1]; + bedrockTextureValue = IdentifierUtils.toBedrockTexturePath("textures/" + path); + } else { + Path resourcePath; + if (bedrockTexturePaths.size() > 1) { + resourcePath = bedrockTexturePaths.get(state); + } else if (bedrockTexturePaths.size() == 1) { + resourcePath = bedrockTexturePaths.values().stream() + .findFirst().get(); + } else { + RiftLog.RESOURCE_NOT_FOUND.send(item.getKey()); + return List.of(); + } + + Path reducedPath = PathUtils.getPathFromRoot(resourcePath, "textures"); + if (reducedPath != null) { + bedrockTextureValue = IdentifierUtils.toBedrockTexturePath(reducedPath.toString()) + .replaceFirst("\\.[^/.]+$", ""); + } + } + + if (bedrockTextureValue == null) { + RiftLog.RESOURCE_NOT_FOUND.send(item.getKey()); + return List.of(); + } + + resolved.add(new ResolvedItemResource( + item, state, resourceId, modelResourceId, + bedrockIdentifier, bedrockTexturePath, bedrockTextureValue)); + } + + return resolved; + } +} diff --git a/src/main/java/fr/openmc/riftengine/core/resolvers/items/ResolvedItemResource.java b/src/main/java/fr/openmc/riftengine/core/resolvers/items/ResolvedItemResource.java new file mode 100644 index 0000000..b8cd587 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/resolvers/items/ResolvedItemResource.java @@ -0,0 +1,22 @@ +package fr.openmc.riftengine.core.resolvers.items; + +import fr.openmc.riftengine.api.scanner.items.ItemEntry; + +import java.nio.file.Path; + +public record ResolvedItemResource(ItemEntry item, + String state, // bottom, top, side + String resourceId, // ex aywenite (sans le namespace devant), cloud_fishing_rod_cast + String modelResourceId, // ex omc_dream:ia_auto/dream_boot + String bedrockIdentifier, // + Path sourcePath, + String bedrockTexturePath // ex textures/aywenite + ) { + public String bedrockIdWithState(String state) { + return state.equals(ItemEntry.DEFAULT_STATE) ? item.getKey() : (item.getKey() + "_" + state); + } + + public boolean isVanilla() { + return resourceId.startsWith("minecraft:"); + } +} diff --git a/src/main/java/fr/openmc/riftengine/core/utils/IdentifierUtils.java b/src/main/java/fr/openmc/riftengine/core/utils/IdentifierUtils.java index aaeaea3..b167d4d 100644 --- a/src/main/java/fr/openmc/riftengine/core/utils/IdentifierUtils.java +++ b/src/main/java/fr/openmc/riftengine/core/utils/IdentifierUtils.java @@ -24,6 +24,13 @@ public static String normalizeId(String id, String defaultNamespace) { return defaultNamespace + ":" + id; } + public static String removeNamespace(String namespacedId) { + String[] splited = namespacedId.split(":"); + if (splited.length != 2) return namespacedId; + + return splited[1]; + } + /** * Résout un identifiant en un chemin de fichier dans les assets */