Compare commits

...

9 Commits

Author SHA1 Message Date
李昌哲
84fc1d0d24 Merge 0d2c952a54 into 9602736335 2025-08-14 18:42:49 +08:00
Jaffe2718
0d2c952a54 Unify the test mod ID 2025-08-14 18:41:43 +08:00
Jaffe2718
a940a96bc7 better test 2025-08-13 23:23:16 +08:00
Jaffe2718
b7c9d83078 - fix: compatible for the case if the config class of mod updated 2025-08-06 18:48:53 +08:00
Martin Prokoph
9602736335 fix: screen titles not showing 2025-06-17 23:44:21 +02:00
Martin Prokoph
30d213b92c feat: NeoForge 1.21.6 2025-06-17 18:00:22 +02:00
Martin Prokoph
b61b2cdf12 port: update to full 1.21.6 2025-06-17 17:55:20 +02:00
Martin Prokoph
bcde119f23 fix: correctly wrap option text labels 2025-06-17 17:54:53 +02:00
Martin Prokoph
b08e38ae11 port: 1.21.6 (pre1) 2025-05-28 23:28:03 +02:00
20 changed files with 180 additions and 90 deletions

View File

@@ -3,7 +3,7 @@ import groovy.json.JsonOutput
plugins { plugins {
id "architectury-plugin" version "3.4-SNAPSHOT" id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.7-SNAPSHOT" apply false id "dev.architectury.loom" version "1.10.+" apply false
id "me.shedaniel.unified-publishing" version "0.1.+" apply false id "me.shedaniel.unified-publishing" version "0.1.+" apply false
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
} }

View File

@@ -1,3 +1,7 @@
plugins {
id 'java'
}
architectury { architectury {
common(rootProject.enabled_platforms.split(",")) common(rootProject.enabled_platforms.split(","))
} }
@@ -21,3 +25,16 @@ publishing {
// Add repositories to publish to here. // Add repositories to publish to here.
} }
} }
configurations {
testOutput.extendsFrom(testImplementation)
}
tasks.register('testJar', Jar) {
from sourceSets.test.output
archiveClassifier = 'tests'
}
artifacts {
testOutput testJar
}

View File

@@ -45,6 +45,6 @@ public class MidnightConfigOverviewScreen extends Screen {
public void render(DrawContext context, int mouseX, int mouseY, float delta) { public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta); super.render(context, mouseX, mouseY, delta);
this.list.render(context, mouseX, mouseY, delta); this.list.render(context, mouseX, mouseY, delta);
context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFF); context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFFFF);
} }
} }

View File

