@@ -3,49 +3,57 @@ package dev.slne.surf.api.velocity.server
33import com.google.common.reflect.TypeToken
44import com.velocitypowered.api.event.EventManager
55import com.velocitypowered.api.event.EventTask
6- import dev.slne.surf.api.velocity.server.reflection.VelocityReflection
7- import java.util.function.BiConsumer
6+ import com.velocitypowered.proxy.event.VelocityEventManager
7+ import dev.slne.surf.api.core.invoker.HiddenInvokerUtil
8+ import dev.slne.surf.api.shared.api.util.InternalInvokerApi
9+ import dev.slne.surf.api.velocity.server.reflection.VelocityEventManagerReflection
10+ import java.lang.invoke.MethodHandles
811import java.util.function.BiFunction
9- import java.util.function.Function
10- import java.util.function.Predicate
1112import kotlin.coroutines.Continuation
1213import kotlin.coroutines.EmptyCoroutineContext
1314import kotlin.coroutines.startCoroutine
14- import kotlin.reflect.jvm.kotlinFunction
1515import com.velocitypowered.api.event.Continuation as EventContinuation
1616
17+
1718class SuspendingEventHandler (private val eventManager : EventManager ) {
1819
19- @Suppress(" RedundantSamConstructor" )
2020 fun register () {
21- VelocityReflection .EVENT_MANAGER_PROXY .registerHandlerAdapter(
22- eventManager,
21+ registerValidationAdapter()
22+ }
23+
24+ @OptIn(InternalInvokerApi ::class )
25+ private fun registerValidationAdapter () {
26+ require(eventManager is VelocityEventManager ) { " Only VelocityEventManager is supported" }
27+
28+ val handler = VelocityEventManagerReflection .createCustomHandlerAdapter(
2329 " surf_api_suspending_event_handler" ,
24- Predicate { method -> method.kotlinFunction?.isSuspend == true },
25- BiConsumer { method, errors ->
26- val function = method.kotlinFunction!!
27- // parameters includes receiver, but excludes continuation
28- if (function.parameters.size != 2 ) {
29- errors + = " Expected 1 parameter, but got ${function.parameters.size - 1 } . You only need the event parameter."
30- }
31- if (function.returnType.classifier != Unit ::class ) {
32- errors + = " Expected return type of Unit, but got ${function.returnType} ."
30+ HiddenInvokerUtil ::isSuspendFunction,
31+ { method, errors ->
32+ if (method.parameterCount != 2 ) {
33+ errors + = " Expected exactly one event parameter, got ${method.parameterCount - 1 } ."
3334 }
3435 },
3536 object : TypeToken < suspend (Any , Any ) -> Unit > () {},
36- Function { function ->
37+ { function ->
3738 BiFunction { instance, event ->
3839 suspendingEventTask {
3940 function(instance, event)
4041 }
4142 }
42- }
43+ },
44+ lookup
4345 )
46+
47+ VelocityEventManagerReflection .getHandlerAdapters(eventManager).add(handler)
4448 }
4549
4650 private fun suspendingEventTask (handler : suspend () -> Unit ) =
4751 EventTask .withContinuation { handler.startCoroutine(it.asCoroutineContinuation()) }
4852
4953 private fun EventContinuation.asCoroutineContinuation (): Continuation <Unit > =
5054 Continuation (EmptyCoroutineContext ) { if (it.isFailure) resumeWithException(it.exceptionOrNull()) else resume() }
55+
56+ companion object {
57+ private val lookup = MethodHandles .lookup();
58+ }
5159}
0 commit comments