From 22898399667789032a1f82637dfb37ec35c03340 Mon Sep 17 00:00:00 2001 From: JFronny Date: Thu, 29 Dec 2022 15:51:08 +0100 Subject: [PATCH] Use new config compiler and experiment with panama (untested and disabled) --- build.gradle.kts | 57 ++++++++------- gradle.properties | 8 +-- settings.gradle.kts | 4 -- .../io/gitlab/jfronny/breakme/BreakMe.java | 3 +- .../gitlab/jfronny/breakme/BreakMeConfig.java | 30 ++++---- .../breakme/crash/unsafe/WinApiProvider.java | 69 +++++++++++++++++++ .../resources/assets/breakme/lang/en_us.json | 16 ++--- src/main/resources/fabric.mod.json | 2 +- 8 files changed, 127 insertions(+), 62 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a7a4e99..c6d9b5c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,15 +1,13 @@ import com.squareup.javapoet.ClassName -import com.squareup.javapoet.ParameterizedTypeName -import com.squareup.javapoet.TypeName -import java.nio.file.Files +import com.squareup.javapoet.TypeSpec import io.gitlab.jfronny.scripts.* -import java.util.LinkedList +import java.nio.file.Files +import java.util.* import javax.lang.model.element.Modifier.* plugins { - id("jfmod") version "1.2-SNAPSHOT" - id("jf.codegen") version "1.2-SNAPSHOT" - id("io.gitlab.jfronny.libjf.libjf-config-compiler-plugin") + id("jfmod") version "1.3-SNAPSHOT" + id("jf.codegen") version "1.3-SNAPSHOT" } if (flavour == "") flavour = "modrinth" @@ -21,7 +19,7 @@ dependencies { modLocalRuntime("io.gitlab.jfronny.libjf:libjf-devutil:${prop("libjf_version")}") modLocalRuntime("io.gitlab.jfronny.libjf:libjf-config-ui-tiny-v1:${prop("libjf_version")}") modLocalRuntime("net.fabricmc.fabric-api:fabric-api:${prop("fabric_version")}") - modLocalRuntime("com.terraformersmc:modmenu:5.0.0-alpha.4") + modLocalRuntime("com.terraformersmc:modmenu:5.0.2") } fun list(`package`: String) = Files.list(projectDir.resolve("src/main/java").resolve(`package`.replace('.', '/')).toPath()).use { stream -> @@ -45,24 +43,33 @@ if (flavour == "curseforge") { sourceSets { main { generate(project) { - `class`("io.gitlab.jfronny.breakme.crash", "KnownProviders") { + val providerType = ClassName.get("io.gitlab.jfronny.breakme.crash", "CrashProvider") + + `enum`("io.gitlab.jfronny.breakme.crash", "Method") { modifiers(PUBLIC) - val type = ParameterizedTypeName.get(ClassName.get(Map::class.java), TypeName.get(String::class.java), ClassName.get("io.gitlab.jfronny.breakme.crash", "CrashProvider")) - field(type, "PROVIDERS", PUBLIC, STATIC, FINAL) { - initializer { - add("Map.of(\$>") - if (!classes.isEmpty()) { - indent() - var first = false - for (klazz in classes) { - if (!first) first = true - else add(",") - val name = klazz.simpleName() - add("\n\$S, new \$T()", name.substring(0, name.length - "Provider".length), klazz) - } - add("\n") - } - add("\$<)") + + superInterface(providerType) + + for (klazz in classes) { + val name = klazz.simpleName() + enumConstant(name.substring(0, name.length - "Provider".length), TypeSpec.anonymousClassBuilder("new \$T()", klazz).build()) + } + + field(providerType, "provider", PRIVATE, FINAL) + + constructor { + parameter(providerType, "provider") + code { + addStatement("this.provider = provider") + } + } + + method("crash") { + modifiers(PUBLIC) + exception(Exception::class.java) + annotation(Override::class.java) + code { + addStatement("provider.crash()") } } } diff --git a/gradle.properties b/gradle.properties index 77ffd7a..52c73b1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ # https://fabricmc.net/develop/ minecraft_version=1.19.3 -yarn_mappings=build.2 -loader_version=0.14.11 +yarn_mappings=build.5 +loader_version=0.14.12 maven_group=io.gitlab.jfronny archives_base_name=breakme @@ -13,5 +13,5 @@ curseforge_id=400842 curseforge_required_dependencies=libjf curseforge_optional_dependencies=modmenu -fabric_version=0.68.1+1.19.3 -libjf_version=3.3.0 +fabric_version=0.70.0+1.19.3 +libjf_version=3.4.1 diff --git a/settings.gradle.kts b/settings.gradle.kts index ebbedd8..e4f0c78 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,13 +1,9 @@ pluginManagement { - val libjf_version: String by settings repositories { maven("https://maven.fabricmc.net/") // FabricMC maven("https://maven.frohnmeyer-wds.de/artifacts") // scripts gradlePluginPortal() } - plugins { - id("io.gitlab.jfronny.libjf.libjf-config-compiler-plugin") version libjf_version - } } rootProject.name = "breakme" diff --git a/src/main/java/io/gitlab/jfronny/breakme/BreakMe.java b/src/main/java/io/gitlab/jfronny/breakme/BreakMe.java index b39147f..0741032 100644 --- a/src/main/java/io/gitlab/jfronny/breakme/BreakMe.java +++ b/src/main/java/io/gitlab/jfronny/breakme/BreakMe.java @@ -1,6 +1,5 @@ package io.gitlab.jfronny.breakme; -import io.gitlab.jfronny.breakme.crash.KnownProviders; import io.gitlab.jfronny.commons.log.Logger; import net.fabricmc.api.ModInitializer; import net.minecraft.entity.player.PlayerEntity; @@ -19,7 +18,7 @@ public class BreakMe implements ModInitializer { || BreakMeConfig.event == BreakMeConfig.Cause.Damage || (BreakMeConfig.event == BreakMeConfig.Cause.Death && player.isDead())) { LOGGER.info("Invoking the crash"); - KnownProviders.PROVIDERS.get(BreakMeConfig.method).crash(); + BreakMeConfig.method.crash(); } } } diff --git a/src/main/java/io/gitlab/jfronny/breakme/BreakMeConfig.java b/src/main/java/io/gitlab/jfronny/breakme/BreakMeConfig.java index a7fe778..c5518a3 100644 --- a/src/main/java/io/gitlab/jfronny/breakme/BreakMeConfig.java +++ b/src/main/java/io/gitlab/jfronny/breakme/BreakMeConfig.java @@ -1,12 +1,12 @@ package io.gitlab.jfronny.breakme; -import io.gitlab.jfronny.breakme.crash.KnownProviders; -import io.gitlab.jfronny.libjf.config.api.v1.JfCustomConfig; -import io.gitlab.jfronny.libjf.config.api.v1.dsl.DSL; +import io.gitlab.jfronny.breakme.crash.Method; +import io.gitlab.jfronny.libjf.config.api.v1.*; -public class BreakMeConfig implements JfCustomConfig { - public static Cause event = Cause.Death; - public static String method = "Exception"; +@JfConfig +public class BreakMeConfig { + @Entry public static Cause event = Cause.Death; + @Entry public static Method method = Method.Exception; public enum Cause { Damage, @@ -16,17 +16,11 @@ public class BreakMeConfig implements JfCustomConfig { None } - @Override - public void register(DSL.Defaulted dsl) { - dsl.register(builder -> builder - .value("event", event, Cause.class, () -> event, v -> event = v) - .value("method", method, KnownProviders.PROVIDERS.keySet().toArray(String[]::new), () -> method, v -> method = v) - .addVerifier(() -> { - if (!KnownProviders.PROVIDERS.containsKey(BreakMeConfig.method)) { - BreakMeConfig.method = "None"; - BreakMe.LOGGER.error("Could not find specified crash provider, defaulting to None"); - } - }) - ); + @Verifier + public static void validProvider() { + if (BreakMeConfig.method == null) { + BreakMeConfig.method = Method.None; + BreakMe.LOGGER.error("Could not find specified crash provider, defaulting to None"); + } } } diff --git a/src/main/java/io/gitlab/jfronny/breakme/crash/unsafe/WinApiProvider.java b/src/main/java/io/gitlab/jfronny/breakme/crash/unsafe/WinApiProvider.java index 1426bf0..3079f12 100644 --- a/src/main/java/io/gitlab/jfronny/breakme/crash/unsafe/WinApiProvider.java +++ b/src/main/java/io/gitlab/jfronny/breakme/crash/unsafe/WinApiProvider.java @@ -4,12 +4,81 @@ import io.gitlab.jfronny.breakme.BreakMe; import io.gitlab.jfronny.breakme.crash.CrashProvider; import java.io.IOException; +//import java.lang.foreign.*; +//import java.lang.invoke.MethodHandle; +// +//import static java.lang.foreign.ValueLayout.*; public class WinApiProvider implements CrashProvider { private native void CrashWindows_Native(); @Override public void crash() { +// try { +// // Alternate Panama-based implementation +// // To be tested and enabled once panama is out of preview +// System.loadLibrary("ntdll"); +// +// // Anonymous class with utility methods +// var n = new Object() { +// private final Linker linker = Linker.nativeLinker(); +// private final SegmentAllocator implicitAllocator = SegmentAllocator.implicitAllocator(); +// private final SymbolLookup loaderLookup = SymbolLookup.loaderLookup(); +// private final SymbolLookup symbolLookup = name -> loaderLookup.lookup(name).or(() -> linker.defaultLookup().lookup(name)); +// +// MethodHandle downcallHandle(String name, FunctionDescriptor fdesc) { +// return symbolLookup.lookup(name). +// map(addr -> linker.downcallHandle(addr, fdesc)). +// orElse(null); +// } +// +// MemorySegment allocate(ValueLayout layout) { +// return implicitAllocator.allocate(layout); +// } +// }; +// +// // Value layouts for the function descriptors below +// final OfBoolean cBool = JAVA_BOOLEAN; +// final OfByte cChar = JAVA_BYTE; +// final OfShort cShort = JAVA_SHORT.withBitAlignment(16); +// final OfInt cInt = JAVA_INT.withBitAlignment(32); +// final OfInt cLong = JAVA_INT.withBitAlignment(32); +// final OfLong cLongLong = JAVA_LONG.withBitAlignment(64); +// final OfFloat cFloat = JAVA_FLOAT.withBitAlignment(32); +// final OfDouble cDouble = JAVA_DOUBLE.withBitAlignment(64); +// final OfAddress cPointer = ADDRESS.withBitAlignment(64); +// +// // Function definitions for rtlAdjustPrivilege and ntRaiseHardError +// // IntPtr RtlAdjustPrivilege(int Privilege, bool bEnablePrivilege, bool IsThreadPrivilege, out bool PreviousValue); +// // typedef NTSTATUS(NTAPI *pdef_RtlAdjustPrivilege)(ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled); +// final FunctionDescriptor rtlAdjustPrivilege$fd = FunctionDescriptor.of(cInt, cInt, cBool, cPointer); +// final MethodHandle rtlAdjustPrivilege = n.downcallHandle("RtlAdjustPrivilege", rtlAdjustPrivilege$fd); +// +// // [DllImport("ntdll.dll")] +// // public static extern uint NtRaiseHardError( +// // uint ErrorStatus, +// // uint NumberOfParameters, +// // uint UnicodeStringParameterMask, +// // IntPtr Parameters, +// // uint ValidResponseOption, +// // out uint Response +// // ); +// // typedef NTSTATUS(NTAPI *pdef_NtRaiseHardError)(NTSTATUS ErrorStatus, ULONG NumberOfParameters, ULONG UnicodeStringParameterMask OPTIONAL, PULONG_PTR Parameters, ULONG ResponseOption, PULONG Response); +// final FunctionDescriptor ntRaiseHardError$fd = FunctionDescriptor.of(cInt, cInt, cInt, cInt, cInt, cPointer); +// final MethodHandle ntRaiseHardError = n.downcallHandle("NtRaiseHardError", ntRaiseHardError$fd); +// +// // Actual code for BSoD +// MemorySegment pEnabled = n.allocate(cBool); +// rtlAdjustPrivilege.invokeExact(19, true, false, pEnabled); +// +// MemorySegment pResponse = n.allocate(cInt); +// ntRaiseHardError.invokeExact(0xc0000022, 0, 0, 0, 6, pResponse); +// } catch (Throwable e) { +// BreakMe.LOGGER.error("Could not create BSoD", e); +// return; +// } + try { + // Old implementation using DLL NativeUtils.loadLibraryFromJar("/native/natives.dll"); this.CrashWindows_Native(); } catch (IOException e) { diff --git a/src/main/resources/assets/breakme/lang/en_us.json b/src/main/resources/assets/breakme/lang/en_us.json index 42a36a4..b11d46a 100644 --- a/src/main/resources/assets/breakme/lang/en_us.json +++ b/src/main/resources/assets/breakme/lang/en_us.json @@ -7,12 +7,12 @@ "breakme.jfconfig.enum.Cause.All": "Damage or Death", "breakme.jfconfig.enum.Cause.None": "None", "breakme.jfconfig.method": "Method", - "breakme.jfconfig.method.tooltip": "The method used to perform the crash", - "breakme.jfconfig.method.Exception": "Safe_Universal_Exception", - "breakme.jfconfig.method.ExitCode": "Broken_Universal_ExitCode", - "breakme.jfconfig.method.SecurityException": "SemiUnsafe_Universal_Exception", - "breakme.jfconfig.method.Forkbomb": "Unsafe_Universal_Forkbomb", - "breakme.jfconfig.method.Shutdown": "SemiUnsafe_Universal_Shutdown", - "breakme.jfconfig.method.WinApi": "Unsafe_Windows_WinAPI", - "breakme.jfconfig.method.None": "None" + "breakme.jfconfig.enum.Method.tooltip": "The method used to perform the crash", + "breakme.jfconfig.enum.Method.Exception": "Safe_Universal_Exception", + "breakme.jfconfig.enum.Method.ExitCode": "Broken_Universal_ExitCode", + "breakme.jfconfig.enum.Method.SecurityException": "SemiUnsafe_Universal_Exception", + "breakme.jfconfig.enum.Method.Forkbomb": "Unsafe_Universal_Forkbomb", + "breakme.jfconfig.enum.Method.Shutdown": "SemiUnsafe_Universal_Shutdown", + "breakme.jfconfig.enum.Method.WinApi": "Unsafe_Windows_WinAPI", + "breakme.jfconfig.enum.Method.None": "None" } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index b58d34c..d3edc81 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -16,7 +16,7 @@ "environment": "*", "entrypoints": { "main": ["io.gitlab.jfronny.breakme.BreakMe"], - "libjf:config": ["io.gitlab.jfronny.breakme.BreakMeConfig"] + "libjf:config": ["io.gitlab.jfronny.breakme.JFC_BreakMeConfig"] }, "mixins": [ "breakme.mixins.json"