Skip to content

Commit

Permalink
feat(version-support): add 1.19.4, 1.19.3, 1.19.2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
StillLutto committed Dec 20, 2024
1 parent d326e6a commit 344a574
Show file tree
Hide file tree
Showing 25 changed files with 2,445 additions and 8 deletions.
3 changes: 3 additions & 0 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ version = versionVar
dependencies {
compileOnly("org.spigotmc:spigot-api:1.20.6-R0.1-SNAPSHOT")
implementation(project(":common"))
implementation(project(":v1_19_2"))
implementation(project(":v1_19_3"))
implementation(project(":v1_19_4"))
implementation(project(":v1_20"))
implementation(project(":v1_20_1"))
implementation(project(":v1_20_2"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import org.jetbrains.annotations.ApiStatus
@ApiStatus.Internal
object CommandManager {
val registrars: Map<String, AbstractCommandRegistrar> = mapOf(
"1.19.2" to com.undefined.stellar.v1_19_2.CommandRegistrar,
"1.19.3" to com.undefined.stellar.v1_19_3.CommandRegistrar,
"1.19.4" to com.undefined.stellar.v1_19_4.CommandRegistrar,
"1.20" to com.undefined.stellar.v1_20.CommandRegistrar,
"1.20.1" to com.undefined.stellar.v1_20_1.CommandRegistrar,
"1.20.2" to com.undefined.stellar.v1_20_2.CommandRegistrar,
Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ allprojects {
dependencies {
implementation(project(":api"))
implementation(project(":common"))
implementation(project(":v1_19_3:", "reobf"))
implementation(project(":v1_19_4:", "reobf"))
implementation(project(":v1_20", "reobf"))
implementation(project(":v1_20_1", "reobf"))
implementation(project(":v1_20_2", "reobf"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:Suppress("DEPRECATION")

package com.undefined.stellar.argument

import com.undefined.stellar.AbstractStellarCommand
Expand Down Expand Up @@ -31,7 +33,12 @@ import org.bukkit.OfflinePlayer
import org.bukkit.entity.Player
import java.util.*

@Suppress("DEPRECATION")
/**
* An open class that adds all the methods for adding arguments
*
* @code
* @since 1.0
*/
open class ArgumentHandler {

open val base: AbstractStellarCommand<*> get() = throw IllegalStateException("Cannot access the getter from the property base when it hasn't been overridden!")
Expand Down
3 changes: 3 additions & 0 deletions server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ dependencies {

implementation(project(":api"))
implementation(project(":common"))
implementation(project(":v1_19_2:", "reobf"))
implementation(project(":v1_19_3:", "reobf"))
implementation(project(":v1_19_4:", "reobf"))
implementation(project(":v1_20:", "reobf"))
implementation(project(":v1_20_1:", "reobf"))
implementation(project(":v1_20_2:", "reobf"))
Expand Down
10 changes: 4 additions & 6 deletions server/src/main/kotlin/com/undefined/stellar/Main.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package com.undefined.stellar

import org.bukkit.Instrument
import org.bukkit.Location
import org.bukkit.entity.Player
import org.bukkit.plugin.java.JavaPlugin

class Main : JavaPlugin() {

override fun onEnable() {
val command = StellarCommand("test")
command
.addArgument("t")
.addArguments
.addInstrumentArgument("block")
command.addArgument("t")
.addLocationArgument("block")
.addExecution<Player> {
sender.sendMessage(getArgument<Instrument>("block").name)
sender.sendMessage(getArgument<Location>("block").toVector().toString())
}
command.register(this)
}
Expand Down
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
rootProject.name = "stellar"
include("server", "api", "common", "v1_20", "v1_20_1", "v1_20_2", "v1_20_4", "v1_20_6", "v1_21", "v1_21_1", "v1_21_3", "v1_21_4")
include("server", "api", "common", "v1_19_2", "v1_19_3", "v1_19_4", "v1_20", "v1_20_1", "v1_20_2", "v1_20_4", "v1_20_6", "v1_21", "v1_21_1", "v1_21_3", "v1_21_4")
26 changes: 26 additions & 0 deletions v1_19_2/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
plugins {
kotlin("jvm") version "1.9.22"
id("io.papermc.paperweight.userdev") version "1.7.1"
}

paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.REOBF_PRODUCTION

dependencies {
paperweight.paperDevBundle("1.19.2-R0.1-SNAPSHOT")
pluginRemapper("net.fabricmc:tiny-remapper:0.10.3:fat")
compileOnly(project(":common"))
}

tasks {
compileKotlin {
kotlinOptions.jvmTarget = "17"
}
}

java {
disableAutoTargetJvm()
}

kotlin {
jvmToolchain(17)
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.undefined.stellar.v1_19_2

import com.mojang.brigadier.builder.LiteralArgumentBuilder
import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.tree.LiteralCommandNode
import com.undefined.stellar.AbstractStellarCommand
import com.undefined.stellar.argument.AbstractStellarArgument
import com.undefined.stellar.data.help.CustomCommandHelpTopic
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
import net.minecraft.commands.CommandSourceStack
import net.minecraft.server.MinecraftServer
import org.bukkit.Bukkit

object BrigadierCommandHelper {

val COMMAND_SOURCE: CommandSourceStack by lazy {
MinecraftServer.getServer().createCommandSourceStack()
}
val dispatcher by lazy { MinecraftServer.getServer().functions.dispatcher }
val version: String = "1.19.2"

fun register(command: LiteralArgumentBuilder<CommandSourceStack>): LiteralCommandNode<CommandSourceStack>? =
dispatcher.register(command)

fun handleHelpTopic(command: AbstractStellarCommand<*>) {
Bukkit.getServer().helpMap.addTopic(
CustomCommandHelpTopic(command.name, command.description, command.helpTopic) {
val context = MinecraftServer.getServer().createCommandSourceStack()
val requirements = command.requirements.all { it(this) }
val permissionRequirements = command.permissionRequirements.all {
if (it.permission.isEmpty()) context.hasPermission(it.level)
else context.hasPermission(it.level, it.permission)
}
requirements.and(permissionRequirements)
}
)
}

fun handleExecutions(command: AbstractStellarCommand<*>, context: CommandContext<CommandSourceStack>) {
val stellarContext = CommandContextAdapter.getStellarCommandContext(context)

for (runnable in command.base.runnables) runnable(stellarContext)
val arguments = getArguments(command.base, context)
for (argument in arguments) for (runnable in argument.runnables) runnable(stellarContext)
for (execution in command.executions) execution(stellarContext)
}

fun fulfillsRequirements(command: AbstractStellarCommand<*>, source: CommandSourceStack): Boolean {
val fulfillsExecutionRequirements = command.requirements.all { it(source.bukkitSender) }
val fulfillsPermissionRequirements = command.permissionRequirements.all { source.hasPermission(it.level, it.permission) }
return fulfillsExecutionRequirements.and(fulfillsPermissionRequirements)
}

fun handleFailureMessageAndExecutions(command: AbstractStellarCommand<*>, context: CommandContext<CommandSourceStack>) {
for (execution in command.failureExecutions) execution(CommandContextAdapter.getStellarCommandContext(context))
for (message in command.failureMessages) context.source.bukkitSender.sendMessage(LegacyComponentSerializer.legacySection().serialize(message))
for (message in command.globalFailureMessages) context.source.bukkitSender.sendMessage(LegacyComponentSerializer.legacySection().serialize(message))
}

fun getArguments(
baseCommand: AbstractStellarCommand<*>,
context: CommandContext<CommandSourceStack>,
currentIndex: Int = 1,
listOfArguments: List<AbstractStellarArgument<*>> = emptyList()
): List<AbstractStellarArgument<*>> {
if (listOfArguments.size == context.nodes.size - 1) return listOfArguments
for (argument in baseCommand.arguments)
if (argument.name == context.nodes[currentIndex].node.name)
return getArguments(argument, context, currentIndex + 1, listOfArguments + argument)
return emptyList()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.undefined.stellar.v1_19_2

import com.mojang.brigadier.Command
import com.mojang.brigadier.builder.ArgumentBuilder
import com.mojang.brigadier.builder.LiteralArgumentBuilder
import com.mojang.brigadier.builder.RequiredArgumentBuilder
import com.undefined.stellar.AbstractStellarCommand
import com.undefined.stellar.argument.AbstractStellarArgument
import com.undefined.stellar.argument.LiteralStellarArgument
import com.undefined.stellar.argument.types.primitive.PhraseArgument
import net.minecraft.commands.CommandSourceStack

object CommandAdapter {

fun getBaseCommand(command: AbstractStellarCommand<*>, name: String = command.name): LiteralArgumentBuilder<CommandSourceStack> {
val brigadierCommand = LiteralArgumentBuilder.literal<CommandSourceStack>(name)
handleCommandFunctions(command, brigadierCommand)
handleArguments(command, brigadierCommand)
return brigadierCommand
}

fun handleCommandFunctions(command: AbstractStellarCommand<*>, brigadierCommand: ArgumentBuilder<CommandSourceStack, *>) {
if (command.executions.isNotEmpty() || command.executions.isNotEmpty())
brigadierCommand.executes { context ->
BrigadierCommandHelper.handleExecutions(command, context)
1
}
brigadierCommand.requires { source ->
BrigadierCommandHelper.fulfillsRequirements(command, source)
}
}

fun handleArguments(command: AbstractStellarCommand<*>, brigadierCommand: ArgumentBuilder<CommandSourceStack, *>) {
for (argument in command.arguments) {
when (argument) {
is LiteralStellarArgument -> handleLiteralArgument(argument, brigadierCommand)
is PhraseArgument-> handlePhraseArgument(argument, brigadierCommand)
else -> handleRequiredArgument(argument, brigadierCommand)
}
}
}

private fun handleLiteralArgument(argument: LiteralStellarArgument, brigadierCommand: ArgumentBuilder<CommandSourceStack, *>) {
for (argumentBuilder in ArgumentHelper.getLiteralArguments(argument)) {
handleCommandFunctions(argument, argumentBuilder)
handleArguments(argument, argumentBuilder)
brigadierCommand.then(argumentBuilder)
}
}

private fun handlePhraseArgument(argument: PhraseArgument, brigadierCommand: ArgumentBuilder<CommandSourceStack, *>) {
val argumentBuilder = ArgumentHelper.getRequiredArgumentBuilder(argument)
handleCommandFunctions(argument, argumentBuilder)
handleGreedyStringWordFunctions(argument, argumentBuilder)
brigadierCommand.then(argumentBuilder)
}

private fun handleGreedyStringWordFunctions(argument: PhraseArgument, argumentBuilder: RequiredArgumentBuilder<CommandSourceStack, *>) {
argumentBuilder.executes { context ->
val greedyContext = CommandContextAdapter.getGreedyCommandContext(context)

for (i in greedyContext.arguments.indices) {
val word = argument.words[i] ?: continue
for (runnable in word.runnables) runnable(greedyContext)
if (i == greedyContext.arguments.lastIndex)
for (execution in word.executions) execution(greedyContext)
}
Command.SINGLE_SUCCESS
}

argumentBuilder.suggests { context, builder ->
val greedyContext = CommandContextAdapter.getGreedyCommandContext(context)
var prevChar = ' '
val input = ArgumentHelper.getArgumentInput(context, argument.name) ?: ""
val amountOfSpaces: Int = if (input.isEmpty()) 0 else input.count {
if (prevChar == ' ' && it == ' ') return@count false
prevChar = it
it == ' '
}
val newBuilder = builder.createOffset(builder.input.lastIndexOf(' ') + 1)
val word = argument.words[amountOfSpaces] ?: return@suggests newBuilder.buildFuture()
for (stellarSuggestion in word.suggestions)
for (suggestion in stellarSuggestion.get(greedyContext))
newBuilder.suggest(suggestion.text) { suggestion.tooltip }
newBuilder.buildFuture()
}
}

private fun handleRequiredArgument(argument: AbstractStellarArgument<*>, brigadierCommand: ArgumentBuilder<CommandSourceStack, *>) {
val argumentBuilder = ArgumentHelper.getRequiredArgumentBuilder(argument)
handleCommandFunctions(argument, argumentBuilder)
handleArguments(argument, argumentBuilder)
brigadierCommand.then(argumentBuilder)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.undefined.stellar.v1_19_2

import com.mojang.brigadier.context.CommandContext
import com.undefined.stellar.AbstractStellarCommand
import com.undefined.stellar.StellarCommands
import com.undefined.stellar.argument.AbstractStellarArgument
import com.undefined.stellar.argument.LiteralStellarArgument
import com.undefined.stellar.argument.types.custom.CustomArgument
import com.undefined.stellar.data.argument.CommandNode
import com.undefined.stellar.data.argument.PhraseCommandContext
import com.undefined.stellar.exception.DuplicateArgumentNameException
import com.undefined.stellar.exception.LiteralArgumentMismatchException
import io.papermc.paper.adventure.PaperAdventure
import net.kyori.adventure.identity.Identity
import net.minecraft.commands.CommandSource
import net.minecraft.commands.CommandSourceStack
import net.minecraft.network.chat.Component
import net.minecraft.server.MinecraftServer
import net.minecraft.world.phys.Vec2
import net.minecraft.world.phys.Vec3
import org.bukkit.command.CommandSender

object CommandContextAdapter {

fun getStellarCommandContext(context: CommandContext<CommandSourceStack>): com.undefined.stellar.data.argument.CommandContext<CommandSender> {
val input = context.input.removePrefix("/")
val baseCommand: AbstractStellarCommand<*> = StellarCommands.getStellarCommand(context.nodes[0].node.name)!!
val arguments = BrigadierCommandHelper.getArguments(baseCommand, context)
if (arguments.filter { it !is LiteralStellarArgument }.groupingBy { it.name }.eachCount().any { it.value > 1 }) throw DuplicateArgumentNameException()
val parsedArguments: CommandNode =
BrigadierCommandHelper.getArguments(baseCommand, context)
.associate<AbstractStellarArgument<*>, String, (com.undefined.stellar.data.argument.CommandContext<CommandSender>) -> Any?> { argument ->
if (argument is CustomArgument) return@associate Pair(argument.name) { argument.parse(it) }
if (argument is LiteralStellarArgument) return@associate Pair(argument.name) { throw LiteralArgumentMismatchException() }
Pair(argument.name) {
ArgumentHelper.getParsedArgument(context, argument)
}
} as CommandNode
return com.undefined.stellar.data.argument.CommandContext(
parsedArguments,
context.source.bukkitSender,
input
)
}

fun getGreedyCommandContext(context: CommandContext<CommandSourceStack>): PhraseCommandContext<CommandSender> {
val input = context.input.removePrefix("/")
val words = input.split(' ').toMutableList()

val totalOtherArguments = context.nodes.size - 1
for (i in (1..totalOtherArguments)) words.removeFirst()
return PhraseCommandContext(
words,
context.source.bukkitSender,
input
)
}

fun getCommandSourceStack(sender: CommandSender): CommandSourceStack {
val overworld = MinecraftServer.getServer().overworld()
return CommandSourceStack(
Source(sender),
Vec3.atLowerCornerOf(overworld.getSharedSpawnPos()),
Vec2.ZERO,
overworld,
4,
sender.name,
Component.literal(sender.name),
MinecraftServer.getServer(),
null
)
}

@JvmRecord
@Suppress("DEPRECATION")
private data class Source(val sender: CommandSender) : CommandSource {
override fun sendSystemMessage(message: Component) {
sender.sendMessage(Identity.nil(), PaperAdventure.asAdventure(message))
}

override fun acceptsSuccess(): Boolean {
return true
}

override fun acceptsFailure(): Boolean {
return true
}

override fun shouldInformAdmins(): Boolean {
return false
}

override fun getBukkitSender(stack: CommandSourceStack): CommandSender {
return this.sender
}
}

}
Loading

0 comments on commit 344a574

Please sign in to comment.