Let plugins intercept Events

Support for PlayerEvents already exists, but general event
support wasn't included in the original KotlinPluginScript.
This commit is contained in:
Major
2017-09-24 18:13:17 +01:00
parent ae3d3c7ce2
commit cb9e6f353d
2 changed files with 116 additions and 67 deletions
@@ -7,6 +7,7 @@ import org.apollo.game.message.impl.ButtonMessage
import org.apollo.game.model.World import org.apollo.game.model.World
import org.apollo.game.model.entity.Player import org.apollo.game.model.entity.Player
import org.apollo.game.model.entity.setting.PrivilegeLevel import org.apollo.game.model.entity.setting.PrivilegeLevel
import org.apollo.game.model.event.Event
import org.apollo.game.model.event.EventListener import org.apollo.game.model.event.EventListener
import org.apollo.game.model.event.PlayerEvent import org.apollo.game.model.event.PlayerEvent
import org.apollo.game.plugin.PluginContext import org.apollo.game.plugin.PluginContext
@@ -18,29 +19,34 @@ import kotlin.script.templates.ScriptTemplateDefinition
scriptFilePattern = ".*\\.plugin\\.kts" scriptFilePattern = ".*\\.plugin\\.kts"
) )
abstract class KotlinPluginScript(private var world: World, val context: PluginContext) { abstract class KotlinPluginScript(private var world: World, val context: PluginContext) {
var startListener: (World) -> Unit = { _ -> }; var startListener: (World) -> Unit = { _ -> }
var stopListener: (World) -> Unit = { _ -> }; var stopListener: (World) -> Unit = { _ -> }
/** /**
* Create a new [MessageHandler]. * Creates a [MessageHandler].
*/ */
fun <T : Message> on(type: () -> KClass<T>) = KotlinMessageHandler<T>(world, context, type.invoke()) fun <T : Message> on(type: () -> KClass<T>) = KotlinMessageHandler(world, context, type.invoke())
/** /**
* Create a new [EventListener] for a type of [PlayerEvent]. * Create an [EventListener] for a [PlayerEvent].
*/ */
fun <T : PlayerEvent> on_player_event(type: () -> KClass<T>) = KotlinPlayerEventHandler(world, type.invoke()) fun <T : PlayerEvent> on_player_event(type: () -> KClass<T>) = KotlinPlayerEventHandler(world, type.invoke())
/** /**
* Create a new [CommandHandler] for the given _command_ name, which only players with a [PrivelegeLevel] * Create an [EventListener] for an [Event].
* of _privileges_ and above can use. */
fun <T : Event> on_event(type: () -> KClass<T>) = KotlinEventHandler(world, type.invoke())
/**
* Create a [CommandListener] for the given [command] name, which only players with a [PrivilegeLevel]
* of [privileges] and above can use.
*/ */
fun on_command(command: String, privileges: PrivilegeLevel) = KotlinCommandHandler(world, command, privileges) fun on_command(command: String, privileges: PrivilegeLevel) = KotlinCommandHandler(world, command, privileges)
/** /**
* Create a new [ButtonMessage] [MessageHandler] for the given _button_ id. * Create a [ButtonMessage] [MessageHandler] for the given [id].
*/ */
fun on_button(button: Int) = on { ButtonMessage::class }.where { widgetId == button } fun on_button(id: Int) = on { ButtonMessage::class }.where { widgetId == id }
fun start(callback: (World) -> Unit) { fun start(callback: (World) -> Unit) {
this.startListener = callback this.startListener = callback
@@ -57,13 +63,19 @@ abstract class KotlinPluginScript(private var world: World, val context: PluginC
fun doStop(world: World) { fun doStop(world: World) {
this.stopListener.invoke(world) this.stopListener.invoke(world)
} }
} }
/**
* A proxy interface for any handler that operates on [Player]s.
*/
interface KotlinPlayerHandlerProxyTrait<S : Any> { interface KotlinPlayerHandlerProxyTrait<S : Any> {
var callback: S.(Player) -> Unit var callback: S.(Player) -> Unit
var predicate: S.() -> Boolean var predicate: S.() -> Boolean
fun register()
fun where(predicate: S.() -> Boolean): KotlinPlayerHandlerProxyTrait<S> { fun where(predicate: S.() -> Boolean): KotlinPlayerHandlerProxyTrait<S> {
this.predicate = predicate this.predicate = predicate
return this return this
@@ -74,15 +86,18 @@ interface KotlinPlayerHandlerProxyTrait<S : Any> {
this.register() this.register()
} }
fun register()
fun handleProxy(player: Player, subject: S) { fun handleProxy(player: Player, subject: S) {
if (subject.predicate()) { if (subject.predicate()) {
subject.callback(player) subject.callback(player)
} }
} }
} }
/**
* A handler for [PlayerEvent]s.
*/
class KotlinPlayerEventHandler<T : PlayerEvent>(val world: World, val type: KClass<T>) : class KotlinPlayerEventHandler<T : PlayerEvent>(val world: World, val type: KClass<T>) :
KotlinPlayerHandlerProxyTrait<T>, EventListener<T> { KotlinPlayerHandlerProxyTrait<T>, EventListener<T> {
@@ -94,6 +109,37 @@ class KotlinPlayerEventHandler<T : PlayerEvent>(val world: World, val type: KCla
} }
/**
* A handler for [Event]s.
*/
class KotlinEventHandler<S : Event>(val world: World, val type: KClass<S>) : EventListener<S> {
private var callback: S.() -> Unit = {}
private var predicate: S.() -> Boolean = { true }
fun where(predicate: S.() -> Boolean): KotlinEventHandler<S> {
this.predicate = predicate
return this
}
fun then(callback: S.() -> Unit) {
this.callback = callback
this.register()
}
override fun handle(event: S) {
if (event.predicate()) {
event.callback()
}
}
fun register() = world.listenFor(type.java, this)
}
/**
* A handler for [Message]s.
*/
class KotlinMessageHandler<T : Message>(val world: World, val context: PluginContext, val type: KClass<T>) : class KotlinMessageHandler<T : Message>(val world: World, val context: PluginContext, val type: KClass<T>) :
KotlinPlayerHandlerProxyTrait<T>, MessageHandler<T>(world) { KotlinPlayerHandlerProxyTrait<T>, MessageHandler<T>(world) {
@@ -105,6 +151,9 @@ class KotlinMessageHandler<T : Message>(val world: World, val context: PluginCon
} }
/**
* A handler for [Command]s.
*/
class KotlinCommandHandler(val world: World, val command: String, privileges: PrivilegeLevel) : class KotlinCommandHandler(val world: World, val command: String, privileges: PrivilegeLevel) :
KotlinPlayerHandlerProxyTrait<Command>, CommandListener(privileges) { KotlinPlayerHandlerProxyTrait<Command>, CommandListener(privileges) {
+4 -4
View File
@@ -7,19 +7,19 @@
*/ */
import org.apollo.game.command.Command import org.apollo.game.command.Command
import org.apollo.game.message.handler.MessageHandlerChainSet
import org.apollo.game.message.impl.ButtonMessage import org.apollo.game.message.impl.ButtonMessage
import org.apollo.game.model.World import org.apollo.game.model.World
import org.apollo.game.model.area.RegionRepository
import org.apollo.game.model.entity.*
import org.apollo.game.model.entity.setting.PrivilegeLevel import org.apollo.game.model.entity.setting.PrivilegeLevel
import org.apollo.game.model.event.Event
import org.apollo.game.model.event.PlayerEvent import org.apollo.game.model.event.PlayerEvent
import org.apollo.game.plugin.kotlin.* import org.apollo.game.plugin.kotlin.KotlinEventHandler
import org.apollo.game.plugin.kotlin.KotlinPlayerHandlerProxyTrait
import org.apollo.net.message.Message import org.apollo.net.message.Message
import kotlin.reflect.KClass import kotlin.reflect.KClass
fun <T : Message> on(type: () -> KClass<T>): KotlinPlayerHandlerProxyTrait<T> = null!! fun <T : Message> on(type: () -> KClass<T>): KotlinPlayerHandlerProxyTrait<T> = null!!
fun <T : PlayerEvent> on_player_event(type: () -> KClass<T>): KotlinPlayerHandlerProxyTrait<T> = null!! fun <T : PlayerEvent> on_player_event(type: () -> KClass<T>): KotlinPlayerHandlerProxyTrait<T> = null!!
fun <T : Event> on_event(type: () -> KClass<T>): KotlinEventHandler<T> = null!!
fun on_command(command: String, privileges: PrivilegeLevel): KotlinPlayerHandlerProxyTrait<Command> = null!! fun on_command(command: String, privileges: PrivilegeLevel): KotlinPlayerHandlerProxyTrait<Command> = null!!
fun on_button(button: Int): KotlinPlayerHandlerProxyTrait<ButtonMessage> = null!! fun on_button(button: Int): KotlinPlayerHandlerProxyTrait<ButtonMessage> = null!!