fix: NeoForge 21.1.235 API - ModConfigSpec, EventBusSubscriber, ResourceLocation.fromNamespaceAndPath, DynamicTexture

This commit is contained in:
SashegDev
2026-08-24 03:23:12 +03:00
parent 6021a7c60b
commit 2b4cd71f3f
11 changed files with 177 additions and 160 deletions
+37 -26
View File
@@ -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'
])
}
}
+9 -6
View File
@@ -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
+3 -2
View File
@@ -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'
}
@@ -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();
}
}
@@ -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();
}
}
}
}
@@ -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();
}
}
}
@@ -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<Frame> 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++) {
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);
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;
if (frames.isEmpty()) return null;
if (frames.size() > 1) {
long now = System.currentTimeMillis();
int delay = frames.get(frameIdx).delayMs;
int delay = frames.get(frameIdx).delayMs();
if (now - lastFrameMs > delay) {
frameIdx = (frameIdx + 1) % frames.size();
lastFrameMs = now;
texLoc = frames.get(frameIdx).tex.getTextureLocation();
texLoc = frames.get(frameIdx).loc();
}
}
return texLoc;
}
@@ -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();
e.registerAboveAll(ResourceLocation.fromNamespaceAndPath("justasplash", "splash"), (guiGraphics, deltaTracker) -> SplashRenderer.render(guiGraphics));
}
}
@@ -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();
}
}
@@ -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<String> SPLASH_IMAGE;
public static final ConfigValue<String> SPLASH_SOUND;
public static final DoubleValue FADE;
public static final DoubleValue VOLUME;
public static final ModConfigSpec.ConfigValue<String> SPLASH_IMAGE;
public static final ModConfigSpec.ConfigValue<String> 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");
}
}
@@ -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"