From 8f411b6517fbd31a96b2b630a7515274b8ca1abf Mon Sep 17 00:00:00 2001 From: 3arthqu4ke <56741599+3arthqu4ke@users.noreply.github.com> Date: Sat, 24 Aug 2024 12:01:11 +0200 Subject: [PATCH] Improved documentation --- DEV.md | 48 --------------------------- README.md | 68 ++++++++++++++++++++++++++++++-------- headlessmc-lwjgl/README.md | 2 +- 3 files changed, 56 insertions(+), 62 deletions(-) delete mode 100644 DEV.md diff --git a/DEV.md b/DEV.md deleted file mode 100644 index 8aaace92..00000000 --- a/DEV.md +++ /dev/null @@ -1,48 +0,0 @@ -## Setup - -Just import the [build.gradle](build.gradle) into an IDE of your choice and you should be good to go. - -In order to keep compatibility with older Java and Minecraft versions HeadlessMc uses Java language level 8. It can be -built with any JDK ≥ 8, but language features > 8 can't be used. Starting with JDK 9 the `--release` flag will be -used to cross compile the project to Java 8 bytecode. - -HeadlessMc uses [project lombok](https://github.com/projectlombok/lombok) to eliminate Java boilerplate. - -## Structure - -HeadlessMc is divided into multiple gradle subprojects. - -**headlessmc-api** and **headlessmc-commons**: are used by both the launcher and the runtime and mainly contain the -command system logic. - -**headlessmc-launcher**: is, well, the launcher. It contains all launching logic, instrumentation and depends on -headlessmc-lwjgl and some other libraries. The jars created by building headlessmc-lwjgl and the headlessmc-runtime will -be included as resources in the launcher jar. When launching the game with command/lwjgl support, those jars will be -unpacked and added to the classpath. - -**headlessmc-runtime**: contains the commands which can be used while the game is running. In order to add command -support to a game without modifying classes it will be started using the runtimes' main-class which will then call the -games main-class. - -**headlessmc-lwjgl**: contains the RedirectionApi and a class transformer which can be used by the launchers' -instrumentation, injected as a JavaAgent or as a launchwrapper Tweaker and will transform methods in every `org.lwjgl` -class this way: - -```java -public method(... args) { - return () RedirectionApi.invoke(this, ";method()", .class, args); -} -``` - -The RedirectionApi can return a default value for all datatypes except abstract classes (interfaces will be implemented -using `java.lang.reflect.Proxy`), but we can also redirect a call manually like this: - -```java -RedirectionApi.getRedirectionManager().redirect(";method()", ); -``` - -**buildSrc**: A gradle plugin allowing us to generate Java 9+ module-info classes. For an example take a look at the -headlessmc-lwjgl [build.gradle](headlessmc-lwjgl/build.gradle), there we open all packages in order to allow the -transformed lwjgl classes to access the RedirectionApi (to do that we also need to transform lwjgls' module-info to open -the headlessmc.lwjgl module). I tried around with other gradle plugins which allow you to cross compile to Java 8 while -generating module-info classes but all caused problems in one way or the other. \ No newline at end of file diff --git a/README.md b/README.md index 93b521d7..3553d9ad 100644 --- a/README.md +++ b/README.md @@ -52,28 +52,47 @@ with the `forge`, `fabric`, and `neoforge` commands, e.g. `fabric 1.21`. 10. If you are ready to launch the game execute `launch `. If you want to start the game in headless mode add the `-lwjgl` flag. +### HeadlessMc-Specifics + The [hmc-specifics](https://github.com/3arthqu4ke/hmc-specifics) are mods that you can place inside your .minecraft/mods folder. -With HeadlessMc they allow you to control the game via the command line, e.g. +Together with HeadlessMc they allow you to control the game via the command line, e.g. by sending chat messages and commands with `msg ""`, visualizing the menus displayed by Minecraft via `gui` and clicking through menus via `click`. -Arguments passed to commands have to be separated using spaces. If you want to pass an Argument which contains spaces -you need to escape it using quotation marks, like this: -`"argument with spaces"`. -Quotation marks and backslashes can be escaped by using a backslash. -So `msg "A text with spaces"` will send the chat message `A text with spaces`, -while `msg "\"A text with spaces\"" additional space` -will send the chat message `"A text with spaces"` and the argument `additional space` will be dropped. +### Docker -HeadlessMc also has a preconfigured [docker image](https://hub.docker.com/r/3arthqu4ke/headlessmc/), +A preconfigured [docker image](https://hub.docker.com/r/3arthqu4ke/headlessmc/) exists, which comes with Java 8, 17 and 21 installed. -Pull it via `docker pull 3arthqu4ke/headlessmc` -and run it with `docker run -i -t -p 3arthqu4ke/headlessmc`. +Pull it via `docker pull 3arthqu4ke/headlessmc:latest` +and run it with `docker run -it 3arthqu4ke/headlessmc:latest`. Inside the container you can use the `hmc` command anywhere. +### Android + +HeadlessMc can run inside Termux. +* Download Termux from F-Droid, NOT from the PlayStore. +* Install Java: `apt update && apt upgrade $ apt install openjdk-` +* Download the headlessmc-launcher-wrapper.jar into Termux. +* Disable JLine, as we could not get it to work on Termux for now, + by adding `hmc.jline.enabled=false` to the HeadlessMC/config.properties. +* Now you can use HeadlessMc like you do on Desktop or Docker. + +### Web + +HeadlessMc can run inside the browser, kinda. +First, there is CheerpJ, a WebAssembly JVM, +but it does not support all features we need to launch the game. +The CheerpJ instance can be tried out [here](https://3arthqu4ke.github.io/headlessmc/). +Secondly, there is [container2wasm](https://github.com/headlesshq/hmc-container2wasm), +which can translate the HeadlessMc Docker container +to WebAssembly and the run it inside the browser, but this is extremly slow. + +### Optimizations + HeadlessMc achieves headless mode by patching the LWJGL library: -every of its functions is rewritten to do nothing, or to return stub values. +every of its functions is rewritten to do nothing, or to return stub values +(you can read more about this [here](headlessmc-lwjgl/README.md)). This has the advantage of being independent of Minecraft versions, but comes with some overhead. A Minecraft version dependent approach are the [hmc-optimizations](https://github.com/3arthqu4ke/hmc-optimizations), @@ -81,6 +100,8 @@ another set of mods which patch Minecraft itself to skip all rendering code. You can also achieve headless mode without patching lwjgl by running headlessmc with a virtual framebuffer like [Xvfb](https://www.x.org/releases/X11R7.6/doc/man/man1/Xvfb.1.xhtml). +### Configuring HeadlessMc + HeadlessMc can be configured using properties. These can be passed as SystemProperties from the command line or via the `HeadlessMc/config.properties` file. Additional configs can be added to the `HeadlessMc/configs` folder. For available information see the [HmcProperties](headlessmc-commons/src/main/java/me/earth/headlessmc/config/HmcProperties.java), the @@ -88,7 +109,17 @@ information see the [HmcProperties](headlessmc-commons/src/main/java/me/earth/he [RuntimeProperties](headlessmc-runtime/src/main/java/me/earth/headlessmc/runtime/RuntimeProperties.java) or the [LwjglProperties](headlessmc-lwjgl/src/main/java/me/earth/headlessmc/lwjgl/LwjglProperties.java). -## Building from Source +### A Note on command arguments + +Arguments passed to commands have to be separated using spaces. If you want to pass an Argument which contains spaces +you need to escape it using quotation marks, like this: +`"argument with spaces"`. +Quotation marks and backslashes can be escaped by using a backslash. +So `msg "A text with spaces"` will send the chat message `A text with spaces`, +while `msg "\"A text with spaces\"" additional space` +will send the chat message `"A text with spaces"` and the argument `additional space` will be dropped. + +## Building, Developing and Contributing Simply run `./gradlew build` or import the [build.gradle](build.gradle) into an IDE of your choice, and you should be good to go. @@ -99,6 +130,17 @@ built with any JDK ≥ 8, but language features > 8 can't be used. HeadlessMc uses [project lombok](https://github.com/projectlombok/lombok) to eliminate Java boilerplate. +The (sparse) javadoc can be found [here](https://3arthqu4ke.github.io/headlessmc/javadoc/). + +Contributions are welcome! + +### Plugins + +You can also write Plugins for HeadlessMc. +Plugins can run through the `headlessmc-launcher-wrapper`, +which launches the `headlessmc-launcher` on another classloader. +You can find a small example [here](headlessmc-launcher-wrapper/src/testPlugin). + ## License and Libraries Some cool libraries we use: diff --git a/headlessmc-lwjgl/README.md b/headlessmc-lwjgl/README.md index ac2fa0b5..602b89f4 100644 --- a/headlessmc-lwjgl/README.md +++ b/headlessmc-lwjgl/README.md @@ -1,4 +1,4 @@ -# HeadlessMc-Lwjgl +# HeadlessMc-LWJGL This module is responsible for instrumenting the LWJGL library and thus making the Minecraft client "headless".