Skip to content

Commit 1350d88

Browse files
backup
1 parent 8bf89b0 commit 1350d88

23 files changed

Lines changed: 5683 additions & 1161 deletions

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Starting with 1.21.11, Mojang ships unobfuscated JARs.
77
## Requirements
88

99
- JDK 21+
10+
- GraalVM 21+ (native builds)
1011

1112
## Setup
1213

@@ -50,6 +51,7 @@ export IDEA_JDK="/usr/lib/jvm/java-21-jetbrains"
5051
│ └── server/ # server patches (mymod.patch)
5152
├── server/src/ # shared/server source
5253
├── client/src/ # client-only source
54+
├── native/ # GraalVM substitutions and configs
5355
└── prism-instance/ # PrismLauncher instance template
5456
```
5557

@@ -133,6 +135,31 @@ prism-instance/
133135
└── custom.mods.json # jarMods component
134136
```
135137

138+
## Native Builds
139+
140+
### Build
141+
142+
```bash
143+
./gradlew nativeServer
144+
./gradlew nativeClient
145+
```
146+
147+
### Run
148+
149+
```bash
150+
./gradlew runNativeServer
151+
./gradlew runNativeClient
152+
```
153+
154+
### Reachability Metadata
155+
156+
Run the game, trigger as many code paths as possible, then quit. Agent merges into `native/configs/`, can be run multiple times.
157+
158+
```bash
159+
./gradlew nativeServerAgent
160+
./gradlew nativeClientAgent
161+
```
162+
136163
## Decompiler
137164

138165
Uses Vineflower with standard flags. Patches fix type inference issues, lambda captures, and other decompiler artifacts.

build.gradle

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ ext {
4141
]
4242

4343
assetsVer = '29'
44+
serverMain = 'net.minecraft.server.Main'
45+
clientMain = 'net.minecraft.client.main.Main'
4446
}
4547

