diff --git a/odinclient/build.gradle.kts b/odinclient/build.gradle.kts index cdbd3eb15..c26e06818 100644 --- a/odinclient/build.gradle.kts +++ b/odinclient/build.gradle.kts @@ -83,6 +83,7 @@ tasks { jar { manifest.attributes( + "FMLCorePlugin" to "me.odinmain.lwjgl.plugin.LWJGLLoadingPlugin", "FMLCorePluginContainsFMLMod" to true, "ForceLoadAsMod" to true, "MixinConfigs" to "mixins.odinclient.json", diff --git a/odinmain/build.gradle.kts b/odinmain/build.gradle.kts index 5c9a13103..f344795ba 100644 --- a/odinmain/build.gradle.kts +++ b/odinmain/build.gradle.kts @@ -1,3 +1,4 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { @@ -9,18 +10,33 @@ plugins { kotlin("jvm") version "2.0.0-Beta1" id("net.kyori.blossom") version "1.3.1" } - group = "me.odinmain" - blossom { replaceToken("@VER@", version) } - sourceSets.main { java.srcDir(file("$projectDir/src/main/kotlin")) output.setResourcesDir(sourceSets.main.flatMap { it.java.classesDirectory }) } +val lwjgl: Configuration by configurations.creating +val lwjglNative: Configuration by configurations.creating { + isTransitive =true +} + +val lwjglJar = tasks.create("lwjglJar") { + group = "shadow" + archiveClassifier.set("lwjgl") + configurations = listOf(lwjgl) + exclude("META-INF/versions/**") + exclude("**/module-info.class") + exclude("**/package-info.class") + relocate("org.lwjgl", "org.lwjgl3") { + include("org.lwjgl.PointerBuffer") + include("org.lwjgl.BufferUtils") + } +} + repositories { mavenCentral() maven("https://repo.spongepowered.org/maven/") @@ -36,34 +52,36 @@ dependencies { minecraft("com.mojang:minecraft:1.8.9") mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9") forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") - implementation(kotlin("stdlib-jdk8")) - annotationProcessor("org.spongepowered:mixin:0.8.5:processor") compileOnly("org.spongepowered:mixin:0.8.5") - shadowImpl("gg.essential:loader-launchwrapper:1.1.3") compileOnly("gg.essential:essential-1.8.9-forge:12132+g6e2bf4dc5") - //api("com.mojang:brigadier:1.0.18") - shadowImpl("com.github.Stivais:Commodore:3f4a14b1cf") { exclude(module = "kotlin-stdlib-jdk8") exclude(module = "kotlin-reflect") } + + lwjgl("org.lwjgl:lwjgl:3.3.0") + lwjgl("org.lwjgl:lwjgl-tinyfd:3.3.0") + lwjgl("org.lwjgl:lwjgl-nanovg:3.3.0") + lwjglNative("org.lwjgl:lwjgl:3.3.0:natives-windows") + lwjglNative("org.lwjgl:lwjgl-tinyfd:3.3.0:natives-windows") + lwjglNative("org.lwjgl:lwjgl-nanovg:3.3.0:natives-windows") + implementation(lwjglJar.outputs.files) } tasks { jar { + dependsOn(lwjglJar) dependsOn(shadowJar) enabled = false } - remapJar { archiveBaseName = "odinmain" input = shadowJar.get().archiveFile } - shadowJar { archiveBaseName = "odinmain" archiveClassifier = "dev" @@ -71,11 +89,9 @@ tasks { configurations = listOf(shadowImpl) mergeServiceFiles() } - withType { options.encoding = "UTF-8" } - withType { kotlinOptions { jvmTarget = "1.8" @@ -85,4 +101,4 @@ tasks { java.toolchain.languageVersion.set(JavaLanguageVersion.of(8)) -kotlin.jvmToolchain(8) +kotlin.jvmToolchain(8) \ No newline at end of file diff --git a/odinmain/src/main/kotlin/me/odinmain/OdinMain.kt b/odinmain/src/main/kotlin/me/odinmain/OdinMain.kt index c6ec44d68..30259f7a7 100644 --- a/odinmain/src/main/kotlin/me/odinmain/OdinMain.kt +++ b/odinmain/src/main/kotlin/me/odinmain/OdinMain.kt @@ -13,6 +13,7 @@ import me.odinmain.features.impl.render.DevPlayers import me.odinmain.features.impl.render.WaypointManager import me.odinmain.features.impl.skyblock.PartyNote import me.odinmain.font.OdinFont +import me.odinmain.lwjgl.LWJGLTest import me.odinmain.ui.clickgui.ClickGUI import me.odinmain.ui.util.shader.RoundedRect import me.odinmain.utils.ServerUtils @@ -73,6 +74,7 @@ object OdinMain { WaypointManager, DevPlayers, PartyNote, + LWJGLTest::class, //HighlightRenderer, //OdinUpdater, this diff --git a/odinmain/src/main/kotlin/me/odinmain/lwjgl/LWJGLFunctionProvider.kt b/odinmain/src/main/kotlin/me/odinmain/lwjgl/LWJGLFunctionProvider.kt new file mode 100644 index 000000000..541300bb6 --- /dev/null +++ b/odinmain/src/main/kotlin/me/odinmain/lwjgl/LWJGLFunctionProvider.kt @@ -0,0 +1,33 @@ +package me.odinmain.lwjgl + +import org.lwjgl.opengl.GLContext +import org.lwjgl.system.FunctionProvider +import java.lang.reflect.Method +import java.nio.ByteBuffer + +class LWJGLFunctionProvider : FunctionProvider { + + private var getFunctionAddress: Method? = null + + init { + try { + getFunctionAddress = GLContext::class.java.getDeclaredMethod("getFunctionAddress", String::class.java) + getFunctionAddress?.isAccessible = true + } catch (e: Exception) { + throw RuntimeException(e) + } + } + + override fun getFunctionAddress(functionName: CharSequence): Long { + try { + return getFunctionAddress!!.invoke(null, functionName.toString()) as Long + } catch (e: Exception) { + throw RuntimeException(e) + } + } + + override fun getFunctionAddress(byteBuffer: ByteBuffer?): Long { + throw UnsupportedOperationException() + } + +} \ No newline at end of file diff --git a/odinmain/src/main/kotlin/me/odinmain/lwjgl/LWJGLTest.kt b/odinmain/src/main/kotlin/me/odinmain/lwjgl/LWJGLTest.kt new file mode 100644 index 000000000..d0a878a6d --- /dev/null +++ b/odinmain/src/main/kotlin/me/odinmain/lwjgl/LWJGLTest.kt @@ -0,0 +1,62 @@ +package me.odinmain.lwjgl + +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.GuiScreen +import net.minecraft.client.renderer.GlStateManager +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import org.lwjgl.nanovg.NVGColor +import org.lwjgl.nanovg.NanoVG.* +import org.lwjgl.nanovg.NanoVGGL2.NVG_ANTIALIAS +import org.lwjgl.nanovg.NanoVGGL2.nvgCreate +import org.lwjgl.opengl.Display +import org.lwjgl.opengl.GL11 + + +class LWJGLTest : GuiScreen() { + + var vg: Long = 0 + + override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) { + super.drawScreen(mouseX, mouseY, partialTicks) + + if (vg == 0L) { + vg = nvgCreate(NVG_ANTIALIAS) + if (vg == 0L) { + throw RuntimeException("Failed to create nvg context") + } + } + + val fb = Minecraft.getMinecraft().framebuffer + if (!fb.isStencilEnabled) { + fb.enableStencil() + } + + GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) + + nvgBeginFrame(vg, Display.getWidth().toFloat(), Display.getHeight().toFloat(), 1f) + + nvgBeginPath(vg) + nvgRect(vg, 100f, 100f, 120f, 30f) + nvgCircle(vg, 120f, 120f, 5f) + nvgPathWinding(vg, NVG_HOLE) + val color = NVGColor.create() + nvgRGBA(255.toByte(), 192.toByte(), 0.toByte(), 255.toByte(), color) + nvgFillColor(vg, color) + nvgFill(vg) + + nvgEndFrame(vg) + + GlStateManager.popAttrib() + } + + var gui: GuiScreen = LWJGLTest() + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (mc.thePlayer != null && mc.thePlayer != null) { + Minecraft.getMinecraft().displayGuiScreen(gui) + } + } + +} \ No newline at end of file diff --git a/odinmain/src/main/kotlin/me/odinmain/lwjgl/plugin/LWJGLClassTransformer.kt b/odinmain/src/main/kotlin/me/odinmain/lwjgl/plugin/LWJGLClassTransformer.kt new file mode 100644 index 000000000..96e7e1ea5 --- /dev/null +++ b/odinmain/src/main/kotlin/me/odinmain/lwjgl/plugin/LWJGLClassTransformer.kt @@ -0,0 +1,57 @@ +package me.odinmain.lwjgl.plugin + +import net.minecraft.launchwrapper.IClassTransformer +import org.objectweb.asm.ClassReader +import org.objectweb.asm.ClassWriter +import org.objectweb.asm.Opcodes +import org.objectweb.asm.tree.* + + +class LWJGLClassTransformer : IClassTransformer { + + override fun transform(name: String, transformedName: String, basicClass: ByteArray): ByteArray { + if (name == "org.lwjgl.nanovg.NanoVGGLConfig") { + val reader = ClassReader(basicClass) + val node = ClassNode() + reader.accept(node, ClassReader.EXPAND_FRAMES) + + for (method in node.methods) { + if (method.name == "configGL") { + val list = InsnList() + + list.add(VarInsnNode(Opcodes.LLOAD, 0)) + list.add(TypeInsnNode(Opcodes.NEW, "me/odinmain/lwjgl/LWJGLFunctionProvider")) + list.add(InsnNode(Opcodes.DUP)) + list.add( + MethodInsnNode( + Opcodes.INVOKESPECIAL, + "me/main/lwjgl/FunctionProvider", + "", + "()V", + false + ) + ) + list.add( + MethodInsnNode( + Opcodes.INVOKESTATIC, + "org/lwjgl/nanovg/NanoVGGLConfig", + "config", + "(JLorg/lwjgl/system/FunctionProvider;)V", + false + ) + ) + list.add(InsnNode(Opcodes.RETURN)) + + method.instructions.clear() + method.instructions.insert(list) + } + } + + val cw = ClassWriter(ClassWriter.COMPUTE_FRAMES) + node.accept(cw) + return cw.toByteArray() + } + return basicClass + } + +} \ No newline at end of file diff --git a/odinmain/src/main/kotlin/me/odinmain/lwjgl/plugin/LWJGLLoadingPlugin.kt b/odinmain/src/main/kotlin/me/odinmain/lwjgl/plugin/LWJGLLoadingPlugin.kt new file mode 100644 index 000000000..8451056c0 --- /dev/null +++ b/odinmain/src/main/kotlin/me/odinmain/lwjgl/plugin/LWJGLLoadingPlugin.kt @@ -0,0 +1,40 @@ +package me.odinmain.lwjgl.plugin + +import net.minecraft.launchwrapper.Launch +import net.minecraft.launchwrapper.LaunchClassLoader +import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin + + +class LWJGLLoadingPlugin : IFMLLoadingPlugin { + + init { + try { + val exceptionsField = LaunchClassLoader::class.java.getDeclaredField("classLoaderExceptions") + exceptionsField.isAccessible = true + val exceptions = exceptionsField[Launch.classLoader] as MutableSet<*> + exceptions.remove("org.lwjgl.") + } catch (e: Exception) { + throw RuntimeException("e") + } + } + + override fun getASMTransformerClass(): Array { + return arrayOf("me.odinmain.lwjgl.plugin.LWJGLClassTransformer") + } + + override fun getModContainerClass(): String? { + return null + } + + override fun getSetupClass(): String? { + return null + } + + override fun injectData(data: Map) { + } + + override fun getAccessTransformerClass(): String? { + return null + } + +} \ No newline at end of file