Compare commits
10 commits
682cff9a8b
...
c75c4cfabc
| Author | SHA1 | Date | |
|---|---|---|---|
| c75c4cfabc | |||
| 336ac4cad5 | |||
| ef32f9dbc4 | |||
| 1429286ce8 | |||
| 4db84feb43 | |||
| dd25337ed6 | |||
| 0086329da9 | |||
| f1b67ed17f | |||
| a8807c9d7e | |||
| a2d1153ae8 |
86 changed files with 1514 additions and 1439 deletions
7
.bazelrc
Normal file
7
.bazelrc
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
build --java_language_version=25
|
||||||
|
build --java_runtime_version=25
|
||||||
|
build --tool_java_language_version=25
|
||||||
|
build --tool_java_runtime_version=25
|
||||||
|
build --define=maven_repo=https://repo.lab0x13.site/snapshots
|
||||||
|
build --remote_cache=https://cache.lab0x13.site
|
||||||
|
build --remote_upload_local_results=false
|
||||||
15
.forgejo/workflows/publish-artifact.yml
Normal file
15
.forgejo/workflows/publish-artifact.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: "git.lab0x13.site/scrow/bazel-java:0.5"
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
- id: build
|
||||||
|
run: |
|
||||||
|
bazel build //bukkit:bukkit.publish //core:core.publish //velocity:velocity.publish \
|
||||||
|
--remote_cache='https://${{ secrets.CACHE_USERNAME }}:${{ secrets.CACHE_PASSWORD }}@cache.lab0x13.site' --remote_upload_local_results
|
||||||
13
.gitignore
vendored
13
.gitignore
vendored
|
|
@ -1,9 +1,10 @@
|
||||||
.gradle
|
/.idea/inspectionProfiles
|
||||||
build/
|
/MODULE.bazel.lock
|
||||||
!gradle/wrapper/gradle-wrapper.jar
|
/.bazelbsp
|
||||||
!**/src/main/**/build/
|
/bazel-bin
|
||||||
!**/src/test/**/build/
|
/bazel-out
|
||||||
.kotlin
|
/bazel-KenCommandAPI
|
||||||
|
/bazel-testlogs
|
||||||
|
|
||||||
### IntelliJ IDEA ###
|
### IntelliJ IDEA ###
|
||||||
.idea/modules.xml
|
.idea/modules.xml
|
||||||
|
|
|
||||||
17
.idea/bazelVersionCache.xml
generated
Normal file
17
.idea/bazelVersionCache.xml
generated
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="BazelGithubResolverVersionCache">
|
||||||
|
<forks>
|
||||||
|
<entry key="bazelbuild">
|
||||||
|
<fork_state>
|
||||||
|
<option name="name" value="bazelbuild" />
|
||||||
|
<option name="version" value="9.2.0" />
|
||||||
|
<option name="lastUpdated" value="1785771270076" />
|
||||||
|
</fork_state>
|
||||||
|
</entry>
|
||||||
|
</forks>
|
||||||
|
</component>
|
||||||
|
<component name="BazelVersionCache">
|
||||||
|
<option name="resolverId" value="github" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
30
.idea/gradle.xml
generated
30
.idea/gradle.xml
generated
|
|
@ -1,34 +1,4 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
|
||||||
<option name="linkedExternalProjectsSettings">
|
|
||||||
<GradleProjectSettings>
|
|
||||||
<compositeConfiguration>
|
|
||||||
<compositeBuild compositeDefinitionSource="SCRIPT">
|
|
||||||
<builds>
|
|
||||||
<build path="$PROJECT_DIR$/../build-logic" name="build-logic">
|
|
||||||
<projects>
|
|
||||||
<project path="$PROJECT_DIR$/../build-logic" />
|
|
||||||
<project path="$PROJECT_DIR$/../build-logic/convention" />
|
|
||||||
</projects>
|
|
||||||
</build>
|
|
||||||
</builds>
|
|
||||||
</compositeBuild>
|
|
||||||
</compositeConfiguration>
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="gradleJvm" value="#JAVA_HOME" />
|
|
||||||
<option name="modules">
|
|
||||||
<set>
|
|
||||||
<option value="$PROJECT_DIR$" />
|
|
||||||
<option value="$PROJECT_DIR$/kencommandapi-bukkit" />
|
|
||||||
<option value="$PROJECT_DIR$/kencommandapi-core" />
|
|
||||||
<option value="$PROJECT_DIR$/kencommandapi-velocity" />
|
|
||||||
<option value="$PROJECT_DIR$/../build-logic" />
|
|
||||||
<option value="$PROJECT_DIR$/../build-logic/convention" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</GradleProjectSettings>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
</project>
|
||||||
25
.idea/jsonSchemas.xml
generated
Normal file
25
.idea/jsonSchemas.xml
generated
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JsonSchemaMappingsProjectConfiguration">
|
||||||
|
<state>
|
||||||
|
<map>
|
||||||
|
<entry key="GitHub Workflow">
|
||||||
|
<value>
|
||||||
|
<SchemaInfo>
|
||||||
|
<option name="name" value="GitHub Workflow" />
|
||||||
|
<option name="relativePathToSchema" value="https://www.schemastore.org/github-workflow.json" />
|
||||||
|
<option name="applicationDefined" value="true" />
|
||||||
|
<option name="patterns">
|
||||||
|
<list>
|
||||||
|
<Item>
|
||||||
|
<option name="path" value=".forgejo/workflows/publish-artifact.yml" />
|
||||||
|
</Item>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</SchemaInfo>
|
||||||
|
</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</state>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_25" />
|
||||||
</project>
|
</project>
|
||||||
59
.idea/runConfigurations.xml
generated
Normal file
59
.idea/runConfigurations.xml
generated
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="com.android.tools.idea.run.AndroidConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.run.configuration.AndroidComplicationRunConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.run.configuration.AndroidTileRunConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.run.configuration.AndroidWatchFaceRunConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.testartifacts.instrumented.AndroidTestConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.testartifacts.junit.TestClassAndroidConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.testartifacts.junit.TestDirectoryAndroidConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.testartifacts.junit.TestMethodAndroidConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.testartifacts.junit.TestPackageAndroidConfigurationProducer" />
|
||||||
|
<option value="com.android.tools.idea.testartifacts.junit.TestPatternConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.application.ApplicationConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.AllInDirectoryConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.TestClassConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradle.native.KotlinNativeRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.run.KotlinJvmTestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.run.KotlinJvmTestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.run.KotlinMultiplatformJvmTestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.run.KotlinMultiplatformJvmTestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.testing.KotlinMultiplatformAllInDirectoryConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.testing.KotlinMultiplatformAllInPackageConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.testing.common.KotlinMultiplatformCommonTestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.testing.common.KotlinMultiplatformCommonTestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.testing.js.KotlinMultiplatformJsTestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.testing.js.KotlinMultiplatformJsTestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.testing.native.KotlinMultiplatformNativeTestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.gradleJava.testing.native.KotlinMultiplatformNativeTestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinJUnitRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinJvmTestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinJvmTestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinMultiplatformJvmTestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinMultiplatformJvmTestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinPatternConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.GradleGroovyScriptRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInDirectoryGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.PatternGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.plugins.gradle.service.execution.GradleRuntimeConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
|
|
@ -2,6 +2,5 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="" vcs="Git" />
|
<mapping directory="" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/../build-logic" vcs="Git" />
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
293
.idea/workspace.xml
generated
293
.idea/workspace.xml
generated
|
|
@ -3,30 +3,49 @@
|
||||||
<component name="AutoImportSettings">
|
<component name="AutoImportSettings">
|
||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="BazelBinPathService">
|
||||||
|
<option name="bazelBin" value="$USER_HOME$/.cache/bazel/_bazel_a/ddb0601c3c3f894317d0e9fe2e5bde13/execroot/_main/bazel-out/k8-fastbuild/bin" />
|
||||||
|
<option name="execRoot" value="$USER_HOME$/.cache/bazel/_bazel_a/ddb0601c3c3f894317d0e9fe2e5bde13/execroot/_main" />
|
||||||
|
</component>
|
||||||
|
<component name="BazelProjectContextService">
|
||||||
|
<option name="bazelBin" value="$USER_HOME$/.cache/bazel/_bazel_a/ddb0601c3c3f894317d0e9fe2e5bde13/execroot/_main/bazel-out/k8-fastbuild/bin" />
|
||||||
|
<option name="bazelReleaseVersion" value="9.2.0" />
|
||||||
|
<option name="execRoot" value="$USER_HOME$/.cache/bazel/_bazel_a/ddb0601c3c3f894317d0e9fe2e5bde13/execroot/_main" />
|
||||||
|
<option name="workspaceName" value="_main" />
|
||||||
|
</component>
|
||||||
|
<component name="BazelProjectProperties">
|
||||||
|
<option name="bazelProject" value="true" />
|
||||||
|
<option name="defaultJdkName" value="KenCommandAPI-jdk-e101e" />
|
||||||
|
<option name="initialized" value="true" />
|
||||||
|
<option name="rootDirUrl" value="file://$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
|
<component name="BazelRepoMappingService">
|
||||||
|
<option name="apparentRepoNameToCanonicalName">
|
||||||
|
<map>
|
||||||
|
<entry key="" value="" />
|
||||||
|
<entry key="bazel_tools" value="bazel_tools" />
|
||||||
|
<entry key="maven" value="rules_jvm_external++maven+maven" />
|
||||||
|
<entry key="rules_java" value="rules_java+" />
|
||||||
|
<entry key="rules_jvm_external" value="rules_jvm_external+" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
<option name="canonicalRepoNameToPath">
|
||||||
|
<map>
|
||||||
|
<entry key="" value="$PROJECT_DIR$" />
|
||||||
|
<entry key="bazel_tools" value="$USER_HOME$/.cache/bazel/_bazel_a/ddb0601c3c3f894317d0e9fe2e5bde13/external/bazel_tools" />
|
||||||
|
<entry key="rules_java+" value="$USER_HOME$/.cache/bazel/_bazel_a/ddb0601c3c3f894317d0e9fe2e5bde13/external/rules_java+" />
|
||||||
|
<entry key="rules_jvm_external+" value="$USER_HOME$/.cache/bazel/_bazel_a/ddb0601c3c3f894317d0e9fe2e5bde13/external/rules_jvm_external+" />
|
||||||
|
<entry key="rules_jvm_external++maven+maven" value="$USER_HOME$/.cache/bazel/_bazel_a/ddb0601c3c3f894317d0e9fe2e5bde13/external/rules_jvm_external++maven+maven" />
|
||||||
|
</map>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="6414223f-1761-4683-97f5-9dab59d6c44a" name="Changes" comment=".">
|
<list default="true" id="6414223f-1761-4683-97f5-9dab59d6c44a" name="Changes" comment="refactor ig">
|
||||||
<change afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser2/AbstractCommandParser.java" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/.forgejo/workflows/publish-artifact.yml" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser2/InvocationCommandParser.java" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/.idea/jsonSchemas.xml" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser2/SuggestionCommandParser.java" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.bazelrc" beforeDir="false" afterPath="$PROJECT_DIR$/.bazelrc" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/TODO" beforeDir="false" afterPath="$PROJECT_DIR$/TODO" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle.kts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/BukkitKenCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/BukkitKenCommand.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/CommandAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/CommandAPI.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/TabCompleteListener.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-bukkit/src/main/java/de/kentoj/kencommandapi/TabCompleteListener.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/CommandHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/CommandHandler.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/node/CommandNode.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/literal/Literal.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/node/RootCommandNode.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/literal/RootLiteral.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser/CommandParser.java" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/parser/ParseResult.java" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/platform/HasPermissionMethod.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/api/platform/HasPermissionMethod.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/internal/CommandNodeImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/internal/LiteralImpl.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/internal/RootCommandNodeImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-core/src/main/java/de/kentoj/kencommandapi/internal/RootLiteralImpl.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/test/java/de/kentoj/kencommandapi/api/parser/CommandHandlerTest.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-core/src/test/java/de/kentoj/kencommandapi/api/parser/CommandHandlerTest.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/test/java/de/kentoj/kencommandapi/api/parser/CommandParserTest.java" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-core/src/test/java/de/kentoj/kencommandapi/api/parser/ENV.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-core/src/test/java/de/kentoj/kencommandapi/api/parser/ENV.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-velocity/src/main/java/de/kentoj/kencommandapi/CommandAPI.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-velocity/src/main/java/de/kentoj/kencommandapi/CommandAPI.java" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/kencommandapi-velocity/src/main/java/de/kentoj/kencommandapi/VelocityCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/kencommandapi-velocity/src/main/java/de/kentoj/kencommandapi/VelocityCommand.java" afterDir="false" />
|
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
|
@ -85,19 +104,6 @@
|
||||||
<item name="Tasks" type="e4a08cd1:TasksNode" />
|
<item name="Tasks" type="e4a08cd1:TasksNode" />
|
||||||
<item name="publishing" type="c8890929:TasksNode$1" />
|
<item name="publishing" type="c8890929:TasksNode$1" />
|
||||||
</path>
|
</path>
|
||||||
<path>
|
|
||||||
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
|
||||||
<item name="KenCommandAPI" type="f1a62948:ProjectNode" />
|
|
||||||
<item name="KenCommandAPI" type="2d1252cf:ModuleNode" />
|
|
||||||
<item name="kencommandapi-bukkit" type="2d1252cf:ModuleNode" />
|
|
||||||
</path>
|
|
||||||
<path>
|
|
||||||
<item name="" type="6a2764b6:ExternalProjectsStructure$RootNode" />
|
|
||||||
<item name="KenCommandAPI" type="f1a62948:ProjectNode" />
|
|
||||||
<item name="KenCommandAPI" type="2d1252cf:ModuleNode" />
|
|
||||||
<item name="kencommandapi-bukkit" type="2d1252cf:ModuleNode" />
|
|
||||||
<item name="Tasks" type="e4a08cd1:TasksNode" />
|
|
||||||
</path>
|
|
||||||
</expand>
|
</expand>
|
||||||
<select />
|
<select />
|
||||||
</tree_state>
|
</tree_state>
|
||||||
|
|
@ -118,6 +124,7 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="GradleScriptDefinitionsStorage" workingDir="$PROJECT_DIR$" gradleHome="$USER_HOME$/.gradle/wrapper/dists/gradle-8.14-bin/38aieal9i53h9rfe7vjup95b9/gradle-8.14" javaHome="/usr/lib/jvm/default-jdk" gradleVersion="8.14" />
|
<component name="GradleScriptDefinitionsStorage" workingDir="$PROJECT_DIR$" gradleHome="$USER_HOME$/.gradle/wrapper/dists/gradle-8.14-bin/38aieal9i53h9rfe7vjup95b9/gradle-8.14" javaHome="/usr/lib/jvm/default-jdk" gradleVersion="8.14" />
|
||||||
<component name="HighlightingSettingsPerFile">
|
<component name="HighlightingSettingsPerFile">
|
||||||
|
<setting file="file://$PROJECT_DIR$/kencommandapi-core/BUILD" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="jrt:///usr/lib/jvm/openjdk21!/java.base/java/util/function/Function.class" root0="SKIP_INSPECTION" />
|
<setting file="jrt:///usr/lib/jvm/openjdk21!/java.base/java/util/function/Function.class" root0="SKIP_INSPECTION" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProblemsViewState">
|
<component name="ProblemsViewState">
|
||||||
|
|
@ -136,6 +143,14 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
|
"Bazel.//bukkit:bukkit.publish.executor": "Run",
|
||||||
|
"Bazel.//core:core.publish.executor": "Run",
|
||||||
|
"Bazel.//kencommandapi-velocity:velocity.publish.executor": "Run",
|
||||||
|
"Bazel.//velocity:velocity.publish.executor": "Run",
|
||||||
|
"Bazel.Run //kencommandapi-bukkit:bukkit.publish.executor": "Run",
|
||||||
|
"Bazel.Run //kencommandapi-core:core.publish.executor": "Run",
|
||||||
|
"Bazel.Run //kencommandapi-core:export.publish.executor": "Run",
|
||||||
|
"Bazel.Run //kencommandapi-velocity:velocity.publish.executor": "Run",
|
||||||
"Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [:kencommandapi-core:de.kentoj.kencommandapi.Main.main()].executor": "Run",
|
"Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [:kencommandapi-core:de.kentoj.kencommandapi.Main.main()].executor": "Run",
|
||||||
"Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [build].executor": "Run",
|
"Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [build].executor": "Run",
|
||||||
"Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [publish].executor": "Run",
|
"Gradle./home/a/src/kento2/KenCommandAPI/kencommandapi-core [publish].executor": "Run",
|
||||||
|
|
@ -147,6 +162,7 @@
|
||||||
"Gradle.KenCommandAPI [build].executor": "Run",
|
"Gradle.KenCommandAPI [build].executor": "Run",
|
||||||
"Gradle.KenCommandAPI [clean test].executor": "Run",
|
"Gradle.KenCommandAPI [clean test].executor": "Run",
|
||||||
"Gradle.KenCommandAPI [clean].executor": "Run",
|
"Gradle.KenCommandAPI [clean].executor": "Run",
|
||||||
|
"Gradle.KenCommandAPI [javadoc].executor": "Run",
|
||||||
"Gradle.KenCommandAPI [publishAllPublicationsToScrowRepository].executor": "Run",
|
"Gradle.KenCommandAPI [publishAllPublicationsToScrowRepository].executor": "Run",
|
||||||
"Gradle.KenCommandAPI [publish].executor": "Run",
|
"Gradle.KenCommandAPI [publish].executor": "Run",
|
||||||
"Gradle.KenCommandAPI [test].executor": "Run",
|
"Gradle.KenCommandAPI [test].executor": "Run",
|
||||||
|
|
@ -160,12 +176,21 @@
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
|
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||||
|
"SHARE_PROJECT_CONFIGURATION_FILES": "true",
|
||||||
|
"bazel.project.detector.is.bazel.project": "true",
|
||||||
|
"codeWithMe.voiceChat.enabledByDefault": "false",
|
||||||
|
"com.intellij.ide.FileNotInSourceRootChecker.no.check": "true",
|
||||||
"git-widget-placeholder": "master",
|
"git-widget-placeholder": "master",
|
||||||
"kotlin-language-version-configured": "true",
|
"kotlin-language-version-configured": "true",
|
||||||
"last_opened_file_path": "/home/a/src/scrow/core",
|
"last_opened_file_path": "/home/a/src/random/rules_jvm_external",
|
||||||
|
"node.js.detected.package.jshint": "true",
|
||||||
|
"node.js.selected.package.jshint": "",
|
||||||
|
"nodejs_package_manager_path": "npm",
|
||||||
"project.structure.last.edited": "Modules",
|
"project.structure.last.edited": "Modules",
|
||||||
"project.structure.proportion": "0.15",
|
"project.structure.proportion": "0.15",
|
||||||
"project.structure.side.proportion": "0.6268199",
|
"project.structure.side.proportion": "0.6268199",
|
||||||
|
"remote.dev.show.docker.config.missing.jdk.notification": "false",
|
||||||
"settings.editor.selected.configurable": "preferences.pluginManager"
|
"settings.editor.selected.configurable": "preferences.pluginManager"
|
||||||
}
|
}
|
||||||
}</component>
|
}</component>
|
||||||
|
|
@ -178,19 +203,26 @@
|
||||||
<recent name="de.kencommand.api" />
|
<recent name="de.kencommand.api" />
|
||||||
</key>
|
</key>
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$/kencommandapi-velocity" />
|
||||||
|
<recent name="$PROJECT_DIR$/gradle" />
|
||||||
|
<recent name="$PROJECT_DIR$/kencommandapi-core/src/test/java/a" />
|
||||||
<recent name="$PROJECT_DIR$/kencommandapi-core" />
|
<recent name="$PROJECT_DIR$/kencommandapi-core" />
|
||||||
<recent name="$PROJECT_DIR$/kencommandapi-velocity/src/main/java/de/kentoj/kencommandapi" />
|
<recent name="$PROJECT_DIR$/kencommandapi-velocity/src/main/java/de/kentoj/kencommandapi" />
|
||||||
<recent name="$PROJECT_DIR$/src/main/java/de/kencommand/api" />
|
|
||||||
</key>
|
</key>
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
|
<recent name="$PROJECT_DIR$/third_party" />
|
||||||
|
<recent name="$PROJECT_DIR$" />
|
||||||
<recent name="$PROJECT_DIR$/kencommandapi-core" />
|
<recent name="$PROJECT_DIR$/kencommandapi-core" />
|
||||||
</key>
|
</key>
|
||||||
|
<key name="ExtractSuperBase.RECENT_KEYS">
|
||||||
|
<recent name="de.kentoj.kencommandapi.api.invocation" />
|
||||||
|
</key>
|
||||||
<key name="CopyClassDialog.RECENTS_KEY">
|
<key name="CopyClassDialog.RECENTS_KEY">
|
||||||
|
<recent name="de.kentoj.kencommandapi.api.literal" />
|
||||||
<recent name="de.kentoj.kencommandapi.api.parser2" />
|
<recent name="de.kentoj.kencommandapi.api.parser2" />
|
||||||
<recent name="de.kentoj.kencommandapi.api.invocation" />
|
<recent name="de.kentoj.kencommandapi.api.invocation" />
|
||||||
<recent name="de.kentoj.kencommandapi.internal" />
|
<recent name="de.kentoj.kencommandapi.internal" />
|
||||||
<recent name="de.kentoj.kencommandapi.api" />
|
<recent name="de.kentoj.kencommandapi.api" />
|
||||||
<recent name="de.kentoj.kencommandapi.impl" />
|
|
||||||
</key>
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunAnythingCache">
|
<component name="RunAnythingCache">
|
||||||
|
|
@ -200,34 +232,62 @@
|
||||||
<command value="gradlew buildEnvironment" />
|
<command value="gradlew buildEnvironment" />
|
||||||
<command value="./gradlew clean test" />
|
<command value="./gradlew clean test" />
|
||||||
<command value="gradlew test" />
|
<command value="gradlew test" />
|
||||||
|
<command value="bazel build //:kencommandapi-core" />
|
||||||
|
<command value="bazel build //:core" />
|
||||||
|
<command value="bazel build //kencommandapi-core:core" />
|
||||||
|
<command value="bazel build //kencommandapi-core:core --sandbox_debug " />
|
||||||
|
<command value="bazel build //kencommandapi-core:core " />
|
||||||
|
<command value="bazel build //kencommandapi-bukkit:bukkit --verbose_failures+" />
|
||||||
|
<command value="bazel build //kencommandapi-bukkit:bukkit --verbose_failures" />
|
||||||
|
<command value="bazel build //kencommandapi-core:core --nojava_header_compilation" />
|
||||||
|
<command value="bazel build //kencommandapi-bukkit:bukkit" />
|
||||||
|
<command value="bazel build //kencommandapi-bukkit:bukkit --nojava_header_compilation" />
|
||||||
|
<command value="bazel sync --only=maven --verbose_failures" />
|
||||||
|
<command value="bazel build //kencommandapi-core:core-lib" />
|
||||||
|
<command value="bazel build //kencommandapi-core:core-lib --verbose" />
|
||||||
|
<command value="bazel build //kencommandapi-core:core-lib -v" />
|
||||||
|
<command value="bazel build //kencommandapi-core:core-lib --help" />
|
||||||
|
<command value="bazel build -v //kencommandapi-core:core-lib " />
|
||||||
|
<command value="bazel -v build //kencommandapi-core:core-lib " />
|
||||||
|
<command value="bazel -v build //kencommandapi-core:core-lib --subcommands " />
|
||||||
|
<command value="bazel build //kencommandapi-core:core-lib --subcommands " />
|
||||||
|
<command value="bazel build //kencommandapi-core:core-lib --subcommands --verbose_failures" />
|
||||||
|
<command value="bazel shutdown" />
|
||||||
|
<command value="bazel clean" />
|
||||||
|
<command value="bazel clean --expunge" />
|
||||||
|
<command value="bazel build bukkit" />
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager" selected="Gradle.KenCommandAPI [publish]">
|
<component name="RunManager" selected="Bazel.//bukkit:bukkit.publish">
|
||||||
<configuration name="CommandParserTest.checkArgumentExpected" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
<configuration name="//bukkit:bukkit.publish" type="BazelRunConfigurationType" temporary="true">
|
||||||
<ExternalSystemSettings>
|
<bsp-state handler-provider-id="GenericRunHandlerProvider" check-visibility="true">
|
||||||
<option name="executionName" />
|
<bsp-target>@//bukkit:bukkit.publish</bsp-target>
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<handler-state />
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
</bsp-state>
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value=":kencommandapi-core:test" />
|
|
||||||
<option value="--tests" />
|
|
||||||
<option value=""de.kentoj.kencommandapi.api.parser.CommandParserTest.checkArgumentExpected"" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>true</RunAsTest>
|
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration name="KenCommandAPI [build]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
<configuration name="//core:core.publish" type="BazelRunConfigurationType" temporary="true">
|
||||||
|
<bsp-state handler-provider-id="GenericRunHandlerProvider" check-visibility="true">
|
||||||
|
<bsp-target>@//core:core.publish</bsp-target>
|
||||||
|
<handler-state />
|
||||||
|
</bsp-state>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="//kencommandapi-velocity:velocity.publish" type="BazelRunConfigurationType" temporary="true">
|
||||||
|
<bsp-state handler-provider-id="GenericRunHandlerProvider" check-visibility="true">
|
||||||
|
<bsp-target>@//kencommandapi-velocity:velocity.publish</bsp-target>
|
||||||
|
<handler-state />
|
||||||
|
</bsp-state>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="//velocity:velocity.publish" type="BazelRunConfigurationType" temporary="true">
|
||||||
|
<bsp-state handler-provider-id="GenericRunHandlerProvider" check-visibility="true">
|
||||||
|
<bsp-target>@//velocity:velocity.publish</bsp-target>
|
||||||
|
<handler-state />
|
||||||
|
</bsp-state>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="KenCommandAPI [publishAllPublicationsToScrowRepository]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
<ExternalSystemSettings>
|
<ExternalSystemSettings>
|
||||||
<option name="executionName" />
|
<option name="executionName" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
|
@ -238,94 +298,49 @@
|
||||||
</option>
|
</option>
|
||||||
<option name="taskNames">
|
<option name="taskNames">
|
||||||
<list>
|
<list>
|
||||||
<option value="build" />
|
<option value="publishAllPublicationsToScrowRepository" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
<option name="vmOptions" />
|
<option name="vmOptions" />
|
||||||
</ExternalSystemSettings>
|
</ExternalSystemSettings>
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<ExternalSystemDebugDisabled>false</ExternalSystemDebugDisabled>
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
<RunAsTest>false</RunAsTest>
|
<RunAsTest>false</RunAsTest>
|
||||||
|
<GradleProfilingDisabled>false</GradleProfilingDisabled>
|
||||||
|
<GradleCoverageDisabled>false</GradleCoverageDisabled>
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration name="KenCommandAPI [clean test]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
<configuration default="true" type="JetRunConfigurationType">
|
||||||
<ExternalSystemSettings>
|
<module name="build-logic.convention.main" />
|
||||||
<option name="executionName" />
|
<method v="2">
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
<option name="Make" enabled="true" />
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
</method>
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="clean" />
|
|
||||||
<option value="test" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
</configuration>
|
||||||
<configuration name="KenCommandAPI [publish]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
<configuration default="true" type="KotlinStandaloneScriptRunConfigurationType">
|
||||||
<ExternalSystemSettings>
|
<module name="build-logic.convention.main" />
|
||||||
<option name="executionName" />
|
<option name="filePath" />
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="publish" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
<configuration name="KenCommandAPI [test]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
|
||||||
<ExternalSystemSettings>
|
|
||||||
<option name="executionName" />
|
|
||||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
|
||||||
<option name="externalSystemIdString" value="GRADLE" />
|
|
||||||
<option name="scriptParameters" value="" />
|
|
||||||
<option name="taskDescriptions">
|
|
||||||
<list />
|
|
||||||
</option>
|
|
||||||
<option name="taskNames">
|
|
||||||
<list>
|
|
||||||
<option value="test" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="vmOptions" />
|
|
||||||
</ExternalSystemSettings>
|
|
||||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
|
||||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
|
||||||
<DebugAllEnabled>false</DebugAllEnabled>
|
|
||||||
<RunAsTest>false</RunAsTest>
|
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
<recent_temporary>
|
<recent_temporary>
|
||||||
<list>
|
<list>
|
||||||
<item itemvalue="Gradle.KenCommandAPI [publish]" />
|
<item itemvalue="Bazel.//bukkit:bukkit.publish" />
|
||||||
<item itemvalue="Gradle.KenCommandAPI [build]" />
|
<item itemvalue="Bazel.//core:core.publish" />
|
||||||
<item itemvalue="Gradle.KenCommandAPI [test]" />
|
<item itemvalue="Bazel.//velocity:velocity.publish" />
|
||||||
<item itemvalue="Gradle.KenCommandAPI [clean test]" />
|
<item itemvalue="Bazel.//kencommandapi-velocity:velocity.publish" />
|
||||||
<item itemvalue="Gradle.CommandParserTest.checkArgumentExpected" />
|
<item itemvalue="Bazel.//kencommandapi-velocity:velocity.publish" />
|
||||||
</list>
|
</list>
|
||||||
</recent_temporary>
|
</recent_temporary>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="SharedIndexes">
|
||||||
|
<attachedChunks>
|
||||||
|
<set>
|
||||||
|
<option value="bundled-jdk-30f59d01ecdd-63390994e64e-intellij.indexing.shared.core-IU-262.8665.337" />
|
||||||
|
<option value="bundled-js-predefined-d6986cc7102b-4abd2a77f808-JavaScript-IU-262.8665.337" />
|
||||||
|
</set>
|
||||||
|
</attachedChunks>
|
||||||
|
</component>
|
||||||
<component name="TaskManager">
|
<component name="TaskManager">
|
||||||
<task active="true" id="Default" summary="Default task">
|
<task active="true" id="Default" summary="Default task">
|
||||||
<changelist id="6414223f-1761-4683-97f5-9dab59d6c44a" name="Changes" comment="" />
|
<changelist id="6414223f-1761-4683-97f5-9dab59d6c44a" name="Changes" comment="" />
|
||||||
|
|
@ -561,6 +576,9 @@
|
||||||
<option name="localTasksCounter" value="29" />
|
<option name="localTasksCounter" value="29" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="3" />
|
||||||
|
</component>
|
||||||
<component name="Vcs.Log.Tabs.Properties">
|
<component name="Vcs.Log.Tabs.Properties">
|
||||||
<option name="TAB_STATES">
|
<option name="TAB_STATES">
|
||||||
<map>
|
<map>
|
||||||
|
|
@ -579,10 +597,17 @@
|
||||||
<MESSAGE value="need to implement some argument types" />
|
<MESSAGE value="need to implement some argument types" />
|
||||||
<MESSAGE value="implement PlayerArgumentType implement OfflinePlayerArgumentType" />
|
<MESSAGE value="implement PlayerArgumentType implement OfflinePlayerArgumentType" />
|
||||||
<MESSAGE value="fix aliases not being registered" />
|
<MESSAGE value="fix aliases not being registered" />
|
||||||
<MESSAGE value="add TODO" />
|
|
||||||
<MESSAGE value="make SuggestionProvider use CompletableFuture" />
|
<MESSAGE value="make SuggestionProvider use CompletableFuture" />
|
||||||
<MESSAGE value="currently refactoring a lot." />
|
<MESSAGE value="currently refactoring a lot." />
|
||||||
|
<MESSAGE value="reworked parsing" />
|
||||||
|
<MESSAGE value="add TODO" />
|
||||||
<MESSAGE value="." />
|
<MESSAGE value="." />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="." />
|
<MESSAGE value="use version catalog" />
|
||||||
|
<MESSAGE value="BAZEL" />
|
||||||
|
<MESSAGE value="BAZEL + some code" />
|
||||||
|
<MESSAGE value="works" />
|
||||||
|
<MESSAGE value="make velocity work" />
|
||||||
|
<MESSAGE value="refactor ig" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="refactor ig" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
30
MODULE.bazel
Normal file
30
MODULE.bazel
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
bazel_dep(name = "rules_java", version = "9.7.0")
|
||||||
|
bazel_dep(name = "rules_jvm_external", version = "7.1")
|
||||||
|
|
||||||
|
git_override(
|
||||||
|
module_name = "rules_jvm_external",
|
||||||
|
remote = "http://forge.kentoj.de/scrow/rules_jvm_external.git",
|
||||||
|
)
|
||||||
|
|
||||||
|
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
|
||||||
|
maven.install(
|
||||||
|
name = "maven",
|
||||||
|
artifacts = [
|
||||||
|
"com.leakyabstractions:result-api:1.0.1.0",
|
||||||
|
"com.leakyabstractions:result:1.0.2.0",
|
||||||
|
"org.jetbrains:annotations:26.0.2-1",
|
||||||
|
"com.google.guava:guava:33.5.0-jre",
|
||||||
|
"org.projectlombok:lombok:1.18.46",
|
||||||
|
"org.slf4j:slf4j-api:2.0.18",
|
||||||
|
"org.slf4j:slf4j-simple:2.0.18",
|
||||||
|
"net.kyori:adventure-api:5.2.0",
|
||||||
|
"io.papermc.paper:paper-api:[26.2.build,)",
|
||||||
|
"com.velocitypowered:velocity-api:4.1.0-20260802.091736-8",
|
||||||
|
],
|
||||||
|
repositories = [
|
||||||
|
"https://repo.papermc.io/repository/maven-public/",
|
||||||
|
],
|
||||||
|
known_contributing_modules = ["protobuf"],
|
||||||
|
)
|
||||||
|
|
||||||
|
use_repo(maven, "maven")
|
||||||
99
README.md
99
README.md
|
|
@ -1,2 +1,97 @@
|
||||||
example usage:
|
## TODO
|
||||||
http://forge.kentoj.de/scrow/core/src/commit/a55d9857738425e099fe9650cc1a705ceb2ece00/core-bukkit-impl/src/main/java/de/kentoj/scrow/bukkit/command/economy
|
|
||||||
|
CI/CD to publish automatically
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
after installing bazel:
|
||||||
|
```shell
|
||||||
|
bazel build //bukkit
|
||||||
|
bazel build //core
|
||||||
|
bazel build //velocity
|
||||||
|
```
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
- argument's can't require specific permissions.
|
||||||
|
|
||||||
|
## Design
|
||||||
|
|
||||||
|
Commands are trees of Literals.
|
||||||
|
Literals can have arguments.
|
||||||
|
Literals can also have Executors.
|
||||||
|
|
||||||
|
arguments can be optional by giving them a default value.
|
||||||
|
arguments can have suggestions.
|
||||||
|
|
||||||
|
`/feed <user>`:
|
||||||
|
- feed is the root literal
|
||||||
|
- `<user>` is an argument: it's value is a User Object
|
||||||
|
|
||||||
|
To allow the use of `/feed` without giving a user's name, i.e. to make the argument optional, we need to assign the
|
||||||
|
user-argument a default value.
|
||||||
|
|
||||||
|
### An example command
|
||||||
|
|
||||||
|
Let's say we want to make a command that allows seeing how many coins another User has.
|
||||||
|
If we don't specify a user, it should instead show the coins the sender has.
|
||||||
|
|
||||||
|
### As a tree
|
||||||
|
|
||||||
|
Visualized as a tree, we have a Node/Literal `coins` with an alias `balance` with an optional argument called `user`.
|
||||||
|
To make an argument optional, it must have a default value.
|
||||||
|
|
||||||
|
```text
|
||||||
|
literal:coins/balance
|
||||||
|
- has argument:user
|
||||||
|
- has executor:getCoins
|
||||||
|
```
|
||||||
|
|
||||||
|
### As code
|
||||||
|
|
||||||
|
```java
|
||||||
|
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the amount coins a user has.
|
||||||
|
* If no user is given, it should show the amount the sender of the command has.
|
||||||
|
*/
|
||||||
|
public class CoinsCommand {
|
||||||
|
|
||||||
|
private final RootLiteral<User> rootLiteral;
|
||||||
|
private final CommandArgumentSpec<User, User> userArg;
|
||||||
|
|
||||||
|
public CoinsCommand() {
|
||||||
|
userArg = CommandArgumentSpec.builder("user", new UserArgumentType<User>())
|
||||||
|
.withRequirement(p -> !p.hasPermission("economy.immune.getcoins"),
|
||||||
|
"you can't see that player's balance")
|
||||||
|
.withDefaultValue(CommandContext::sender)
|
||||||
|
.build();
|
||||||
|
rootLiteral = Literal.<User>builder("coins", "balance")
|
||||||
|
.withPermission("economy.command.coins")
|
||||||
|
.withArgument(userArg)
|
||||||
|
.withSyncExecutor(this::getCoins)
|
||||||
|
.asRootLiteral(MessageStyle.PLAIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<Object, String> getCoins(CommandContext<User> ctx) {
|
||||||
|
var user = ctx.getArg(userArg);
|
||||||
|
ctx.getSender().sendMessage(user.name() + " has " + user.coins() + " coins");
|
||||||
|
return Results.success(new Object());
|
||||||
|
}
|
||||||
|
|
||||||
|
public RootLiteral<User> rootLiteral() {
|
||||||
|
return rootLiteral;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If we wanted to report an error, we could do for example `return Results.failure("That user doesn't exist")`.
|
||||||
|
However, if we have a smart UserArgumentType, it automatically makes sure that the user exists.
|
||||||
|
Additionally, we can also a Requirement in the CommandArgumentSpec.
|
||||||
|
|
||||||
|
The registration of the command is platform-dependant. Typically, a class called CommandAPI can be used.
|
||||||
|
```java
|
||||||
|
CommandAPI api = new CommandAPI();
|
||||||
|
register(new CoinsCommand().rootLiteral());
|
||||||
|
```
|
||||||
10
TODO
10
TODO
|
|
@ -1,10 +0,0 @@
|
||||||
- suggest next literal/argument
|
|
||||||
- fix:
|
|
||||||
```
|
|
||||||
[22:05:39 ERROR]: Could not pass event AsyncTabCompleteEvent to CoreBukkit v1.0.0-SNAPSHOT
|
|
||||||
java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
|
|
||||||
at core-bukkit-impl-all-1783368113525.jar//de.kentoj.kencommandapi.api.parser2.SuggestionCommandParser.getSuggestions(SuggestionCommandParser.java:39) ~[?:?]
|
|
||||||
at core-bukkit-impl-all-1783368113525.jar//de.kentoj.kencommandapi.api.CommandHandler.getSuggestions(CommandHandler.java:44) ~[?:?]
|
|
||||||
at core-bukkit-impl-all-1783368113525.jar//de.kentoj.kencommandapi.TabCompleteListener.onAsyncTabComplete(TabCompleteListener.java:27) ~[?:?]
|
|
||||||
at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:80) ~[paper-api-1.21.11-R0.1-SNAPSHOT.jar:?]
|
|
||||||
```
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
group = "de.kentoj.scrow"
|
|
||||||
version = "0.33-SNAPSHOT"
|
|
||||||
|
|
||||||
subprojects {
|
|
||||||
group = rootProject.group
|
|
||||||
version = rootProject.version
|
|
||||||
}
|
|
||||||
15
bukkit/BUILD
Normal file
15
bukkit/BUILD
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
load("@rules_jvm_external//:defs.bzl", "artifact", "java_export")
|
||||||
|
|
||||||
|
java_export(
|
||||||
|
name = "bukkit",
|
||||||
|
maven_coordinates = "de.kentoj.scrow:kencommandapi-bukkit:0.34-SNAPSHOT",
|
||||||
|
srcs = glob(["src/main/**/*.java"]),
|
||||||
|
deps = [
|
||||||
|
"//core",
|
||||||
|
artifact("org.jetbrains:annotations"),
|
||||||
|
artifact("io.papermc.paper:paper-api"),
|
||||||
|
],
|
||||||
|
exports = [
|
||||||
|
"//core",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package de.kentoj.kencommandapi;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.CommandHandler;
|
||||||
|
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||||
|
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class BukkitKenCommand<T extends CommandSender> extends Command {
|
||||||
|
|
||||||
|
private final RootLiteral<T> rootLiteral;
|
||||||
|
private final CommandHandler<T> commandHandler;
|
||||||
|
private final Class<T> senderType;
|
||||||
|
|
||||||
|
protected BukkitKenCommand(CommandHandler<T> commandHandler, RootLiteral<T> rootLiteral, Class<T> senderType) {
|
||||||
|
super(rootLiteral.names()[0]);
|
||||||
|
this.commandHandler = commandHandler;
|
||||||
|
this.rootLiteral = rootLiteral;
|
||||||
|
this.senderType = senderType;
|
||||||
|
|
||||||
|
this.setAliases(Arrays.asList(rootLiteral.names()));
|
||||||
|
this.setPermission(rootLiteral.permission());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(@NotNull CommandSender commandSender, @NotNull String commandLabel, @NotNull String[] args) {
|
||||||
|
if (!senderType.isInstance(commandSender)) {
|
||||||
|
commandSender.sendMessage(MessageStyle.PLAIN.err("You can't use that command"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
T sender = senderType.cast(commandSender);
|
||||||
|
|
||||||
|
commandHandler.invoke(rootLiteral, sender, Stream.of(args).filter(str -> !str.isEmpty()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,15 +13,17 @@ import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CommandAPI {
|
public class CommandAPI<T extends CommandSender> {
|
||||||
|
|
||||||
private final CommandHandler<CommandSender> commandHandler;
|
private final CommandHandler<T> commandHandler;
|
||||||
private final List<RootLiteral<CommandSender>> registeredNodes = new ArrayList<>();
|
private final List<RootLiteral<T>> registeredNodes = new ArrayList<>();
|
||||||
private final SimpleCommandMap commandMap;
|
private final SimpleCommandMap commandMap;
|
||||||
|
private final Class<T> senderType;
|
||||||
|
|
||||||
public CommandAPI(Plugin plugin) {
|
public CommandAPI(Plugin plugin, Class<T> senderType) {
|
||||||
|
this.senderType = senderType;
|
||||||
this.commandHandler = new CommandHandler<>(CommandSender::sendMessage, Permissible::hasPermission);
|
this.commandHandler = new CommandHandler<>(CommandSender::sendMessage, Permissible::hasPermission);
|
||||||
Bukkit.getPluginManager().registerEvents(new TabCompleteListener(this, commandHandler), plugin);
|
Bukkit.getPluginManager().registerEvents(new TabCompleteListener<>(this, commandHandler, senderType), plugin);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Field field = Bukkit.getPluginManager().getClass().getDeclaredField("commandMap");
|
Field field = Bukkit.getPluginManager().getClass().getDeclaredField("commandMap");
|
||||||
|
|
@ -32,17 +34,17 @@ public class CommandAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable RootLiteral<CommandSender> getRegistered(String name) {
|
@Nullable RootLiteral<T> getRegistered(String name) {
|
||||||
for (var node : registeredNodes) {
|
for (var node : registeredNodes) {
|
||||||
for (String nodeName : node.getNames()) {
|
for (String nodeName : node.names()) {
|
||||||
if (nodeName.equals(name)) return node;
|
if (nodeName.equals(name)) return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(RootLiteral<CommandSender> rootNode) {
|
public void register(RootLiteral<T> rootNode) {
|
||||||
registeredNodes.add(rootNode);
|
registeredNodes.add(rootNode);
|
||||||
commandMap.register(rootNode.getNames()[0], new BukkitKenCommand(commandHandler, rootNode));
|
commandMap.register(rootNode.names()[0], new BukkitKenCommand<>(commandHandler, rootNode, senderType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
package de.kentoj.kencommandapi;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent;
|
||||||
|
import de.kentoj.kencommandapi.api.CommandHandler;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class TabCompleteListener<T extends CommandSender> implements Listener {
|
||||||
|
|
||||||
|
private final CommandAPI<T> commandAPI;
|
||||||
|
private final CommandHandler<T> commandHandler;
|
||||||
|
private final Class<T> senderType;
|
||||||
|
|
||||||
|
public TabCompleteListener(CommandAPI<T> commandAPI, CommandHandler<T> commandHandler, Class<T> senderType) {
|
||||||
|
this.commandAPI = commandAPI;
|
||||||
|
this.commandHandler = commandHandler;
|
||||||
|
this.senderType = senderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
public void onAsyncTabComplete(AsyncTabCompleteEvent ev) {
|
||||||
|
if (!ev.isCommand()) return;
|
||||||
|
var args = ev.getBuffer().substring(1).split(" ");
|
||||||
|
if (args.length == 0) return;
|
||||||
|
|
||||||
|
var label = args[0];
|
||||||
|
{
|
||||||
|
// commands can be called with a '<plugin name>:' prefix. strip it.
|
||||||
|
int l = label.indexOf(':');
|
||||||
|
if (l >= 0)
|
||||||
|
label = label.substring(l + 1);
|
||||||
|
}
|
||||||
|
var literal = commandAPI.getRegistered(label);
|
||||||
|
if (literal == null) return;
|
||||||
|
|
||||||
|
if (!senderType.isInstance(ev.getSender()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
T sender = senderType.cast(ev.getSender());
|
||||||
|
ev.setHandled(true);
|
||||||
|
ev.setCompletions(commandHandler.getSuggestions(literal, sender, Arrays.copyOfRange(args, 1, args.length), ev.getBuffer().endsWith(" ")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,14 +2,13 @@ package de.kentoj.kencommandapi.suggestionprovider;
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PlayerSuggestionProvider implements SuggestionProvider<CommandSender> {
|
public final class PlayerSuggestionProvider<T> implements SuggestionProvider<T> {
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandSender __) {
|
public List<String> suggest(T __) {
|
||||||
return Bukkit.getOnlinePlayers().stream()
|
return Bukkit.getOnlinePlayers().stream()
|
||||||
.map(Player::getName)
|
.map(Player::getName)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package de.kentoj.kencommandapi.type;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
||||||
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
|
import de.kentoj.kencommandapi.suggestionprovider.PlayerSuggestionProvider;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.OfflinePlayer;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class OfflinePlayerArgumentType<T> implements ArgumentType<T, OfflinePlayer> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OfflinePlayer parseInputUnchecked(String string) {
|
||||||
|
// UUIDs are always 36 chars
|
||||||
|
if (string.length() == 36) {
|
||||||
|
try {
|
||||||
|
return Bukkit.getOfflinePlayer(UUID.fromString(string));
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
throw new IllegalArgumentException("Invalid UUID");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OfflinePlayer player = Bukkit.getPlayerExact(string);
|
||||||
|
if (player == null || (!player.hasPlayedBefore() && !player.isOnline()))
|
||||||
|
throw new IllegalArgumentException("Player not found");
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SuggestionProvider<T> getDefaultSuggestionProvider() {
|
||||||
|
return new PlayerSuggestionProvider<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package de.kentoj.kencommandapi.type;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
||||||
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
|
import de.kentoj.kencommandapi.suggestionprovider.PlayerSuggestionProvider;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class PlayerArgumentType<T> implements ArgumentType<T, Player> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Player parseInputUnchecked(String string) {
|
||||||
|
var player = Bukkit.getPlayer(string);
|
||||||
|
if (player == null) throw new IllegalArgumentException("player not online");
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SuggestionProvider<T> getDefaultSuggestionProvider() {
|
||||||
|
return new PlayerSuggestionProvider<>();
|
||||||
|
}
|
||||||
|
}
|
||||||
16
core/BUILD
Normal file
16
core/BUILD
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
load("@rules_jvm_external//:defs.bzl", "artifact", "java_export")
|
||||||
|
|
||||||
|
java_export(
|
||||||
|
name = "core",
|
||||||
|
maven_coordinates = "de.kentoj.scrow:kencommandapi-core:0.34-SNAPSHOT",
|
||||||
|
srcs = glob(["src/main/**/*.java"]),
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
deps = [
|
||||||
|
artifact("com.leakyabstractions:result-api"),
|
||||||
|
artifact("com.leakyabstractions:result"),
|
||||||
|
artifact("org.jetbrains:annotations"),
|
||||||
|
artifact("com.google.guava:guava"),
|
||||||
|
artifact("org.slf4j:slf4j-api"),
|
||||||
|
artifact("net.kyori:adventure-api"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package de.kentoj.kencommandapi.api;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||||
|
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
||||||
|
import de.kentoj.kencommandapi.api.platform.SendMessageMethod;
|
||||||
|
import de.kentoj.kencommandapi.internal.parser.CommandParseHelper;
|
||||||
|
import de.kentoj.kencommandapi.internal.parser.InvocationCommandParser;
|
||||||
|
import de.kentoj.kencommandapi.internal.parser.SuggestionCommandParser;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class CommandHandler<T> {
|
||||||
|
|
||||||
|
private final SendMessageMethod<T> sendMessageMethod;
|
||||||
|
private final InvocationCommandParser<T> invocationParser;
|
||||||
|
private final SuggestionCommandParser<T> suggestionParser;
|
||||||
|
|
||||||
|
public CommandHandler(SendMessageMethod<T> sendMessageMethod, HasPermissionMethod<T> hasPermissionMethod) {
|
||||||
|
this.sendMessageMethod = sendMessageMethod;
|
||||||
|
var parseHelper = new CommandParseHelper<>(hasPermissionMethod);
|
||||||
|
invocationParser = new InvocationCommandParser<>(parseHelper);
|
||||||
|
suggestionParser = new SuggestionCommandParser<>(parseHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void invoke(RootLiteral<T> rootLiteral, T sender, Stream<String> args) {
|
||||||
|
invocationParser.parse(rootLiteral, sender, args.toList().iterator())
|
||||||
|
.ifSuccessOrElse(data -> exec(rootLiteral, data),
|
||||||
|
err -> sendMessageMethod.send(sender, rootLiteral.messageStyle().err(err)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void exec(RootLiteral<T> rootLiteral, InvocationCommandParser<T>.ExecutionData data) {
|
||||||
|
var ctx = data.context();
|
||||||
|
data.executor().execute(ctx)
|
||||||
|
.whenComplete((result, ex) -> {
|
||||||
|
if (ex != null)
|
||||||
|
sendMessageMethod.send(ctx.sender(), rootLiteral.messageStyle().exception(ex));
|
||||||
|
result.ifFailure(err ->
|
||||||
|
sendMessageMethod.send(ctx.sender(), rootLiteral.messageStyle().err(err)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getSuggestions(RootLiteral<T> rootNode, T sender, String[] args, boolean trailingSpace) {
|
||||||
|
return suggestionParser.suggest(rootNode, sender, Arrays.stream(args).iterator(), trailingSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
package de.kentoj.kencommandapi.api.argument;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param <V> type of the parsed argument value
|
||||||
|
*/
|
||||||
|
public record ArgumentRequirement<V>(
|
||||||
|
Predicate<V> predicate,
|
||||||
|
String message
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
@ -2,21 +2,31 @@ package de.kentoj.kencommandapi.api.argument;
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public interface ArgumentType<T, V> {
|
public interface ArgumentType<T, V> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* parses the given input and returns it.
|
||||||
|
* Unlike {@link CommandArgumentSpec#parseInput(String)}, this does not check any additional requirements.
|
||||||
|
*
|
||||||
* @throws IllegalArgumentException if string invalid
|
* @throws IllegalArgumentException if string invalid
|
||||||
|
* @see CommandArgumentSpec#parseInput(String)
|
||||||
|
* @see CommandArgumentSpecBuilder#withRequirement(Predicate, String)
|
||||||
*/
|
*/
|
||||||
V parseInput(String string);
|
V parseInputUnchecked(String input) throws IllegalArgumentException;
|
||||||
|
|
||||||
SuggestionProvider<T> defaultSuggestionProvider();
|
/**
|
||||||
|
* @see CommandArgumentSpec#suggestionProvider()
|
||||||
|
*/
|
||||||
|
SuggestionProvider<T> getDefaultSuggestionProvider();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return whether this argument is greedy. Greedy arguments consume all remaining input instead of a single word.
|
* @return whether this argument is greedy. Greedy arguments consume all remaining input instead of a single word.
|
||||||
* For example, given the 2 words "hello" "world" as input, a greedy argument parses "hello world" as a single value.
|
* For example, given the 2 words "hello" "world" as input, a greedy argument parses "hello world" as a single value.
|
||||||
* Greedy arguments may not be followed by another argument or a literal
|
* Greedy arguments may not be followed by another argument or a literal
|
||||||
*/
|
*/
|
||||||
default boolean isGreedy() {
|
default boolean greedy() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package de.kentoj.kencommandapi.api.argument;
|
||||||
|
|
||||||
|
public interface CommandArgument<T, V> {
|
||||||
|
|
||||||
|
V value();
|
||||||
|
|
||||||
|
CommandArgumentSpec<T, V> argument();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
package de.kentoj.kencommandapi.api.argument;
|
||||||
|
|
||||||
|
public record CommandArgumentImpl<T, V>(
|
||||||
|
V value,
|
||||||
|
CommandArgumentSpec<T, V> argument
|
||||||
|
) implements CommandArgument<T, V> {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package de.kentoj.kencommandapi.api.argument;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||||
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public sealed interface CommandArgumentSpec<T, V> permits CommandArgumentSpecImpl {
|
||||||
|
|
||||||
|
static <T, V> CommandArgumentSpecBuilder<T, V> builder(String id, ArgumentType<T, V> type) {
|
||||||
|
return new CommandArgumentSpecBuilder<>(id, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
String id();
|
||||||
|
|
||||||
|
ArgumentType<T, V> type();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws IllegalArgumentException if string invalid or if a requirement is not met
|
||||||
|
*/
|
||||||
|
V parseInput(String rawInput);
|
||||||
|
|
||||||
|
@Nullable Function<CommandContext<T>, V> defaultValueProvider();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the explicitly set SuggestionProvider or the default suggestions for the type if unset/null
|
||||||
|
*/
|
||||||
|
/* explicit @NotNull to avoid confusion */
|
||||||
|
@NotNull SuggestionProvider<T> suggestionProvider();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
package de.kentoj.kencommandapi.api.argument;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||||
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param <T> type of the command sender
|
||||||
|
* @param <V> type of the value
|
||||||
|
*/
|
||||||
|
public class CommandArgumentSpecBuilder<T, V> {
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
private final ArgumentType<T, V> type;
|
||||||
|
private @Nullable Function<CommandContext<T>, V> defaultValueProvider;
|
||||||
|
private @Nullable SuggestionProvider<T> suggestionProvider;
|
||||||
|
private final List<ArgumentRequirement<V>> requirements = new ArrayList<>();
|
||||||
|
|
||||||
|
public CommandArgumentSpecBuilder(String id, ArgumentType<T, V> type) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandArgumentSpecBuilder<T, V> withRequirement(Predicate<V> predicate, String message) {
|
||||||
|
requirements.add(new ArgumentRequirement<>(predicate, message));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandArgumentSpecBuilder<T, V> withDefaultValue(@Nullable Function<CommandContext<T>, V> defaultValueProvider) {
|
||||||
|
this.defaultValueProvider = defaultValueProvider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandArgumentSpecBuilder<T, V> withSuggestionProvider(@Nullable SuggestionProvider<T> suggestionProvider) {
|
||||||
|
this.suggestionProvider = suggestionProvider;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandArgumentSpec<T, V> build() {
|
||||||
|
return new CommandArgumentSpecImpl<>(id, type, requirements, defaultValueProvider, suggestionProvider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
package de.kentoj.kencommandapi.api.argument;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||||
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public record CommandArgumentSpecImpl<T, V>(
|
||||||
|
String id,
|
||||||
|
ArgumentType<T, V> type,
|
||||||
|
List<ArgumentRequirement<V>> requirements,
|
||||||
|
Function<CommandContext<T>, V> defaultValueProvider,
|
||||||
|
@Nullable SuggestionProvider<T> suggestionProvider
|
||||||
|
) implements CommandArgumentSpec<T, V> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public V parseInput(String rawInput) {
|
||||||
|
var parsed = type.parseInputUnchecked(rawInput);
|
||||||
|
for (var requirement : requirements) {
|
||||||
|
if (!requirement.predicate().test(parsed))
|
||||||
|
throw new IllegalArgumentException(requirement.message());
|
||||||
|
}
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Function<CommandContext<T>, V> defaultValueProvider() {
|
||||||
|
return defaultValueProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull SuggestionProvider<T> suggestionProvider() {
|
||||||
|
return suggestionProvider != null ? suggestionProvider : type.getDefaultSuggestionProvider();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,17 +2,16 @@ package de.kentoj.kencommandapi.api.argument.types;
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
import de.kentoj.kencommandapi.api.suggestion.NoSuggestionProvider;
|
|
||||||
|
|
||||||
public class IntegerArgumentType<T> implements ArgumentType<T, Integer> {
|
public class IntegerArgumentType<T> implements ArgumentType<T, Integer> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer parseInput(String string) {
|
public Integer parseInputUnchecked(String string) {
|
||||||
return Integer.parseInt(string);
|
return Integer.parseInt(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SuggestionProvider<T> defaultSuggestionProvider() {
|
public SuggestionProvider<T> getDefaultSuggestionProvider() {
|
||||||
return new NoSuggestionProvider<>();
|
return SuggestionProvider.none();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
package de.kentoj.kencommandapi.api.argument.types;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
||||||
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
|
|
||||||
|
public record StringArgumentType<T>(boolean greedy) implements ArgumentType<T, String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String parseInputUnchecked(String string) {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SuggestionProvider<T> getDefaultSuggestionProvider() {
|
||||||
|
return SuggestionProvider.none();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
package de.kentoj.kencommandapi.api.invocation;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface CommandContext<T> {
|
||||||
|
|
||||||
|
T sender();
|
||||||
|
|
||||||
|
<V> CommandArgument<T, V> getParsedArgument(String id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the value of the argument with the specified id
|
||||||
|
* @param <V> the type of the value of the argument with the specified id
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
default <V> V getArg(String id) {
|
||||||
|
return (V) getParsedArgument(id).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param arg the argument whose value to return
|
||||||
|
* @return the value of the argument
|
||||||
|
* @param <V> the type of the value of the argument
|
||||||
|
*/
|
||||||
|
default <V> V getArg(CommandArgumentSpec<T, V> arg) {
|
||||||
|
return getArg(arg.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
default <V> CommandArgument<T, V> getParsedArgument(CommandArgumentSpec<T, V> arg) {
|
||||||
|
return getParsedArgument(arg.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, CommandArgument<T, ?>> parsedArguments();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
package de.kentoj.kencommandapi.api.literal;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface Literal<T> {
|
||||||
|
static <T> LiteralBuilder<T> builder(String... name) {
|
||||||
|
return new LiteralBuilder<>(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull String[] names();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return what the literal does
|
||||||
|
*/
|
||||||
|
@Nullable String description();
|
||||||
|
|
||||||
|
List<CommandArgumentSpec<T, ?>> arguments();
|
||||||
|
|
||||||
|
@Nullable CommandExecutor<T> executor();
|
||||||
|
|
||||||
|
@Nullable Literal<T> getLiteral(@NotNull String name);
|
||||||
|
|
||||||
|
@NotNull List<Literal<T>> literals();
|
||||||
|
|
||||||
|
@Nullable String permission();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
package de.kentoj.kencommandapi.api.literal;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.SyncCommandExecutor;
|
||||||
|
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
|
||||||
|
public final class LiteralBuilder<T> {
|
||||||
|
|
||||||
|
private final String[] names;
|
||||||
|
private @Nullable String description;
|
||||||
|
private @Nullable CommandExecutor<T> executor;
|
||||||
|
private @Nullable String permission;
|
||||||
|
private final List<CommandArgumentSpec<T, ?>> arguments = new ArrayList<>();
|
||||||
|
private final List<Literal<T>> literals = new ArrayList<>();
|
||||||
|
|
||||||
|
LiteralBuilder(String... names) {
|
||||||
|
checkArgument(names.length > 0, "at least one name is required");
|
||||||
|
this.names = names;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param description what the literal does
|
||||||
|
*/
|
||||||
|
public LiteralBuilder<T> withDescription(@Nullable String description) {
|
||||||
|
this.description = description;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiteralBuilder<T> withExecutor(@Nullable CommandExecutor<T> executor) {
|
||||||
|
this.executor = executor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiteralBuilder<T> withSyncExecutor(@Nullable SyncCommandExecutor<T> executor) {
|
||||||
|
return withExecutor(executor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiteralBuilder<T> withPermission(@Nullable String permission) {
|
||||||
|
this.permission = permission;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws IllegalArgumentException if there is already an argument with the same id
|
||||||
|
* @throws IllegalStateException if a greedy argument was added to the literal previously
|
||||||
|
*/
|
||||||
|
public LiteralBuilder<T> withArgument(CommandArgumentSpec<T, ?> argument) {
|
||||||
|
checkArgument(!hasGreedyArg(), "cannot add an argument after a greedy argument");
|
||||||
|
if (arguments.stream().anyMatch(arg -> arg.id().equals(argument.id())))
|
||||||
|
throw new IllegalArgumentException("cannot add multiple arguments with the same id");
|
||||||
|
|
||||||
|
this.arguments.add(argument);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws IllegalArgumentException if there is already a literal with the same name
|
||||||
|
* @throws IllegalStateException if a greedy argument was added to the literal previously
|
||||||
|
*/
|
||||||
|
public LiteralBuilder<T> withLiteral(Literal<T> literal) {
|
||||||
|
checkArgument(!hasGreedyArg(), "cannot add a literal after a greedy argument");
|
||||||
|
for (String name : literal.names())
|
||||||
|
for (var l : literals)
|
||||||
|
if (l.getLiteral(name) != null)
|
||||||
|
throw new IllegalArgumentException("literal with same name already exists");
|
||||||
|
|
||||||
|
this.literals.add(literal);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RootLiteral<T> asRootLiteral(MessageStyle messageStyle) {
|
||||||
|
return new RootLiteralImpl<>(names, description, literals, arguments, executor, permission, messageStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Literal<T> build() {
|
||||||
|
return new LiteralImpl<>(names, description, literals, arguments, executor, permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasGreedyArg() {
|
||||||
|
if (arguments.isEmpty()) return false;
|
||||||
|
var arg = arguments.getLast();
|
||||||
|
return arg != null && arg.type().greedy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
package de.kentoj.kencommandapi.api.literal;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param description what the literal does
|
||||||
|
*/
|
||||||
|
record LiteralImpl<T>(
|
||||||
|
String[] names,
|
||||||
|
String description,
|
||||||
|
List<Literal<T>> literals,
|
||||||
|
List<CommandArgumentSpec<T, ?>> arguments,
|
||||||
|
CommandExecutor<T> executor,
|
||||||
|
@Nullable String permission
|
||||||
|
) implements Literal<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Literal<T> getLiteral(@NotNull String name) {
|
||||||
|
for (Literal<T> literal : literals) {
|
||||||
|
for (var literalName : literal.names()) {
|
||||||
|
if (literalName.equalsIgnoreCase(name))
|
||||||
|
return literal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
package de.kentoj.kencommandapi.api.literal;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||||
|
|
||||||
|
public sealed interface RootLiteral<T> extends Literal<T> permits RootLiteralImpl {
|
||||||
|
|
||||||
|
MessageStyle messageStyle();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
package de.kentoj.kencommandapi.api.literal;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||||
|
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
record RootLiteralImpl<T>(
|
||||||
|
String[] names,
|
||||||
|
String description,
|
||||||
|
List<Literal<T>> literals,
|
||||||
|
List<CommandArgumentSpec<T, ?>> arguments,
|
||||||
|
CommandExecutor<T> executor,
|
||||||
|
@Nullable String permission,
|
||||||
|
MessageStyle messageStyle
|
||||||
|
) implements RootLiteral<T> {
|
||||||
|
@Override
|
||||||
|
public @Nullable Literal<T> getLiteral(@NotNull String name) {
|
||||||
|
for (var l : literals) {
|
||||||
|
for (var lName : l.names())
|
||||||
|
if (lName.equalsIgnoreCase(name))
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@ package de.kentoj.kencommandapi.api.platform;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
public class PlainMessageStyle implements MessageStyle {
|
class PlainMessageStyle implements MessageStyle {
|
||||||
@Override
|
@Override
|
||||||
public Component ok(Component msg) {
|
public Component ok(Component msg) {
|
||||||
return msg;
|
return msg;
|
||||||
|
|
@ -2,10 +2,8 @@ package de.kentoj.kencommandapi.api.suggestion;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public class NoSuggestionProvider<T> implements SuggestionProvider<T> {
|
|
||||||
|
|
||||||
|
class NoSuggestionProvider<T> implements SuggestionProvider<T> {
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(T __) {
|
public List<String> suggest(T __) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
package de.kentoj.kencommandapi.api.suggestion;
|
package de.kentoj.kencommandapi.api.suggestion;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
public interface SuggestionProvider<T> {
|
public interface SuggestionProvider<T> {
|
||||||
|
|
||||||
|
static <T> SuggestionProvider<T> none() {
|
||||||
|
return new NoSuggestionProvider<>();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return an unfiltered(no permission checks or filtering by input) list of strings that may be used for the argument/literal
|
* @return an unfiltered(no permission checks or filtering by input) list of strings that may be used for the argument/literal
|
||||||
*/
|
*/
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package de.kentoj.kencommandapi.internal;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public record CommandContextImpl<T>(
|
||||||
|
T sender,
|
||||||
|
Map<String, CommandArgument<T, ?>> parsedArguments
|
||||||
|
) implements CommandContext<T> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <V> CommandArgument<T, V> getParsedArgument(String id) {
|
||||||
|
try {
|
||||||
|
//noinspection unchecked
|
||||||
|
return (CommandArgument<T, V>) parsedArguments.get(id);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
throw new RuntimeException("requested argument with wrong type", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package de.kentoj.kencommandapi.internal.parser;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||||
|
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public final class CommandParseHelper<T> {
|
||||||
|
private final HasPermissionMethod<T> hasPermission;
|
||||||
|
|
||||||
|
public CommandParseHelper(HasPermissionMethod<T> hasPermission) {
|
||||||
|
this.hasPermission = hasPermission;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPermission(T sender, Literal<T> literal) {
|
||||||
|
if (literal.permission() == null) return true;
|
||||||
|
return hasPermission.test(sender, literal.permission());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String parseInput(Iterator<String> tokenIter, boolean isGreedy) {
|
||||||
|
if (!isGreedy)
|
||||||
|
return tokenIter.next();
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
tokenIter.forEachRemaining(tok -> builder.append(" ").append(tok));
|
||||||
|
builder.deleteCharAt(0);
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
package de.kentoj.kencommandapi.internal.parser;
|
||||||
|
|
||||||
|
import com.leakyabstractions.result.api.Result;
|
||||||
|
import com.leakyabstractions.result.core.Results;
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgumentImpl;
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgumentSpec;
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
||||||
|
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
||||||
|
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||||
|
import de.kentoj.kencommandapi.internal.CommandContextImpl;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
public class InvocationCommandParser<T> {
|
||||||
|
|
||||||
|
private final CommandParseHelper<T> helper;
|
||||||
|
|
||||||
|
public InvocationCommandParser(CommandParseHelper<T> helper) {
|
||||||
|
this.helper = helper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<ExecutionData, String> parse(
|
||||||
|
Literal<T> rootLiteral,
|
||||||
|
T sender,
|
||||||
|
Iterator<String> tokenIter
|
||||||
|
) {
|
||||||
|
Literal<T> currentLiteral = rootLiteral;
|
||||||
|
var ctx = new CommandContextImpl<>(sender, new HashMap<>());
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
{
|
||||||
|
var result = processArguments(currentLiteral, ctx, tokenIter)
|
||||||
|
.ifSuccess(ctx.parsedArguments()::putAll);
|
||||||
|
if (result.hasFailure())
|
||||||
|
return result.mapSuccess(_ -> null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tokenIter.hasNext()) {
|
||||||
|
if (currentLiteral.executor() == null)
|
||||||
|
return Results.failure("Literal expected");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var literalName = tokenIter.next();
|
||||||
|
var nextLiteral = currentLiteral.getLiteral(literalName);
|
||||||
|
var isIncompleteOrUnknown = nextLiteral == null || !helper.hasPermission(sender, nextLiteral);
|
||||||
|
if (isIncompleteOrUnknown)
|
||||||
|
return Results.failure("Unknown literal: " + literalName);
|
||||||
|
currentLiteral = nextLiteral;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Results.success(new ExecutionData(currentLiteral.executor(), ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Result<Map<String, CommandArgument<T, ?>>, String> processArguments(
|
||||||
|
Literal<T> literal,
|
||||||
|
CommandContext<T> ctx,
|
||||||
|
Iterator<String> tokenIter
|
||||||
|
) {
|
||||||
|
Map<String, CommandArgument<T, ?>> parsedArguments = new HashMap<>();
|
||||||
|
|
||||||
|
for (var _argument : literal.arguments()) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
var argument = ((CommandArgumentSpec<T, Object>) _argument);
|
||||||
|
|
||||||
|
Object value;
|
||||||
|
if (!tokenIter.hasNext()) {
|
||||||
|
if (argument.defaultValueProvider() == null)
|
||||||
|
return Results.failure("Argument expected: " + argument.id());
|
||||||
|
value = requireNonNull(argument.defaultValueProvider()).apply(ctx);
|
||||||
|
} else {
|
||||||
|
var input = helper.parseInput(tokenIter, argument.type().greedy());
|
||||||
|
try {
|
||||||
|
value = argument.parseInput(input);
|
||||||
|
} catch (IllegalArgumentException ex) {
|
||||||
|
return Results.failure("Illegal argument '" + input + "' for " + argument.id() + ": " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedArguments.put(argument.id(), new CommandArgumentImpl<>(value, argument));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Results.success(parsedArguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ExecutionData {
|
||||||
|
private final CommandExecutor<T> executor;
|
||||||
|
private final CommandContext<T> context;
|
||||||
|
|
||||||
|
public ExecutionData(CommandExecutor<T> executor, CommandContext<T> context) {
|
||||||
|
this.executor = executor;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandExecutor<T> executor() {
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CommandContext<T> context() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
package de.kentoj.kencommandapi.internal.parser;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class SuggestionCommandParser<T> {
|
||||||
|
|
||||||
|
private final CommandParseHelper<T> helper;
|
||||||
|
|
||||||
|
public SuggestionCommandParser(CommandParseHelper<T> helper) {
|
||||||
|
this.helper = helper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> suggest(
|
||||||
|
Literal<T> rootLiteral,
|
||||||
|
T sender,
|
||||||
|
Iterator<String> tokenIter,
|
||||||
|
boolean suggestNext
|
||||||
|
) {
|
||||||
|
Literal<T> currentLiteral = rootLiteral;
|
||||||
|
Literal<T> previousLiteral = null;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
var argumentSuggestions = processArguments(currentLiteral, tokenIter, sender, suggestNext);
|
||||||
|
if (argumentSuggestions != null)
|
||||||
|
return argumentSuggestions;
|
||||||
|
|
||||||
|
if (!tokenIter.hasNext()) {
|
||||||
|
if (suggestNext || previousLiteral == null)
|
||||||
|
return suggestions(currentLiteral, sender).toList();
|
||||||
|
return suggestions(previousLiteral, sender).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
var input = tokenIter.next();
|
||||||
|
var nextLiteral = currentLiteral.getLiteral(input);
|
||||||
|
var isIncompleteOrUnknown = nextLiteral == null || !helper.hasPermission(sender, nextLiteral);
|
||||||
|
if (isIncompleteOrUnknown) {
|
||||||
|
var finalInput = input.toLowerCase();
|
||||||
|
return suggestions(currentLiteral, sender)
|
||||||
|
.filter(name -> name.toLowerCase().startsWith(finalInput))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
previousLiteral = currentLiteral;
|
||||||
|
currentLiteral = nextLiteral;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private @Nullable List<String> processArguments(
|
||||||
|
Literal<T> literal,
|
||||||
|
Iterator<String> tokenIter,
|
||||||
|
T sender,
|
||||||
|
boolean suggestNext
|
||||||
|
) {
|
||||||
|
var argsIter = literal.arguments().iterator();
|
||||||
|
|
||||||
|
/*
|
||||||
|
for each argument:
|
||||||
|
if no next token: suggest current
|
||||||
|
parse token
|
||||||
|
if not last token: skip
|
||||||
|
if nextToken:
|
||||||
|
if has next argument: suggest next argument
|
||||||
|
else: return null
|
||||||
|
return current argument's suggestions filtered
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (argsIter.hasNext()) {
|
||||||
|
var argument = argsIter.next();
|
||||||
|
if (!tokenIter.hasNext())
|
||||||
|
return argument.suggestionProvider().suggest(sender);
|
||||||
|
var input = helper.parseInput(tokenIter, argument.type().greedy()).toLowerCase();
|
||||||
|
if (tokenIter.hasNext())
|
||||||
|
continue;
|
||||||
|
if (suggestNext) {
|
||||||
|
if (argsIter.hasNext())
|
||||||
|
return argsIter.next().suggestionProvider().suggest(sender);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return argument.suggestionProvider().suggest(sender).stream()
|
||||||
|
.filter(suggestion -> suggestion.toLowerCase().startsWith(input))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Stream<String> suggestions(Literal<T> literal, T sender) {
|
||||||
|
return literal.literals().stream()
|
||||||
|
.filter(lit -> helper.hasPermission(sender, lit))
|
||||||
|
.map(Literal::names)
|
||||||
|
.flatMap(Arrays::stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
package de.kentoj.kencommandapi.api.parser;
|
||||||
|
|
||||||
|
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
||||||
|
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
|
||||||
|
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||||
|
import de.kentoj.kencommandapi.api.literal.Literal;
|
||||||
|
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||||
|
import de.kentoj.kencommandapi.internal.parser.SuggestionCommandParser;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class SuggestionCommandParserTest {
|
||||||
|
|
||||||
|
private final SuggestionCommandParser<Object> suggestionParser;
|
||||||
|
private final Literal<Object> rootLiteral;
|
||||||
|
|
||||||
|
public SuggestionCommandParserTest() {
|
||||||
|
rootLiteral = Literal.rootLiteral(MessageStyle.PLAIN, "someRootNode");
|
||||||
|
suggestionParser = new SuggestionCommandParser<>((__, ___) -> true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void suggestNextArgument() {
|
||||||
|
var arg = CommandArgument.arg("someArg", new StringArgumentType<>());
|
||||||
|
arg.setSuggestionProvider(__ -> List.of("foo", "bar"));
|
||||||
|
rootLiteral.addArgument(arg);
|
||||||
|
|
||||||
|
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args(""));
|
||||||
|
assertEquals(Stream.of("foo", "bar").sorted().toList(), suggestions.stream().sorted().toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void suggestNextArgumentAtSpace() {
|
||||||
|
var uselessArg = CommandArgument.arg("someUselessArg", new StringArgumentType<>());
|
||||||
|
var arg = CommandArgument.arg("someArg", new StringArgumentType<>());
|
||||||
|
arg.setSuggestionProvider(__ -> List.of("foo", "bar"));
|
||||||
|
rootLiteral.addArgument(uselessArg);
|
||||||
|
rootLiteral.addArgument(arg);
|
||||||
|
|
||||||
|
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args("hi "));
|
||||||
|
assertEquals(Stream.of("foo", "bar").sorted().toList(), suggestions.stream().sorted().toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void suggestCurrentArgument() {
|
||||||
|
var arg = CommandArgument.arg("someArg", new StringArgumentType<>());
|
||||||
|
arg.setSuggestionProvider(__ -> List.of("foo", "bar"));
|
||||||
|
rootLiteral.addArgument(arg);
|
||||||
|
|
||||||
|
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args("f"));
|
||||||
|
assertEquals(List.of("foo"), suggestions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void suggestNextLiteral() {
|
||||||
|
var literalFoo = Literal.literal("foo");
|
||||||
|
var literalBar = Literal.literal("bar");
|
||||||
|
rootLiteral.addLiteral(literalFoo);
|
||||||
|
rootLiteral.addLiteral(literalBar);
|
||||||
|
|
||||||
|
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args(""));
|
||||||
|
assertEquals(Stream.of("foo", "bar").sorted().toList(), suggestions.stream().sorted().toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void suggestCurrentLiteral() {
|
||||||
|
var literalFoo = Literal.literal("foo");
|
||||||
|
var literalBar = Literal.literal("bar");
|
||||||
|
rootLiteral.addLiteral(literalFoo);
|
||||||
|
rootLiteral.addLiteral(literalBar);
|
||||||
|
|
||||||
|
var suggestions = suggestionParser.getSuggestions(rootLiteral, ENV.SENDER, args("f"));
|
||||||
|
assertEquals(List.of("foo"), suggestions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] args(String input) {
|
||||||
|
List<String> args = new ArrayList<>(Arrays.asList(input.split(" ")));
|
||||||
|
if (input.endsWith(" "))
|
||||||
|
args.add("");
|
||||||
|
return args.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
6
gradle/wrapper/gradle-wrapper.properties
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
|
|
@ -1,6 +0,0 @@
|
||||||
#Tue Apr 14 21:48:06 CEST 2026
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
|
||||||
distributionPath=wrapper/dists
|
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
|
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
|
||||||
234
gradlew
vendored
234
gradlew
vendored
|
|
@ -1,234 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright © 2015-2021 the original authors.
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# Gradle start up script for POSIX generated by Gradle.
|
|
||||||
#
|
|
||||||
# Important for running:
|
|
||||||
#
|
|
||||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
|
||||||
# noncompliant, but you have some other compliant shell such as ksh or
|
|
||||||
# bash, then to run this script, type that shell name before the whole
|
|
||||||
# command line, like:
|
|
||||||
#
|
|
||||||
# ksh Gradle
|
|
||||||
#
|
|
||||||
# Busybox and similar reduced shells will NOT work, because this script
|
|
||||||
# requires all of these POSIX shell features:
|
|
||||||
# * functions;
|
|
||||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
|
||||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
|
||||||
# * compound commands having a testable exit status, especially «case»;
|
|
||||||
# * various built-in commands including «command», «set», and «ulimit».
|
|
||||||
#
|
|
||||||
# Important for patching:
|
|
||||||
#
|
|
||||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
|
||||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
|
||||||
#
|
|
||||||
# The "traditional" practice of packing multiple parameters into a
|
|
||||||
# space-separated string is a well documented source of bugs and security
|
|
||||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
|
||||||
# options in "$@", and eventually passing that to Java.
|
|
||||||
#
|
|
||||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
|
||||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
|
||||||
# see the in-line comments for details.
|
|
||||||
#
|
|
||||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
|
||||||
# Darwin, MinGW, and NonStop.
|
|
||||||
#
|
|
||||||
# (3) This script is generated from the Groovy template
|
|
||||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
|
||||||
# within the Gradle project.
|
|
||||||
#
|
|
||||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Attempt to set APP_HOME
|
|
||||||
|
|
||||||
# Resolve links: $0 may be a link
|
|
||||||
app_path=$0
|
|
||||||
|
|
||||||
# Need this for daisy-chained symlinks.
|
|
||||||
while
|
|
||||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
|
||||||
[ -h "$app_path" ]
|
|
||||||
do
|
|
||||||
ls=$( ls -ld "$app_path" )
|
|
||||||
link=${ls#*' -> '}
|
|
||||||
case $link in #(
|
|
||||||
/*) app_path=$link ;; #(
|
|
||||||
*) app_path=$APP_HOME$link ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
|
||||||
|
|
||||||
APP_NAME="Gradle"
|
|
||||||
APP_BASE_NAME=${0##*/}
|
|
||||||
|
|
||||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
|
||||||
|
|
||||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
|
||||||
MAX_FD=maximum
|
|
||||||
|
|
||||||
warn () {
|
|
||||||
echo "$*"
|
|
||||||
} >&2
|
|
||||||
|
|
||||||
die () {
|
|
||||||
echo
|
|
||||||
echo "$*"
|
|
||||||
echo
|
|
||||||
exit 1
|
|
||||||
} >&2
|
|
||||||
|
|
||||||
# OS specific support (must be 'true' or 'false').
|
|
||||||
cygwin=false
|
|
||||||
msys=false
|
|
||||||
darwin=false
|
|
||||||
nonstop=false
|
|
||||||
case "$( uname )" in #(
|
|
||||||
CYGWIN* ) cygwin=true ;; #(
|
|
||||||
Darwin* ) darwin=true ;; #(
|
|
||||||
MSYS* | MINGW* ) msys=true ;; #(
|
|
||||||
NONSTOP* ) nonstop=true ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
|
||||||
if [ -n "$JAVA_HOME" ] ; then
|
|
||||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
|
||||||
# IBM's JDK on AIX uses strange locations for the executables
|
|
||||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
|
||||||
else
|
|
||||||
JAVACMD=$JAVA_HOME/bin/java
|
|
||||||
fi
|
|
||||||
if [ ! -x "$JAVACMD" ] ; then
|
|
||||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
JAVACMD=java
|
|
||||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
|
|
||||||
Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
location of your Java installation."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Increase the maximum file descriptors if we can.
|
|
||||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
|
||||||
case $MAX_FD in #(
|
|
||||||
max*)
|
|
||||||
MAX_FD=$( ulimit -H -n ) ||
|
|
||||||
warn "Could not query maximum file descriptor limit"
|
|
||||||
esac
|
|
||||||
case $MAX_FD in #(
|
|
||||||
'' | soft) :;; #(
|
|
||||||
*)
|
|
||||||
ulimit -n "$MAX_FD" ||
|
|
||||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Collect all arguments for the java command, stacking in reverse order:
|
|
||||||
# * args from the command line
|
|
||||||
# * the main class name
|
|
||||||
# * -classpath
|
|
||||||
# * -D...appname settings
|
|
||||||
# * --module-path (only if needed)
|
|
||||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
|
||||||
|
|
||||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
|
||||||
if "$cygwin" || "$msys" ; then
|
|
||||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
|
||||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
|
||||||
|
|
||||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
|
||||||
|
|
||||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
|
||||||
for arg do
|
|
||||||
if
|
|
||||||
case $arg in #(
|
|
||||||
-*) false ;; # don't mess with options #(
|
|
||||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
|
||||||
[ -e "$t" ] ;; #(
|
|
||||||
*) false ;;
|
|
||||||
esac
|
|
||||||
then
|
|
||||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
|
||||||
fi
|
|
||||||
# Roll the args list around exactly as many times as the number of
|
|
||||||
# args, so each arg winds up back in the position where it started, but
|
|
||||||
# possibly modified.
|
|
||||||
#
|
|
||||||
# NB: a `for` loop captures its iteration list before it begins, so
|
|
||||||
# changing the positional parameters here affects neither the number of
|
|
||||||
# iterations, nor the values presented in `arg`.
|
|
||||||
shift # remove old arg
|
|
||||||
set -- "$@" "$arg" # push replacement arg
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Collect all arguments for the java command;
|
|
||||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
|
||||||
# shell script including quotes and variable substitutions, so put them in
|
|
||||||
# double quotes to make sure that they get re-expanded; and
|
|
||||||
# * put everything else in single quotes, so that it's not re-expanded.
|
|
||||||
|
|
||||||
set -- \
|
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
|
||||||
-classpath "$CLASSPATH" \
|
|
||||||
org.gradle.wrapper.GradleWrapperMain \
|
|
||||||
"$@"
|
|
||||||
|
|
||||||
# Use "xargs" to parse quoted args.
|
|
||||||
#
|
|
||||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
|
||||||
#
|
|
||||||
# In Bash we could simply go:
|
|
||||||
#
|
|
||||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
|
||||||
# set -- "${ARGS[@]}" "$@"
|
|
||||||
#
|
|
||||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
|
||||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
|
||||||
# character that might be a shell metacharacter, then use eval to reverse
|
|
||||||
# that process (while maintaining the separation between arguments), and wrap
|
|
||||||
# the whole thing up as a single "set" statement.
|
|
||||||
#
|
|
||||||
# This will of course break if any of these variables contains a newline or
|
|
||||||
# an unmatched quote.
|
|
||||||
#
|
|
||||||
|
|
||||||
eval "set -- $(
|
|
||||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
|
||||||
xargs -n1 |
|
|
||||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
|
||||||
tr '\n' ' '
|
|
||||||
)" '"$@"'
|
|
||||||
|
|
||||||
exec "$JAVACMD" "$@"
|
|
||||||
89
gradlew.bat
vendored
89
gradlew.bat
vendored
|
|
@ -1,89 +0,0 @@
|
||||||
@rem
|
|
||||||
@rem Copyright 2015 the original author or authors.
|
|
||||||
@rem
|
|
||||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
@rem you may not use this file except in compliance with the License.
|
|
||||||
@rem You may obtain a copy of the License at
|
|
||||||
@rem
|
|
||||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
@rem
|
|
||||||
@rem Unless required by applicable law or agreed to in writing, software
|
|
||||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
@rem See the License for the specific language governing permissions and
|
|
||||||
@rem limitations under the License.
|
|
||||||
@rem
|
|
||||||
|
|
||||||
@if "%DEBUG%" == "" @echo off
|
|
||||||
@rem ##########################################################################
|
|
||||||
@rem
|
|
||||||
@rem Gradle startup script for Windows
|
|
||||||
@rem
|
|
||||||
@rem ##########################################################################
|
|
||||||
|
|
||||||
@rem Set local scope for the variables with windows NT shell
|
|
||||||
if "%OS%"=="Windows_NT" setlocal
|
|
||||||
|
|
||||||
set DIRNAME=%~dp0
|
|
||||||
if "%DIRNAME%" == "" set DIRNAME=.
|
|
||||||
set APP_BASE_NAME=%~n0
|
|
||||||
set APP_HOME=%DIRNAME%
|
|
||||||
|
|
||||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
|
||||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
|
||||||
|
|
||||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
|
||||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
|
||||||
|
|
||||||
@rem Find java.exe
|
|
||||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
|
||||||
|
|
||||||
set JAVA_EXE=java.exe
|
|
||||||
%JAVA_EXE% -version >NUL 2>&1
|
|
||||||
if "%ERRORLEVEL%" == "0" goto execute
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:findJavaFromJavaHome
|
|
||||||
set JAVA_HOME=%JAVA_HOME:"=%
|
|
||||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
|
||||||
|
|
||||||
if exist "%JAVA_EXE%" goto execute
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
|
||||||
echo.
|
|
||||||
echo Please set the JAVA_HOME variable in your environment to match the
|
|
||||||
echo location of your Java installation.
|
|
||||||
|
|
||||||
goto fail
|
|
||||||
|
|
||||||
:execute
|
|
||||||
@rem Setup the command line
|
|
||||||
|
|
||||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
|
||||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
|
||||||
|
|
||||||
:end
|
|
||||||
@rem End local scope for the variables with windows NT shell
|
|
||||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
|
||||||
|
|
||||||
:fail
|
|
||||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
|
||||||
rem the _cmd.exe /c_ return code!
|
|
||||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
|
||||||
exit /b 1
|
|
||||||
|
|
||||||
:mainEnd
|
|
||||||
if "%OS%"=="Windows_NT" endlocal
|
|
||||||
|
|
||||||
:omega
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
plugins {
|
|
||||||
id("java")
|
|
||||||
id("scrow.scrow-publish")
|
|
||||||
id("scrow.base-dependencies")
|
|
||||||
id("scrow.java-library")
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven("https://repo.papermc.io/repository/maven-public/") {
|
|
||||||
name = "papermc"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
compileOnly(project(":kencommandapi-core"))
|
|
||||||
compileOnly("io.papermc.paper:paper-api:1.21.11-rc3-R0.1-SNAPSHOT")
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
create<MavenPublication>("KenCommandAPI") {
|
|
||||||
groupId = rootProject.group.toString()
|
|
||||||
version = rootProject.version.toString()
|
|
||||||
artifactId = project.name
|
|
||||||
from(components["java"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
package de.kentoj.kencommandapi;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.CommandHandler;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
|
||||||
import org.bukkit.command.Command;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class BukkitKenCommand extends Command {
|
|
||||||
|
|
||||||
private final RootLiteral<CommandSender> rootNode;
|
|
||||||
private final CommandHandler<CommandSender> commandHandler;
|
|
||||||
|
|
||||||
protected BukkitKenCommand(
|
|
||||||
CommandHandler<CommandSender> commandHandler,
|
|
||||||
RootLiteral<CommandSender> rootLiteral
|
|
||||||
) {
|
|
||||||
super(rootLiteral.getNames()[0]);
|
|
||||||
this.commandHandler = commandHandler;
|
|
||||||
this.rootNode = rootLiteral;
|
|
||||||
this.setAliases(Arrays.asList(rootLiteral.getNames()));
|
|
||||||
this.setPermission(rootLiteral.getPermission());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args) {
|
|
||||||
commandHandler.invoke(rootNode, sender, args);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
package de.kentoj.kencommandapi;
|
|
||||||
|
|
||||||
import com.destroystokyo.paper.event.server.AsyncTabCompleteEvent;
|
|
||||||
import de.kentoj.kencommandapi.api.CommandHandler;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class TabCompleteListener implements Listener {
|
|
||||||
|
|
||||||
private final CommandAPI commandAPI;
|
|
||||||
private final CommandHandler<CommandSender> commandHandler;
|
|
||||||
|
|
||||||
@EventHandler(ignoreCancelled = true)
|
|
||||||
public void onAsyncTabComplete(AsyncTabCompleteEvent ev) {
|
|
||||||
if (!ev.isCommand()) return;
|
|
||||||
|
|
||||||
var args = ev.getBuffer().substring(1).split(" ");
|
|
||||||
var label = args[0];
|
|
||||||
var rootNode = commandAPI.getRegistered(label);
|
|
||||||
if (rootNode == null) return;
|
|
||||||
ev.setHandled(true);
|
|
||||||
ev.setCompletions(commandHandler.getSuggestions(rootNode, ev.getSender(), Arrays.copyOfRange(args, 1, args.length)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.type;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
|
||||||
import de.kentoj.kencommandapi.suggestionprovider.PlayerSuggestionProvider;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.OfflinePlayer;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class OfflinePlayerArgumentType implements ArgumentType<CommandSender, OfflinePlayer> {
|
|
||||||
|
|
||||||
@Getter(lazy = true)
|
|
||||||
private static final OfflinePlayerArgumentType instance = new OfflinePlayerArgumentType();
|
|
||||||
|
|
||||||
// TODO make work with player names on offline players
|
|
||||||
@Override
|
|
||||||
public OfflinePlayer parseInput(String string) {
|
|
||||||
OfflinePlayer player = Bukkit.getPlayerExact(string);
|
|
||||||
if (player == null) {
|
|
||||||
try {
|
|
||||||
player = Bukkit.getOfflinePlayer(UUID.fromString(string));
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
throw new IllegalArgumentException("not an UUID or online player");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!player.hasPlayedBefore() && !player.isOnline()) throw new IllegalArgumentException("Player not found");
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SuggestionProvider<CommandSender> defaultSuggestionProvider() {
|
|
||||||
return new PlayerSuggestionProvider();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.type;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
|
||||||
import de.kentoj.kencommandapi.suggestionprovider.PlayerSuggestionProvider;
|
|
||||||
import lombok.AccessLevel;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.command.CommandSender;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
|
||||||
public class PlayerArgumentType implements ArgumentType<CommandSender, Player> {
|
|
||||||
|
|
||||||
@Getter(lazy = true)
|
|
||||||
private static final PlayerArgumentType instance = new PlayerArgumentType();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Player parseInput(String string) {
|
|
||||||
var player = Bukkit.getPlayer(string);
|
|
||||||
if (player == null) throw new IllegalArgumentException("player not online");
|
|
||||||
return player;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SuggestionProvider<CommandSender> defaultSuggestionProvider() {
|
|
||||||
return new PlayerSuggestionProvider();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
plugins {
|
|
||||||
id("java")
|
|
||||||
id("scrow.scrow-publish")
|
|
||||||
id("scrow.base-dependencies")
|
|
||||||
id("scrow.java-library")
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-api:6.1.1")
|
|
||||||
// https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:6.1.1")
|
|
||||||
// https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher
|
|
||||||
testImplementation("org.junit.platform:junit-platform-launcher:6.1.1")
|
|
||||||
testImplementation("net.kyori:adventure-api:5.2.0")
|
|
||||||
|
|
||||||
compileOnly("net.kyori:adventure-api:5.2.0")
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.test {
|
|
||||||
useJUnitPlatform()
|
|
||||||
testLogging {
|
|
||||||
showStandardStreams = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
create<MavenPublication>("KenCommandAPI") {
|
|
||||||
groupId = rootProject.group.toString()
|
|
||||||
version = rootProject.version.toString()
|
|
||||||
artifactId = project.name
|
|
||||||
from(components["java"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.invocation.CommandContext;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
|
||||||
import de.kentoj.kencommandapi.api.parser2.InvocationCommandParser;
|
|
||||||
import de.kentoj.kencommandapi.api.parser2.SuggestionCommandParser;
|
|
||||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
|
||||||
import de.kentoj.kencommandapi.api.platform.SendMessageMethod;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class CommandHandler<T> {
|
|
||||||
|
|
||||||
private final SendMessageMethod<T> sendMessageMethod;
|
|
||||||
|
|
||||||
private final InvocationCommandParser<T> invocationParser;
|
|
||||||
private final SuggestionCommandParser<T> suggestionParser;
|
|
||||||
|
|
||||||
public CommandHandler(SendMessageMethod<T> sendMessageMethod, HasPermissionMethod<T> hasPermissionMethod) {
|
|
||||||
this.sendMessageMethod = sendMessageMethod;
|
|
||||||
invocationParser = new InvocationCommandParser<>(hasPermissionMethod);
|
|
||||||
suggestionParser = new SuggestionCommandParser<>(hasPermissionMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("CodeBlock2Expr")
|
|
||||||
public void invoke(RootLiteral<T> rootLiteral, T sender, String[] args) {
|
|
||||||
invocationParser.invoke(rootLiteral, sender, args)
|
|
||||||
.ifSuccessOrElse(data -> {
|
|
||||||
var ctx = new CommandContext<>(sender, data.getArguments());
|
|
||||||
data.getExecutor().execute(ctx).whenComplete((result, ex) -> {
|
|
||||||
if (ex != null)
|
|
||||||
sendMessageMethod.send(sender, rootLiteral.getMessageStyle().exception(ex));
|
|
||||||
result.ifFailure(err ->
|
|
||||||
sendMessageMethod.send(sender, rootLiteral.getMessageStyle().err(err)));
|
|
||||||
});
|
|
||||||
}, err -> {
|
|
||||||
sendMessageMethod.send(sender, rootLiteral.getMessageStyle().err(err));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getSuggestions(RootLiteral<T> rootNode, T sender, String[] args) {
|
|
||||||
return suggestionParser.getSuggestions(rootNode, sender, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.argument;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
|
||||||
import de.kentoj.kencommandapi.internal.CommandArgumentImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
public interface CommandArgument<T, V> {
|
|
||||||
|
|
||||||
static <T, V> CommandArgument<T, V> arg(String id, ArgumentType<T, V> type) {
|
|
||||||
return new CommandArgumentImpl<>(id, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
String getId();
|
|
||||||
|
|
||||||
ArgumentType<T, V> getType();
|
|
||||||
|
|
||||||
void setDefaultValueProvider(@Nullable Function<T, V> defaultValueProvider);
|
|
||||||
|
|
||||||
@Nullable Function<T, V> getDefaultValueProvider();
|
|
||||||
|
|
||||||
void setSuggestionProvider(@Nullable SuggestionProvider<T> suggestionProvider);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the explicitly set SuggestionProvider or the default suggestions for the type if unset/null
|
|
||||||
*/
|
|
||||||
@NotNull SuggestionProvider<T> getSuggestionProvider();
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.argument.types;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
|
||||||
import de.kentoj.kencommandapi.api.suggestion.NoSuggestionProvider;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class StringArgumentType<T> implements ArgumentType<T, String> {
|
|
||||||
|
|
||||||
private final boolean isGreedy;
|
|
||||||
|
|
||||||
public StringArgumentType() {
|
|
||||||
this(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String parseInput(String string) {
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SuggestionProvider<T> defaultSuggestionProvider() {
|
|
||||||
return new NoSuggestionProvider<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isGreedy() {
|
|
||||||
return this.isGreedy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.invocation;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class CommandContext<T> {
|
|
||||||
@Getter
|
|
||||||
private final T sender;
|
|
||||||
@Getter
|
|
||||||
private final Map<String, ParsedArgument<T, ?>> parsedArguments;
|
|
||||||
|
|
||||||
public <V> ParsedArgument<T, V> getParsedArgument(String name) {
|
|
||||||
try {
|
|
||||||
//noinspection unchecked
|
|
||||||
return (ParsedArgument<T, V>) parsedArguments.get(name);
|
|
||||||
} catch (ClassCastException e) {
|
|
||||||
throw new RuntimeException("requested argument with wrong type", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <V> V getArg(String name) {
|
|
||||||
return (V) getParsedArgument(name).getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public <V> V getArg(CommandArgument<T, V> arg) {
|
|
||||||
return getArg(arg.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public <V> ParsedArgument<T, V> getParsedArgument(CommandArgument<T, V> arg) {
|
|
||||||
return getParsedArgument(arg.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.invocation;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
|
|
||||||
public interface ParsedArgument<T, V> {
|
|
||||||
|
|
||||||
V getValue();
|
|
||||||
|
|
||||||
CommandArgument<T, V> getArgument();
|
|
||||||
}
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.literal;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
|
||||||
import de.kentoj.kencommandapi.internal.LiteralImpl;
|
|
||||||
import de.kentoj.kencommandapi.internal.RootLiteralImpl;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public interface Literal<T> {
|
|
||||||
static <T> Literal<T> literal(String... name) {
|
|
||||||
return new LiteralImpl<>(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static <T> RootLiteral<T> rootLiteral(MessageStyle messageStyle, String...name) {
|
|
||||||
return new RootLiteralImpl<>(messageStyle, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull String[] getNames();
|
|
||||||
|
|
||||||
void setDescription(@Nullable String description);
|
|
||||||
|
|
||||||
@Nullable String getDescription();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* arguments
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws IllegalArgumentException if there is already an argument with the same id
|
|
||||||
* @throws IllegalStateException if a greedy argument was added to the literal previously
|
|
||||||
* @throws IllegalStateException if the literal already has a child literal assigned to it
|
|
||||||
*/
|
|
||||||
<V> void addArgument(CommandArgument<T, V> argument);
|
|
||||||
|
|
||||||
List<CommandArgument<T, ?>> getArguments();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* literals
|
|
||||||
*/
|
|
||||||
|
|
||||||
void setExecutor(@Nullable CommandExecutor<T> executor);
|
|
||||||
|
|
||||||
@Nullable CommandExecutor<T> getExecutor();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws IllegalArgumentException if there is already a literal with the same name
|
|
||||||
* @throws IllegalStateException if a greedy argument was added to the literal previously
|
|
||||||
* @throws IllegalStateException if the literal already has an argument assigned to it
|
|
||||||
*/
|
|
||||||
void addLiteral(@NotNull Literal<T> literal);
|
|
||||||
|
|
||||||
@Nullable Literal<T> getLiteral(@NotNull String name);
|
|
||||||
|
|
||||||
@NotNull Set<Literal<T>> getLiterals();
|
|
||||||
|
|
||||||
@Nullable String getPermission();
|
|
||||||
|
|
||||||
void setPermission(@Nullable String permission);
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.literal;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
|
||||||
|
|
||||||
public interface RootLiteral<T> extends Literal<T> {
|
|
||||||
|
|
||||||
MessageStyle getMessageStyle();
|
|
||||||
|
|
||||||
void setMessageStyle(MessageStyle messageStyle);
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.parser2;
|
|
||||||
|
|
||||||
import com.leakyabstractions.result.api.Result;
|
|
||||||
import com.leakyabstractions.result.core.Results;
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
|
||||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public abstract class AbstractCommandParser<T> {
|
|
||||||
|
|
||||||
private final HasPermissionMethod<T> hasPermission;
|
|
||||||
|
|
||||||
protected boolean hasPermission(T sender, Literal<T> literal) {
|
|
||||||
if (literal.getPermission() == null) return true;
|
|
||||||
return hasPermission.test(sender, literal.getPermission());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String parseInput(String[] args, AtomicInteger index, boolean isGreedy) {
|
|
||||||
if (!isGreedy)
|
|
||||||
return args[index.getAndIncrement()];
|
|
||||||
|
|
||||||
var ret = String.join(" ", Arrays.copyOfRange(args, index.get(), args.length));
|
|
||||||
index.set(args.length);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Result<Object, String> parseArgument(CommandArgument<T, Object> argument, String input) {
|
|
||||||
try {
|
|
||||||
return Results.success(argument.getType().parseInput(input));
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
return Results.failure("Illegal argument '" + input + "' for " + argument.getId() + ": " + ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.parser2;
|
|
||||||
|
|
||||||
import com.leakyabstractions.result.api.Result;
|
|
||||||
import com.leakyabstractions.result.core.Results;
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
|
||||||
import de.kentoj.kencommandapi.api.invocation.ParsedArgument;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
|
||||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
|
||||||
import de.kentoj.kencommandapi.internal.ParsedArgumentImpl;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class InvocationCommandParser<T> extends AbstractCommandParser<T> {
|
|
||||||
|
|
||||||
public InvocationCommandParser(HasPermissionMethod<T> hasPermission) {
|
|
||||||
super(hasPermission);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Result<ExecutionData, String> invoke(
|
|
||||||
RootLiteral<T> rootLiteral,
|
|
||||||
T sender,
|
|
||||||
String[] args
|
|
||||||
) {
|
|
||||||
Map<String, ParsedArgument<T, ?>> parsedArguments = new HashMap<>();
|
|
||||||
Literal<T> currentLiteral = rootLiteral;
|
|
||||||
AtomicInteger index = new AtomicInteger(0);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
for (var _argument : currentLiteral.getArguments()) {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
var argument = ((CommandArgument<T, Object>) _argument);
|
|
||||||
|
|
||||||
Object value;
|
|
||||||
if (index.get() >= args.length) {
|
|
||||||
if (argument.getDefaultValueProvider() == null)
|
|
||||||
return Results.failure("Argument expected: " + argument.getId());
|
|
||||||
value = argument.getDefaultValueProvider().apply(sender);
|
|
||||||
} else {
|
|
||||||
var input = parseInput(args, index, argument.getType().isGreedy());
|
|
||||||
var parseResult = parseArgument(argument, input);
|
|
||||||
if (parseResult.hasFailure()) return parseResult.mapSuccess(__ -> null);
|
|
||||||
value = parseResult.getSuccess().orElseThrow();
|
|
||||||
}
|
|
||||||
|
|
||||||
parsedArguments.put(argument.getId(), new ParsedArgumentImpl<>(value, argument));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index.get() >= args.length) {
|
|
||||||
if (currentLiteral.getExecutor() == null)
|
|
||||||
return Results.failure("Literal expected");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var literalName = args[index.getAndIncrement()];
|
|
||||||
var nextLiteral = currentLiteral.getLiteral(literalName);
|
|
||||||
if (nextLiteral == null || !hasPermission(sender, nextLiteral))
|
|
||||||
return Results.failure("Unknown literal: " + literalName);
|
|
||||||
currentLiteral = nextLiteral;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Results.success(new ExecutionData(currentLiteral.getExecutor(), parsedArguments));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value
|
|
||||||
public class ExecutionData {
|
|
||||||
CommandExecutor<T> executor;
|
|
||||||
Map<String, ParsedArgument<T, ?>> arguments;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.parser2;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
|
||||||
import de.kentoj.kencommandapi.api.platform.HasPermissionMethod;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class SuggestionCommandParser<T> extends AbstractCommandParser<T> {
|
|
||||||
|
|
||||||
public SuggestionCommandParser(HasPermissionMethod<T> hasPermission) {
|
|
||||||
super(hasPermission);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getSuggestions(
|
|
||||||
RootLiteral<T> rootNode,
|
|
||||||
T sender,
|
|
||||||
String[] args
|
|
||||||
) {
|
|
||||||
Literal<T> currentLiteral = rootNode;
|
|
||||||
AtomicInteger index = new AtomicInteger(0);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
for (var argument : currentLiteral.getArguments()) {
|
|
||||||
// TODO somewhere suggest next argument at trailing space
|
|
||||||
if (index.getAndIncrement() >= args.length)
|
|
||||||
return argument.getSuggestionProvider().suggest(sender);
|
|
||||||
if (argument.getType().isGreedy())
|
|
||||||
index.set(args.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (index.get() >= args.length) {
|
|
||||||
// TODO suggest next argument at trailing space
|
|
||||||
if (currentLiteral.getExecutor() == null)
|
|
||||||
return suggestions(currentLiteral, sender).toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
var input = args[index.getAndIncrement()];
|
|
||||||
var nextLiteral = currentLiteral.getLiteral(input);
|
|
||||||
if (nextLiteral == null || !hasPermission(sender, nextLiteral)) {
|
|
||||||
var finalInput = input.toLowerCase();
|
|
||||||
return suggestions(currentLiteral, sender)
|
|
||||||
.filter(name -> name.toLowerCase().startsWith(finalInput))
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
|
|
||||||
currentLiteral = nextLiteral;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Stream<String> suggestions(Literal<T> literal, T sender) {
|
|
||||||
return literal.getLiterals().stream()
|
|
||||||
.filter(lit -> hasPermission(sender, lit))
|
|
||||||
.map(Literal::getNames)
|
|
||||||
.flatMap(Arrays::stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.internal;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class CommandArgumentImpl<T, V> implements CommandArgument<T, V> {
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String id;
|
|
||||||
@Getter
|
|
||||||
private final ArgumentType<T, V> type;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private @Nullable Function<T, V> defaultValueProvider = null;
|
|
||||||
@Setter
|
|
||||||
private @Nullable SuggestionProvider<T> suggestionProvider;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @NotNull SuggestionProvider<T> getSuggestionProvider() {
|
|
||||||
if (suggestionProvider == null)
|
|
||||||
return getType().defaultSuggestionProvider();
|
|
||||||
return this.suggestionProvider;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,72 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.internal;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
import de.kentoj.kencommandapi.api.invocation.CommandExecutor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class LiteralImpl<T> implements Literal<T> {
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private final String[] names;
|
|
||||||
@Getter
|
|
||||||
private final Set<Literal<T>> literals = new HashSet<>();
|
|
||||||
@Getter
|
|
||||||
private final List<CommandArgument<T, ?>> arguments = new ArrayList<>();
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private @Nullable CommandExecutor<T> executor;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private @Nullable String permission = null;
|
|
||||||
|
|
||||||
public LiteralImpl(String[] names) {
|
|
||||||
if (names.length == 0) throw new IllegalArgumentException("at least one name is required");
|
|
||||||
this.names = names;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addLiteral(@NotNull Literal<T> literal) {
|
|
||||||
if (isGreedy()) throw new IllegalStateException("can't add literal to a node with a greedy argument");
|
|
||||||
for (String name : literal.getNames())
|
|
||||||
if (getLiteral(name) != null)
|
|
||||||
throw new IllegalArgumentException("literal with same name already exists");
|
|
||||||
literals.add(literal);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Literal<T> getLiteral(@NotNull String name) {
|
|
||||||
for (var literal : literals)
|
|
||||||
for (String literalName : literal.getNames())
|
|
||||||
if (literalName.equalsIgnoreCase(name)) return literal;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <V> void addArgument(CommandArgument<T, V> argument) {
|
|
||||||
if (isGreedy()) throw new IllegalStateException("can't add literal to a node with a greedy argument");
|
|
||||||
if (arguments.stream().anyMatch(arg -> arg.getId().equals(argument.getId())))
|
|
||||||
throw new IllegalArgumentException("argument with same identifier is already added");
|
|
||||||
arguments.add(argument);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isGreedy() {
|
|
||||||
if (arguments.isEmpty()) return false;
|
|
||||||
var arg = arguments.getLast();
|
|
||||||
return arg != null && arg.getType().isGreedy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.internal;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
import de.kentoj.kencommandapi.api.invocation.ParsedArgument;
|
|
||||||
import lombok.Value;
|
|
||||||
|
|
||||||
@Value
|
|
||||||
public class ParsedArgumentImpl<T, V> implements ParsedArgument<T, V> {
|
|
||||||
V value;
|
|
||||||
CommandArgument<T, V> argument;
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.internal;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
public class RootLiteralImpl<T> extends LiteralImpl<T> implements RootLiteral<T> {
|
|
||||||
@Setter
|
|
||||||
@Getter
|
|
||||||
private MessageStyle messageStyle;
|
|
||||||
|
|
||||||
public RootLiteralImpl(MessageStyle messageStyle, String[] names) {
|
|
||||||
super(names);
|
|
||||||
this.messageStyle = messageStyle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
package de.kentoj.kencommandapi.api.parser;
|
|
||||||
|
|
||||||
import de.kentoj.kencommandapi.api.CommandHandler;
|
|
||||||
import de.kentoj.kencommandapi.api.argument.CommandArgument;
|
|
||||||
import de.kentoj.kencommandapi.api.argument.types.StringArgumentType;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.Literal;
|
|
||||||
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
public class CommandHandlerTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void suggestArgument() {
|
|
||||||
var rootNode = Literal.rootLiteral(MessageStyle.PLAIN, "someRootNode");
|
|
||||||
var arg = CommandArgument.arg("someArg", new StringArgumentType<>());
|
|
||||||
arg.setSuggestionProvider(__ -> List.of("a", "b", "c"));
|
|
||||||
rootNode.addArgument(arg);
|
|
||||||
rootNode.setExecutor(ENV.EMPTY_EXECUTOR);
|
|
||||||
|
|
||||||
var handler = new CommandHandler<>((__, ___) -> {}, (__, ___) -> true);
|
|
||||||
var suggestions = handler.getSuggestions(rootNode, ENV.SENDER, new String[0]);
|
|
||||||
assertEquals(List.of("a", "b", "c"), suggestions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void suggestLiterals() {
|
|
||||||
var rootNode = Literal.rootLiteral(MessageStyle.PLAIN, "someRootNode");
|
|
||||||
var literal1 = Literal.literal("lit1");
|
|
||||||
var literal2 = Literal.literal("lit2");
|
|
||||||
rootNode.addLiteral(literal1);
|
|
||||||
rootNode.addLiteral(literal2);
|
|
||||||
|
|
||||||
var handler = new CommandHandler<>((__, ___) -> {}, (__, ___) -> true);
|
|
||||||
var suggestions = handler.getSuggestions(rootNode, ENV.SENDER, new String[0]);
|
|
||||||
assertEquals(List.of("lit1", "lit2"), suggestions.stream().sorted().toList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
plugins {
|
|
||||||
id("java")
|
|
||||||
id("scrow.scrow-publish")
|
|
||||||
id("scrow.base-dependencies")
|
|
||||||
id("scrow.java-library")
|
|
||||||
}
|
|
||||||
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
name = "papermc"
|
|
||||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
// https://docs.papermc.io/velocity/dev/creating-your-first-plugin/
|
|
||||||
annotationProcessor("com.velocitypowered:velocity-api:3.5.0-SNAPSHOT")
|
|
||||||
compileOnly("com.velocitypowered:velocity-api:3.5.0-SNAPSHOT")
|
|
||||||
|
|
||||||
api(project(":kencommandapi-core"))
|
|
||||||
}
|
|
||||||
|
|
||||||
publishing {
|
|
||||||
publications {
|
|
||||||
create<MavenPublication>("KenCommandAPI") {
|
|
||||||
groupId = rootProject.group.toString()
|
|
||||||
version = rootProject.version.toString()
|
|
||||||
artifactId = project.name
|
|
||||||
from(components["java"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
package de.kentoj.kencommandapi;
|
|
||||||
|
|
||||||
import com.velocitypowered.api.command.CommandSource;
|
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
|
||||||
import de.kentoj.kencommandapi.api.CommandHandler;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class CommandAPI {
|
|
||||||
|
|
||||||
private final ProxyServer server;
|
|
||||||
private final CommandHandler<CommandSource> commandHandler =
|
|
||||||
new CommandHandler<>(CommandSource::sendMessage, CommandSource::hasPermission);
|
|
||||||
|
|
||||||
public void register(RootLiteral<CommandSource> rootNode) {
|
|
||||||
var cm = server.getCommandManager();
|
|
||||||
var meta = cm.metaBuilder(rootNode.getNames()[0])
|
|
||||||
.aliases(Arrays.copyOfRange(rootNode.getNames(), 1, rootNode.getNames().length))
|
|
||||||
.build();
|
|
||||||
cm.register(meta, new VelocityCommand(commandHandler, rootNode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
package de.kentoj.kencommandapi;
|
|
||||||
|
|
||||||
import com.velocitypowered.api.command.CommandSource;
|
|
||||||
import com.velocitypowered.api.command.SimpleCommand;
|
|
||||||
import de.kentoj.kencommandapi.api.CommandHandler;
|
|
||||||
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class VelocityCommand implements SimpleCommand {
|
|
||||||
|
|
||||||
private final CommandHandler<CommandSource> commandHandler;
|
|
||||||
private final RootLiteral<CommandSource> rootNode;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(Invocation invocation) {
|
|
||||||
commandHandler.invoke(rootNode, invocation.source(), invocation.arguments());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasPermission(Invocation ctx) {
|
|
||||||
if (rootNode.getPermission() == null) return true;
|
|
||||||
return ctx.source().hasPermission(rootNode.getPermission());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> suggest(Invocation invocation) {
|
|
||||||
return commandHandler.getSuggestions(rootNode, invocation.source(), invocation.arguments());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
pluginManagement {
|
|
||||||
includeBuild("../build-logic")
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("scrow.scrow-repository")
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencyResolutionManagement {
|
|
||||||
repositories {
|
|
||||||
maven {
|
|
||||||
name = "papermc"
|
|
||||||
url = uri("https://repo.papermc.io/repository/maven-public/")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rootProject.name = "KenCommandAPI"
|
|
||||||
|
|
||||||
include("kencommandapi-core")
|
|
||||||
include("kencommandapi-bukkit")
|
|
||||||
include("kencommandapi-velocity")
|
|
||||||
15
velocity/BUILD
Normal file
15
velocity/BUILD
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
load("@rules_jvm_external//:defs.bzl", "artifact", "java_export")
|
||||||
|
|
||||||
|
java_export(
|
||||||
|
name = "velocity",
|
||||||
|
maven_coordinates = "de.kentoj.scrow:kencommandapi-velocity:0.34-SNAPSHOT",
|
||||||
|
srcs = glob(["src/main/**/*.java"]),
|
||||||
|
deps = [
|
||||||
|
"//core",
|
||||||
|
artifact("org.jetbrains:annotations"),
|
||||||
|
artifact("com.velocitypowered:velocity-api"),
|
||||||
|
],
|
||||||
|
exports = [
|
||||||
|
"//core",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package de.kentoj.kencommandapi;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
|
import de.kentoj.kencommandapi.api.CommandHandler;
|
||||||
|
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public class CommandAPI<T extends CommandSource> {
|
||||||
|
|
||||||
|
private final ProxyServer server;
|
||||||
|
private final Class<T> senderType;
|
||||||
|
private final CommandHandler<T> commandHandler = new CommandHandler<>(T::sendMessage, T::hasPermission);
|
||||||
|
|
||||||
|
public CommandAPI(ProxyServer server, Class<T> senderType) {
|
||||||
|
this.server = server;
|
||||||
|
this.senderType = senderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(RootLiteral<T> rootNode) {
|
||||||
|
var cm = server.getCommandManager();
|
||||||
|
var meta = cm.metaBuilder(rootNode.names()[0])
|
||||||
|
.aliases(Arrays.copyOfRange(rootNode.names(), 1, rootNode.names().length))
|
||||||
|
.build();
|
||||||
|
cm.register(meta, new VelocityCommand<>(commandHandler, rootNode, senderType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
package de.kentoj.kencommandapi;
|
||||||
|
|
||||||
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
|
import com.velocitypowered.api.command.RawCommand;
|
||||||
|
import de.kentoj.kencommandapi.api.CommandHandler;
|
||||||
|
import de.kentoj.kencommandapi.api.literal.RootLiteral;
|
||||||
|
import de.kentoj.kencommandapi.api.platform.MessageStyle;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class VelocityCommand<T extends CommandSource> implements RawCommand {
|
||||||
|
|
||||||
|
private final CommandHandler<T> commandHandler;
|
||||||
|
private final RootLiteral<T> rootNode;
|
||||||
|
private final Class<T> senderType;
|
||||||
|
|
||||||
|
public VelocityCommand(CommandHandler<T> commandHandler, RootLiteral<T> rootNode, Class<T> senderType) {
|
||||||
|
this.commandHandler = commandHandler;
|
||||||
|
this.rootNode = rootNode;
|
||||||
|
this.senderType = senderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Invocation invocation) {
|
||||||
|
if (!senderType.isInstance(invocation.source())) {
|
||||||
|
invocation.source().sendMessage(MessageStyle.PLAIN.err("You can't use that command"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
T sender = senderType.cast(invocation.source());
|
||||||
|
|
||||||
|
var args = Arrays.stream(invocation.arguments().split(" "))
|
||||||
|
.filter(a -> !a.isEmpty());
|
||||||
|
commandHandler.invoke(rootNode, sender, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasPermission(Invocation ctx) {
|
||||||
|
if (rootNode.permission() == null) return true;
|
||||||
|
return ctx.source().hasPermission(rootNode.permission());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> suggest(Invocation invocation) {
|
||||||
|
if (!senderType.isInstance(invocation.source()))
|
||||||
|
return Collections.emptyList();
|
||||||
|
T sender = senderType.cast(invocation.source());
|
||||||
|
|
||||||
|
var args = invocation.arguments().split(" ");
|
||||||
|
return commandHandler.getSuggestions(rootNode, sender, args, invocation.arguments().endsWith(" "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,16 +4,17 @@ import com.velocitypowered.api.command.CommandSource;
|
||||||
import com.velocitypowered.api.proxy.Player;
|
import com.velocitypowered.api.proxy.Player;
|
||||||
import com.velocitypowered.api.proxy.ProxyServer;
|
import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
public final class PlayerSuggestionProvider implements SuggestionProvider<CommandSource> {
|
||||||
public class PlayerSuggestionProvider implements SuggestionProvider<CommandSource> {
|
|
||||||
|
|
||||||
private final ProxyServer proxyServer;
|
private final ProxyServer proxyServer;
|
||||||
|
|
||||||
|
public PlayerSuggestionProvider(ProxyServer proxyServer) {
|
||||||
|
this.proxyServer = proxyServer;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandSource __) {
|
public List<String> suggest(CommandSource __) {
|
||||||
return proxyServer.getAllPlayers().stream()
|
return proxyServer.getAllPlayers().stream()
|
||||||
|
|
@ -6,22 +6,24 @@ import com.velocitypowered.api.proxy.ProxyServer;
|
||||||
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
import de.kentoj.kencommandapi.api.argument.ArgumentType;
|
||||||
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
import de.kentoj.kencommandapi.api.suggestion.SuggestionProvider;
|
||||||
import de.kentoj.kencommandapi.suggestionprovider.PlayerSuggestionProvider;
|
import de.kentoj.kencommandapi.suggestionprovider.PlayerSuggestionProvider;
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class PlayerArgumentType implements ArgumentType<CommandSource, Player> {
|
public class PlayerArgumentType implements ArgumentType<CommandSource, Player> {
|
||||||
|
|
||||||
private final ProxyServer server;
|
private final ProxyServer server;
|
||||||
|
|
||||||
|
public PlayerArgumentType(ProxyServer server) {
|
||||||
|
this.server = server;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Player parseInput(String string) {
|
public Player parseInputUnchecked(String input) {
|
||||||
var player = server.getPlayer(string).orElse(null);
|
var player = server.getPlayer(input).orElse(null);
|
||||||
if (player == null) throw new IllegalArgumentException("Player not online");
|
if (player == null) throw new IllegalArgumentException("Player not online");
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SuggestionProvider<CommandSource> defaultSuggestionProvider() {
|
public SuggestionProvider<CommandSource> getDefaultSuggestionProvider() {
|
||||||
return new PlayerSuggestionProvider(server);
|
return new PlayerSuggestionProvider(server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue