From 08aafe20bc35e3ac54538a918a60fcc69f6aea3c Mon Sep 17 00:00:00 2001 From: iambibi <89582596+iambibi@users.noreply.github.com> Date: Wed, 21 Oct 2026 19:07:41 +0200 Subject: [PATCH 1/2] feat: start of chest gui --- build.gradle | 7 +- gradle.properties | 2 + libs/OpenMC.jar | Bin 7013915 -> 7016732 bytes .../fr/openmc/riftengine/core/RiftLog.java | 1 - .../core/converter/ConverterManager.java | 12 ++ .../writers/blocks/BlocksMappingWriter.java | 2 +- .../glyph/chestgui/ChestGuiTextureWriter.java | 16 +++ .../glyph/chestgui/ChestScreenWriter.java | 117 ++++++++++++++++++ .../glyph/chestgui/ResolvedChestGui.java | 20 +++ .../writers/glyph/font/FontWriter.java | 2 +- .../writers/glyph/icons/IconsWriter.java | 4 +- .../writers/items/ItemsTextureWriter.java | 3 +- .../textures/TooltipTextureWriter.java | 7 +- .../core/listeners/ChestGuiTitleListener.java | 74 +++++++++++ .../core/registry/glyphs/GlyphsRegistry.java | 4 +- .../registry/glyphs/types/TooltipGlyph.java | 2 +- .../resolvers/items/ItemResourceResolver.java | 2 +- .../riftengine/core/utils/FloodgateUtils.java | 10 ++ .../core/utils/IdentifierUtils.java | 100 --------------- src/main/resources/paper-plugin.yml | 3 + 20 files changed, 271 insertions(+), 117 deletions(-) create mode 100644 src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestGuiTextureWriter.java create mode 100644 src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestScreenWriter.java create mode 100644 src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ResolvedChestGui.java create mode 100644 src/main/java/fr/openmc/riftengine/core/listeners/ChestGuiTitleListener.java create mode 100644 src/main/java/fr/openmc/riftengine/core/utils/FloodgateUtils.java delete mode 100644 src/main/java/fr/openmc/riftengine/core/utils/IdentifierUtils.java diff --git a/build.gradle b/build.gradle index ef50236..174ea8b 100644 --- a/build.gradle +++ b/build.gradle @@ -8,10 +8,13 @@ version = '0.5-SNAPSHOT' repositories { mavenCentral() + + // * ProtocolLib + maven {url "https://repo.dmulloy2.net/repository/public/"} // * GeyserMC maven {url "https://repo.opencollab.dev/main/"} // * PaperMC - maven { url = "https://repo.papermc.io/repository/maven-public/" } + maven {url = "https://repo.papermc.io/repository/maven-public/" } // * ItemsAdder maven {url "https://maven.devs.beer/"} } @@ -20,8 +23,10 @@ dependencies { paperweight.paperDevBundle "${minecraftVersion}.build.${paperVersion}" // Dependancies + compileOnly "net.dmulloy2:ProtocolLib:${protocolLibVersion}" compileOnly "beer.devs:itemsadder-api:${itemsAdderVersion}" compileOnly "org.geysermc.geyser:api:${geyserApiVersion}" + compileOnly "org.geysermc.floodgate:api:${floodgateApiVersion}" compileOnly files("libs/OpenMC.jar") implementation "org.jetbrains:annotations:${jetbrainsAnnotationsVersion}" diff --git a/gradle.properties b/gradle.properties index 05b0013..8257d71 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,8 +6,10 @@ minecraftVersion = 26.3 paperVersion = 180-stable # Dependencies versions +protocolLibVersion = 5.4.0 itemsAdderVersion = 4.0.18-beta-10 geyserApiVersion = 2.10.0-SNAPSHOT +floodgateApiVersion = 2.2.5-SNAPSHOT jetbrainsAnnotationsVersion = 26.1.0 lombokVersion = 1.18.46 diff --git a/libs/OpenMC.jar b/libs/OpenMC.jar index 18216070dbe1229914ae8a9fd9a136512f8c549e..d5c2c2a9badf78a9c2beef15aed28388d667295b 100644 GIT binary patch delta 58796 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 chestGuis = new ArrayList<>(); + private static final String OUTPUT_FILE = "ui/chest_screen.json"; + public static final String PREFIX = "rift"; + private final String namespace = "chest"; + + private final String TEMPLATE_CHEST_SCREEN = """ + { + "namespace": , + + "chest_label": { + "type": "label", + "layer": 2, + "offset": [7, -1], + "size": ["90%", "default"], + "anchor_from": "top_left", + "anchor_to": "top_left", + "text": "$container_title", + "color": "$title_text_color", + "localize": "$localize_title", + "enable_profanity_filter": true, + "$atext": "$container_title", + "visible": "($atext - ':' = $atext)" + } + } + """; + + @Override + public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { + JsonObject root = JsonUtils.parseJson(TEMPLATE_CHEST_SCREEN + .replace("", namespace) + .replace("", PREFIX)); + + this.handleChestGui(javaRootPath, root); + this.handlePanelTopHalf(root); + + + Path outputFile = bedrockRootPath.resolve(OUTPUT_FILE); + this.writeJsonFile(outputFile, root); + } + + private final String TEMPLATE_CHEST_GUI = """ + { + "type": "image", + "texture": "", + "size": [, ], + "keep_ratio": false, + "offset": [1, ], + "anchor_from": "top_middle", + "anchor_to": "top_middle", + "layer": 4, + "$atext": "$container_title", + "visible": "" + } + """; + + // todo: voir offset_x qd https://github.com/PluginBugs/Issues-ItemsAdder/issues/5576 + private void handleChestGui(Path javaRootPath, JsonObject root) { + for (ResolvedChestGui chestGui : chestGuis) { + root.add(PREFIX + "_" + chestGui.key(), JsonUtils.parseJson(TEMPLATE_CHEST_GUI + .replace("", chestGui.bedrockTexturePath(javaRootPath).toString()) + .replace("", String.valueOf(chestGui.width())) + .replace("", String.valueOf(chestGui.height())) + .replace("", String.valueOf(-(chestGui.entry().yPosition()-5))) + .replace("", + "(not ($atext - '" + PREFIX + ":" + chestGui.key() + "' = $atext))"))); + } + } + + private final String TEMPLATE_PANEL_TOP_HALF = """ + { + "modifications": [ + { + "array_name": "controls", + "operation": "insert_front", + "value": [] + } + ] + } + """; + + private void handlePanelTopHalf(JsonObject root) { + JsonObject panelTopHalf = JsonUtils.parseJson(TEMPLATE_PANEL_TOP_HALF); + + JsonArray modifications = panelTopHalf.getAsJsonArray("modifications"); + + for (JsonElement modification : modifications) { + if (!(modification instanceof JsonObject obj)) continue; + + JsonArray value = obj.getAsJsonArray("value"); + + for (ResolvedChestGui chestGui : chestGuis) { + JsonObject chestGuiValue = new JsonObject(); + chestGuiValue.add(PREFIX + "_" + chestGui.key() + + "@" + namespace + "." + PREFIX + "_" + chestGui.key(), new JsonObject()); + value.add(chestGuiValue); + } + } + + for (String prefix : new String[] {"large_chest", "small_chest"}) { + root.add(prefix + "_panel_top_half", panelTopHalf); + } + } +} diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ResolvedChestGui.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ResolvedChestGui.java new file mode 100644 index 0000000..ace32c7 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ResolvedChestGui.java @@ -0,0 +1,20 @@ +package fr.openmc.riftengine.core.converter.writers.glyph.chestgui; + +import fr.openmc.riftengine.api.scanner.icons.IconEntry; +import fr.openmc.riftengine.core.utils.PathUtils; + +import java.nio.file.Path; + +public record ResolvedChestGui(IconEntry entry, int width, int height) { + public String key() { + return entry.key(); + } + + public Path javaTexturePath(Path javaRootPath) { + return entry.path().apply(javaRootPath); + } + + public Path bedrockTexturePath(Path javaRootPath) { + return PathUtils.getPathFromRoot(javaTexturePath(javaRootPath), "textures") ; + } +} 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 4e21cec..6b0527b 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 @@ -4,10 +4,10 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import fr.openmc.riftengine.api.utils.IdentifierUtils; import fr.openmc.riftengine.core.RiftRegistry; import fr.openmc.riftengine.core.converter.writers.PackWriter; import fr.openmc.riftengine.core.registry.glyphs.types.FontGlyph; -import fr.openmc.riftengine.core.utils.IdentifierUtils; import fr.openmc.riftengine.core.utils.ScanUtils; import java.io.File; 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 b864955..e47a51e 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 @@ -7,6 +7,8 @@ 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.glyph.chestgui.ChestScreenWriter; +import fr.openmc.riftengine.core.converter.writers.glyph.chestgui.ResolvedChestGui; import fr.openmc.riftengine.core.registry.glyphs.GlyphsRegistry; import fr.openmc.riftengine.core.registry.glyphs.types.IconGlyph; @@ -77,7 +79,7 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { } if (type.equals(IconsType.MENU_GUI)) { - RiftLog.DETECTED_AS_MENU_GUI.send(entry.namespacedId()); + ChestScreenWriter.chestGuis.add(new ResolvedChestGui(entry, image.getWidth(), image.getHeight())); continue; } 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 cd9dffa..834f51c 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,10 +1,10 @@ package fr.openmc.riftengine.core.converter.writers.items; import fr.openmc.riftengine.api.scanner.items.ItemEntry; +import fr.openmc.riftengine.api.utils.IdentifierUtils; 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 java.io.IOException; import java.nio.file.Path; @@ -26,7 +26,6 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { for (ResolvedItemResource resource : resources) { if (resource.isVanilla()) continue; - 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/tooltip/textures/TooltipTextureWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/tooltip/textures/TooltipTextureWriter.java index b53c515..02e70e2 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/tooltip/textures/TooltipTextureWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/tooltip/textures/TooltipTextureWriter.java @@ -1,13 +1,13 @@ package fr.openmc.riftengine.core.converter.writers.tooltip.textures; import fr.openmc.riftengine.api.scanner.items.ItemEntry; +import fr.openmc.riftengine.api.utils.IdentifierUtils; import fr.openmc.riftengine.core.RiftLog; import fr.openmc.riftengine.core.converter.writers.PackWriter; import fr.openmc.riftengine.core.resolvers.mcmeta.gui.GuiMcMetaResolver; import fr.openmc.riftengine.core.resolvers.mcmeta.gui.ResolvedGuiMcMeta; import fr.openmc.riftengine.core.resolvers.tooltip.ResolvedTooltipResource; import fr.openmc.riftengine.core.resolvers.tooltip.TooltipResourceResolver; -import fr.openmc.riftengine.core.utils.IdentifierUtils; import java.io.IOException; import java.nio.file.Path; @@ -15,11 +15,6 @@ import java.util.List; import java.util.Map; - -// - ecrire les textures dans le resourcepack bedrock -// * faire un scanner pour savoir les frames, fps, et tt chose qui sont relié entre les textures et ui_common.json -// - allouer un glyph pour chaque "type" de tooltip + le mettre dans l'item name + demander reload ia -// - ecrire le ui/ui_common.json (une giga template que j'adapte en fonction des textures) public class TooltipTextureWriter implements PackWriter { private final List items; private final GuiMcMetaResolver guiResolver; diff --git a/src/main/java/fr/openmc/riftengine/core/listeners/ChestGuiTitleListener.java b/src/main/java/fr/openmc/riftengine/core/listeners/ChestGuiTitleListener.java new file mode 100644 index 0000000..2b6a007 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/listeners/ChestGuiTitleListener.java @@ -0,0 +1,74 @@ +package fr.openmc.riftengine.core.listeners; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.WrappedChatComponent; +import fr.openmc.core.OMCRegistry; +import fr.openmc.riftengine.api.utils.IdentifierUtils; +import fr.openmc.riftengine.core.converter.writers.glyph.chestgui.ChestScreenWriter; +import fr.openmc.riftengine.core.utils.FloodgateUtils; +import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +public class ChestGuiTitleListener extends PacketAdapter { + private final Set offsetCaracter; + private final Map cacheUnicode; + + public ChestGuiTitleListener(Path javaRootPath, Path itemsAdderDataPath, Plugin plugin) throws IOException { + super(plugin, ListenerPriority.LOWEST, PacketType.Play.Server.OPEN_WINDOW); + this.offsetCaracter = OMCRegistry.SCANNERS.OFFSET_CARACTER.scan(javaRootPath); + this.cacheUnicode = OMCRegistry.SCANNERS.CARACTER_UNICODE_CACHE.scan(itemsAdderDataPath); + } + + @Override + public void onPacketSending(PacketEvent event) { + Player player = event.getPlayer(); + if (!FloodgateUtils.isBedrock(player)) return; + + PacketContainer packet = event.getPacket(); + WrappedChatComponent title = packet.getChatComponents().read(0); + if (title == null) return; + + String raw = PlainTextComponentSerializer.plainText() + .serialize(GsonComponentSerializer.gson().deserialize(title.getJson())); + + // * si l'inv est fait en sorte que le title se resolve au client ex. §r§f:offset_-48::city_template3x9: + // * sinon on nettoie le string pour savoir si il contient un offset, donc un potentiel menu + if (raw.contains(":offset_")) { + String[] parts = raw.split("::"); + if (parts.length < 2) return; + + String menuName = parts[1].replace(":", ""); + packet.getChatComponents().write(0, WrappedChatComponent.fromText(ChestScreenWriter.PREFIX + ":" + menuName)); + } else { + boolean hasOffset = raw.chars() + .mapToObj(c -> (char) c) + .anyMatch(offsetCaracter::contains); + + if (!hasOffset) return; + + // * on supprime les offsets et les caracteres basiques pour ne garder que le caractere du menu + String cleaned = raw.chars() + .mapToObj(c -> String.valueOf((char) c)) + .filter(c -> c.length() == 1 && !offsetCaracter.contains(c.charAt(0))) + .collect(Collectors.joining()) + .replaceAll("§[0-9a-fk-or]", ""); + + char menuChar = cleaned.charAt(0); + + packet.getChatComponents().write(0, WrappedChatComponent.fromText( + ChestScreenWriter.PREFIX + ":" + IdentifierUtils.removeNamespace(cacheUnicode.get(menuChar)))); + } + } +} \ No newline at end of file diff --git a/src/main/java/fr/openmc/riftengine/core/registry/glyphs/GlyphsRegistry.java b/src/main/java/fr/openmc/riftengine/core/registry/glyphs/GlyphsRegistry.java index 56e82fb..a49b086 100644 --- a/src/main/java/fr/openmc/riftengine/core/registry/glyphs/GlyphsRegistry.java +++ b/src/main/java/fr/openmc/riftengine/core/registry/glyphs/GlyphsRegistry.java @@ -11,10 +11,10 @@ public class GlyphsRegistry extends Registry public static final int GRID_SIZE = 16; public static final int MAX_PER_PAGE = GRID_SIZE * GRID_SIZE; - private final List SLOT_GLYPH = new ArrayList<>(List.of( + public static final List SLOT_GLYPH = new ArrayList<>(List.of( "E2", "E3", "E4", "E5", "E6", "E7", "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7")); - public static final String TOOLTIP_PAGE = "F8"; + public static final String OTHER_PAGE = "F8"; // tooltip, gui ... tout ceux qui ont juste besoin d'etre identifié private int nextPageIndex = 0; public String nextGlyphPage() { diff --git a/src/main/java/fr/openmc/riftengine/core/registry/glyphs/types/TooltipGlyph.java b/src/main/java/fr/openmc/riftengine/core/registry/glyphs/types/TooltipGlyph.java index 25b12e8..2d3754f 100644 --- a/src/main/java/fr/openmc/riftengine/core/registry/glyphs/types/TooltipGlyph.java +++ b/src/main/java/fr/openmc/riftengine/core/registry/glyphs/types/TooltipGlyph.java @@ -10,7 +10,7 @@ public class TooltipGlyph extends Glyph { private final ResolvedTooltipResource tooltipResource; public TooltipGlyph(String namespacedId, int row, int col, ResolvedTooltipResource tooltipResource) { - super(namespacedId, GlyphsRegistry.TOOLTIP_PAGE, row, col); + super(namespacedId, GlyphsRegistry.OTHER_PAGE, row, col); this.tooltipResource = tooltipResource; } } \ 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 index 01078be..ccf6b59 100644 --- a/src/main/java/fr/openmc/riftengine/core/resolvers/items/ItemResourceResolver.java +++ b/src/main/java/fr/openmc/riftengine/core/resolvers/items/ItemResourceResolver.java @@ -1,9 +1,9 @@ package fr.openmc.riftengine.core.resolvers.items; import fr.openmc.riftengine.api.scanner.items.ItemEntry; +import fr.openmc.riftengine.api.utils.IdentifierUtils; 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; diff --git a/src/main/java/fr/openmc/riftengine/core/utils/FloodgateUtils.java b/src/main/java/fr/openmc/riftengine/core/utils/FloodgateUtils.java new file mode 100644 index 0000000..4984d8f --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/utils/FloodgateUtils.java @@ -0,0 +1,10 @@ +package fr.openmc.riftengine.core.utils; + +import org.bukkit.entity.Player; +import org.geysermc.floodgate.api.FloodgateApi; + +public class FloodgateUtils { + public static boolean isBedrock(Player player) { + return FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId()); + } +} diff --git a/src/main/java/fr/openmc/riftengine/core/utils/IdentifierUtils.java b/src/main/java/fr/openmc/riftengine/core/utils/IdentifierUtils.java deleted file mode 100644 index b167d4d..0000000 --- a/src/main/java/fr/openmc/riftengine/core/utils/IdentifierUtils.java +++ /dev/null @@ -1,100 +0,0 @@ -package fr.openmc.riftengine.core.utils; - -import java.nio.file.Path; - -public class IdentifierUtils { - /** - * Normalise un identifiant (qui n'a pas un namespace devant - * @param id l'id (font/default.png, minecraft:font/default.png) - * @return l'id final - */ - public static String normalizeId(String id) { - return normalizeId(id, "minecraft"); - } - - /** - * Normalise un identifiant (qui n'a pas un namespace devant - * @param id l'id (font/default.png, minecraft:font/default.png) - * @param defaultNamespace le namespace par défaut à utiliser, si on est dans un fichier d'items adder par ex - * @return l'id final - */ - public static String normalizeId(String id, String defaultNamespace) { - if (id.split(":").length == 2) return id; - - 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 - */ - public static Path resolveTextureId(Path rootPath, String id) { - String normalizedId = normalizeId(id); - String[] split = normalizedId.split(":", 2); - - String namespace; - String texturePath; - - if (split.length == 2) { - namespace = split[0]; - texturePath = split[1]; - } else { - namespace = "minecraft"; - texturePath = split[0]; - } - - if (!texturePath.endsWith(".png")) { - texturePath += ".png"; - } - - return rootPath - .resolve("assets") - .resolve(namespace) - .resolve("textures") - .resolve(texturePath); - } - - /** - * Résout un identifiant en un chemin de fichier dans les assets pour les models - */ - public static Path resolveModelId(Path rootPath, String id) { - String normalizedId = normalizeId(id); - String[] split = normalizedId.split(":", 2); - - String namespace; - String modelPath; - - if (split.length == 2) { - namespace = split[0]; - modelPath = split[1]; - } else { - namespace = "minecraft"; - modelPath = split[0]; - } - - if (!modelPath.endsWith(".json")) { - modelPath += ".json"; - } - - return rootPath - .resolve("assets") - .resolve(namespace) - .resolve("models") - .resolve(modelPath); - } - - public static String toBedrockTexturePath(String javaPath) { - if (javaPath.startsWith("textures/item/")) - return "textures/items/" + javaPath.substring("textures/item/".length()); - if (javaPath.startsWith("textures/block/")) - return "textures/blocks/" + javaPath.substring("textures/block/".length()); - - return javaPath; - } -} diff --git a/src/main/resources/paper-plugin.yml b/src/main/resources/paper-plugin.yml index 70b0652..060d616 100644 --- a/src/main/resources/paper-plugin.yml +++ b/src/main/resources/paper-plugin.yml @@ -14,5 +14,8 @@ dependencies: load: BEFORE required: true Geyser-Spigot: + load: BEFORE + required: true + floodgate: load: BEFORE required: true \ No newline at end of file From 933729e2468d17b8f91d6b04c1c516a6e8317076 Mon Sep 17 00:00:00 2001 From: iambibi <89582596+iambibi@users.noreply.github.com> Date: Sun, 25 Oct 2026 10:54:34 +0100 Subject: [PATCH 2/2] bump to 0.6 + fix menus --- build.gradle | 2 +- .../glyph/chestgui/ChestGuiTextureWriter.java | 8 +- .../glyph/chestgui/ChestScreenWriter.java | 19 ++- .../riftengine/core/utils/ImageUtils.java | 111 ++++++++++++++++++ 4 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 src/main/java/fr/openmc/riftengine/core/utils/ImageUtils.java diff --git a/build.gradle b/build.gradle index 174ea8b..737dcf8 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'fr.openmc.riftengine' -version = '0.5-SNAPSHOT' +version = '0.6-SNAPSHOT' repositories { mavenCentral() diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestGuiTextureWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestGuiTextureWriter.java index 03111c1..f87273f 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestGuiTextureWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestGuiTextureWriter.java @@ -1,7 +1,9 @@ package fr.openmc.riftengine.core.converter.writers.glyph.chestgui; import fr.openmc.riftengine.core.converter.writers.PackWriter; +import fr.openmc.riftengine.core.utils.ImageUtils; +import java.awt.image.BufferedImage; import java.io.IOException; import java.nio.file.Path; @@ -9,8 +11,10 @@ public class ChestGuiTextureWriter implements PackWriter { @Override public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { for (ResolvedChestGui chestGui : ChestScreenWriter.chestGuis) { - this.copyFile(chestGui.javaTexturePath(javaRootPath), - bedrockRootPath.resolve(chestGui.bedrockTexturePath(javaRootPath))); + BufferedImage src = ImageUtils.read(chestGui.javaTexturePath(javaRootPath)); + Path target = bedrockRootPath.resolve(chestGui.bedrockTexturePath(javaRootPath)); + + ImageUtils.writePng(ImageUtils.center(src), target); } } } diff --git a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestScreenWriter.java b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestScreenWriter.java index 1990173..3ee86fd 100644 --- a/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestScreenWriter.java +++ b/src/main/java/fr/openmc/riftengine/core/converter/writers/glyph/chestgui/ChestScreenWriter.java @@ -5,7 +5,9 @@ import com.google.gson.JsonObject; import fr.openmc.core.utils.JsonUtils; import fr.openmc.riftengine.core.converter.writers.PackWriter; +import fr.openmc.riftengine.core.utils.ImageUtils; +import java.awt.image.BufferedImage; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; @@ -58,7 +60,7 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { "texture": "", "size": [, ], "keep_ratio": false, - "offset": [1, ], + "offset": [, ], "anchor_from": "top_middle", "anchor_to": "top_middle", "layer": 4, @@ -67,14 +69,23 @@ public void write(Path bedrockRootPath, Path javaRootPath) throws IOException { } """; - // todo: voir offset_x qd https://github.com/PluginBugs/Issues-ItemsAdder/issues/5576 - private void handleChestGui(Path javaRootPath, JsonObject root) { + private void handleChestGui(Path javaRootPath, JsonObject root) throws IOException { for (ResolvedChestGui chestGui : chestGuis) { + BufferedImage src = ImageUtils.read(chestGui.javaTexturePath(javaRootPath)); + BufferedImage centered = ImageUtils.center(src); + + int shift = ImageUtils.centerShiftY(src); + int offsetY = 5 - chestGui.entry().yPosition() - shift; + + int gridLeft = ImageUtils.findGridLeft(centered); + int offsetX = gridLeft == -1 ? 0 : 7 - gridLeft - (176 - centered.getWidth()) / 2; + root.add(PREFIX + "_" + chestGui.key(), JsonUtils.parseJson(TEMPLATE_CHEST_GUI .replace("", chestGui.bedrockTexturePath(javaRootPath).toString()) .replace("", String.valueOf(chestGui.width())) .replace("", String.valueOf(chestGui.height())) - .replace("", String.valueOf(-(chestGui.entry().yPosition()-5))) + .replace("", String.valueOf(offsetY)) + .replace("", String.valueOf(offsetX)) .replace("", "(not ($atext - '" + PREFIX + ":" + chestGui.key() + "' = $atext))"))); } diff --git a/src/main/java/fr/openmc/riftengine/core/utils/ImageUtils.java b/src/main/java/fr/openmc/riftengine/core/utils/ImageUtils.java new file mode 100644 index 0000000..91ba915 --- /dev/null +++ b/src/main/java/fr/openmc/riftengine/core/utils/ImageUtils.java @@ -0,0 +1,111 @@ +package fr.openmc.riftengine.core.utils; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public final class ImageUtils { + public static BufferedImage read(Path path) throws IOException { + return ImageIO.read(path.toFile()); + } + + public static void writePng(BufferedImage image, Path target) throws IOException { + Files.createDirectories(target.getParent()); + ImageIO.write(image, "png", target.toFile()); + } + + public static BufferedImage center(BufferedImage src) { + return center(src, src.getWidth(), src.getHeight()); + } + + public static BufferedImage center(BufferedImage src, int canvasW, int canvasH) { + int minX = src.getWidth(), minY = src.getHeight(), maxX = -1, maxY = -1; + + // * detecte les zones transparentes + for (int y = 0; y < src.getHeight(); y++) { + for (int x = 0; x < src.getWidth(); x++) { + if ((src.getRGB(x, y) >>> 24) != 0) { + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + } + } + } + + if (maxX < 0) return src; + + int contentW = maxX - minX + 1; + int contentH = maxY - minY + 1; + int offsetX = (canvasW - contentW) / 2; + int offsetY = (canvasH - contentH) / 2; + + BufferedImage result = new BufferedImage(canvasW, canvasH, BufferedImage.TYPE_INT_ARGB); + for (int y = 0; y < contentH; y++) { + for (int x = 0; x < contentW; x++) { + result.setRGB(offsetX + x, offsetY + y, src.getRGB(minX + x, minY + y)); + } + } + return result; + } + + /** + * Grossomodo calcule la valeur y ou y'a une zone transparentes + */ + public static int centerShiftY(BufferedImage src) { + int minY = -1; + int maxY = -1; + + for (int y = 0; y < src.getHeight(); y++) { + for (int x = 0; x < src.getWidth(); x++) { + if ((src.getRGB(x, y) >>> 24) != 0) { + if (minY == -1) minY = y; + maxY = y; + break; + } + } + } + + if (minY == -1) return 0; + + int contentH = maxY - minY + 1; + return (src.getHeight() - contentH) / 2 - minY; + } + + public static int findGridLeft(BufferedImage img) { + int w = img.getWidth(), h = img.getHeight(); + + long[] edge = new long[w]; + for (int x = 1; x < w; x++) { + long s = 0; + for (int y = 0; y < h; y++) s += Math.abs(lum(img, x, y) - lum(img, x - 1, y)); + edge[x] = s; + } + + long[] score = new long[w]; + long best = -1; + int bestX = -1; + for (int p = 1; p + 162 < w; p++) { + long s = 0; + for (int k = 0; k <= 9; k++) s += edge[p + k * 18]; + score[p] = s; + if (s > best) { best = s; bestX = p; } + } + if (bestX == -1) return -1; + + long rival = 0; + for (int p = 1; p + 162 < w; p++) { + int d = Math.floorMod(p - bestX, 18); + if (Math.min(d, 18 - d) > 2) rival = Math.max(rival, score[p]); + } + return best >= rival * 1.15 ? bestX : -1; + } + + private static int lum(BufferedImage img, int x, int y) { + int argb = img.getRGB(x, y); + if ((argb >>> 24) == 0) return 0; + return (((argb >> 16) & 255) + ((argb >> 8) & 255) + (argb & 255)) / 3; + } +}