Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve commands #578

Merged
merged 6 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,31 +61,5 @@ class InstructionTask(

companion object {
const val MAX_INSTRUCTIONS = 20

fun Flow<Int>.test() {

flow<List<Int>> {
coroutineScope {
val upstreamChannel = buffer(10).produceIn(this)
upstreamChannel.tryReceive().getOrNull()
}
}
}

@JvmStatic
fun main(args: Array<String>): Unit = runBlocking {

val channel = Channel<Int>(5)

for (i in 0 until 4) {
channel.send(i)
}
launch {
for (i in 0 until 5) {
val it = channel.tryReceive().getOrNull() ?: break
println(it)
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package world.gregs.voidps.engine.client.ui.event

import world.gregs.voidps.engine.client.ui.chat.Colours
import world.gregs.voidps.engine.client.ui.chat.toTag
import world.gregs.voidps.engine.entity.character.Character
import world.gregs.voidps.engine.entity.character.mode.interact.Interaction
import world.gregs.voidps.engine.entity.character.player.Player
Expand All @@ -21,23 +23,61 @@ data class Command(
2 -> character["rights", "none"]
else -> null
}

companion object {
var count = 0
val adminCommands = mutableListOf<String>()
val modCommands = mutableListOf<String>()
}
}

fun adminCommand(vararg commands: String, block: suspend Command.() -> Unit) {
fun adminCommand(command: String, description: String = "", aliases: List<String> = emptyList(), block: suspend Command.() -> Unit) {
if (description.isNotBlank()) {
Command.adminCommands.add("${Colours.BLUE.toTag()}${command}</col>")
}
val index = command.indexOfFirst { it == '(' || it == '[' }
val commandName = (if (index != -1) command.substring(0, index) else command).trim()
val handler: suspend Command.(Player) -> Unit = {
block.invoke(this)
}
for (command in commands) {
Events.handle("command", command, "admin", handler = handler)
Events.handle("command", commandName, "admin", handler = handler)
for (alias in aliases) {
if (description.isNotBlank()) {
Command.adminCommands.add("${Colours.BLUE.toTag()}${command.replace(commandName, alias)}</col>")
}
Events.handle("command", alias, "admin", handler = handler)
}

if (description.isNotBlank()) {
Command.adminCommands.add(description)
Command.adminCommands.add("")
}
}

fun modCommand(vararg commands: String, block: suspend Command.() -> Unit) {
fun modCommand(command: String, description: String = "", aliases: List<String> = emptyList(), block: suspend Command.() -> Unit) {
if (description.isNotBlank()) {
Command.modCommands.add("${Colours.BLUE.toTag()}${command}</col>")
Command.adminCommands.add("${Colours.BLUE.toTag()}${command}</col>")
}
val index = command.indexOfFirst { it == '(' || it == '[' }
val commandName = (if (index != -1) command.substring(0, index) else command).trim()
val handler: suspend Command.(Player) -> Unit = {
block.invoke(this)
}
for (command in commands) {
Events.handle("command", command, "mod", handler = handler)
Events.handle("command", command, "admin", handler = handler)
Events.handle("command", commandName, "mod", handler = handler)
Events.handle("command", commandName, "admin", handler = handler)
for (alias in aliases) {
if (description.isNotBlank()) {
Command.modCommands.add("${Colours.BLUE.toTag()}${command.replace(commandName, alias)}</col>")
Command.adminCommands.add("${Colours.BLUE.toTag()}${command.replace(commandName, alias)}</col>")
}
Events.handle("command", alias, "mod", handler = handler)
Events.handle("command", alias, "admin", handler = handler)
}
if (description.isNotBlank()) {
Command.modCommands.add(description)
Command.adminCommands.add(description)
Command.modCommands.add("")
Command.adminCommands.add("")
}
}
25 changes: 14 additions & 11 deletions engine/src/main/kotlin/world/gregs/voidps/engine/event/Events.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,7 @@ class Events(
}
}
runBlocking {
for (handler in handlers) {
if (event is CancellableEvent && event.cancelled) {
break
}
handler.invoke(event, dispatcher)
}
handleEvent(handlers, event, dispatcher)
}
return true
}
Expand All @@ -85,14 +80,22 @@ class Events(
all?.invoke(dispatcher, event)
}
scope.launch(errorHandler) {
for (handler in handlers) {
if (event is CancellableEvent && event.cancelled) {
break
}
handleEvent(handlers, event, dispatcher)
}
return true
}

private suspend fun handleEvent(handlers: Set<suspend Event.(EventDispatcher) -> Unit>, event: Event, dispatcher: EventDispatcher) {
for (handler in handlers) {
if (event is CancellableEvent && event.cancelled) {
break
}
try {
handler.invoke(event, dispatcher)
} catch (e: Exception) {
logger.warn(e) { "Error in event handler $dispatcher $event $handler" }
}
}
return true
}

fun contains(dispatcher: EventDispatcher, event: Event): Boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package world.gregs.voidps.engine.event
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import kotlin.test.Test
import org.junit.jupiter.api.Assertions.assertTrue

class EventsTest {

Expand All @@ -19,6 +20,19 @@ class EventsTest {
assertEquals(setOf(handler), result)
}

@Test
fun `Exceptions thrown in handlers are handled`() {
val trie = Events()
val handler: suspend Event.(EventDispatcher) -> Unit = {
throw IllegalStateException("tantrum")
}
trie.insert(arrayOf("param1"), handler)

val result = trie.emit(entity, event("param1"))

assertTrue(result)
}

@Test
fun `Exact match non string values`() {
val trie = Events()
Expand Down
9 changes: 6 additions & 3 deletions game/src/main/kotlin/world/gregs/voidps/bot/BotSpawns.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package world.gregs.voidps.bot
import kotlinx.coroutines.*
import world.gregs.voidps.engine.Contexts
import world.gregs.voidps.engine.client.PlayerAccountLoader
import world.gregs.voidps.engine.client.message
import world.gregs.voidps.engine.client.ui.event.adminCommand
import world.gregs.voidps.engine.data.AccountManager
import world.gregs.voidps.engine.data.Settings
Expand Down Expand Up @@ -70,7 +71,7 @@ worldTimerTick("bot_spawn") {
spawn()
}

adminCommand("bots") {
adminCommand("bots (count)", "spawn (count) number of bots") {
val count = content.toIntOrNull() ?: 1
GlobalScope.launch {
repeat(count) {
Expand All @@ -86,7 +87,7 @@ adminCommand("bots") {
}
}

adminCommand("clear_bots") {
adminCommand("clear_bots [count]", "clear all or some amount of bots") {
val count = content.toIntOrNull() ?: MAX_PLAYERS
World.queue("bot_${counter}") {
val manager = get<AccountManager>()
Expand All @@ -96,15 +97,17 @@ adminCommand("clear_bots") {
}
}

adminCommand("bot") {
adminCommand("bot", "toggle yourself on/off as a bot player") {
if (player.isBot) {
player.clear("bot")
player.message("Bot disabled.")
} else {
val bot = player.initBot()
if (content.isNotBlank()) {
player["task_bot"] = content
}
bot.emit(StartBot)
player.message("Bot enabled.")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package world.gregs.voidps.world.activity.achievement

import world.gregs.voidps.engine.client.message
import world.gregs.voidps.engine.client.ui.chat.plural
import world.gregs.voidps.engine.client.ui.event.adminCommand
import world.gregs.voidps.engine.client.ui.event.interfaceOpen
import world.gregs.voidps.engine.client.ui.interfaceOption
import world.gregs.voidps.engine.client.ui.open
Expand Down Expand Up @@ -218,12 +217,4 @@ interfaceOption("Hint", "hint_*", "task_system") {
player["world_map_marker_1"] = tile
player["world_map_marker_text_1"] = ""
player.open("world_map")
}

adminCommand("tasks", "achievements") {
for (struct in structDefinitions.definitions) {
if (struct.stringId.endsWith("_task")) {
player[struct.stringId] = true
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import world.gregs.voidps.engine.entity.obj.objectOperate
import world.gregs.voidps.engine.inv.sendInventory
import world.gregs.voidps.world.activity.bank.Bank.tabs

adminCommand("bank") {
adminCommand("bank", "open your bank anywhere") {
player.open("bank")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ settingsReload {
}
}

adminCommand("star") {
adminCommand("star [minutes]", "start a new shooting star event in [minutes]") {
cleanseEvent(true)
val minutes = content.toIntOrNull()
if (minutes != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package world.gregs.voidps.world.activity.quest

import world.gregs.voidps.engine.client.ui.Interfaces
import world.gregs.voidps.engine.client.ui.close
import world.gregs.voidps.engine.client.ui.dialogue.continueDialogue
import world.gregs.voidps.engine.client.ui.event.interfaceRefresh
Expand Down Expand Up @@ -44,17 +45,20 @@ continueDialogue("book_long", "turn_page_left") { player ->

fun refreshBook(player: Player, book: String) {
val name: String = player["book"] ?: return
val pageNumber: Int = player["book_page"] ?: return
player.interfaces.apply {
sendText(book, "title", books.title(name))
sendText(book, "page_number_left", (pageNumber + 1).toString())
sendText(book, "page_number_right", (pageNumber + 2).toString())
val pages = books.get(name)
sendVisibility(book, "turn_page_left", pageNumber > 0)
sendVisibility(book, "turn_page_right", pageNumber < pages.lastIndex)
val page = pages.getOrNull(pageNumber)?.lines()
for (i in 0 until if (book == "book_long") 30 else 21) {
sendText(book, "line${i + 1}", page?.getOrNull(i) ?: "")
}
val page: Int = player["book_page"] ?: return
val pages = books.get(name)
player.interfaces.display(book, books.title(book), page, pages)
}

fun Interfaces.display(book: String, title: String, pageNumber: Int, pages: List<String>) {
sendText(book, "title", title)
sendText(book, "page_number_left", (pageNumber + 1).toString())
sendText(book, "page_number_right", (pageNumber + 2).toString())
sendVisibility(book, "turn_page_left", pageNumber > 0)
sendVisibility(book, "turn_page_right", pageNumber < pages.lastIndex)
val lines = pages.getOrNull(pageNumber)?.lines()
for (i in 0 until if (book == "book_long") 30 else 21) {
println("Send line${i + 1} ${lines?.getOrNull(i)}")
sendText(book, "line${i + 1}", lines?.getOrNull(i) ?: "")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ import world.gregs.voidps.engine.client.ui.open
import world.gregs.voidps.engine.entity.character.player.Player
import world.gregs.voidps.engine.entity.item.Item

val quests = listOf(
"unstable_foundations",
"cooks_assistant",
"demon_slayer",
"dorics_quest",
"gunnars_ground",
"the_restless_ghost",
"rune_mysteries",
"the_knights_sword",
// mini-quests
"enter_the_abyss",
)

fun Player.quest(name: String): String = this[name, "unstarted"]

fun Player.questComplete(name: String): Boolean = quest(name) == "completed"
Expand Down

This file was deleted.

Loading
Loading