@@ -4,12 +4,13 @@ import com.google.common.collect.Lists;
import com.google.gson.*; import com.google.gson.stream.*; import com.google.gson.*; import com.google.gson.stream.*;
import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.lib.util.PlatformFunctions;
import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gl.RenderPipelines;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element; import net.minecraft.client.gui.Selectable; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.screen.ConfirmLinkScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ConfirmLinkScreen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tab.GridScreenTab; import net.minecraft.client.gui.tab.Tab; import net.minecraft.client.gui.tab.TabManager; import net.minecraft.client.gui.tab.GridScreenTab; import net.minecraft.client.gui.tab.Tab; import net.minecraft.client.gui.tab.TabManager;
import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.*; import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.*;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.screen.ScreenTexts; import net.minecraft.screen.ScreenTexts;
@@ -131,7 +132,7 @@ public abstract class MidnightConfig {
entries.values().forEach(info -> { entries.values().forEach(info -> {
if (info.field != null && info.entry != null) { if (info.field != null && info.entry != null) {
try { try {
info.value = info.field.get(null); info.value = info.field.get(null) == null ? info.defaultValue : info.field.get(null);
info.tempValue = info.toTemporaryValue(); info.tempValue = info.toTemporaryValue();
info.updateConditions(); info.updateConditions();
} catch (IllegalAccessException ignored) {} } catch (IllegalAccessException ignored) {}
@@ -446,7 +447,7 @@ public abstract class MidnightConfig {
public void render(DrawContext context, int mouseX, int mouseY, float delta) { public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta); super.render(context, mouseX, mouseY, delta);
this.list.render(context, mouseX, mouseY, delta); this.list.render(context, mouseX, mouseY, delta);
if (tabs.size() < 2) context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFF); if (tabs.size() < 2) context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFFFF);
} }
} }
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
@@ -458,7 +459,7 @@ public abstract class MidnightConfig {
@Override @Override
protected void drawHeaderAndFooterSeparators(DrawContext context) { protected void drawHeaderAndFooterSeparators(DrawContext context) {
if (renderHeaderSeparator) super.drawHeaderAndFooterSeparators(context); if (renderHeaderSeparator) super.drawHeaderAndFooterSeparators(context);
else context.drawTexture(RenderLayer::getGuiTextured, this.client.world == null ? Screen.FOOTER_SEPARATOR_TEXTURE : Screen.INWORLD_FOOTER_SEPARATOR_TEXTURE, this.getX(), this.getBottom(), 0, 0, this.getWidth(), 2, 32, 2); else context.drawTexture(RenderPipelines.GUI_TEXTURED, this.client.world == null ? Screen.FOOTER_SEPARATOR_TEXTURE : Screen.INWORLD_FOOTER_SEPARATOR_TEXTURE, this.getX(), this.getBottom(), 0, 0, this.getWidth(), 2, 32, 2);
} }
public void addButton(List<ClickableWidget> buttons, Text text, EntryInfo info) { this.addEntry(new ButtonEntry(buttons, text, info)); } public void addButton(List<ClickableWidget> buttons, Text text, EntryInfo info) { this.addEntry(new ButtonEntry(buttons, text, info)); }
public void clear() { this.clearEntries(); } public void clear() { this.clearEntries(); }
@@ -479,18 +480,16 @@ public abstract class MidnightConfig {
if (text != null && (!text.getString().contains("spacer") || !buttons.isEmpty())) { if (text != null && (!text.getString().contains("spacer") || !buttons.isEmpty())) {
title = new MultilineTextWidget((centered) ? (scaledWidth / 2 - (textRenderer.getWidth(text) / 2)) : 12, 0, Text.of(text), textRenderer); title = new MultilineTextWidget((centered) ? (scaledWidth / 2 - (textRenderer.getWidth(text) / 2)) : 12, 0, Text.of(text), textRenderer);
title.setCentered(centered);
if (info != null) title.setTooltip(info.getTooltip(false)); if (info != null) title.setTooltip(info.getTooltip(false));
title.setMaxWidth(buttons.size() > 1 ? buttons.get(1).getX() - 24 : scaledWidth - 24); title.setMaxWidth(!buttons.isEmpty() ? buttons.get(buttons.size() > 2 ? buttons.size()-1 : 0).getX() - 16 : scaledWidth - 24);
} }
} }
public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
buttons.forEach(b -> { b.setY(y); b.render(context, mouseX, mouseY, tickDelta);}); buttons.forEach(b -> { b.setY(y); b.render(context, mouseX, mouseY, tickDelta);});
if (title != null) { if (title != null) {
title.setY(y+5); title.setY(y+5);
title.renderWidget(context, mouseX, mouseY, tickDelta); title.render(context, mouseX, mouseY, tickDelta);
boolean tooltipVisible = mouseX >= title.getX() && mouseX < title.getWidth() + title.getX() && mouseY >= title.getY() && mouseY < title.getHeight() + title.getY();
if (tooltipVisible && title.getTooltip() != null) context.drawOrderedTooltip(textRenderer, title.getTooltip().getLines(MinecraftClient.getInstance()), mouseX, mouseY);
if (info.entry != null && !this.buttons.isEmpty() && this.buttons.getFirst() instanceof ClickableWidget widget) { if (info.entry != null && !this.buttons.isEmpty() && this.buttons.getFirst() instanceof ClickableWidget widget) {
int idMode = this.info.entry.idMode(); int idMode = this.info.entry.idMode();

View File

@@ -1,14 +0,0 @@
package eu.midnightdust.lib.util;
import java.awt.Color;
public class MidnightColorUtil {
/**
* @param colorStr e.g. "FFFFFF" or "#FFFFFF"
* @return Color as RGB
*/
public static Color hex2Rgb(String colorStr) {
try { return Color.decode("#" + colorStr.replace("#", ""));
} catch (Exception ignored) { return Color.BLACK; }
}
}

View File

@@ -1,4 +1,4 @@
package eu.midnightdust.fabric.example; package eu.midnightdust.test;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;

View File

@@ -1,7 +1,7 @@
package eu.midnightdust.fabric.example.config; package eu.midnightdust.test.config;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import eu.midnightdust.fabric.example.MidnightLibExtras; import eu.midnightdust.test.MidnightLibExtras;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import net.minecraft.text.MutableText; import net.minecraft.text.MutableText;
import net.minecraft.text.Text; import net.minecraft.text.Text;

View File

@@ -11,7 +11,27 @@ architectury {
fabric() fabric()
} }
sourceSets {
test {
compileClasspath += main.compileClasspath
runtimeClasspath += main.runtimeClasspath
java {
srcDirs.add('src/test/java' as File)
}
resources {
srcDirs.add('src/test/resources' as File)
}
}
}
loom { loom {
runs {
testClient {
client()
configName = "Test Minecraft Client"
source sourceSets.test
}
}
} }
configurations { configurations {
@@ -27,10 +47,12 @@ configurations {
dependencies { dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
modCompileOnly ("com.terraformersmc:modmenu:${rootProject.mod_menu_version}") modCompileOnly("com.terraformersmc:modmenu:${rootProject.mod_menu_version}")
common(project(path: ":common", configuration: "namedElements")) { transitive false } common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
testImplementation common(project(path: ':common', configuration: 'testOutput'))
} }
processResources { processResources {
@@ -41,6 +63,14 @@ processResources {
} }
} }
processTestResources {
inputs.property "version", rootProject.version
filesMatching("fabric.mod.json") {
expand "version": rootProject.version
}
}
shadowJar { shadowJar {
exclude "architectury.common.json" exclude "architectury.common.json"
@@ -71,7 +101,7 @@ unifiedPublishing {
releaseType = "$project.release_type" releaseType = "$project.release_type"
changelog = releaseChangelog() changelog = releaseChangelog()
gameVersions = [] gameVersions = []
gameLoaders = ["fabric","quilt"] gameLoaders = ["fabric", "quilt"]
mainPublication remapJar mainPublication remapJar
relations { relations {
depends { depends {

View File

@@ -0,0 +1,12 @@
package eu.midnightdust.test.fabric;
import eu.midnightdust.test.config.MidnightConfigExample;
import eu.midnightdust.lib.config.MidnightConfig;
import net.fabricmc.api.ModInitializer;
public class MLExampleFabric implements ModInitializer {
@Override
public void onInitialize() {
MidnightConfig.init("modid", MidnightConfigExample.class);
}
}

View File

@@ -1,10 +1,10 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"id": "midnightlib-example", "id": "modid",
"version": "${version}", "version": "${version}",
"name": "MidnightLib Example", "name": "MidnightLib Test Mod",
"description": "Wow, you can do so much.", "description": "Example Mod for Team MidnightDust's mods.",
"authors": [ "MidnightDust" ], "authors": [ "MidnightDust" ],
"license": "CC0", "license": "CC0",
@@ -13,7 +13,7 @@
"environment": "*", "environment": "*",
"entrypoints": { "entrypoints": {
"main": [ "main": [
"eu.midnightdust.fabric.example.MLExampleFabric" "eu.midnightdust.test.fabric.MLExampleFabric"
] ]
}, },
"depends": { "depends": {

View File

@@ -1,21 +1,21 @@
org.gradle.jvmargs=-Xmx4096M org.gradle.jvmargs=-Xmx4096M
minecraft_version=1.21.4 minecraft_version=1.21.6
supported_versions=1.21.5 supported_versions=
yarn_mappings=1.21.4+build.1 yarn_mappings=1.21.6+build.1
enabled_platforms=fabric,neoforge enabled_platforms=fabric,neoforge
archives_base_name=midnightlib archives_base_name=midnightlib
mod_version=1.7.3 mod_version=1.7.6-rc.1
maven_group=eu.midnightdust maven_group=eu.midnightdust
release_type=release release_type=release
curseforge_id=488090 curseforge_id=488090
modrinth_id=codAaoxh modrinth_id=codAaoxh
fabric_loader_version=0.16.9 fabric_loader_version=0.16.14
fabric_api_version=0.110.5+1.21.4 fabric_api_version=0.127.0+1.21.6
neoforge_version=21.4.3-beta neoforge_version=21.6.0-beta
yarn_mappings_patch_neoforge_version = 1.21+build.4 yarn_mappings_patch_neoforge_version = 1.21+build.4
mod_menu_version = 9.0.0 mod_menu_version = 9.0.0

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip distributionUrl=https://mirrors.aliyun.com/gradle/distributions/v8.14.3/gradle-8.14.3-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -13,11 +13,44 @@ repositories {
architectury { architectury {
platformSetupLoomIde() platformSetupLoomIde()
neoForge() neoForge {
platformPackage = "neoforge"
}
}
sourceSets {
test {
compileClasspath += main.compileClasspath
runtimeClasspath += main.runtimeClasspath
java {
srcDirs.add('src/test/java' as File)
}
resources {
srcDirs.add('src/test/resources' as File)
}
}
} }
loom { loom {
accessWidenerPath = project(":common").loom.accessWidenerPath accessWidenerPath = project(":common").loom.accessWidenerPath
runs {
testClient {
client()
name = "Test Minecraft Client"
mods {
create('midnightlib') {
sourceSet sourceSets.main
}
create('modid') { // test mod
sourceSet sourceSets.test
}
}
source sourceSets.test
}
}
} }
configurations { configurations {
@@ -44,6 +77,10 @@ dependencies {
common(project(path: ':common', configuration: 'namedElements')) { transitive false } common(project(path: ':common', configuration: 'namedElements')) { transitive false }
shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge') shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge')
// testImplementation common(project(path: ':common', configuration: 'namedElements')) { transitive false }
testImplementation common(project(path: ':common', configuration: 'testOutput')) { transitive false }
testImplementation sourceSets.main.output
} }
processResources { processResources {
@@ -54,6 +91,14 @@ processResources {
} }
} }
processTestResources {
inputs.property 'version', rootProject.version
filesMatching('META-INF/neoforge.mods.toml') {
expand version: rootProject.version
}
}
shadowJar { shadowJar {
configurations = [project.configurations.shadowBundle] configurations = [project.configurations.shadowBundle]
archiveClassifier = 'dev-shadow' archiveClassifier = 'dev-shadow'
@@ -105,4 +150,4 @@ unifiedPublishing {
} }
} }
} }
} }

View File

@@ -0,0 +1,12 @@
package eu.midnightdust.test.neoforge;
import eu.midnightdust.test.config.MidnightConfigExample;
import net.neoforged.fml.common.Mod;
@Mod(MLExampleNeoForge.MODID)
public class MLExampleNeoForge {
public static final String MODID = "modid";
public MLExampleNeoForge() {
MidnightConfigExample.init(MODID, MidnightConfigExample.class);
}
}

View File

@@ -0,0 +1,34 @@
modLoader = "javafml"
loaderVersion = "[2,)"
#issueTrackerURL = ""
license = "MIT License"
[[mods]]
modId = "modid"
version = "${version}"
displayName = "MidnightLib Test Mod"
authors = "TeamMidnightDust, Motschen"
description = '''
Example Mod for Team MidnightDust's mods.
'''
[[dependencies.modid]]
modId = "neoforge"
mandatory = true
versionRange = "[20.5,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.modid]]
modId = "minecraft"
mandatory = true
versionRange = "[1.20.5,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.modid]]
modId = "midnightlib"
mandatory = true
versionRange = "[1.0,)"
ordering = "NONE"
side = "BOTH"

View File

@@ -9,9 +9,7 @@ pluginManagement {
include("common") include("common")
include("fabric") include("fabric")
include("test-fabric")
include("neoforge") include("neoforge")
include("test-neoforge")
//include("quilt") //include("quilt")
rootProject.name = "midnightlib" rootProject.name = "midnightlib"

View File

@@ -1,32 +0,0 @@
plugins {
id 'com.github.johnrengelman.shadow'
id "me.shedaniel.unified-publishing"
}
repositories {
maven { url "https://maven.terraformersmc.com/releases" }
}
architectury {
platformSetupLoomIde()
fabric()
}
loom {
}
configurations {
common
shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files.
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentFabric.extendsFrom common
archivesBaseName = rootProject.archives_base_name + "-fabric"
}
dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
implementation project(path: ":fabric", configuration: "namedElements")
common(project(path: ":common", configuration: "namedElements")) { transitive false }
}

View File

@@ -1,11 +0,0 @@
package eu.midnightdust.fabric.example;
import eu.midnightdust.fabric.example.config.MidnightConfigExample;
import net.fabricmc.api.ModInitializer;
public class MLExampleFabric implements ModInitializer {
@Override
public void onInitialize() {
MidnightConfigExample.init("modid", MidnightConfigExample.class);
}
}