mirror of
https://github.com/2006-Scape/apollo.git
synced 2026-07-03 00:38:21 +00:00
Reorganise kotlin message handlers
This commit is contained in:
@@ -13,17 +13,29 @@ class KotlinCommandHandler(
|
|||||||
val world: World,
|
val world: World,
|
||||||
val command: String,
|
val command: String,
|
||||||
privileges: PrivilegeLevel
|
privileges: PrivilegeLevel
|
||||||
) : KotlinPlayerHandlerProxyTrait<Command>, CommandListener(privileges) {
|
) : CommandListener(privileges) {
|
||||||
|
|
||||||
override var callback: Command.(Player) -> Unit = {}
|
var callback: Command.(Player) -> Unit = {}
|
||||||
override var predicate: Command.() -> Boolean = { true }
|
var predicate: Command.() -> Boolean = { true }
|
||||||
|
|
||||||
override fun execute(player: Player, command: Command) {
|
override fun execute(player: Player, command: Command) {
|
||||||
handleProxy(player, command)
|
if (command.predicate()) {
|
||||||
|
command.callback(player)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun register() {
|
fun register() {
|
||||||
world.commandDispatcher.register(command, this)
|
world.commandDispatcher.register(command, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun where(predicate: Command.() -> Boolean): KotlinCommandHandler {
|
||||||
|
this.predicate = predicate
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun then(callback: Command.(Player) -> Unit) {
|
||||||
|
this.callback = callback
|
||||||
|
this.register()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -7,15 +7,15 @@ import org.apollo.game.plugin.PluginContext
|
|||||||
import org.apollo.net.message.Message
|
import org.apollo.net.message.Message
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
class KotlinMessageHandler<T : ListenableContext, F : Message>(
|
class KotlinMessageHandler<F : Message, T : ListenableContext>(
|
||||||
world: World,
|
world: World,
|
||||||
private val listenable: MessageListenable<T, F>,
|
private val listenable: MessageListenable<F, T>,
|
||||||
private val callback: T.() -> Unit
|
private val callback: T.() -> Unit
|
||||||
) : MessageHandler<F>(world) {
|
) : MessageHandler<F>(world) {
|
||||||
|
|
||||||
override fun handle(player: Player, message: F) {
|
override fun handle(player: Player, message: F) {
|
||||||
val context = listenable.from(player, message)
|
val context = listenable.createContext(player, message)
|
||||||
context.callback()
|
context?.callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,34 +20,34 @@ abstract class KotlinPluginScript(var world: World, val context: PluginContext)
|
|||||||
|
|
||||||
private var stopListener: (World) -> Unit = { _ -> }
|
private var stopListener: (World) -> Unit = { _ -> }
|
||||||
|
|
||||||
fun <T : ListenableContext, F : Any> on(listenable: Listenable<T, F>, callback: T.() -> Unit) {
|
fun <T : Any, C : ListenableContext> on(listenable: Listenable<T, C>, callback: C.() -> Unit) {
|
||||||
// Smart-casting/type-inference is completely broken in this function in intelliJ, so assign to otherwise
|
// Smart-casting/type-inference is completely broken in this function in intelliJ, so assign to otherwise
|
||||||
// pointless `l` values for now.
|
// pointless `l` values for now.
|
||||||
|
|
||||||
return when (listenable) {
|
return when (listenable) {
|
||||||
is MessageListenable -> {
|
is MessageListenable -> {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val l = listenable as MessageListenable<T, Message>
|
val l = listenable as MessageListenable<Message, C>
|
||||||
|
|
||||||
val handler = KotlinMessageHandler(world, l, callback)
|
val handler = KotlinMessageHandler(world, l, callback)
|
||||||
context.addMessageHandler(l.type.java, handler)
|
context.addMessageHandler(l.type.java, handler)
|
||||||
}
|
}
|
||||||
is PlayerEventListenable -> {
|
is PlayerEventListenable -> {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val l = listenable as PlayerEventListenable<T, PlayerEvent>
|
val l = listenable as PlayerEventListenable<PlayerEvent, C>
|
||||||
|
|
||||||
world.listenFor(l.type.java) { event ->
|
world.listenFor(l.type.java) { event ->
|
||||||
val context = l.from(event)
|
val context = l.createContext(event)
|
||||||
context.callback()
|
context?.callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is EventListenable -> {
|
is EventListenable -> {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val l = listenable as EventListenable<T, Event>
|
val l = listenable as EventListenable<Event, C>
|
||||||
|
|
||||||
world.listenFor(l.type.java) { event ->
|
world.listenFor(l.type.java) { event ->
|
||||||
val context = l.from(event)
|
val context = l.createContext(event)
|
||||||
context.callback()
|
context?.callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,24 +9,24 @@ import kotlin.reflect.KClass
|
|||||||
/**
|
/**
|
||||||
* A game occurrence that can be listened to.
|
* A game occurrence that can be listened to.
|
||||||
*/
|
*/
|
||||||
sealed class Listenable<T : ListenableContext, F : Any> {
|
sealed class Listenable<T : Any, C : ListenableContext> {
|
||||||
abstract val type: KClass<F>
|
abstract val type: KClass<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class EventListenable<T : ListenableContext, F : Event> : Listenable<T, F>() {
|
abstract class EventListenable<T : Event, C : ListenableContext> : Listenable<T, C>() {
|
||||||
abstract fun from(event: F): T
|
abstract fun createContext(event: T): C?
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class MessageListenable<T : ListenableContext, F : Message> : Listenable<T, F>() {
|
abstract class MessageListenable<T : Message, C : ListenableContext> : Listenable<T, C>() {
|
||||||
abstract fun from(player: Player, message: F): T
|
abstract fun createContext(player: Player, message: T): C?
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class PlayerEventListenable<T : ListenableContext, F : PlayerEvent> : EventListenable<T, F>() {
|
abstract class PlayerEventListenable<T : PlayerEvent, C : ListenableContext> : EventListenable<T, C>() {
|
||||||
|
|
||||||
abstract fun from(player: Player, event: F): T
|
abstract fun createContext(player: Player, event: T): C?
|
||||||
|
|
||||||
override fun from(event: F): T {
|
final override fun createContext(event: T): C? {
|
||||||
return from(event.player, event)
|
return createContext(event.player, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,15 @@
|
|||||||
package org.apollo.game.plugin.kotlin
|
package org.apollo.game.plugin.kotlin
|
||||||
|
|
||||||
|
import org.apollo.game.model.entity.Player
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains contextual information for a [Listenable].
|
* Contextual information for a [Listenable].
|
||||||
*/
|
*/
|
||||||
interface ListenableContext
|
interface ListenableContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contextual information for a [Listenable] involving a specific [Player].
|
||||||
|
*/
|
||||||
|
interface PlayerContext : ListenableContext {
|
||||||
|
val player: Player
|
||||||
|
}
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
package org.apollo.game.plugin.kotlin.action.obj
|
|
||||||
|
|
||||||
import org.apollo.cache.def.ObjectDefinition
|
|
||||||
import org.apollo.game.message.impl.ObjectActionMessage
|
|
||||||
import org.apollo.game.model.entity.EntityType
|
|
||||||
import org.apollo.game.model.entity.Player
|
|
||||||
import org.apollo.game.model.entity.obj.GameObject
|
|
||||||
import org.apollo.game.plugin.kotlin.action.ActionListenableContext
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An interaction between a [Player] and an [interactive] [GameObject].
|
|
||||||
*/
|
|
||||||
class ObjectAction<T : InteractiveObject?>(
|
|
||||||
override val option: String,
|
|
||||||
override val player: Player,
|
|
||||||
val target: GameObject,
|
|
||||||
val interactive: T
|
|
||||||
) : ActionListenableContext {
|
|
||||||
|
|
||||||
companion object : ObjectActionListenable() {
|
|
||||||
|
|
||||||
override fun from(player: Player, message: ObjectActionMessage): ObjectAction<*> {
|
|
||||||
val def = ObjectDefinition.lookup(message.id)
|
|
||||||
val selectedAction = def.menuActions[message.option]
|
|
||||||
|
|
||||||
val obj = player.world.regionRepository
|
|
||||||
.fromPosition(message.position)
|
|
||||||
.getEntities<GameObject>(message.position, EntityType.DYNAMIC_OBJECT, EntityType.STATIC_OBJECT)
|
|
||||||
.first { it.definition == def }
|
|
||||||
|
|
||||||
return ObjectAction(selectedAction, player, obj, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val type = ObjectActionMessage::class
|
|
||||||
|
|
||||||
override fun <T : InteractiveObject> from(
|
|
||||||
player: Player,
|
|
||||||
other: ObjectActionMessage,
|
|
||||||
objects: List<T>
|
|
||||||
): ObjectAction<T> {
|
|
||||||
val def = ObjectDefinition.lookup(other.id)
|
|
||||||
val selectedAction = def.menuActions[other.option]
|
|
||||||
|
|
||||||
val obj = player.world.regionRepository
|
|
||||||
.fromPosition(other.position)
|
|
||||||
.getEntities<GameObject>(other.position, EntityType.DYNAMIC_OBJECT, EntityType.STATIC_OBJECT)
|
|
||||||
.first { it.definition == def }
|
|
||||||
|
|
||||||
return ObjectAction(selectedAction, player, obj, objects.first { it.instanceOf(obj) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+5
-7
@@ -1,9 +1,8 @@
|
|||||||
package org.apollo.game.plugin.kotlin.action
|
package org.apollo.game.plugin.kotlin.message.action
|
||||||
|
|
||||||
import org.apollo.game.model.entity.Player
|
|
||||||
import org.apollo.game.plugin.kotlin.KotlinPluginScript
|
import org.apollo.game.plugin.kotlin.KotlinPluginScript
|
||||||
import org.apollo.game.plugin.kotlin.ListenableContext
|
|
||||||
import org.apollo.game.plugin.kotlin.MessageListenable
|
import org.apollo.game.plugin.kotlin.MessageListenable
|
||||||
|
import org.apollo.game.plugin.kotlin.PlayerContext
|
||||||
import org.apollo.net.message.Message
|
import org.apollo.net.message.Message
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,8 +14,8 @@ import org.apollo.net.message.Message
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
inline fun <T : ActionListenableContext, reified F : Message> KotlinPluginScript.on(
|
inline fun <T : ActionContext, reified F : Message> KotlinPluginScript.on(
|
||||||
listenable: MessageListenable<T, F>,
|
listenable: MessageListenable<F, T>,
|
||||||
option: String,
|
option: String,
|
||||||
crossinline callback: T.() -> Unit
|
crossinline callback: T.() -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -27,7 +26,6 @@ inline fun <T : ActionListenableContext, reified F : Message> KotlinPluginScript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ActionListenableContext : ListenableContext {
|
interface ActionContext : PlayerContext {
|
||||||
val option: String
|
val option: String
|
||||||
val player: Player
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package org.apollo.game.plugin.kotlin.action.obj
|
package org.apollo.game.plugin.kotlin.message.action.obj
|
||||||
|
|
||||||
import org.apollo.game.model.entity.obj.GameObject
|
import org.apollo.game.model.entity.obj.GameObject
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package org.apollo.game.plugin.kotlin.message.action.obj
|
||||||
|
|
||||||
|
import org.apollo.cache.def.ObjectDefinition
|
||||||
|
import org.apollo.game.message.impl.ObjectActionMessage
|
||||||
|
import org.apollo.game.model.entity.EntityType
|
||||||
|
import org.apollo.game.model.entity.Player
|
||||||
|
import org.apollo.game.model.entity.obj.GameObject
|
||||||
|
import org.apollo.game.plugin.kotlin.message.action.ActionContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interaction between a [Player] and an [interactive] [GameObject].
|
||||||
|
*/
|
||||||
|
class ObjectAction<T : InteractiveObject?>( // TODO split into two classes, one with T and one without?
|
||||||
|
override val player: Player,
|
||||||
|
override val option: String,
|
||||||
|
val target: GameObject,
|
||||||
|
val interactive: T
|
||||||
|
) : ActionContext {
|
||||||
|
|
||||||
|
companion object : ObjectActionListenable() {
|
||||||
|
|
||||||
|
override val type = ObjectActionMessage::class
|
||||||
|
|
||||||
|
override fun createContext(player: Player, message: ObjectActionMessage): ObjectAction<*>? {
|
||||||
|
return create<InteractiveObject>(player, message, objects = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : InteractiveObject> createContext(
|
||||||
|
player: Player,
|
||||||
|
other: ObjectActionMessage,
|
||||||
|
objects: List<T>
|
||||||
|
): ObjectAction<T>? {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return create(player, other, objects) as ObjectAction<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T : InteractiveObject> create(
|
||||||
|
player: Player,
|
||||||
|
other: ObjectActionMessage,
|
||||||
|
objects: List<T>?
|
||||||
|
): ObjectAction<*>? {
|
||||||
|
val def = ObjectDefinition.lookup(other.id)
|
||||||
|
val selectedAction = def.menuActions[other.option]
|
||||||
|
|
||||||
|
val obj = player.world.regionRepository
|
||||||
|
.fromPosition(other.position)
|
||||||
|
.getEntities<GameObject>(other.position, EntityType.DYNAMIC_OBJECT, EntityType.STATIC_OBJECT)
|
||||||
|
.find { it.definition == def }
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
if (objects == null) {
|
||||||
|
return ObjectAction(player, selectedAction, obj, null)
|
||||||
|
} else {
|
||||||
|
val interactive = objects.find { it.instanceOf(obj) } ?: return null
|
||||||
|
return ObjectAction(player, selectedAction, obj, interactive)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+4
-4
@@ -1,17 +1,17 @@
|
|||||||
package org.apollo.game.plugin.kotlin.action.obj
|
package org.apollo.game.plugin.kotlin.message.action.obj
|
||||||
|
|
||||||
import org.apollo.game.message.impl.ObjectActionMessage
|
import org.apollo.game.message.impl.ObjectActionMessage
|
||||||
import org.apollo.game.model.entity.Player
|
import org.apollo.game.model.entity.Player
|
||||||
import org.apollo.game.plugin.kotlin.MessageListenable
|
import org.apollo.game.plugin.kotlin.MessageListenable
|
||||||
|
|
||||||
abstract class ObjectActionListenable : MessageListenable<ObjectAction<*>, ObjectActionMessage>() {
|
abstract class ObjectActionListenable : MessageListenable<ObjectActionMessage, ObjectAction<*>>() {
|
||||||
|
|
||||||
override val type = ObjectActionMessage::class
|
override val type = ObjectActionMessage::class
|
||||||
|
|
||||||
abstract fun <T : InteractiveObject> from(
|
abstract fun <T : InteractiveObject> createContext(
|
||||||
player: Player,
|
player: Player,
|
||||||
other: ObjectActionMessage,
|
other: ObjectActionMessage,
|
||||||
objects: List<T>
|
objects: List<T>
|
||||||
): ObjectAction<T>
|
): ObjectAction<T>?
|
||||||
|
|
||||||
}
|
}
|
||||||
+6
-23
@@ -1,4 +1,4 @@
|
|||||||
package org.apollo.game.plugin.kotlin.action.obj
|
package org.apollo.game.plugin.kotlin.message.action.obj
|
||||||
|
|
||||||
import org.apollo.cache.def.ObjectDefinition
|
import org.apollo.cache.def.ObjectDefinition
|
||||||
import org.apollo.game.message.handler.MessageHandler
|
import org.apollo.game.message.handler.MessageHandler
|
||||||
@@ -8,18 +8,6 @@ import org.apollo.game.model.entity.EntityType
|
|||||||
import org.apollo.game.model.entity.Player
|
import org.apollo.game.model.entity.Player
|
||||||
import org.apollo.game.model.entity.obj.GameObject
|
import org.apollo.game.model.entity.obj.GameObject
|
||||||
import org.apollo.game.plugin.kotlin.KotlinPluginScript
|
import org.apollo.game.plugin.kotlin.KotlinPluginScript
|
||||||
import org.apollo.game.plugin.kotlin.action.on
|
|
||||||
|
|
||||||
@Deprecated("example function, remove")
|
|
||||||
fun KotlinPluginScript.x() {
|
|
||||||
on(ObjectAction, option = "Trade", objects = listOf()) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
on(ObjectAction, option = "Trade") {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a listener for [ObjectActionMessage]s that occur on any of the given [InteractiveObject]s using the
|
* Registers a listener for [ObjectActionMessage]s that occur on any of the given [InteractiveObject]s using the
|
||||||
@@ -27,7 +15,7 @@ fun KotlinPluginScript.x() {
|
|||||||
*
|
*
|
||||||
* ```
|
* ```
|
||||||
* on(ObjectAction, option = "Open", objects = DOORS.toList()) {
|
* on(ObjectAction, option = "Open", objects = DOORS.toList()) {
|
||||||
* player.sendMessage("You open the door")
|
* player.sendMessage("You open the door.")
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
@@ -39,10 +27,8 @@ fun <T : InteractiveObject> KotlinPluginScript.on(
|
|||||||
) {
|
) {
|
||||||
if (objects.isEmpty()) {
|
if (objects.isEmpty()) {
|
||||||
on(listenable) {
|
on(listenable) {
|
||||||
if (this.option.equals(option, ignoreCase = true)) {
|
@Suppress("UNCHECKED_CAST") (callback as ObjectAction<*>.() -> Unit)
|
||||||
@Suppress("UNCHECKED_CAST") (this as ObjectAction<T>)
|
callback(this)
|
||||||
callback()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val handler = ObjectActionMessageHandler(world, listenable, objects, option, callback)
|
val handler = ObjectActionMessageHandler(world, listenable, objects, option, callback)
|
||||||
@@ -50,9 +36,6 @@ fun <T : InteractiveObject> KotlinPluginScript.on(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A [MessageHandler]
|
|
||||||
*/
|
|
||||||
class ObjectActionMessageHandler<T : InteractiveObject>(
|
class ObjectActionMessageHandler<T : InteractiveObject>(
|
||||||
world: World,
|
world: World,
|
||||||
private val listenable: ObjectActionListenable,
|
private val listenable: ObjectActionListenable,
|
||||||
@@ -71,8 +54,8 @@ class ObjectActionMessageHandler<T : InteractiveObject>(
|
|||||||
.first { it.definition == def }
|
.first { it.definition == def }
|
||||||
|
|
||||||
if (option.equals(selectedAction, ignoreCase = true) && objects.any { it.instanceOf(obj) }) {
|
if (option.equals(selectedAction, ignoreCase = true) && objects.any { it.instanceOf(obj) }) {
|
||||||
val context = listenable.from(player, message, objects)
|
val context = listenable.createContext(player, message, objects)
|
||||||
context.callback()
|
context?.callback()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user