Skip to content
Open
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 @@ -64,6 +64,13 @@ class SimpleCommandBody(val func: CommandComponent.() -> Unit = {}) {
}
}

private fun SimpleCommandBody.registerTo(component: CommandComponent) {
component.literal(name, *aliases, optional = optional, permission = permission, hidden = hidden, description = description) {
func(this)
this@registerTo.children.forEach { it.registerTo(this) }
}
}

@Suppress("DuplicatedCode")
@Inject
@Awake
Expand Down Expand Up @@ -138,18 +145,7 @@ class SimpleCommandRegister : ClassVisitor(0) {
command(name, alias, description, usage, permission, permissionMessage, permissionDefault, permissionChildren, newParser) {
main[clazz.name]?.func?.invoke(this)
body[clazz.name]?.forEach { body ->
fun register(body: SimpleCommandBody, component: CommandComponent) {
component.literal(body.name, *body.aliases, optional = body.optional, permission = body.permission, hidden = body.hidden, description = body.description) {
if (body.children.isEmpty()) {
body.func(this)
} else {
body.children.forEach { children ->
register(children, this)
}
}
}
}
register(body, this)
body.registerTo(this)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package taboolib.common.platform.command

import org.junit.jupiter.api.Assertions.assertArrayEquals
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import taboolib.common.platform.command.component.CommandBase
import taboolib.common.platform.command.component.CommandComponent
import taboolib.common.platform.command.component.CommandComponentLiteral

class SimpleCommandTest {

@Test
fun `empty body tree still applies body function`() {
val body = SimpleCommandBody {
literal("declared")
}.apply {
name = "root"
}
val command = CommandBase()

register(body, command)

val root = command.children.single() as CommandComponentLiteral
assertArrayEquals(arrayOf("root"), root.aliases)
assertArrayEquals(arrayOf("declared"), (root.children.single() as CommandComponentLiteral).aliases)
}

@Test
fun `body function and nested bodies register consistently`() {
val body = SimpleCommandBody {
literal("declared")
}.apply {
name = "root"
children += SimpleCommandBody {
literal("leaf")
}.apply {
name = "nested"
}
}
val command = CommandBase()

register(body, command)

val root = command.children.single() as CommandComponentLiteral
assertEquals(2, root.children.size)
assertArrayEquals(arrayOf("declared"), (root.children[0] as CommandComponentLiteral).aliases)
val nested = root.children[1] as CommandComponentLiteral
assertArrayEquals(arrayOf("nested"), nested.aliases)
assertArrayEquals(arrayOf("leaf"), (nested.children.single() as CommandComponentLiteral).aliases)
}

private fun register(body: SimpleCommandBody, component: CommandComponent) {
val method = Class.forName("taboolib.common.platform.command.SimpleCommandKt")
.getDeclaredMethod("registerTo", SimpleCommandBody::class.java, CommandComponent::class.java)
method.isAccessible = true
method.invoke(null, body, component)
}
}
8 changes: 8 additions & 0 deletions platform/platform-bukkit-impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,12 @@ dependencies {
// XSeries
compileOnly("com.google.code.findbugs:jsr305:3.0.2")
compileOnly("org.apache.logging.log4j:log4j-api:2.14.1")

testImplementation(project(":common"))
testImplementation(project(":common-platform-api"))
testImplementation(project(":common-util"))
testImplementation("io.paper:folia-api:1.21.4")
testImplementation("net.kyori:adventure-api:4.17.0")
testImplementation("net.kyori:adventure-text-minimessage:4.17.0")
testImplementation("net.md-5:bungeecord-chat:1.20")
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class BukkitPlayer(val player: Player) : ProxyPlayer {
override var bedSpawnLocation: Location?
get() = player.bedSpawnLocation?.toProxyLocation()
set(value) {
player.bedSpawnLocation = value!!.toBukkitLocation()
player.bedSpawnLocation = value?.toBukkitLocation()
}

override var displayName: String?
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package taboolib.platform.type

import org.bukkit.entity.Player
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Test
import java.lang.reflect.Proxy

class BukkitPlayerTest {

@Test
fun `null bed spawn location reaches bukkit setter`() {
var calls = 0
val player = Proxy.newProxyInstance(Player::class.java.classLoader, arrayOf(Player::class.java)) { _, method, args ->
if (method.name == "setBedSpawnLocation" && method.parameterCount == 1) {
calls++
assertNull(args?.firstOrNull())
null
} else {
defaultValue(method.returnType)
}
} as Player

BukkitPlayer(player).bedSpawnLocation = null

assertEquals(1, calls)
}

private fun defaultValue(type: Class<*>): Any? {
return when (type) {
java.lang.Boolean.TYPE -> false
java.lang.Byte.TYPE -> 0.toByte()
java.lang.Short.TYPE -> 0.toShort()
java.lang.Integer.TYPE -> 0
java.lang.Long.TYPE -> 0L
java.lang.Float.TYPE -> 0F
java.lang.Double.TYPE -> 0.0
java.lang.Character.TYPE -> '\u0000'
else -> null
}
}
}
2 changes: 2 additions & 0 deletions platform/platform-bungee-impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ dependencies {
compileOnly(project(":common-platform-api"))
compileOnly(project(":platform:platform-bungee"))
compileOnly("net.md_5.bungee:BungeeCord:1")

testImplementation("net.md_5.bungee:BungeeCord:1")
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,20 @@ class BungeeCommand : PlatformCommand {
commandBuilder: CommandBase.() -> Unit,
) {
val permission = command.permission.ifEmpty { "${plugin.description.name}.command.use" }
BungeeCord.getInstance().pluginManager.registerCommand(BungeePlugin.getInstance(), object : Command(command.name, permission), TabExecutor {

override fun execute(sender: CommandSender, args: Array<String>) {
executor.execute(adaptCommandSender(sender), command, command.name, args)
}

override fun onTabComplete(sender: CommandSender, args: Array<String>): MutableIterable<String> {
return completer.execute(adaptCommandSender(sender), command, command.name, args)?.toMutableList() ?: ArrayList()
val registeredCommand = RegisteredBungeeCommand(
command.name,
permission,
command.aliases,
execute = { sender, args -> executor.execute(adaptCommandSender(sender), command, command.name, args) },
complete = { sender, args ->
completer.execute(adaptCommandSender(sender), command, command.name, args)?.toMutableList() ?: ArrayList()
}
})
)
BungeeCord.getInstance().pluginManager.registerCommand(BungeePlugin.getInstance(), registeredCommand)
}

override fun unregisterCommand(command: String) {
val instance = BungeeCord.getInstance().pluginManager.getProperty<MutableMap<String, Command>>("commandMap")!![command] ?: return
val instance = BungeeCord.getInstance().pluginManager.getProperty<MutableMap<String, Command>>("commandMap")?.get(command) ?: return
BungeeCord.getInstance().pluginManager.unregisterCommand(instance)
}

Expand All @@ -82,4 +82,21 @@ class BungeeCommand : PlatformCommand {
}
sender.cast<CommandSender>().sendMessage(*components.toTypedArray())
}
}
}

private class RegisteredBungeeCommand(
name: String,
permission: String,
aliases: List<String>,
private val execute: (CommandSender, Array<String>) -> Unit,
private val complete: (CommandSender, Array<String>) -> MutableIterable<String>,
) : Command(name, permission, *aliases.toTypedArray()), TabExecutor {

override fun execute(sender: CommandSender, args: Array<String>) {
execute.invoke(sender, args)
}

override fun onTabComplete(sender: CommandSender, args: Array<String>): MutableIterable<String> {
return complete.invoke(sender, args)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,10 @@ class BungeePlayer(val player: ProxiedPlayer) : ProxyPlayer {
}

override fun sendTitle(title: String?, subtitle: String?, fadein: Int, stay: Int, fadeout: Int) {
val (titleComponent, subtitleComponent) = bungeeTitleComponents(title, subtitle)
val titleMessage = BungeePlugin.getInstance().proxy.createTitle().also {
it.title(TextComponent(title ?: ""))
it.subTitle(TextComponent(title ?: ""))
it.title(titleComponent)
it.subTitle(subtitleComponent)
it.fadeIn(fadein)
it.stay(stay)
it.fadeOut(fadeout)
Expand Down Expand Up @@ -332,4 +333,8 @@ class BungeePlayer(val player: ProxiedPlayer) : ProxyPlayer {
BungeePlayer(e.player).quitCallback.forEach { it.run() }
}
}
}

private fun bungeeTitleComponents(title: String?, subtitle: String?): Pair<TextComponent, TextComponent> {
return TextComponent(title ?: "") to TextComponent(subtitle ?: "")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package taboolib.platform

import net.md_5.bungee.api.CommandSender
import net.md_5.bungee.api.chat.TextComponent
import net.md_5.bungee.api.plugin.Command
import org.junit.jupiter.api.Assertions.assertArrayEquals
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class BungeeCompatibilityTest {

@Test
fun `registered command keeps configured aliases`() {
val command = registeredCommand(listOf("alias", "short"))

assertEquals("main", command.name)
assertEquals("plugin.command.main", command.permission)
assertArrayEquals(arrayOf("alias", "short"), command.aliases)
}

@Test
fun `title components keep title and subtitle independent`() {
val (title, subtitle) = titleComponents("Title", "Subtitle")
assertEquals("Title", title.text)
assertEquals("Subtitle", subtitle.text)

val (emptyTitle, emptySubtitle) = titleComponents(null, null)
assertEquals("", emptyTitle.text)
assertEquals("", emptySubtitle.text)
}

private fun registeredCommand(aliases: List<String>): Command {
val constructor = Class.forName("taboolib.platform.RegisteredBungeeCommand").declaredConstructors.single()
constructor.isAccessible = true
val execute: (CommandSender, Array<String>) -> Unit = { _, _ -> }
val complete: (CommandSender, Array<String>) -> MutableIterable<String> = { _, _ -> mutableListOf() }
return constructor.newInstance("main", "plugin.command.main", aliases, execute, complete) as Command
}

@Suppress("UNCHECKED_CAST")
private fun titleComponents(title: String?, subtitle: String?): Pair<TextComponent, TextComponent> {
val method = Class.forName("taboolib.platform.type.BungeePlayerKt")
.getDeclaredMethod("bungeeTitleComponents", String::class.java, String::class.java)
method.isAccessible = true
return method.invoke(null, title, subtitle) as Pair<TextComponent, TextComponent>
}
}
9 changes: 9 additions & 0 deletions platform/platform-hytale/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,13 @@ dependencies {
compileOnly(project(":common-util"))
compileOnly(project(":common-platform-api"))
compileOnly("com.hypixel:hytale-server:1.0.0")

testImplementation(project(":common"))
testImplementation(project(":common-util"))
testImplementation(project(":common-platform-api"))
testImplementation("com.hypixel:hytale-server:1.0.0")
}

tasks.test {
systemProperty("java.util.logging.manager", "com.hypixel.hytale.logger.backend.HytaleLogManager")
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,15 @@ class HytaleAdapter : PlatformAdapter {
}

override fun adaptPlayer(any: Any): ProxyPlayer {
return HytalePlayer(any as Player)
return if (any is ProxyPlayer) any else HytalePlayer(any as Player)
}

override fun adaptCommandSender(any: Any): ProxyCommandSender {
return if (any is Player) adaptPlayer(any) else HytaleCommandSender(any as CommandSender)
return when (any) {
is ProxyCommandSender -> any
is Player -> adaptPlayer(any)
else -> HytaleCommandSender(any as CommandSender)
}
}

override fun adaptLocation(any: Any): Location {
Expand Down
Loading
Loading