• Stars
    star
    159
  • Rank 235,865 (Top 5 %)
  • Language
    Java
  • License
    GNU Lesser Genera...
  • Created almost 2 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A mod to run Minecraft 1.7.10 using LWJGL3 and Java 17+

LWJGL3ify

Brings LWJGL3 and modern Java versions to Minecraft 1.7.10.

Usage

Lwjgl3ify depends on Unimixins (https://github.com/LegacyModdingMC/UniMixins/), use at least version 0.1.7 with the GTNHMixins module. Hodgepodge (https://github.com/GTNewHorizons/Hodgepodge) is strongly recommended, it has many Java 17+ compatibility patches for ARR mods (Biomes'o'Plenty, Witchery, JourneyMap, and more) which we could not directly fix in the GTNH forks.

Client

Non-GTNH 1.7.10 instance setup

If you are using a GregTech New Horizons pre-packaged Java 17+ instance, skip to the next section!

To install in PrismLauncher or MultiMC:

Copy the contents of lwjgl3ify-VERSION-multimc.zip to instances/My Modpack/. mmc-pack.json needs to be overwritten. Reload the launcher, and it should show up modified versions of Forge, Minecraft and LWJGL3 in the instance window. Put the mod jar (lwjgl3ify-VERSION.jar) in mods/ in your instance's minecraft folder, it will get loaded as a coremod. The forgePatches jar will get automatically downloaded by the launcher.

Change the instance java version to 17.0.6, 19.0.2, 20 or 21 (or newer), these are the currently supported versions. You can also use Java 11 if you remove the -Djava.security.manager=allow argument from patches/me.eigenraven.lwjgl3ify.forgepatches.json.

MultiMC setup (GTNH and non-GTNH)

For MultiMC, you need to manually put in extra java arguments, prismlauncher can load them from the patches json files automatically:

--illegal-access=warn -Djava.security.manager=allow -Dfile.encoding=UTF-8 --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED --add-opens jdk.naming.dns/com.sun.jndi.dns=ALL-UNNAMED,java.naming --add-opens java.desktop/sun.awt.image=ALL-UNNAMED --add-modules jdk.dynalink --add-opens jdk.dynalink/jdk.dynalink.beans=ALL-UNNAMED --add-modules java.sql.rowset --add-opens java.sql.rowset/javax.sql.rowset.serial=ALL-UNNAMED

Tweaking configs

If you want to tweak your default window size, OpenGL context properties or other more advanced settings, check out the config file in config/lwjgl3ify.cfg after the first startup.

Server

First, install a working 1.7.10 Forge server, from a modpack zip or using forge's installer. Then, install the mod jar (and unimixins, hodgepodge and gtnhlib as needed) in mods/, and download the forgePatches jar. Put the forgePatches jar in the same folder as your forge-universal and minecraft server jars. Thermos/Crucible/Hybrid servers are not supported!. Lwjgl3ify also depends on Unimixins (https://github.com/LegacyModdingMC/UniMixins/), use at least version 0.1.7. Rename the forgePatches jar to just lwjgl3ify-forgePatches.jar. Create a file named java9args.txt with the contents of the file in this repository. You can now launch the server with a command like the following, assuming the first java executable on your PATH is java 11/17/19:

java -Xmx6G -Xms6G @java9args.txt nogui

How does it work?

There are a few components to enabling modern java and lwjgl usage on old minecraft versions, lwjgl3ify implements these for 1.7.10 specifically:

  • A modified launcher profile (templates are in prism-libraries) to modify the library list loaded into the java classpath - to install LWJGL3, ASM 9.4, new Apache Commons and our forgePatches jar.
  • A custom server launcher jar with the modified Class-Path META-INF manifest entry (integrated into our forgePatches jar)
  • An updated launchwrapper with a java 9+-compatible classpath discovery mechanism at https://github.com/GTNewHorizons/LegacyLauncher. This might be replaced in the future with a java instrumentation agent to transform those classes at runtime instead due to unclear licensing.
  • A lot of add-opens flags for the JVM to allow reflection into JVM internals. Unfortunately a lot of libraries and mods depend on this to work, even weird ones like java.text or nio internals in case of Netty.
  • A partially auto-generated compatibility shim redirecting lwjgl2 api calls into the matching lwjgl3 calls (in src/main/java/org/lwjglx, src/generated/java/org/lwjglx), the generator is in src/util/java
  • Dummy org/lwjgl/* classes matching the classes removed from lwjgl3 (e.g. Display) for mods that rely on finding them under that location in the classpath - e.g. for mixin metadata
  • Replacement GL vendor information provider for crash reports, the old one caused JVM crashes if it was used from a thread without a valid OpenGL context
  • Asm transformers:
    • Asm transformer renaming any access to org/lwjgl to org/lwjglx after all other transformations have been done to the class - in LwjglRedirectTransformer.java
    • javax/xml/bind -> jakarta/xml/bind/ asm transformer and a shaded version of jakarta.xml.bind, because that API was removed from JRE 11
    • Extensible enum transformer (copied under the lgpl license from Forge for minecraft 1.19.3) to replace a lot of the EnumHelper usages
    • Object holders unfinalizer, to remove the need for overwriting static final fields in Forge.
    • FixConstantPoolInterfaceMethodRefHelper is a transformer to fix a javac 8/asm 5.0 reobfuscator bug which generated wrong entries in the constant pool if method handles to interface methods were used
  • Mixins:
    • Object holder modifications to no longer write to static final fields
    • JarDiscoverer change to ignore module-info.class and META-INF/versions/* classes because it's not Java 9-aware
    • PostMixinTransformInjector used to move our asm transformer to run after the mixin processing
  • UnsafeHacks class from modern forge, modified to work in more usecases, for replacing some static final writes where it was not feasible/easy to remove final.
  • Forge patches, which are modified classes from Forge that cannot be transformed because they are loaded too early - so we load a forgePatches jar before Forge in the classpath to replace them:
    • EventSubscriptionTransformer: the format of subclass annotation descriptors has slightly changed in Java 17, this makes the annotation discovery compatible with both
    • TerminalTransformer: modify to accept classfiles newer than what asm5 supported
    • ClassPatchManager: switches the Pack200 implementation to an Apache Commons Compress one because it was removed from newer JDKs
    • TracingPrintStream: commons-compress closes System.out, this blocks this from happening
    • CoreModManager: work around the fact that the system classloader is no longer a URLClassLoader
    • FMLSecurityManager: fix some array index out of bounds exceptions, it is also deprecated in java 17 and will need to be replaced once a new API is available
    • EnumHelper: replace all the enumhelper apis with new variants using the extensible enum transformer and unsafe hacks.
  • Additional performance-enhancing mixins making use of LWJGL3 features:
    • STB_image-based image loader, much faster than Image4J
    • STB_rectpack-based texture sticher, it's nearly instant with tens of thousands of textures, compared to the vanilla code which takes many seconds to stitch that many textures into an atlas

Fixing mods

This mod is not enough to make modpacks work in Java 9+, mods had to be updated. Here's a potentially incomplete list of breaking changes that needed code changes in mods, or mixins to fix non-open-source mods:

System class loader is no longer a URLClassLoader

To get the classpath, simply split System.getProperty("java.class.path") by File.pathSeparator.

Do note that for most mods, their classloader is still a LaunchClassLoader which does extend URLClassLoader.

To modify the URLClassPath you can use the following code:

public static void addUrlToClassloader(ClassLoader loader, URL coreModUrl) {
    try {
        if (loader instanceof URLClassLoader) {
            if (ADDURL == null) {
                ADDURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
                ADDURL.setAccessible(true);
            }
            ADDURL.invoke(loader, coreModUrl);
        } else {
            Field ucpField;
            try {
                // Java 8-11
                ucpField = loader.getClass().getDeclaredField("ucp");
            } catch (NoSuchFieldException e) {
                // Java 17
                ucpField = loader.getClass().getSuperclass().getDeclaredField("ucp");
            }
            ucpField.setAccessible(true);
            // URLClassPath is in different packages in different Java versions, so we use Object.
            final Object ucp = ucpField.get(loader);
            final Method urlAdder = ucp.getClass().getDeclaredMethod("addURL", URL.class);
            urlAdder.invoke(ucp, coreModUrl);
        }
    } catch (ReflectiveOperationException e) {
        throw new RuntimeException("Couldn't add url to classpath in loader " + loader.getClass(), e);
    }
}

java.base/java.lang.reflect classes are protected from reflective access

E.g. Field.class.getDeclaredFields() returns an empty list. The most common use of this was to change the modifiers field to strip final from the Field accessor to trick it into letting you write into static final fields. Instead of that, use an access transformer (public-f class field_srg # field_mcp) to remove the final attribute at class load time. Alternatively, inject a different initializer via Mixins/asm by modifying the class static constructor special method <clinit>.

If that is not feasible (e.g. runtime reflection discovering fields), you can use sun.misc.Unsafe to directly write to the memory location of the final field like so:

final Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
final Unsafe UNSAFE = (Unsafe) theUnsafe.get(null); // Cache this

public static void setField(Field data, Object object, Object value) {
    if (object == null) {
        long offset = UNSAFE.staticFieldOffset(data);
        Object base = UNSAFE.staticFieldBase(data);
        UNSAFE.putObject(base, offset, value);
    } else {
        long offset = UNSAFE.objectFieldOffset(data);
        UNSAFE.putObject(object, offset, value);
    }
}

Beware, the Java JIT compiler will assume that final fields don't change value at runtime, so the value you write there using Unsafe might not actually be read back by some code. This can lead to inconsistent states, where some methods might see the old value while other ones will see the new value, especially if you change the value down a callchain that already read the value earlier.

Development

First, do ./gradlew build and use the zip in ./build/distributions/lwjgl3ify-VERSION-multimc.zip to install lwjgl3ify into a 1.7.10 forge instance in Prism.

Then, for developing locally, in the patches/me.eigenraven.lwjgl3ify.forgepatches.json file replace:

"url": "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"

with:

"MMC-hint": "local"

Inside the libraries array.

Thanks to MMC-hint you can now put the locally built forgePatches jar into instances/My Modpack/libraries/lwjgl3ify-VERSION-forgePatches.jar.

More Repositories

1

GT-New-Horizons-Modpack

New Modpack with Gregtech and Thaumcraft
JavaScript
667
star
2

Angelica

OptiFine replacement for 1.7.10
Java
247
star
3

GT5-Unofficial

Decompiled and modified version of GT5.07.07
Java
51
star
4

RetroFuturaGradle

A Gradle plugin for development of Minecraft 1.7.10 modifications, aiming to replace use of the legacy ForgeGradle toolchain.
Java
43
star
5

NewHorizonsCoreMod

Core Mod for the New Horizons pack
Java
40
star
6

Hodgepodge

A HodgePodge of patches
Java
36
star
7

DreamAssemblerXXL

Python
22
star
8

ServerUtilities

Java
18
star
9

Minetweaker-Gregtech-5-Addon

Minetweaker Addon for all Gregtech 5 Machines
Java
16
star
10

GTplusplus

Merged to https://github.com/GTNewHorizons/GT5-Unofficial/
Java
14
star
11

GTNHLib

GTNH Library
Java
11
star
12

ModularUI

Minecraft 1.7.10 library mod for fancy UI
Java
11
star
13

PersonalSpace

Minecraft 1.7.10 mod for personal dimensions, backwards compatible with UtilityWorlds
Java
9
star
14

worldedit-gtnh

Java
9
star
15

MalisisCore

Java
8
star
16

thaumcraft-research-tweaks

Kotlin
8
star
17

MalisisDoors

Java
7
star
18

NotEnoughIds

GTNH version of fewizz's NotEnoughIds mod
Java
7
star
19

GTNH-Translations

Repository centralising all the translation efforts for the GT:NH modpack
Python
7
star
20

Nutrition

Nutrition fork for Minecraft 1.7.10
Java
6
star
21

waila

Fork of ProfMobius' WAILA mod
Java
6
star
22

Random-Things

Java
6
star
23

CarpentersBlocks

Java
6
star
24

GTNH-Intergalactic

Java
6
star
25

BlockRenderer6343

Render 3D Blocks in Minecraft GUI or World
Java
6
star
26

GTNewHorizons3.0-Core-Mod

GTNH 3.0 for Mc 1.12 or later
Java
5
star
27

BiomeBridge

A complete reqwrite of Biomes O' Plenty for Minecraft 1.7.10
Java
5
star
28

KubaTech

Merged to https://github.com/GTNewHorizons/GT5-Unofficial/ ; It's about the Tea
Java
5
star
29

Amazing-Trophies

Add custom Achievements and Trophies to Minecraft 1.7.10!
Java
5
star
30

GTNHMixins

GTNH Flavored Mixins
Java
5
star
31

ThaumicInventoryScanning

Java
5
star
32

GTNHGradle

This plugin is the container for most of our shared buildscript logic for all GTNH mods and some other 1.7.10 mods. The original buildscript grew to hundreds of lines of Groovy code, using this plugin we can use regular Java classes to compartmentalize that logic and make it easier to extend and update
Java
5
star
33

GTNewHorizons-3.0

4
star
34

EnhancedLootBags

LootBags redefined.
Java
4
star
35

FarmingForEngineers

Backports FarmingForBlockheads to 1.7.10
Java
4
star
36

INpureCore

Java
4
star
37

BeeBetterAtBees-GTNH

Java
4
star
38

RetroFuturaBootstrap

An open source, backwards compatible replacement for LegacyLauncher/LaunchWrapper
Java
4
star
39

AngelicaCompat

Compatibility patches for various mods with Angelica
Java
4
star
40

Alfheim

Kotlin
3
star
41

BrandonsCore

Java
3
star
42

Gravitation-Suite-Neo

Addon mod for Gravitation Suite
Java
3
star
43

GTNH-Actions-Workflows

Github Actions workflows for GTNH repos
Shell
3
star
44

ProjectBlue

Project Blue from greg.ewing. Original site at https://www.cosc.canterbury.ac.nz/greg.ewing/minecraft/mods/ProjectBlue/
Java
3
star
45

AFSU

Java
3
star
46

GTNH-Dev-Doc

Repository giving various docs about the development of the GTNH Modpack
3
star
47

CropsNH

GTNH Style Crops - Fork of Agricraft, inspired by IC2 Crops
Java
3
star
48

Player-API

Java
3
star
49

StructureLib

Java
3
star
50

StorageDrawers-Misc

Various integrations for StorageDrawers
Java
3
star
51

Ztones-Unofficial

Ztones mod for Minecraft 1.7.10 unofficially rewritten from scratch.
Java
3
star
52

Advanced-Botany

Java
3
star
53

StorageDrawers-Forestry

Forestry integration for StorageDrawers
Java
3
star
54

EnderStorage

1.7.10 Fork of EnderStorage
Java
3
star
55

Binnie

Minecraft addons for the Forestry mod. Extra Bees, Extra Trees, Genetics, and more.
Java
3
star
56

IFU

Low Tec Ore Scanner by EnnekPL
Java
2
star
57

AngerMod

Java
2
star
58

NewHorizonsServerCore

Bukkit Plugin for Servers running the GT:NH Pack
Java
2
star
59

Yamcl

Yet another modding CoreLib
Java
2
star
60

ChiselTones

Java
2
star
61

Jabba

Java
2
star
62

GTNH-Soartex-Overrides

GTNH-Soartex-Overrides-TexturePackAddon
2
star
63

StorageDrawers-BiomesOPlenty

BiomesOPlenty integration for StorageDrawers
Java
2
star
64

TravellersGearNeo

A small add-on to add features to the ARR mod Travellers Gear
Java
2
star
65

StorageDrawers-Natura

Natura integration for StorageDrawers
Java
2
star
66

GTNH-DevEnv

Combined multi-project development environment for refactors across GT addons
Kotlin
2
star
67

ModMixins

Basically a fork of Hodgepodge
Kotlin
1
star
68

SleepingBags

Java
1
star
69

SpongePoweredMixin

GTNH Fork of SpongePowered - Mixin
Java
1
star
70

AMDIForge

Forge Plugin for the DataImporter
Java
1
star
71

GigaGramFab

Extra bits of G.
Java
1
star
72

CraftPresence

Java
1
star
73

StorageDrawers-Erebus

Erebus integration for StorageDrawers
Java
1
star
74

p455w0rds-Library

Stuff commonly used by my mods
Java
1
star
75

Obama

Obama
Java
1
star
76

GalacticGregGT5

The rewritten GalacticGreg mod for GregTech5
Java
1
star
77

StructureCompat

Compatibility module for StructureLib. Separated from the main mod to decouple the release cycle.
Java
1
star