4648
task download {
@@ -143,9 +145,7 @@ task modPackServer {
143145
doLast { Mod.pack(rootDir, 'server') }
144146
}
145147

146-
task setupServer { group = 'setup'; dependsOn snapServer }
147-
task setupClient { group = 'setup'; dependsOn snapClient }
148-
task setup { group = 'setup'; dependsOn setupServer, setupClient }
148+
task setup { group = 'setup'; dependsOn snapServer, snapClient }
149149

150150
task genPatchServer {
151151
group = 'patches'
@@ -169,7 +169,7 @@ configure([project(':server'), project(':client')]) {
169169
from(zipTree("${rootDir}/jars/${project.name}.jar")) { include '**/package-info.class' }
170170

171171
manifest {
172-
def main = project.name == 'server' ? 'net.minecraft.server.Main' : 'net.minecraft.client.main.Main'
172+
def main = project.name == 'server' ? serverMain : clientMain
173173
attributes 'Main-Class': main
174174
}
175175

@@ -192,9 +192,7 @@ configure([project(':server'), project(':client')]) {
192192
rename { "${project.name}-${version}_unobfuscated.jar" }
193193
}
194194
}
195-
}
196195

197-
subprojects {
198196
dependencies {
199197
implementation 'com.mojang:authlib:7.0.61'
200198
implementation 'com.mojang:brigadier:1.3.10'
@@ -219,7 +217,7 @@ task runServer(type: JavaExec) {
219217
group = 'run'
220218
doFirst { mkdir 'run_server' }
221219

222-
mainClass = 'net.minecraft.server.Main'
220+
mainClass = serverMain
223221
classpath = project(':server').sourceSets.main.runtimeClasspath
224222
workingDir = file('run_server')
225223

@@ -231,7 +229,7 @@ task runClient(type: JavaExec) {
231229
dependsOn 'assets'
232230
doFirst { mkdir 'run' }
233231

234-
mainClass = 'net.minecraft.client.main.Main'
232+
mainClass = clientMain
235233
classpath = project(':client').sourceSets.main.runtimeClasspath
236234
workingDir = file('run')
237235

@@ -241,10 +239,89 @@ task runClient(type: JavaExec) {
241239
'--assetIndex', assetsVer, '--gameDir', 'run']
242240
}
243241

242+
task runNativeServer(type: Exec) {
243+
group = 'run'
244+
doFirst { mkdir 'run_server' }
245+
246+
commandLine = Native.runCommand(rootDir, 'server', '--nogui')
247+
workingDir = file('run_server')
248+
}
249+
250+
task runNativeClient(type: Exec) {
251+
group = 'run'
252+
dependsOn 'assets'
253+
doFirst { mkdir 'run' }
254+
255+
commandLine = Native.runCommand(rootDir, 'client',
256+
'--version', version, '--accessToken', '0', '--assetsDir', 'assets',
257+
'--assetIndex', assetsVer, '--gameDir', 'run')
258+
workingDir = file('run')
259+
environment '__GL_THREADED_OPTIMIZATIONS', '0'
260+
}
261+
262+
task nativeServerAgent(type: JavaExec) {
263+
group = 'native'
264+
dependsOn ':server:jar'
265+
doFirst { Native.requireGraalVM(); mkdir 'run_server' }
266+
267+
mainClass = serverMain
268+
classpath = project(':server').sourceSets.main.runtimeClasspath
269+
workingDir = file('run_server')
270+
jvmArgs = [Native.agentArg(rootDir, 'server')]
271+
272+
args = ['--nogui']
273+
}
274+
275+
task nativeClientAgent(type: JavaExec) {
276+
group = 'native'
277+
dependsOn ':client:jar', 'assets'
278+
doFirst { Native.requireGraalVM(); mkdir 'run' }
279+
280+
mainClass = clientMain
281+
classpath = project(':client').sourceSets.main.runtimeClasspath
282+
workingDir = file('run')
283+
jvmArgs = [Native.agentArg(rootDir, 'client')]
284+
environment '__GL_THREADED_OPTIMIZATIONS', '0'
285+
286+
args = ['--version', version, '--accessToken', '0', '--assetsDir', 'assets',
287+
'--assetIndex', assetsVer, '--gameDir', 'run']
288+
}
289+
290+
project(':server').tasks.compileJava.mustRunAfter snapServer
291+
project(':client').tasks.compileJava.mustRunAfter snapClient
292+
293+
task nativeServer(type: Exec) {
294+
group = 'native'
295+
dependsOn snapServer, ':server:jar', ':native:jar'
296+
doFirst {
297+
Native.requireGraalVM(); mkdir 'native/build'
298+
def cp = Native.classpath(
299+
project(':server').tasks.jar.archiveFile.get().asFile,
300+
project(':server').sourceSets.main.runtimeClasspath.asPath,
301+
project(':native').tasks.jar.archiveFile.get().asFile)
302+
commandLine = Native.buildCommand(cp, rootDir, 'server', serverMain)
303+
}
304+
workingDir = file('native/build')
305+
}
306+
307+
task nativeClient(type: Exec) {
308+
group = 'native'
309+
dependsOn snapServer, snapClient, ':client:jar', ':native:jar'
310+
doFirst {
311+
Native.requireGraalVM(); mkdir 'native/build'
312+
def cp = Native.classpath(
313+
project(':client').tasks.jar.archiveFile.get().asFile,
314+
project(':client').sourceSets.main.runtimeClasspath.asPath,
315+
project(':native').tasks.jar.archiveFile.get().asFile)
316+
commandLine = Native.buildCommand(cp, rootDir, 'client', clientMain)
317+
}
318+
workingDir = file('native/build')
319+
}
320+
244321
idea.project.settings {
245322
runConfigurations {
246323
'Minecraft Client'(org.jetbrains.gradle.ext.Application) {
247-
mainClass = 'net.minecraft.client.main.Main'
324+
mainClass = clientMain
248325
moduleName = "${rootProject.name}.client.main"
249326
workingDirectory = "${rootDir}/run"
250327
programParameters = "--version ${version} --accessToken 0 " +
@@ -254,7 +331,7 @@ idea.project.settings {
254331
}
255332

256333
'Minecraft Server'(org.jetbrains.gradle.ext.Application) {
257-
mainClass = 'net.minecraft.server.Main'
334+
mainClass = serverMain
258335
moduleName = "${rootProject.name}.server.main"
259336
workingDirectory = "${rootDir}/run_server"
260337
programParameters = 'nogui'
@@ -267,7 +344,7 @@ jar.enabled = false
267344

268345
clean {
269346
delete 'run', 'run_server', 'decompSrc/client', 'patchSrc'
270-
delete 'client/src', 'server/src', 'client/bin', 'server/bin'
347+
delete 'client/src', 'server/src', 'client/bin', 'server/bin', 'native/build'
271348
delete 'jars', 'libs', 'vineflower.jar'
272349
}
273350

buildSrc/src/main/java/Native.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import java.io.*;
2+
import java.util.*;
3+
4+
public class Native {
5+
6+
public static void requireGraalVM() {
7+
if (!new File(bin()).exists())
8+
throw new RuntimeException("Current JDK is not GraalVM (native-image not found)");
9+
}
10+
11+
public static String agentArg(File root, String side) {
12+
return "-agentlib:native-image-agent=config-merge-dir=" + new File(root, "native/configs/" + side);
13+
}
14+
15+
public static String classpath(File projectJar, String runtimeCp, File nativeJar) {
16+
return projectJar.getAbsolutePath() + File.pathSeparator + runtimeCp +
17+
File.pathSeparator + nativeJar.getAbsolutePath();
18+
}
19+
20+
public static List<String> buildCommand(String cp, File root, String side, String mainClass) {
21+
return new ArrayList<>(Arrays.asList(
22+
bin(), "-cp", cp,
23+
"-H:ConfigurationFileDirectories=" + new File(root, "native/configs/" + side),
24+
"-H:Name=" + side,
25+
"--no-fallback", "--gc=serial", "--enable-http", "--enable-https",
26+
"-H:+AddAllCharsets", "-H:+UnlockExperimentalVMOptions", "-Djava.awt.headless=false",
27+
"-H:IncludeResources=data/.*", "-H:IncludeResources=assets/.*",
28+
"--initialize-at-run-time=net.minecraft.TracingExecutor,sun.net.dns.ResolverConfigurationImpl," +
29+
"io.netty,org.apache.logging.log4j,org.apache.logging.slf4j,org.slf4j,com.mojang.logging",
30+
mainClass
31+
));
32+
}
33+
34+
public static List<String> runCommand(File root, String side, String... args) {
35+
List<String> cmd = new ArrayList<>();
36+
cmd.add(new File(root, "native/build/" + side).getAbsolutePath());
37+
cmd.addAll(Arrays.asList(args));
38+
return cmd;
39+
}
40+
41+
private static String bin() {
42+
return System.getProperty("java.home") + "/bin/native-image";
43+
}
44+
}

logs/2025-12-30-1.log.gz

275 Bytes
Binary file not shown.

logs/2026-03-14-1.log.gz

610 Bytes
Binary file not shown.

logs/latest.log

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
[22:06:46] [main/ERROR]: Failed to start the minecraft server
2-
joptsimple.UnrecognizedOptionException: c is not a recognized option
3-
at joptsimple.OptionException.unrecognizedOption(OptionException.java:108)
4-
at joptsimple.OptionParser.validateOptionCharacters(OptionParser.java:633)
5-
at joptsimple.OptionParser.handleShortOptionCluster(OptionParser.java:528)
6-
at joptsimple.OptionParser.handleShortOptionToken(OptionParser.java:523)
7-
at joptsimple.OptionParserState$2.handleArgument(OptionParserState.java:59)
8-
at joptsimple.OptionParser.parse(OptionParser.java:396)
9-
at net.minecraft.server.Main.main(Main.java:87)
1+
[22:41:44] [main/ERROR]: Failed to load properties from file: server.properties
2+
java.nio.file.NoSuchFileException: server.properties
3+
at java.base@21.0.10/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:261)
4+
at java.base@21.0.10/java.nio.file.Files.newByteChannel(Files.java:379)
5+
at java.base@21.0.10/java.nio.file.Files.newByteChannel(Files.java:431)
6+
at java.base@21.0.10/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420)
7+
at java.base@21.0.10/java.nio.file.Files.newInputStream(Files.java:159)
8+
at net.minecraft.server.dedicated.Settings.loadFromFile(Settings.java:38)
9+
at net.minecraft.server.dedicated.DedicatedServerProperties.fromFile(DedicatedServerProperties.java:156)
10+
at net.minecraft.server.dedicated.DedicatedServerSettings.<init>(DedicatedServerSettings.java:12)
11+
at net.minecraft.server.Main.main(Main.java:107)
12+
at java.base@21.0.10/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)
13+
[22:41:44] [main/WARN]: Failed to load eula.txt
14+
[22:41:44] [main/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.

native/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
repositories {
2+
maven { url 'https://maven.fabricmc.net/' }
3+
}
4+
5+
dependencies {
6+
implementation 'org.graalvm.sdk:nativeimage:24.2.1'
7+
implementation 'net.fabricmc:sponge-mixin:0.15.0+mixin.0.8.7'
8+
}

0 commit comments

Comments
 (0)