Skip to content

Commit

Permalink
Implement teleport
Browse files Browse the repository at this point in the history
  • Loading branch information
andyksaw committed Nov 18, 2024
1 parent 2896583 commit 0d7cd81
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,10 @@ internal interface PCBRequest {
@Query(value = "size") size: Int,
): PaginatedResponse<List<Build>>

@GET("v2/minecraft/build/{id}")
suspend fun getBuild(
@Path(value = "id") id: Int,
@POST("v2/minecraft/build/name/search")
@FormUrlEncoded
suspend fun getBuildByName(
@Field(value = "name") name: String,
): Build?

@GET("v2/minecraft/build/name")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ class BuildHttpService(
}
}

suspend fun getByName(name: String) = withContext(Dispatchers.IO) {
responseParser.parse {
retrofit.pcb().getBuildByName(name)
}
}

suspend fun names() = withContext(Dispatchers.IO) {
responseParser.parse {
retrofit.pcb().getNames()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,9 @@ private fun Module.builds() {

factory {
BuildCommand(
plugin = get(),
buildRepository = get(),
server = get(),
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,10 @@ private class Lifecycle : KoinComponent {
.lifecycleManager
.registerEventHandler(LifecycleEvents.COMMANDS) { event ->
event.registrar().register(
get<BuildsCommand>().buildLiteral(plugin = get<JavaPlugin>())
get<BuildsCommand>().buildLiteral()
)
event.registrar().register(
get<BuildCommand>().buildLiteral(plugin = get<JavaPlugin>())
get<BuildCommand>().buildLiteral()
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,80 @@
package com.projectcitybuild.pcbridge.paper.features.builds.commands

import com.github.shynixn.mccoroutine.bukkit.launch
import com.mojang.brigadier.arguments.StringArgumentType
import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.suggestion.SuggestionsBuilder
import com.mojang.brigadier.tree.LiteralCommandNode
import com.projectcitybuild.pcbridge.paper.features.builds.commands.repositories.BuildRepository
import com.projectcitybuild.pcbridge.paper.support.brigadier.executesSuspending
import com.projectcitybuild.pcbridge.paper.support.brigadier.suggestsSuspending
import io.papermc.paper.command.brigadier.CommandSourceStack
import io.papermc.paper.command.brigadier.Commands
import net.kyori.adventure.text.minimessage.MiniMessage
import org.bukkit.Location
import org.bukkit.Server
import org.bukkit.event.player.PlayerTeleportEvent
import org.bukkit.plugin.Plugin

@Suppress("UnstableApiUsage")
class BuildCommand(
private val plugin: Plugin,
private val buildRepository: BuildRepository,
private val server: Server,
) {
fun buildLiteral(plugin: Plugin): LiteralCommandNode<CommandSourceStack> {
fun buildLiteral(): LiteralCommandNode<CommandSourceStack> {
return Commands.literal("build")
.then(
Commands.argument("name", StringArgumentType.string())
.suggests { _, suggestions ->
plugin.launch {
buildRepository.names().forEach(suggestions::suggest)
}
suggestions.buildFuture()
}
.executes { context ->
val name = context.getArgument("name", String::class.java)
context.source.sender.sendMessage(name)
com.mojang.brigadier.Command.SINGLE_SUCCESS
}
Commands.argument("name", StringArgumentType.greedyString())
.suggestsSuspending(plugin, this::suggestBuild)
.executesSuspending(plugin, this::execute)
)
.build()
}

private suspend fun suggestBuild(
context: CommandContext<CommandSourceStack>,
suggestions: SuggestionsBuilder,
) {
val name = suggestions.remaining.lowercase()

// TODO: optimize with a Trie later
buildRepository.names()
.filter { it.lowercase().startsWith(name) }
.forEach(suggestions::suggest)
}

private suspend fun execute(context: CommandContext<CommandSourceStack>) {
val name = context.getArgument("name", String::class.java)

val build = buildRepository.get(name = name)
if (build == null) {
context.source.sender.sendMessage(
MiniMessage.miniMessage().deserialize("Build not found")
)
return
}
val world = server.getWorld(build.world)
if (world == null) {
context.source.sender.sendMessage(
MiniMessage.miniMessage().deserialize("<red>Error: Could not find world ${build.world}</red>")
)
return
}

context.source.sender.sendMessage(
MiniMessage.miniMessage().deserialize("<gray>Teleporting to $name...</gray>")
)
val location = Location(
world,
build.x,
build.y,
build.z,
build.yaw,
build.pitch,
)
context.source.executor?.teleportAsync(
location,
PlayerTeleportEvent.TeleportCause.COMMAND,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,14 @@ import com.mojang.brigadier.tree.LiteralCommandNode
import com.projectcitybuild.pcbridge.paper.features.builds.commands.builds.BuildListCommand
import io.papermc.paper.command.brigadier.CommandSourceStack
import io.papermc.paper.command.brigadier.Commands
import org.bukkit.plugin.Plugin

@Suppress("UnstableApiUsage")
class BuildsCommand(
private val buildListCommand: BuildListCommand,
) {
fun buildLiteral(plugin: Plugin): LiteralCommandNode<CommandSourceStack> {
fun buildLiteral(): LiteralCommandNode<CommandSourceStack> {
return Commands.literal("builds")
.then(buildListCommand.buildLiteral(plugin))
.then(
Commands.literal("create")
.executes { context ->
context.source.sender.sendMessage("create")
com.mojang.brigadier.Command.SINGLE_SUCCESS
}
)
.then(
Commands.literal("move")
.executes { context ->
context.source.sender.sendMessage("move")
com.mojang.brigadier.Command.SINGLE_SUCCESS
}
)
.then(
Commands.literal("rename")
.executes { context ->
context.source.sender.sendMessage("rename")
com.mojang.brigadier.Command.SINGLE_SUCCESS
}
)
.executes { context ->
context.source.sender.sendMessage("root")
com.mojang.brigadier.Command.SINGLE_SUCCESS
}
.then(buildListCommand.buildLiteral())
.build()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import org.bukkit.plugin.Plugin

@Suppress("UnstableApiUsage")
class BuildListCommand(
private val plugin: Plugin,
private val buildRepository: BuildRepository,
) {
fun buildLiteral(plugin: Plugin): LiteralCommandNode<CommandSourceStack> {
fun buildLiteral(): LiteralCommandNode<CommandSourceStack> {
return Commands.literal("list")
.then(
Commands.argument("page", IntegerArgumentType.integer())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class BuildRepository(
}

suspend fun get(name: String): Build? {
return null
return buildHttpService.getByName(name)
}

suspend fun names(): List<String> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.projectcitybuild.pcbridge.paper.support.brigadier

import com.github.shynixn.mccoroutine.bukkit.launch
import com.mojang.brigadier.Command
import com.mojang.brigadier.builder.RequiredArgumentBuilder
import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.suggestion.SuggestionsBuilder
import org.bukkit.plugin.Plugin

/**
* Same as [RequiredArgumentBuilder.suggests] but bridged to a suspending function
*/
fun <S, T> RequiredArgumentBuilder<S, T>.suggestsSuspending(
plugin: Plugin,
block: suspend (CommandContext<S>, SuggestionsBuilder) -> Unit,
): RequiredArgumentBuilder<S, T> {
return suggests { context, suggestions ->
plugin.launch { block(context, suggestions) }
suggestions.buildFuture()
}
}

/**
* Same as [RequiredArgumentBuilder.executes] but bridged to a suspending function
*/
fun <S, T> RequiredArgumentBuilder<S, T>.executesSuspending(
plugin: Plugin,
block: suspend (CommandContext<S>) -> Unit,
): RequiredArgumentBuilder<S, T> {
return executes { context ->
plugin.launch { block(context) }
Command.SINGLE_SUCCESS
}
}

0 comments on commit 0d7cd81

Please sign in to comment.