aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/util/ConditionNBTMixin.kt
blob: cbc1e66cc810462bd475387726cc695a4bc2d3bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package moe.nea.firmament.util

import java.lang.invoke.MethodHandles
import java.util.function.BiPredicate
import java.util.function.Function
import shcm.shsupercm.fabric.citresewn.defaults.cit.conditions.ConditionNBT

object ConditionNBTMixin {
    class Helper<StringMatcher> {

        val stringMatcherType = ConditionNBT::class.java.getDeclaredField("matchString").type

        val accessMatcher = run {
            val matchStringF = ConditionNBT::class.java.getDeclaredField("matchString");
            matchStringF.isAccessible = true
            val l = MethodHandles.privateLookupIn(ConditionNBT::class.java, MethodHandles.lookup())
//            val mt = MethodType.methodType(stringMatcherType, ConditionNBT::class.java)
//            val callsite = LambdaMetafactory.metafactory(
//                l, "apply",
//                MethodType.methodType(Function::class.java),
//                MethodType.methodType(java.lang.Object::class.java, java.lang.Object::class.java),
//                l.unreflectGetter(matchStringF),
//                mt
//            )
            val getter = l.unreflectGetter(matchStringF)
            Function<ConditionNBT, StringMatcher> { getter.invoke(it) as StringMatcher }
        }
        val directCaller = run {
            val matchM = stringMatcherType.getDeclaredMethod("matches", String::class.java);
            matchM.isAccessible = true
            val l = MethodHandles.privateLookupIn(ConditionNBT::class.java, MethodHandles.lookup())
//            val mt = MethodType.methodType(java.lang.Boolean.TYPE, stringMatcherType, String::class.java)
//            val callsite = LambdaMetafactory.metafactory(
//                l, "test",
//                MethodType.methodType(BiPredicate::class.java),
//                mt,
//                l.unreflect(matchM),
//                mt
//            )
            val func = l.unreflect(matchM)
            BiPredicate<StringMatcher, String> { a, b -> func.invoke(a, b) as Boolean }
        }

        fun test(condition: ConditionNBT, text: String): Boolean {
            return directCaller.test(accessMatcher.apply(condition), text) as Boolean
        }
    }

    val helper = Helper<Any>()

    @JvmStatic
    fun invokeDirectConditionNBTStringMatch(
        nbt: ConditionNBT,
        text: String,
    ): Boolean {
        return helper.test(nbt, text)
    }
}