From 2b4cd71f3fb4d2ed75289c10f325d11460ada19d Mon Sep 17 00:00:00 2001 From: SashegDev Date: Mon, 24 Aug 2026 03:23:12 +0300 Subject: [PATCH] fix: NeoForge 21.1.235 API - ModConfigSpec, EventBusSubscriber, ResourceLocation.fromNamespaceAndPath, DynamicTexture --- build.gradle | 63 +++++++------ gradle.properties | 15 ++-- settings.gradle | 5 +- .../me/sashegdev/justasplash/JustASplash.java | 8 -- .../sashegdev/justasplash/client/Hotkey.java | 32 ++----- .../justasplash/client/HotkeyTick.java | 16 ++++ .../justasplash/client/ImageLoader.java | 90 +++++++++++-------- .../justasplash/client/SplashOverlay.java | 45 ++-------- .../justasplash/client/SplashRenderer.java | 33 +++++++ .../justasplash/config/JustASplashConfig.java | 20 ++--- .../resources/META-INF/neoforge.mods.toml | 10 +-- 11 files changed, 177 insertions(+), 160 deletions(-) create mode 100644 src/main/java/me/sashegdev/justasplash/client/HotkeyTick.java create mode 100644 src/main/java/me/sashegdev/justasplash/client/SplashRenderer.java diff --git a/build.gradle b/build.gradle index 226545e..741e9b7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,41 +1,53 @@ plugins { - id 'eclipse' - id 'idea' - id 'maven-publish' - id 'net.neoforged.gradle.userdev' version '7.0.163' + id 'java-library' + id 'net.neoforged.gradle.userdev' version '7.1.38' } -version = findProperty('mod_version') ?: '1.0.0' -group = findProperty('group') ?: 'me.sashegdev.justasplash' -archivesBaseName = findProperty('archives_base_name') ?: 'justasplash' +version = mod_version +group = mod_group_id + +base { + archivesName = mod_id +} java.toolchain.languageVersion = JavaLanguageVersion.of(21) -println "Java: ${java.toolchain.languageVersion.get()} - NeoForge ${findProperty('neo_version')}" - -minecraft { - mappings channel: findProperty('mappings_channel') ?: 'official', version: findProperty('mappings_version') ?: '1.21.1' - copyIdeResources = true -} repositories { mavenCentral() } -dependencies { - implementation "net.neoforged:neoforge:${findProperty('neo_version')}" - implementation "javazoom:jlayer:1.0.1" - implementation "com.googlecode.soundlibs:mp3spi:1.9.5.4" - implementation "com.googlecode.soundlibs:tritonus-share:0.3.7.4" - implementation "com.googlecode.soundlibs:jorbis:0.0.17.4" +runs { + configureEach { + systemProperty 'forge.logging.markers', 'REGISTRIES' + systemProperty 'forge.logging.console.level', 'debug' + workingDirectory project.layout.projectDirectory.dir('run').dir(name) + modSource project.sourceSets.main + } + client { + systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id + } } -tasks.named('processResources', DuplicatesStrategy.INCLUDE).configure { +configurations { + runtimeClasspath.extendsFrom localRuntime +} + +dependencies { + implementation "net.neoforged:neoforge:${neo_version}" + implementation "javazoom:jlayer:1.0.1" + localRuntime "com.googlecode.soundlibs:mp3spi:1.9.5.4" + localRuntime "com.googlecode.soundlibs:tritonus-share:0.3.7.4" + localRuntime "com.googlecode.soundlibs:jorbis:0.0.17.4" +} + +tasks.named('processResources', Copy).configure { var replaceProperties = [ - minecraft_version: findProperty('minecraft_version'), neo_version: findProperty('neo_version'), - loader_version: findProperty('loader_version'), mod_version: findProperty('mod_version') + minecraft_version : minecraft_version, minecraft_version_range: minecraft_version_range, + neo_version : neo_version, loader_version_range: loader_version_range, + mod_version : mod_version ] inputs.properties(replaceProperties) - filesMatching(['META-INF/neoforge.mods.toml', 'pack.mcmeta']) { + filesMatching(['META-INF/neoforge.mods.toml']) { expand(replaceProperties) } } @@ -47,9 +59,8 @@ jar { 'Specification-Vendor' : 'SashegDev', 'Specification-Version' : '1', 'Implementation-Title' : project.name, - 'Implementation-Version' : project.jar.archiveVersion, - 'Implementation-Vendor' : 'SashegDev', - 'Implementation-Timestamp': new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + 'Implementation-Version' : project.version, + 'Implementation-Vendor' : 'SashegDev' ]) } } diff --git a/gradle.properties b/gradle.properties index e356c45..c1c1839 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,10 +1,13 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false + minecraft_version=1.21.1 -neo_version=21.1.133 -loader_version=4.0.24 -mappings_channel=official -mappings_version=1.21.1 +minecraft_version_range=[1.21.1] +neo_version=21.1.235 +loader_version_range=[1,) + +mod_id=justasplash +mod_name=Just A Splash +mod_license=MIT mod_version=1.0.0 -group=me.sashegdev.justasplash -archives_base_name=justasplash +mod_group_id=me.sashegdev.justasplash diff --git a/settings.gradle b/settings.gradle index 98555b6..3a3e5b9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,9 +1,10 @@ pluginManagement { repositories { gradlePluginPortal() - maven { url = "https://maven.neoforged.net/releases" } + maven { url = 'https://maven.neoforged.net/releases' } } } + plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.8.0' + id 'org.gradle.toolchains.foojay-resolver-convention' version '1.0.0' } diff --git a/src/main/java/me/sashegdev/justasplash/JustASplash.java b/src/main/java/me/sashegdev/justasplash/JustASplash.java index 2794d58..84f081c 100644 --- a/src/main/java/me/sashegdev/justasplash/JustASplash.java +++ b/src/main/java/me/sashegdev/justasplash/JustASplash.java @@ -1,23 +1,15 @@ package me.sashegdev.justasplash; -import me.sashegdev.justasplash.client.Hotkey; -import me.sashegdev.justasplash.client.SplashManager; -import me.sashegdev.justasplash.client.SplashOverlay; import me.sashegdev.justasplash.config.JustASplashConfig; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.config.ModConfig; -import net.neoforged.neoforge.client.gui.IConfigScreenFactory; @Mod(value = "justasplash", dist = Dist.CLIENT) public class JustASplash { public JustASplash(IEventBus modBus, ModContainer container) { container.registerConfig(ModConfig.Type.CLIENT, JustASplashConfig.SPEC); - container.registerExtensionPoint(IConfigScreenFactory.class, (c, s) -> JustASplashConfig.createScreen(s)); - Hotkey.register(modBus); - SplashOverlay.register(); - SplashManager.init(); } } diff --git a/src/main/java/me/sashegdev/justasplash/client/Hotkey.java b/src/main/java/me/sashegdev/justasplash/client/Hotkey.java index 9b64c67..388e259 100644 --- a/src/main/java/me/sashegdev/justasplash/client/Hotkey.java +++ b/src/main/java/me/sashegdev/justasplash/client/Hotkey.java @@ -1,34 +1,20 @@ package me.sashegdev.justasplash.client; -import com.mojang.blaze3d.platform.InputConstants; -import net.minecraft.client.KeyMapping; import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.IEventBus; import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; -import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; -import org.lwjgl.glfw.GLFW; -@Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) +@EventBusSubscriber(value = Dist.CLIENT, modid = "justasplash", bus = EventBusSubscriber.Bus.MOD) public class Hotkey { - public static KeyMapping SPLASH = new KeyMapping("key.justasplash.splash", GLFW.GLFW_KEY_Z, "key.categories.justasplash"); + public static final net.minecraft.client.KeyMapping SPLASH = new net.minecraft.client.KeyMapping( + "key.justasplash.splash", + com.mojang.blaze3d.platform.InputConstants.Type.KEYSYM, + org.lwjgl.glfw.GLFW.GLFW_KEY_Z, + "key.categories.justasplash"); - public static void register(IEventBus bus) { - bus.addListener(Hotkey::onRegister); - } - - private static void onRegister(RegisterKeyMappingsEvent e) { + @SubscribeEvent + public static void onRegister(RegisterKeyMappingsEvent e) { e.register(SPLASH); } - - @Mod.EventBusSubscriber(Dist.CLIENT) - public static class Tick { - @SubscribeEvent - public static void onTick(ClientTickEvent.Post e) { - while (SPLASH.consumeClick()) { - SplashManager.trigger(); - } - } - } } diff --git a/src/main/java/me/sashegdev/justasplash/client/HotkeyTick.java b/src/main/java/me/sashegdev/justasplash/client/HotkeyTick.java new file mode 100644 index 0000000..bbee1ff --- /dev/null +++ b/src/main/java/me/sashegdev/justasplash/client/HotkeyTick.java @@ -0,0 +1,16 @@ +package me.sashegdev.justasplash.client; + +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.ClientTickEvent; + +@EventBusSubscriber(value = Dist.CLIENT, modid = "justasplash") +public class HotkeyTick { + @SubscribeEvent + public static void onTick(ClientTickEvent.Post e) { + while (Hotkey.SPLASH.consumeClick()) { + SplashManager.trigger(); + } + } +} diff --git a/src/main/java/me/sashegdev/justasplash/client/ImageLoader.java b/src/main/java/me/sashegdev/justasplash/client/ImageLoader.java index 9b6502a..34bf984 100644 --- a/src/main/java/me/sashegdev/justasplash/client/ImageLoader.java +++ b/src/main/java/me/sashegdev/justasplash/client/ImageLoader.java @@ -4,16 +4,14 @@ import com.mojang.blaze3d.platform.NativeImage; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.resources.ResourceLocation; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.api.distmarker.OnlyIn; import javax.imageio.ImageIO; import javax.imageio.ImageReader; +import javax.imageio.metadata.IIOMetadataNode; import java.io.InputStream; import java.util.ArrayList; import java.util.List; -@OnlyIn(Dist.CLIENT) public class ImageLoader { private static ResourceLocation texLoc; private static int w, h; @@ -21,12 +19,11 @@ public class ImageLoader { private static int frameIdx = 0; private static long lastFrameMs = 0; - record Frame(DynamicTexture tex, int delayMs) {} + record Frame(ResourceLocation loc, int delayMs) {} public static void load(ResourceLocation loc) { try { - var mc = Minecraft.getInstance(); - var rm = mc.getResourceManager(); + var rm = Minecraft.getInstance().getResourceManager(); var res = rm.getResource(loc).orElse(null); if (res == null) return; try (InputStream in = res.open()) { @@ -42,10 +39,9 @@ public class ImageLoader { NativeImage img = NativeImage.read(in); w = img.getWidth(); h = img.getHeight(); - DynamicTexture tex = new DynamicTexture(img); - texLoc = new ResourceLocation("justasplash", "splash_" + System.nanoTime()); - Minecraft.getInstance().getTextureManager().register(texLoc, tex); - frames = List.of(new Frame(tex, 0)); + register(img, 0); + frameIdx = 0; + lastFrameMs = 0; } private static void loadGif(InputStream in) throws Exception { @@ -55,50 +51,68 @@ public class ImageLoader { List list = new ArrayList<>(); for (int i = 0; i < n; i++) { var bi = r.read(i); - int delay = 100; - try { - var meta = r.getImageMetadata(i); - var tree = meta.getAsTree("javax_imageio_gif_image_1.0"); - var gce = tree.getChildNodes(); - for (int j = 0; j < gce.getLength(); j++) { - var node = gce.item(j); - if ("GraphicControlExtension".equals(node.getNodeName())) { - delay = Integer.parseInt(node.getAttributes().getNamedItem("delayTime").getNodeValue()) * 10; - } - } - } catch (Exception ignored) {} - NativeImage img = toNativeImage(bi); + int delay = readGifDelay(r, i); + var img = toNativeImage(bi); w = img.getWidth(); h = img.getHeight(); - DynamicTexture tex = new DynamicTexture(img); - ResourceLocation loc = new ResourceLocation("justasplash", "splash_gif_" + i + "_" + System.nanoTime()); - Minecraft.getInstance().getTextureManager().register(loc, tex); - list.add(new Frame(tex, delay == 0 ? 100 : delay)); + list.add(new Frame(registerImg(img), delay <= 0 ? 100 : delay)); } if (!list.isEmpty()) { frames = list; - texLoc = frames.get(0).tex.getTextureLocation(); + texLoc = list.get(0).loc(); + frameIdx = 0; + lastFrameMs = 0; } } + private static int readGifDelay(ImageReader r, int idx) { + try { + IIOMetadataNode tree = (IIOMetadataNode) r.getImageMetadata(idx).getAsTree("javax_imageio_gif_image_1.0"); + var nodes = tree.getElementsByTagName("GraphicControlExtension"); + for (int j = 0; j < nodes.getLength(); j++) { + return Integer.parseInt(nodes.item(j).getAttributes().getNamedItem("delayTime").getNodeValue()) * 10; + } + } catch (Exception ignored) {} + return 100; + } + + private static ResourceLocation registerImg(NativeImage img) { + ResourceLocation loc = ResourceLocation.fromNamespaceAndPath("justasplash", "dynamic/splash_" + System.nanoTime()); + Minecraft.getInstance().getTextureManager().register(loc, new DynamicTexture(img)); + return loc; + } + + private static void register(NativeImage img, int idx) { + texLoc = registerImg(img); + frames = List.of(new Frame(texLoc, 0)); + } + private static NativeImage toNativeImage(java.awt.image.BufferedImage bi) { int wi = bi.getWidth(), hi = bi.getHeight(); NativeImage img = new NativeImage(wi, hi, false); - for (int y = 0; y < hi; y++) for (int x = 0; x < wi; x++) { - int argb = bi.getRGB(x, y); - img.setPixelRGBA(x, y, argb); + for (int y = 0; y < hi; y++) { + for (int x = 0; x < wi; x++) { + int argb = bi.getRGB(x, y); + int a = (argb >>> 24) & 0xFF; + int r = (argb >> 16) & 0xFF; + int g = (argb >> 8) & 0xFF; + int b = argb & 0xFF; + img.setPixelRGBA(x, y, (a << 24) | (b << 16) | (g << 8) | r); + } } return img; } public static ResourceLocation getTexture() { - if (frames.size() <= 1) return texLoc; - long now = System.currentTimeMillis(); - int delay = frames.get(frameIdx).delayMs; - if (now - lastFrameMs > delay) { - frameIdx = (frameIdx + 1) % frames.size(); - lastFrameMs = now; - texLoc = frames.get(frameIdx).tex.getTextureLocation(); + if (frames.isEmpty()) return null; + if (frames.size() > 1) { + long now = System.currentTimeMillis(); + int delay = frames.get(frameIdx).delayMs(); + if (now - lastFrameMs > delay) { + frameIdx = (frameIdx + 1) % frames.size(); + lastFrameMs = now; + texLoc = frames.get(frameIdx).loc(); + } } return texLoc; } diff --git a/src/main/java/me/sashegdev/justasplash/client/SplashOverlay.java b/src/main/java/me/sashegdev/justasplash/client/SplashOverlay.java index 8dad914..09f6d24 100644 --- a/src/main/java/me/sashegdev/justasplash/client/SplashOverlay.java +++ b/src/main/java/me/sashegdev/justasplash/client/SplashOverlay.java @@ -1,48 +1,15 @@ package me.sashegdev.justasplash.client; -import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.DeltaTracker; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.LayeredDraw; +import net.minecraft.resources.ResourceLocation; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.Mod; +import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.neoforge.client.event.RegisterGuiLayersEvent; +@EventBusSubscriber(value = Dist.CLIENT, modid = "justasplash", bus = EventBusSubscriber.Bus.MOD) public class SplashOverlay { - public static void register() { - } - - @Mod.EventBusSubscriber(value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD) - public static class Reg { - @SubscribeEvent - public static void onLayers(RegisterGuiLayersEvent e) { - e.registerAboveAll(new net.minecraft.resources.ResourceLocation("justasplash", "splash"), SplashOverlay::render); - } - } - - private static void render(GuiGraphics g, DeltaTracker d) { - if (!SplashManager.isShowing()) return; - var mc = Minecraft.getInstance(); - int w = mc.getWindow().getGuiScaledWidth(); - int h = mc.getWindow().getGuiScaledHeight(); - float a = SplashManager.getFadeAlpha(); - if (a <= 0.01f) return; - RenderSystem.enableBlend(); - RenderSystem.setShaderColor(1, 1, 1, a); - var tex = ImageLoader.getTexture(); - if (tex != null) { - int iw = ImageLoader.getWidth(); - int ih = ImageLoader.getHeight(); - float scale = Math.min((float) w / iw, (float) h / ih); - int dw = (int) (iw * scale); - int dh = (int) (ih * scale); - int x = (w - dw) / 2; - int y = (h - dh) / 2; - g.blit(tex, x, y, 0, 0, dw, dh, dw, dh); - } - RenderSystem.setShaderColor(1, 1, 1, 1); - RenderSystem.disableBlend(); + @SubscribeEvent + public static void onLayers(RegisterGuiLayersEvent e) { + e.registerAboveAll(ResourceLocation.fromNamespaceAndPath("justasplash", "splash"), (guiGraphics, deltaTracker) -> SplashRenderer.render(guiGraphics)); } } diff --git a/src/main/java/me/sashegdev/justasplash/client/SplashRenderer.java b/src/main/java/me/sashegdev/justasplash/client/SplashRenderer.java new file mode 100644 index 0000000..3d78a79 --- /dev/null +++ b/src/main/java/me/sashegdev/justasplash/client/SplashRenderer.java @@ -0,0 +1,33 @@ +package me.sashegdev.justasplash.client; + +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.DeltaTracker; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.resources.ResourceLocation; + +public class SplashRenderer { + public static void render(GuiGraphics g) { + if (!SplashManager.isShowing()) return; + var mc = Minecraft.getInstance(); + int w = mc.getWindow().getGuiScaledWidth(); + int h = mc.getWindow().getGuiScaledHeight(); + float a = SplashManager.getFadeAlpha(); + if (a <= 0.01f) return; + RenderSystem.enableBlend(); + RenderSystem.setShaderColor(1f, 1f, 1f, a); + ResourceLocation tex = ImageLoader.getTexture(); + if (tex != null && ImageLoader.getWidth() > 0) { + int iw = ImageLoader.getWidth(); + int ih = ImageLoader.getHeight(); + float scale = Math.max((float) w / iw, (float) h / ih); + int dw = (int) (iw * scale); + int dh = (int) (ih * scale); + int x = (w - dw) / 2; + int y = (h - dh) / 2; + g.blit(tex, x, y, 0, 0, dw, dh, dw, dh); + } + RenderSystem.setShaderColor(1f, 1f, 1f, 1f); + RenderSystem.disableBlend(); + } +} diff --git a/src/main/java/me/sashegdev/justasplash/config/JustASplashConfig.java b/src/main/java/me/sashegdev/justasplash/config/JustASplashConfig.java index d89512f..7def013 100644 --- a/src/main/java/me/sashegdev/justasplash/config/JustASplashConfig.java +++ b/src/main/java/me/sashegdev/justasplash/config/JustASplashConfig.java @@ -1,20 +1,18 @@ package me.sashegdev.justasplash.config; -import net.minecraft.client.gui.screens.Screen; -import net.neoforged.common.ModConfigSpec; -import net.neoforged.neoforge.common.ModConfigSpec.*; +import net.neoforged.neoforge.common.ModConfigSpec; public class JustASplashConfig { public static final ModConfigSpec SPEC; - public static final ConfigValue SPLASH_IMAGE; - public static final ConfigValue SPLASH_SOUND; - public static final DoubleValue FADE; - public static final DoubleValue VOLUME; + public static final ModConfigSpec.ConfigValue SPLASH_IMAGE; + public static final ModConfigSpec.ConfigValue SPLASH_SOUND; + public static final ModConfigSpec.DoubleValue FADE; + public static final ModConfigSpec.DoubleValue VOLUME; static { - Builder b = new Builder(); + ModConfigSpec.Builder b = new ModConfigSpec.Builder(); b.push("splash"); - SPLASH_IMAGE = b.comment("ResourceLocation png|gif in assets/justasplash/ or config/justasplash/ - e.g. justasplash:textures/gui/splashes/splash.png") + SPLASH_IMAGE = b.comment("ResourceLocation png|gif in assets/justasplash/ - e.g. justasplash:textures/gui/splashes/splash.png") .define("splashImage", "justasplash:textures/gui/splashes/splash.png"); SPLASH_SOUND = b.comment("ResourceLocation ogg|mp3 - e.g. justasplash:sounds/splash.ogg, empty to disable") .define("splashSound", "justasplash:sounds/splash.ogg"); @@ -25,8 +23,4 @@ public class JustASplashConfig { b.pop(); SPEC = b.build(); } - - public static Screen createScreen(Screen parent) { - return new net.neoforged.neoforge.client.gui.ConfigurationScreen(parent, SPEC, "justasplash"); - } } diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index dfed8d3..54b81ad 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -1,25 +1,25 @@ modLoader="javafml" -loaderVersion="[4,)" +loaderVersion="${loader_version_range}" license="MIT" issueTrackerURL="https://git.swe.zern.cc/sasheg/justasplash-neo/issues" [[mods]] modId="justasplash" version="${mod_version}" displayName="Just A Splash" -updateJSONURL="https://git.swe.zern.cc/sasheg/justasplash-neo" displayURL="https://git.swe.zern.cc/sasheg/justasplash-neo" -logoFile="justasplash.png" authors="SashegDev" description="Hotkey Z -> fullscreen png/gif + ogg/mp3 splash, 100% -> 0% fade, client only. Fully configurable." + [[dependencies.justasplash]] modId="neoforge" type="required" - versionRange="[21.1.133,21.2)" + versionRange="[21.1.0,)" ordering="NONE" side="CLIENT" + [[dependencies.justasplash]] modId="minecraft" type="required" - versionRange="[1.21.1,1.22)" + versionRange="${minecraft_version_range}" ordering="NONE" side="CLIENT"