From 30fc810d61341ca27cd20351317165491c619c04 Mon Sep 17 00:00:00 2001 From: Cube Date: Sat, 3 Jun 2017 02:22:37 +0300 Subject: [PATCH 01/12] Add base for Kotlin commands --- .../game/plugin/kotlin/KotlinPluginScript.kt | 28 +++++++++++++++++-- game/src/main/kotlin/stub.kt | 9 ++++-- game/src/plugins/cmd/meta.toml | 7 +++++ game/src/plugins/cmd/src/bank-cmd.plugin.kts | 5 ++++ game/src/plugins/stub/stub.kt | 4 +++ 5 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 game/src/plugins/cmd/meta.toml create mode 100644 game/src/plugins/cmd/src/bank-cmd.plugin.kts diff --git a/game/src/main/kotlin/org/apollo/game/plugin/kotlin/KotlinPluginScript.kt b/game/src/main/kotlin/org/apollo/game/plugin/kotlin/KotlinPluginScript.kt index 1a9541a3..710b3ac1 100644 --- a/game/src/main/kotlin/org/apollo/game/plugin/kotlin/KotlinPluginScript.kt +++ b/game/src/main/kotlin/org/apollo/game/plugin/kotlin/KotlinPluginScript.kt @@ -1,10 +1,12 @@ package org.apollo.game.plugin.kotlin +import org.apollo.game.command.Command +import org.apollo.game.command.CommandListener import org.apollo.game.message.handler.MessageHandler import org.apollo.game.model.World import org.apollo.game.model.entity.Player +import org.apollo.game.model.entity.setting.PrivilegeLevel import org.apollo.game.plugin.PluginContext -import org.apollo.game.scheduling.ScheduledTask import org.apollo.net.message.Message import kotlin.reflect.KClass import kotlin.script.templates.ScriptTemplateDefinition @@ -20,6 +22,10 @@ abstract class KotlinPluginScript(private var world: World, val context: PluginC return KotlinMessageHandler(world, context, type.invoke()) } + protected fun on_command(command: String, privileges: PrivilegeLevel): KotlinCommandHandler { + return KotlinCommandHandler(world, command, privileges) + } + protected fun start(callback: (World) -> Unit) { this.startListener = callback } @@ -37,7 +43,6 @@ abstract class KotlinPluginScript(private var world: World, val context: PluginC } } - class KotlinMessageHandler(val world: World, val context: PluginContext, val type: KClass) : MessageHandler(world) { override fun handle(player: Player, message: T) { @@ -61,3 +66,22 @@ class KotlinMessageHandler(val world: World, val context: PluginCon } } + +class KotlinCommandListener(val level: PrivilegeLevel, val function: (Player, Command) -> Unit) : CommandListener(level) { + + override fun execute(player: Player, command: Command) { + function.invoke(player, command) + } + +} + +class KotlinCommandHandler(val world : World, val command: String, val privileges: PrivilegeLevel) { + + var function: (Player, Command) -> Unit = { _, _ -> } + + fun then(function: (Player, Command) -> Unit) { + this.function = function + world.commandDispatcher.register(command, KotlinCommandListener(privileges, function)) + } + +} diff --git a/game/src/main/kotlin/stub.kt b/game/src/main/kotlin/stub.kt index 8c583704..a7e212c7 100644 --- a/game/src/main/kotlin/stub.kt +++ b/game/src/main/kotlin/stub.kt @@ -7,8 +7,9 @@ */ import org.apollo.game.model.World -import org.apollo.game.plugin.PluginContext -import org.apollo.game.plugin.kotlin.* +import org.apollo.game.model.entity.setting.PrivilegeLevel +import org.apollo.game.plugin.kotlin.KotlinCommandHandler +import org.apollo.game.plugin.kotlin.KotlinMessageHandler import org.apollo.net.message.Message import kotlin.reflect.KClass @@ -16,6 +17,10 @@ fun on(type: () -> KClass): KotlinMessageHandler { null!! } +fun on_command(command: String, privileges: PrivilegeLevel): KotlinCommandHandler { + null!! +} + fun start(callback: (World) -> Unit) { } diff --git a/game/src/plugins/cmd/meta.toml b/game/src/plugins/cmd/meta.toml new file mode 100644 index 00000000..141c3a7b --- /dev/null +++ b/game/src/plugins/cmd/meta.toml @@ -0,0 +1,7 @@ +name = "Chat commands" +package = "org.apollo.game.plugin.cmd" +authors = [ "Graham", "cubeee" ] + +[config] +srcDir = "src/" +testDir = "test/" \ No newline at end of file diff --git a/game/src/plugins/cmd/src/bank-cmd.plugin.kts b/game/src/plugins/cmd/src/bank-cmd.plugin.kts new file mode 100644 index 00000000..84de8f0d --- /dev/null +++ b/game/src/plugins/cmd/src/bank-cmd.plugin.kts @@ -0,0 +1,5 @@ +import org.apollo.game.model.entity.setting.PrivilegeLevel + +// Opens the player's bank if they are an administrator. +on_command("bank", PrivilegeLevel.ADMINISTRATOR) + .then { player, _ -> player.openBank() } \ No newline at end of file diff --git a/game/src/plugins/stub/stub.kt b/game/src/plugins/stub/stub.kt index 8c583704..f82da254 100644 --- a/game/src/plugins/stub/stub.kt +++ b/game/src/plugins/stub/stub.kt @@ -16,6 +16,10 @@ fun on(type: () -> KClass): KotlinMessageHandler { null!! } +fun on_command(command: String, privileges: PrivilegeLevel): KotlinCommandHandler { + null!! +} + fun start(callback: (World) -> Unit) { } From 8e8e2d0991e37b39c83d61c35ebd18a3f896a801 Mon Sep 17 00:00:00 2001 From: Cube Date: Sat, 3 Jun 2017 15:23:03 +0300 Subject: [PATCH 02/12] Simplify on_command arguments --- .../org/apollo/game/plugin/kotlin/KotlinPluginScript.kt | 8 ++++---- game/src/plugins/cmd/src/bank-cmd.plugin.kts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/game/src/main/kotlin/org/apollo/game/plugin/kotlin/KotlinPluginScript.kt b/game/src/main/kotlin/org/apollo/game/plugin/kotlin/KotlinPluginScript.kt index 710b3ac1..e186a700 100644 --- a/game/src/main/kotlin/org/apollo/game/plugin/kotlin/KotlinPluginScript.kt +++ b/game/src/main/kotlin/org/apollo/game/plugin/kotlin/KotlinPluginScript.kt @@ -67,19 +67,19 @@ class KotlinMessageHandler(val world: World, val context: PluginCon } -class KotlinCommandListener(val level: PrivilegeLevel, val function: (Player, Command) -> Unit) : CommandListener(level) { +class KotlinCommandListener(val level: PrivilegeLevel, val function: Command.(Player) -> Unit) : CommandListener(level) { override fun execute(player: Player, command: Command) { - function.invoke(player, command) + function.invoke(command, player) } } class KotlinCommandHandler(val world : World, val command: String, val privileges: PrivilegeLevel) { - var function: (Player, Command) -> Unit = { _, _ -> } + var function: Command.(Player) -> Unit = { _ -> } - fun then(function: (Player, Command) -> Unit) { + fun then(function: Command.(Player) -> Unit) { this.function = function world.commandDispatcher.register(command, KotlinCommandListener(privileges, function)) } diff --git a/game/src/plugins/cmd/src/bank-cmd.plugin.kts b/game/src/plugins/cmd/src/bank-cmd.plugin.kts index 84de8f0d..181a1194 100644 --- a/game/src/plugins/cmd/src/bank-cmd.plugin.kts +++ b/game/src/plugins/cmd/src/bank-cmd.plugin.kts @@ -2,4 +2,4 @@ import org.apollo.game.model.entity.setting.PrivilegeLevel // Opens the player's bank if they are an administrator. on_command("bank", PrivilegeLevel.ADMINISTRATOR) - .then { player, _ -> player.openBank() } \ No newline at end of file + .then { player -> player.openBank() } \ No newline at end of file From b99ee9ba31a4ddc8d7412f9191dc7c8785990c31 Mon Sep 17 00:00:00 2001 From: Cube Date: Sat, 3 Jun 2017 18:55:40 +0300 Subject: [PATCH 03/12] Convert ::animate command to Kotlin --- game/src/plugins/cmd/meta.toml | 7 ++++++- .../plugins/cmd/src/animate-cmd.plugin.kts | 9 +++++++++ game/src/plugins/util/command/meta.toml | 5 +++++ game/src/plugins/util/command/src/command.kt | 19 +++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 game/src/plugins/cmd/src/animate-cmd.plugin.kts create mode 100644 game/src/plugins/util/command/meta.toml create mode 100644 game/src/plugins/util/command/src/command.kt diff --git a/game/src/plugins/cmd/meta.toml b/game/src/plugins/cmd/meta.toml index 141c3a7b..84ece10b 100644 --- a/game/src/plugins/cmd/meta.toml +++ b/game/src/plugins/cmd/meta.toml @@ -1,6 +1,11 @@ name = "Chat commands" package = "org.apollo.game.plugin.cmd" -authors = [ "Graham", "cubeee" ] +dependencies = [ "command_utilities" ] +authors = [ + "Graham", + "Major", + "cubeee" +] [config] srcDir = "src/" diff --git a/game/src/plugins/cmd/src/animate-cmd.plugin.kts b/game/src/plugins/cmd/src/animate-cmd.plugin.kts new file mode 100644 index 00000000..55b71306 --- /dev/null +++ b/game/src/plugins/cmd/src/animate-cmd.plugin.kts @@ -0,0 +1,9 @@ +import org.apollo.game.model.Animation +import org.apollo.game.model.entity.setting.PrivilegeLevel + +on_command("animate", PrivilegeLevel.MODERATOR) + .then { player -> + if(valid_arg_length(arguments, 1, player, "Invalid syntax - ::animate [animation-id]")) { + player.playAnimation(Animation(arguments[0].toInt())) + } + } \ No newline at end of file diff --git a/game/src/plugins/util/command/meta.toml b/game/src/plugins/util/command/meta.toml new file mode 100644 index 00000000..2d962919 --- /dev/null +++ b/game/src/plugins/util/command/meta.toml @@ -0,0 +1,5 @@ +name = "command utilities" +package = "org.apollo.game.plugins.util" + +[config] +srcDir = "src/" \ No newline at end of file diff --git a/game/src/plugins/util/command/src/command.kt b/game/src/plugins/util/command/src/command.kt new file mode 100644 index 00000000..bd693948 --- /dev/null +++ b/game/src/plugins/util/command/src/command.kt @@ -0,0 +1,19 @@ +import org.apollo.game.model.entity.Player + +/** + * Checks whether the amount of arguments provided is correct, sending the player the specified + * message if not. + */ +fun valid_arg_length(args: Array, length: Any, player: Player, message: String): Boolean { + val valid = when (length) { + is Int -> length == args.size + is IntRange -> length.contains(args.size) + else -> { + throw IllegalArgumentException("length must be one of the following: Int, IntRange") + } + } + if (!valid) { + player.sendMessage(message) + } + return valid +} \ No newline at end of file From 7df948e12f1195460d306379638c9cca81f6b063 Mon Sep 17 00:00:00 2001 From: Cube Date: Sat, 3 Jun 2017 19:08:52 +0300 Subject: [PATCH 04/12] Convert ::item command to Kotlin --- game/src/plugins/cmd/src/item-cmd.plugin.kts | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 game/src/plugins/cmd/src/item-cmd.plugin.kts diff --git a/game/src/plugins/cmd/src/item-cmd.plugin.kts b/game/src/plugins/cmd/src/item-cmd.plugin.kts new file mode 100644 index 00000000..7f6f2255 --- /dev/null +++ b/game/src/plugins/cmd/src/item-cmd.plugin.kts @@ -0,0 +1,24 @@ +import org.apollo.cache.def.ItemDefinition +import org.apollo.game.model.entity.setting.PrivilegeLevel + +on_command("item", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + if (!valid_arg_length(arguments, 1..2, player, "Invalid syntax - ::item [id] [amount]")) { + return@then + } + + val id = arguments[0].toInt() + val amount = if (arguments.size == 2) arguments[1].toInt() else 1 + + if (id < 0 || id >= ItemDefinition.count()) { + player.sendMessage("The item id you specified is out of bounds!") + return@then + } + + if (amount < 0) { + player.sendMessage("The amount you specified is out of bounds!") + return@then + } + + player.inventory.add(id, amount) + } \ No newline at end of file From 5ea52e00f03d5faf63fbc4f3710ddc34657e4d9c Mon Sep 17 00:00:00 2001 From: Cube Date: Sat, 3 Jun 2017 19:30:22 +0300 Subject: [PATCH 05/12] Convert messaging commands to Kotlin --- game/src/plugins/cmd/src/messaging-cmd.plugin.kts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 game/src/plugins/cmd/src/messaging-cmd.plugin.kts diff --git a/game/src/plugins/cmd/src/messaging-cmd.plugin.kts b/game/src/plugins/cmd/src/messaging-cmd.plugin.kts new file mode 100644 index 00000000..883d7a51 --- /dev/null +++ b/game/src/plugins/cmd/src/messaging-cmd.plugin.kts @@ -0,0 +1,11 @@ +import org.apollo.game.model.entity.setting.PrivilegeLevel + +on_command("broadcast", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + val message = arguments.joinToString(" ") + val broadcast = "[Broadcast] ${player.username.capitalize()}: $message" + + player.world.playerRepository.forEach { other -> + other.sendMessage(broadcast) + } + } From 6db98406d51c334653ff194743b436ca503e90e2 Mon Sep 17 00:00:00 2001 From: Cube Date: Sun, 4 Jun 2017 18:08:53 +0300 Subject: [PATCH 06/12] Overload valid_arg_length --- game/src/plugins/util/command/src/command.kt | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/game/src/plugins/util/command/src/command.kt b/game/src/plugins/util/command/src/command.kt index bd693948..7746d948 100644 --- a/game/src/plugins/util/command/src/command.kt +++ b/game/src/plugins/util/command/src/command.kt @@ -4,16 +4,17 @@ import org.apollo.game.model.entity.Player * Checks whether the amount of arguments provided is correct, sending the player the specified * message if not. */ -fun valid_arg_length(args: Array, length: Any, player: Player, message: String): Boolean { - val valid = when (length) { - is Int -> length == args.size - is IntRange -> length.contains(args.size) - else -> { - throw IllegalArgumentException("length must be one of the following: Int, IntRange") - } - } +fun valid_arg_length(args: Array, length: IntRange, player: Player, message: String): Boolean { + val valid = length.contains(args.size) if (!valid) { player.sendMessage(message) } return valid -} \ No newline at end of file +} + +/** + * Checks whether the amount of arguments provided is correct, sending the player the specified + * message if not. + */ +fun valid_arg_length(args: Array, length: Int, player: Player, message: String) + = valid_arg_length(args, IntRange(length, length), player, message) \ No newline at end of file From 72c0be8ac627fcf9e9608812394a701d13ec8379 Mon Sep 17 00:00:00 2001 From: Cube Date: Sun, 4 Jun 2017 19:56:51 +0300 Subject: [PATCH 07/12] Convert punishment commands to Kotlin --- .../org/apollo/game/model/entity/Player.java | 17 ++++++ game/src/plugins/cmd/meta.toml | 1 + .../src/plugins/cmd/src/punish-cmd.plugin.kts | 60 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 game/src/plugins/cmd/src/punish-cmd.plugin.kts diff --git a/game/src/main/java/org/apollo/game/model/entity/Player.java b/game/src/main/java/org/apollo/game/model/entity/Player.java index 2a323b10..76c06db9 100644 --- a/game/src/main/java/org/apollo/game/model/entity/Player.java +++ b/game/src/main/java/org/apollo/game/model/entity/Player.java @@ -28,6 +28,7 @@ import org.apollo.game.model.entity.attr.AttributeDefinition; import org.apollo.game.model.entity.attr.AttributeMap; import org.apollo.game.model.entity.attr.AttributePersistence; import org.apollo.game.model.entity.attr.NumericalAttribute; +import org.apollo.game.model.entity.attr.BooleanAttribute; import org.apollo.game.model.entity.obj.DynamicGameObject; import org.apollo.game.model.entity.setting.MembershipStatus; import org.apollo.game.model.entity.setting.PrivacyState; @@ -943,6 +944,22 @@ public final class Player extends Mob { this.withdrawingNotes = withdrawingNotes; } + /** + * Ban the player. + */ + public void ban() { + attributes.set("banned", new BooleanAttribute(true)); + } + + /** + * Sets the mute status of a player. + * + * @param muted Whether the player is muted. + */ + public void setMuted(boolean muted) { + attributes.set("muted", new BooleanAttribute(muted)); + } + @Override public void shout(String message, boolean chatOnly) { blockSet.add(SynchronizationBlock.createForceChatBlock(chatOnly ? message : '~' + message)); diff --git a/game/src/plugins/cmd/meta.toml b/game/src/plugins/cmd/meta.toml index 84ece10b..7a255f39 100644 --- a/game/src/plugins/cmd/meta.toml +++ b/game/src/plugins/cmd/meta.toml @@ -4,6 +4,7 @@ dependencies = [ "command_utilities" ] authors = [ "Graham", "Major", + "lare96", "cubeee" ] diff --git a/game/src/plugins/cmd/src/punish-cmd.plugin.kts b/game/src/plugins/cmd/src/punish-cmd.plugin.kts new file mode 100644 index 00000000..619d4674 --- /dev/null +++ b/game/src/plugins/cmd/src/punish-cmd.plugin.kts @@ -0,0 +1,60 @@ + +import org.apollo.game.model.entity.Player +import org.apollo.game.model.entity.setting.PrivilegeLevel + +/** + * Adds a command to mute a player. Admins cannot be muted. + */ +on_command("mute", PrivilegeLevel.MODERATOR) + .then { player -> + val name = arguments.joinToString(" ") + val targetPlayer = player.world.getPlayer(name) + + if (validate(player, targetPlayer)) { + targetPlayer.isMuted = true + player.sendMessage("You have just unmuted ${targetPlayer.username}.") + } + } + +/** + * Adds a command to unmute a player. + */ +on_command("unmute", PrivilegeLevel.MODERATOR) + .then { player -> + val name = arguments.joinToString(" ") + val targetPlayer = player.world.getPlayer(name) + + if (validate(player, targetPlayer)) { + targetPlayer.isMuted = false + player.sendMessage("You have just unmuted ${targetPlayer.username}.") + } + } + +/** + * Adds a command to ban a player. Admins cannot be banned. + */ +on_command("ban", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + val name = arguments.joinToString(" ") + val targetPlayer = player.world.getPlayer(name) + + if (validate(player, targetPlayer)) { + targetPlayer.ban() + targetPlayer.logout() // TODO force logout + player.sendMessage("You have just banned ${targetPlayer.username}.") + } + } + +/** + * Ensures the player isn't null, and that they aren't an Administrator. + */ +fun validate(player: Player, targetPlayer: Player?): Boolean { + if (targetPlayer == null) { + player.sendMessage("That player does not exist.") + return false + } else if (targetPlayer.privilegeLevel == PrivilegeLevel.ADMINISTRATOR) { + player.sendMessage("You cannot perform this action on Administrators.") + return false + } + return true +} \ No newline at end of file From 9f67c308930d790c82d8898f8c9794fbaa2d034a Mon Sep 17 00:00:00 2001 From: Cube Date: Sun, 4 Jun 2017 20:06:29 +0300 Subject: [PATCH 08/12] Convert teleport commands to Kotlin --- .../plugins/cmd/src/teleport-cmd.plugin.kts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 game/src/plugins/cmd/src/teleport-cmd.plugin.kts diff --git a/game/src/plugins/cmd/src/teleport-cmd.plugin.kts b/game/src/plugins/cmd/src/teleport-cmd.plugin.kts new file mode 100644 index 00000000..c6bdba4f --- /dev/null +++ b/game/src/plugins/cmd/src/teleport-cmd.plugin.kts @@ -0,0 +1,28 @@ +import org.apollo.game.model.Position +import org.apollo.game.model.entity.setting.PrivilegeLevel + +/** + * Sends the player's position. + */ +on_command("pos", PrivilegeLevel.MODERATOR) + .then { player -> + player.sendMessage("You are at: ${player.position}.") + } + +/** + * Teleports the player to the specified position. + */ +on_command("tele", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + if (!valid_arg_length(arguments, 2..3, player, "Invalid syntax - ::tele [x] [y] [optional-z]")) { + return@then + } + + val x = arguments[0].toInt() + val y = arguments[1].toInt() + val z = if (arguments.size == 3) arguments[2].toInt() else player.position.height + + if (z in 0..4) { + player.teleport(Position(x, y, z)) + } + } \ No newline at end of file From 4f45f5f1ff3d012678e9f54dd80bd0324f3a6e26 Mon Sep 17 00:00:00 2001 From: Cube Date: Sun, 4 Jun 2017 20:35:23 +0300 Subject: [PATCH 09/12] Convert experience commands to Kotlin --- game/src/plugins/cmd/src/skill-cmd.plugin.kts | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 game/src/plugins/cmd/src/skill-cmd.plugin.kts diff --git a/game/src/plugins/cmd/src/skill-cmd.plugin.kts b/game/src/plugins/cmd/src/skill-cmd.plugin.kts new file mode 100644 index 00000000..519e7701 --- /dev/null +++ b/game/src/plugins/cmd/src/skill-cmd.plugin.kts @@ -0,0 +1,66 @@ + +import org.apollo.game.model.entity.Skill +import org.apollo.game.model.entity.SkillSet +import org.apollo.game.model.entity.setting.PrivilegeLevel + +/** + * Maximises the player's skill set. + */ +on_command("max", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + val skills = player.skillSet + + for (skill in 0 until skills.size()) { + skills.addExperience(skill, SkillSet.MAXIMUM_EXP) + } + } + +/** + * Levels the specified skill to the specified level, optionally updating the current level as well. + */ +on_command("level", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + val invalidSyntax = "Invalid syntax - ::level [skill-id] [level] " + if (arguments.size !in 2..3) { + player.sendMessage(invalidSyntax) + return@then + } + + val skillId = arguments[0].toInt() + val level = arguments[1].toInt() + if (skillId !in 0..20 || level !in 1..99) { + player.sendMessage(invalidSyntax) + return@then + } + + val experience = SkillSet.getExperienceForLevel(level).toDouble() + var current = level + + if (arguments.size == 3 && arguments[2] == "old") { + val skill = player.skillSet.getSkill(skillId) + current = skill.currentLevel + } + + player.skillSet.setSkill(skillId, Skill(experience, current, level)) + } + +/** + * Adds the specified amount of experience to the specified skill. + */ +on_command("xp", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + val invalidSyntax = "Invalid syntax - ::xp [skill-id] [experience]" + if (arguments.size != 2) { + player.sendMessage(invalidSyntax) + return@then + } + + val skillId = arguments[0].toInt() + val experience = arguments[1].toDouble() + if (skillId !in 0..20 || experience <= 0) { + player.sendMessage("Invalid syntax - ::xp [skill-id] [experience]") + return@then + } + + player.skillSet.addExperience(skillId, experience) + } \ No newline at end of file From 3616753d7fabcc70b595e552c680605825b8583e Mon Sep 17 00:00:00 2001 From: Cube Date: Sun, 4 Jun 2017 21:11:37 +0300 Subject: [PATCH 10/12] Convert npc spawn commands to Kotlin --- game/src/plugins/cmd/src/spawn-cmd.plugin.kts | 110 ++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 game/src/plugins/cmd/src/spawn-cmd.plugin.kts diff --git a/game/src/plugins/cmd/src/spawn-cmd.plugin.kts b/game/src/plugins/cmd/src/spawn-cmd.plugin.kts new file mode 100644 index 00000000..7f124d89 --- /dev/null +++ b/game/src/plugins/cmd/src/spawn-cmd.plugin.kts @@ -0,0 +1,110 @@ +import com.google.common.primitives.Ints +import org.apollo.game.model.Position +import org.apollo.game.model.entity.Npc +import org.apollo.game.model.entity.setting.PrivilegeLevel + +/** + * An array of npcs that cannot be spawned. + */ +val blacklist: IntArray = intArrayOf() + +/** + * Spawns a non-blacklisted npc in the specified position, or the player's position if both 'x' and + * 'y' are not supplied. + */ +on_command("spawn", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + val invalidSyntax = "Invalid syntax - ::spawn [npc id] [optional-x] [optional-y] [optional-z]" + if (arguments.size !in intArrayOf(1, 3, 4)) { + player.sendMessage(invalidSyntax) + return@then + } + + val id = Ints.tryParse(arguments[0]) + if (id == null) { + player.sendMessage(invalidSyntax) + return@then + } + + if (id in blacklist) { + player.sendMessage("Sorry, npc $id is blacklisted!") + return@then + } + + val position: Position? + if (arguments.size == 1) { + position = player.position + } else { + var height = player.position.height + if (arguments.size == 4) { + val h = Ints.tryParse(arguments[3]) + if (h == null) { + player.sendMessage(invalidSyntax) + return@then + } + height = h + } + position = Position(arguments[1].toInt(), arguments[2].toInt(), height) + } + + player.world.register(Npc(player.world, id, position)) + } + +/** + * Mass spawns npcs around the player. + */ +on_command("mass", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + val invalidSyntax = "Invalid syntax - ::mass [npc id] [range (1-5)]" + if (arguments.size != 2) { + player.sendMessage(invalidSyntax) + return@then + } + + val id = Ints.tryParse(arguments[0]) + if (id == null) { + player.sendMessage(invalidSyntax) + return@then + } + + val range = Ints.tryParse(arguments[1]) + if (range == null) { + player.sendMessage(invalidSyntax) + return@then + } + + if (id < 0 || range !in 1..5) { + player.sendMessage(invalidSyntax) + return@then + } + + if (id in blacklist) { + player.sendMessage("Sorry, npc $id is blacklisted!") + return@then + } + + val centerPosition = player.position + + val minX = centerPosition.x - range + val minY = centerPosition.y - range + val maxX = centerPosition.x + range + val maxY = centerPosition.y + range + val z = centerPosition.height + + for (x in minX..maxX) { + for (y in minY..maxY) { + player.world.register(Npc(player.world, id, Position(x, y, z))) + } + } + + player.sendMessage("Mass spawning npcs with id $id.") + } + +/** + * Unregisters all npcs from the world npc repository. + */ +on_command("clearnpcs", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + player.world.npcRepository.forEach { npc -> player.world.unregister(npc) } + player.sendMessage("Unregistered all npcs from the world.") + } \ No newline at end of file From 4ca8978ff386d26cb3e9eaa7caebd7847f2eb97c Mon Sep 17 00:00:00 2001 From: Cube Date: Thu, 15 Jun 2017 23:14:34 +0300 Subject: [PATCH 11/12] Convert lookup commands to Kotlin --- game/src/plugins/cmd/src/lookup.plugin.kts | 47 ++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 game/src/plugins/cmd/src/lookup.plugin.kts diff --git a/game/src/plugins/cmd/src/lookup.plugin.kts b/game/src/plugins/cmd/src/lookup.plugin.kts new file mode 100644 index 00000000..4e15713e --- /dev/null +++ b/game/src/plugins/cmd/src/lookup.plugin.kts @@ -0,0 +1,47 @@ +import org.apollo.cache.def.ItemDefinition +import org.apollo.cache.def.NpcDefinition +import org.apollo.cache.def.ObjectDefinition +import org.apollo.game.model.entity.setting.PrivilegeLevel + +on_command("iteminfo", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::npcinfo [npc id]")) { + return@then + } + + val id = arguments[0].toInt() + val definition = ItemDefinition.lookup(id) + val members = if (definition.isMembersOnly) "members" else "not members" + + player.sendMessage("Item $id is called ${definition.name}, is $members only, and has a " + + "team of ${definition.team}.") + player.sendMessage("Its description is \"${definition.description}\".") + } + +on_command("npcinfo", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::npcinfo [npc id]")) { + return@then + } + + val id = arguments[0].toInt() + val definition = NpcDefinition.lookup(id) + val isCombative = if (definition.hasCombatLevel()) "has a combat level of ${definition.combatLevel}" else + "does not have a combat level" + + player.sendMessage("Npc $id is called ${definition.name} and $isCombative.") + player.sendMessage("Its description is \"${definition.description}\".") + } + +on_command("objectinfo", PrivilegeLevel.ADMINISTRATOR) + .then { player -> + if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::objectinfo [object id]")) { + return@then + } + + val id = arguments[0].toInt() + val definition = ObjectDefinition.lookup(id) + player.sendMessage("Object $id is called ${definition.name} and its description is " + + "\"${definition.description}\".") + player.sendMessage("Its width is ${definition.width} and its length is ${definition.length}.") + } \ No newline at end of file From c082f407ad3448510128c4df0dbaf2383d7ba54c Mon Sep 17 00:00:00 2001 From: Cube Date: Thu, 15 Jun 2017 23:39:47 +0300 Subject: [PATCH 12/12] Add input type checking to commands --- .../plugins/cmd/src/animate-cmd.plugin.kts | 12 +++++-- game/src/plugins/cmd/src/item-cmd.plugin.kts | 21 +++++++++++-- game/src/plugins/cmd/src/lookup.plugin.kts | 31 +++++++++++++++---- game/src/plugins/cmd/src/skill-cmd.plugin.kts | 28 ++++++++++++++--- .../plugins/cmd/src/teleport-cmd.plugin.kts | 28 ++++++++++++++--- 5 files changed, 101 insertions(+), 19 deletions(-) diff --git a/game/src/plugins/cmd/src/animate-cmd.plugin.kts b/game/src/plugins/cmd/src/animate-cmd.plugin.kts index 55b71306..cab21041 100644 --- a/game/src/plugins/cmd/src/animate-cmd.plugin.kts +++ b/game/src/plugins/cmd/src/animate-cmd.plugin.kts @@ -1,9 +1,17 @@ +import com.google.common.primitives.Ints import org.apollo.game.model.Animation import org.apollo.game.model.entity.setting.PrivilegeLevel on_command("animate", PrivilegeLevel.MODERATOR) .then { player -> - if(valid_arg_length(arguments, 1, player, "Invalid syntax - ::animate [animation-id]")) { - player.playAnimation(Animation(arguments[0].toInt())) + val invalidSyntax = "Invalid syntax - ::animate [animation-id]" + if(valid_arg_length(arguments, 1, player, invalidSyntax)) { + val id = Ints.tryParse(arguments[0]) + if (id == null) { + player.sendMessage(invalidSyntax) + return@then + } + + player.playAnimation(Animation(id)) } } \ No newline at end of file diff --git a/game/src/plugins/cmd/src/item-cmd.plugin.kts b/game/src/plugins/cmd/src/item-cmd.plugin.kts index 7f6f2255..52eafb18 100644 --- a/game/src/plugins/cmd/src/item-cmd.plugin.kts +++ b/game/src/plugins/cmd/src/item-cmd.plugin.kts @@ -1,14 +1,29 @@ +import com.google.common.primitives.Ints import org.apollo.cache.def.ItemDefinition import org.apollo.game.model.entity.setting.PrivilegeLevel on_command("item", PrivilegeLevel.ADMINISTRATOR) .then { player -> - if (!valid_arg_length(arguments, 1..2, player, "Invalid syntax - ::item [id] [amount]")) { + val invalidSyntax = "Invalid syntax - ::item [id] [amount]" + if (!valid_arg_length(arguments, 1..2, player, invalidSyntax)) { return@then } - val id = arguments[0].toInt() - val amount = if (arguments.size == 2) arguments[1].toInt() else 1 + val id = Ints.tryParse(arguments[0]) + if (id == null) { + player.sendMessage(invalidSyntax) + return@then + } + + var amount = 1 + if (arguments.size == 2) { + val amt = Ints.tryParse(arguments[1]) + if (amt == null) { + player.sendMessage(invalidSyntax) + return@then + } + amount = amt + } if (id < 0 || id >= ItemDefinition.count()) { player.sendMessage("The item id you specified is out of bounds!") diff --git a/game/src/plugins/cmd/src/lookup.plugin.kts b/game/src/plugins/cmd/src/lookup.plugin.kts index 4e15713e..a599c0f4 100644 --- a/game/src/plugins/cmd/src/lookup.plugin.kts +++ b/game/src/plugins/cmd/src/lookup.plugin.kts @@ -1,3 +1,4 @@ +import com.google.common.primitives.Ints import org.apollo.cache.def.ItemDefinition import org.apollo.cache.def.NpcDefinition import org.apollo.cache.def.ObjectDefinition @@ -5,11 +6,17 @@ import org.apollo.game.model.entity.setting.PrivilegeLevel on_command("iteminfo", PrivilegeLevel.ADMINISTRATOR) .then { player -> - if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::npcinfo [npc id]")) { + val invalidSyntax = "Invalid syntax - ::npcinfo [npc id]" + if (!valid_arg_length(arguments, 1, player, invalidSyntax)) { + return@then + } + + val id = Ints.tryParse(arguments[0]) + if (id == null) { + player.sendMessage(invalidSyntax) return@then } - val id = arguments[0].toInt() val definition = ItemDefinition.lookup(id) val members = if (definition.isMembersOnly) "members" else "not members" @@ -20,11 +27,17 @@ on_command("iteminfo", PrivilegeLevel.ADMINISTRATOR) on_command("npcinfo", PrivilegeLevel.ADMINISTRATOR) .then { player -> - if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::npcinfo [npc id]")) { + val invalidSyntax = "Invalid syntax - ::npcinfo [npc id]" + if (!valid_arg_length(arguments, 1, player, invalidSyntax)) { + return@then + } + + val id = Ints.tryParse(arguments[0]) + if (id == null) { + player.sendMessage(invalidSyntax) return@then } - val id = arguments[0].toInt() val definition = NpcDefinition.lookup(id) val isCombative = if (definition.hasCombatLevel()) "has a combat level of ${definition.combatLevel}" else "does not have a combat level" @@ -35,11 +48,17 @@ on_command("npcinfo", PrivilegeLevel.ADMINISTRATOR) on_command("objectinfo", PrivilegeLevel.ADMINISTRATOR) .then { player -> - if (!valid_arg_length(arguments, 1, player, "Invalid syntax - ::objectinfo [object id]")) { + val invalidSyntax = "Invalid syntax - ::objectinfo [object id]" + if (!valid_arg_length(arguments, 1, player, invalidSyntax)) { + return@then + } + + val id = Ints.tryParse(arguments[0]) + if (id == null) { + player.sendMessage(invalidSyntax) return@then } - val id = arguments[0].toInt() val definition = ObjectDefinition.lookup(id) player.sendMessage("Object $id is called ${definition.name} and its description is " + "\"${definition.description}\".") diff --git a/game/src/plugins/cmd/src/skill-cmd.plugin.kts b/game/src/plugins/cmd/src/skill-cmd.plugin.kts index 519e7701..ade6e6c0 100644 --- a/game/src/plugins/cmd/src/skill-cmd.plugin.kts +++ b/game/src/plugins/cmd/src/skill-cmd.plugin.kts @@ -1,4 +1,6 @@ +import com.google.common.primitives.Doubles +import com.google.common.primitives.Ints import org.apollo.game.model.entity.Skill import org.apollo.game.model.entity.SkillSet import org.apollo.game.model.entity.setting.PrivilegeLevel @@ -26,8 +28,17 @@ on_command("level", PrivilegeLevel.ADMINISTRATOR) return@then } - val skillId = arguments[0].toInt() - val level = arguments[1].toInt() + val skillId = Ints.tryParse(arguments[0]) + if (skillId == null) { + player.sendMessage(invalidSyntax) + return@then + } + val level = Ints.tryParse(arguments[1]) + if (level == null) { + player.sendMessage(invalidSyntax) + return@then + } + if (skillId !in 0..20 || level !in 1..99) { player.sendMessage(invalidSyntax) return@then @@ -55,8 +66,17 @@ on_command("xp", PrivilegeLevel.ADMINISTRATOR) return@then } - val skillId = arguments[0].toInt() - val experience = arguments[1].toDouble() + val skillId = Ints.tryParse(arguments[0]) + if (skillId == null) { + player.sendMessage(invalidSyntax) + return@then + } + val experience = Doubles.tryParse(arguments[1]) + if (experience == null) { + player.sendMessage(invalidSyntax) + return@then + } + if (skillId !in 0..20 || experience <= 0) { player.sendMessage("Invalid syntax - ::xp [skill-id] [experience]") return@then diff --git a/game/src/plugins/cmd/src/teleport-cmd.plugin.kts b/game/src/plugins/cmd/src/teleport-cmd.plugin.kts index c6bdba4f..75490b9f 100644 --- a/game/src/plugins/cmd/src/teleport-cmd.plugin.kts +++ b/game/src/plugins/cmd/src/teleport-cmd.plugin.kts @@ -1,3 +1,4 @@ +import com.google.common.primitives.Ints import org.apollo.game.model.Position import org.apollo.game.model.entity.setting.PrivilegeLevel @@ -14,13 +15,32 @@ on_command("pos", PrivilegeLevel.MODERATOR) */ on_command("tele", PrivilegeLevel.ADMINISTRATOR) .then { player -> - if (!valid_arg_length(arguments, 2..3, player, "Invalid syntax - ::tele [x] [y] [optional-z]")) { + val invalidSyntax = "Invalid syntax - ::tele [x] [y] [optional-z]" + if (!valid_arg_length(arguments, 2..3, player, invalidSyntax)) { return@then } - val x = arguments[0].toInt() - val y = arguments[1].toInt() - val z = if (arguments.size == 3) arguments[2].toInt() else player.position.height + val x = Ints.tryParse(arguments[0]) + if (x == null) { + player.sendMessage(invalidSyntax) + return@then + } + + val y = Ints.tryParse(arguments[1]) + if (y == null) { + player.sendMessage(invalidSyntax) + return@then + } + + var z = player.position.height + if (arguments.size == 3) { + val plane = Ints.tryParse(arguments[2]) + if (plane == null) { + player.sendMessage(invalidSyntax) + return@then + } + z = plane + } if (z in 0..4) { player.teleport(Position(x, y, z))