diff --git a/.checkstyle/checkstyle.xml b/.checkstyle/checkstyle.xml index 0561029..a30c703 100644 --- a/.checkstyle/checkstyle.xml +++ b/.checkstyle/checkstyle.xml @@ -1,197 +1,266 @@ - - + + + + + - + + + - Checkstyle configuration that checks the sun coding conventions from: + + + + - - the Java Language Specification at - https://docs.oracle.com/javase/specs/jls/se11/html/index.html + + - - the Sun Code Conventions at https://www.oracle.com/java/technologies/javase/codeconventions-contents.html + + - - the Javadoc guidelines at - https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html + + - - the JDK Api documentation https://docs.oracle.com/en/java/javase/11/ + + + - - some best practices + + + + + - Checkstyle is very configurable. Be sure to read the documentation at - https://checkstyle.org (or in your downloaded distribution). + + - Most Checks are configurable, be sure to consult the documentation. + + - To completely disable a check, just comment it out or delete it from the file. - To suppress certain violations please review suppression filters. + + + + + + - Finally, it is worth reading the documentation. + + ---> + + + + + + - + + - + - - --> - + + + + + + + - + + + + - - - - - + + - - - - - + + - - - + + - - - + + + + - - - + + + + + + - - - - - - - + + + + + + + + + - - - - - - - - - - - - + + - - - - - - + + - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - + + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.editorconfig b/.editorconfig index f72383c..7758b31 100644 --- a/.editorconfig +++ b/.editorconfig @@ -6,7 +6,7 @@ indent_style = space insert_final_newline = true max_line_length = 130 tab_width = 4 -ij_continuation_indent_size = 8 +ij_continuation_indent_size = 4 ij_formatter_off_tag = @formatter:off ij_formatter_on_tag = @formatter:on ij_formatter_tags_enabled = false @@ -137,7 +137,7 @@ ij_java_for_statement_wrap = off ij_java_generate_final_locals = true ij_java_generate_final_parameters = true ij_java_if_brace_force = always -ij_java_imports_layout = *, |, javax.**, java.**, |, $* +ij_java_imports_layout = *, |, $* ij_java_indent_case_from_switch = true ij_java_insert_inner_class_imports = false ij_java_insert_override_annotation = true diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..6377f28 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,16 @@ +name: "build" + +on: + push: + branches: [ "**" ] + tags-ignore: [ "**" ] + pull_request: + release: + types: [ released ] + +jobs: + call-build: + uses: "broccolai/actions/.github/workflows/shared-ci.yml@master" + secrets: inherit + with: + artifacts-path: 'paper/build/libs/tags-paper.jar' diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml deleted file mode 100644 index ca57610..0000000 --- a/.github/workflows/gradle.yml +++ /dev/null @@ -1,30 +0,0 @@ -on : [ push, pull_request ] - -jobs : - build : - - runs-on : ubuntu-latest - - steps : - - uses : actions/checkout@v2 - - name : Set up JDK - uses : actions/setup-java@v2 - with : - distribution: 'temurin' - java-version: '17' - - name : Cache Gradle data - uses : actions/cache@v2 - with : - path : | - ~/.gradle/caches - ~/.gradle/wrapper - key : ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }} - restore-keys : ${{ runner.os }}-gradle - - name : Grant execute permission for gradlew - run : chmod +x gradlew - - name : Build with Gradle - run : ./gradlew build - - uses : actions/upload-artifact@v2 - with : - name : tags-bukkit.jar - path : bukkit/build/libs/tags-bukkit.jar diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index 55023df..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,44 +0,0 @@ -name: Publish package to the broccolai repo -on: - release: - types: [created] -jobs: - publish: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Set up Java - uses: actions/setup-java@v1 - with: - java-version: 1.8 - - name: Grant execute permission for gradlew - run: chmod +x gradlew - - name: Publish package - run: ./gradlew build publish -x signMavenPublication - env: - ORG_GRADLE_PROJECT_broccolaiUsername: ${{ secrets.BROCCOLAI_USERNAME }} - ORG_GRADLE_PROJECT_broccolaiPassword: ${{ secrets.BROCCOLAI_PASSWORD }} - - uses: octokit/request-action@v2.x - id: get_latest_release - with: - route: GET /repos/:repository/releases/latest - repository: ${{ github.repository }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: get upload url - id: get_upload_url - run: | - url=$(echo "$response" | jq -r '.upload_url') - echo "::set-output name=url::$url" - env: - response: ${{ steps.get_latest_release.outputs.data }} - - name: Upload Release Asset - id: upload-release-asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.get_upload_url.outputs.url }} - asset_path: ./bukkit/build/libs/tags-bukkit.jar - asset_name: tags-bukkit.jar - asset_content_type: application/java-archive diff --git a/.gitignore b/.gitignore index 09a7a61..c3ce99b 100644 --- a/.gitignore +++ b/.gitignore @@ -155,5 +155,4 @@ gradle-app.setting # Custom Ignores build.sh .env - -bukkit/run +paper/run diff --git a/api/build.gradle.kts b/api/build.gradle.kts index f9f0c7c..1ca85aa 100644 --- a/api/build.gradle.kts +++ b/api/build.gradle.kts @@ -2,4 +2,5 @@ dependencies { api(libs.guice.core) api(libs.minimessage) api(libs.event.api) + api(libs.configurate) } diff --git a/api/src/main/java/broccolai/tags/api/TagsApi.java b/api/src/main/java/broccolai/tags/api/TagsApi.java index 5bef8ae..aa71c72 100644 --- a/api/src/main/java/broccolai/tags/api/TagsApi.java +++ b/api/src/main/java/broccolai/tags/api/TagsApi.java @@ -16,7 +16,7 @@ public static void register(final @NonNull Injector injector) { INJECTOR = injector; } - public static T getService(final @NonNull Class clazz) { + public static T service(final @NonNull Class clazz) { return INJECTOR.getInstance(clazz); } diff --git a/api/src/main/java/broccolai/tags/api/events/event/TagChangeEvent.java b/api/src/main/java/broccolai/tags/api/events/event/TagChangeEvent.java index 29fd169..029c8e5 100644 --- a/api/src/main/java/broccolai/tags/api/events/event/TagChangeEvent.java +++ b/api/src/main/java/broccolai/tags/api/events/event/TagChangeEvent.java @@ -1,7 +1,7 @@ package broccolai.tags.api.events.event; import broccolai.tags.api.events.Event; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; import net.kyori.event.Cancellable; import org.checkerframework.checker.nullness.qual.NonNull; @@ -10,9 +10,9 @@ public final class TagChangeEvent extends Cancellable.Impl implements Event { private final @NonNull TagsUser user; - private final @NonNull Tag tag; + private final @NonNull ConstructedTag tag; - public TagChangeEvent(final @NonNull TagsUser user, final @NonNull Tag tag) { + public TagChangeEvent(final @NonNull TagsUser user, final @NonNull ConstructedTag tag) { this.user = user; this.tag = tag; } @@ -23,7 +23,7 @@ public TagChangeEvent(final @NonNull TagsUser user, final @NonNull Tag tag) { } @Pure - public @NonNull Tag tag() { + public @NonNull ConstructedTag tag() { return this.tag; } diff --git a/api/src/main/java/broccolai/tags/api/model/tag/ConstructedTag.java b/api/src/main/java/broccolai/tags/api/model/tag/ConstructedTag.java new file mode 100644 index 0000000..ae7abb1 --- /dev/null +++ b/api/src/main/java/broccolai/tags/api/model/tag/ConstructedTag.java @@ -0,0 +1,21 @@ +package broccolai.tags.api.model.tag; + +import broccolai.tags.api.model.Permissible; +import net.kyori.adventure.text.Component; +import org.checkerframework.checker.nullness.qual.NonNull; + +public record ConstructedTag( + int id, + @NonNull String name, + boolean secret, + @NonNull Component component, + @NonNull String reason, + @NonNull TagDisplayInformation displayInformation +) implements Permissible { + + @Override + public @NonNull String permission() { + return "tags.tag." + this.id(); + } + +} diff --git a/api/src/main/java/broccolai/tags/api/model/tag/Tag.java b/api/src/main/java/broccolai/tags/api/model/tag/Tag.java deleted file mode 100644 index 69c0751..0000000 --- a/api/src/main/java/broccolai/tags/api/model/tag/Tag.java +++ /dev/null @@ -1,54 +0,0 @@ -package broccolai.tags.api.model.tag; - -import broccolai.tags.api.model.Permissible; -import net.kyori.adventure.text.Component; -import org.checkerframework.checker.nullness.qual.NonNull; - -public final class Tag implements Permissible { - - private final int id; - private final String name; - private final boolean secret; - private final @NonNull Component component; - private final @NonNull String reason; - - public Tag( - final int id, - final @NonNull String name, - final boolean secret, - final @NonNull Component component, - final @NonNull String reason - ) { - this.id = id; - this.name = name; - this.secret = secret; - this.component = component; - this.reason = reason; - } - - public int id() { - return this.id; - } - - public @NonNull String name() { - return this.name; - } - - public boolean secret() { - return this.secret; - } - - public @NonNull Component component() { - return this.component; - } - - public @NonNull String reason() { - return this.reason; - } - - @Override - public @NonNull String permission() { - return "tags.tag." + this.id(); - } - -} diff --git a/api/src/main/java/broccolai/tags/api/model/tag/TagDisplayInformation.java b/api/src/main/java/broccolai/tags/api/model/tag/TagDisplayInformation.java new file mode 100644 index 0000000..f0cf028 --- /dev/null +++ b/api/src/main/java/broccolai/tags/api/model/tag/TagDisplayInformation.java @@ -0,0 +1,14 @@ +package broccolai.tags.api.model.tag; + +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; + +//todo(josh): split tag into an interface and hide this in the implementation +// and remove configurate as a dependency in for api project +@ConfigSerializable +public record TagDisplayInformation( + @NonNull String material, + @Nullable Integer customModelData +) { +} diff --git a/api/src/main/java/broccolai/tags/api/model/user/TagsUser.java b/api/src/main/java/broccolai/tags/api/model/user/TagsUser.java index c9e3773..2c47f0b 100644 --- a/api/src/main/java/broccolai/tags/api/model/user/TagsUser.java +++ b/api/src/main/java/broccolai/tags/api/model/user/TagsUser.java @@ -1,12 +1,11 @@ package broccolai.tags.api.model.user; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.impl.ConsoleTagsUser; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - import java.util.Optional; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; public interface TagsUser { @@ -14,7 +13,7 @@ public interface TagsUser { @NonNull UUID uuid(); - void setCurrent(@Nullable Tag tag); + void current(@Nullable ConstructedTag tag); @NonNull Optional current(); diff --git a/api/src/main/java/broccolai/tags/api/model/user/impl/ConsoleTagsUser.java b/api/src/main/java/broccolai/tags/api/model/user/impl/ConsoleTagsUser.java index 9df1b06..0cf49b7 100644 --- a/api/src/main/java/broccolai/tags/api/model/user/impl/ConsoleTagsUser.java +++ b/api/src/main/java/broccolai/tags/api/model/user/impl/ConsoleTagsUser.java @@ -1,12 +1,11 @@ package broccolai.tags.api.model.user.impl; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - import java.util.Optional; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; public final class ConsoleTagsUser implements TagsUser { @@ -20,7 +19,7 @@ public final class ConsoleTagsUser implements TagsUser { } @Override - public void setCurrent(final @Nullable Tag tag) { + public void current(final @Nullable ConstructedTag tag) { this.currentTag = tag != null ? tag.id() : null; } diff --git a/api/src/main/java/broccolai/tags/api/model/user/impl/PlayerTagsUser.java b/api/src/main/java/broccolai/tags/api/model/user/impl/PlayerTagsUser.java index df03a6b..ffdc30d 100644 --- a/api/src/main/java/broccolai/tags/api/model/user/impl/PlayerTagsUser.java +++ b/api/src/main/java/broccolai/tags/api/model/user/impl/PlayerTagsUser.java @@ -1,12 +1,11 @@ package broccolai.tags.api.model.user.impl; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; - import java.util.Optional; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; public final class PlayerTagsUser implements TagsUser { @@ -27,7 +26,7 @@ public PlayerTagsUser( } @Override - public void setCurrent(final @Nullable Tag tag) { + public void current(final @Nullable ConstructedTag tag) { this.current = tag != null ? tag.id() : null; } diff --git a/api/src/main/java/broccolai/tags/api/service/ActionService.java b/api/src/main/java/broccolai/tags/api/service/ActionService.java new file mode 100644 index 0000000..09f0f8d --- /dev/null +++ b/api/src/main/java/broccolai/tags/api/service/ActionService.java @@ -0,0 +1,13 @@ +package broccolai.tags.api.service; + +import broccolai.tags.api.model.tag.ConstructedTag; +import broccolai.tags.api.model.user.TagsUser; +import org.checkerframework.checker.nullness.qual.NonNull; + +public interface ActionService { + + boolean select(@NonNull TagsUser user, @NonNull ConstructedTag tag); + + void remove(@NonNull TagsUser user); + +} diff --git a/api/src/main/java/broccolai/tags/api/service/DataService.java b/api/src/main/java/broccolai/tags/api/service/DataService.java index 2c5acb0..e6e8086 100644 --- a/api/src/main/java/broccolai/tags/api/service/DataService.java +++ b/api/src/main/java/broccolai/tags/api/service/DataService.java @@ -2,10 +2,9 @@ import broccolai.tags.api.model.Service; import broccolai.tags.api.model.user.TagsUser; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.Optional; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; public interface DataService extends Service { diff --git a/api/src/main/java/broccolai/tags/api/service/MessageService.java b/api/src/main/java/broccolai/tags/api/service/MessageService.java index 725acae..3aa592e 100644 --- a/api/src/main/java/broccolai/tags/api/service/MessageService.java +++ b/api/src/main/java/broccolai/tags/api/service/MessageService.java @@ -1,31 +1,30 @@ package broccolai.tags.api.service; import broccolai.tags.api.model.Service; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; +import java.util.Collection; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.Collection; - public interface MessageService extends Service { TagResolver prefix(); - Component commandSelect(@NonNull Tag tag); + Component commandSelect(@NonNull ConstructedTag tag); - Component commandList(@NonNull Collection tags); + Component commandList(@NonNull Collection tags); - Component commandInfo(@NonNull Tag tag); + Component commandInfo(@NonNull ConstructedTag tag); - Component commandAdminGive(@NonNull Tag tag, @NonNull TagsUser target); + Component commandAdminGive(@NonNull ConstructedTag tag, @NonNull TagsUser target); - Component commandAdminRemove(@NonNull Tag tag, @NonNull TagsUser target); + Component commandAdminRemove(@NonNull ConstructedTag tag, @NonNull TagsUser target); - Component commandAdminList(@NonNull Collection tags); + Component commandAdminList(@NonNull Collection tags); - Component commandAdminSet(@NonNull Tag tag, @NonNull TagsUser target); + Component commandAdminSet(@NonNull ConstructedTag tag, @NonNull TagsUser target); Component commandErrorUserNotFound(@NonNull String input); diff --git a/api/src/main/java/broccolai/tags/api/service/TagsService.java b/api/src/main/java/broccolai/tags/api/service/TagsService.java index 3d62bf8..8745150 100644 --- a/api/src/main/java/broccolai/tags/api/service/TagsService.java +++ b/api/src/main/java/broccolai/tags/api/service/TagsService.java @@ -1,34 +1,35 @@ package broccolai.tags.api.service; import broccolai.tags.api.model.Service; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; +import broccolai.tags.api.model.tag.TagDisplayInformation; import broccolai.tags.api.model.user.TagsUser; +import java.util.Collection; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.NotNull; -import java.util.Collection; - public interface TagsService extends Service { - @NotNull Tag defaultTag(); + @NotNull ConstructedTag defaultTag(); void create( int id, @NonNull String name, boolean secret, @NonNull String componentString, - @NonNull String reason + @NonNull String reason, + @Nullable TagDisplayInformation information ); - @Nullable Tag load(int id); + @Nullable ConstructedTag load(int id); - @Nullable Tag load(@NonNull String name); + @Nullable ConstructedTag load(@NonNull String name); - @NonNull Tag load(@NonNull TagsUser user); + @NonNull ConstructedTag load(@NonNull TagsUser user); - @NonNull Collection<@NonNull Tag> allTags(); + @NonNull Collection<@NonNull ConstructedTag> allTags(); - @NonNull Collection<@NonNull Tag> allTags(@NonNull TagsUser user); + @NonNull Collection<@NonNull ConstructedTag> allTags(@NonNull TagsUser user); } diff --git a/api/src/main/java/broccolai/tags/api/service/UserService.java b/api/src/main/java/broccolai/tags/api/service/UserService.java index 1005a62..b2fb238 100644 --- a/api/src/main/java/broccolai/tags/api/service/UserService.java +++ b/api/src/main/java/broccolai/tags/api/service/UserService.java @@ -2,12 +2,11 @@ import broccolai.tags.api.model.Service; import broccolai.tags.api.model.user.TagsUser; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.Collection; import java.util.List; import java.util.Map; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; public interface UserService extends Service { diff --git a/build.gradle.kts b/build.gradle.kts index 36dc876..d0dbdfb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,6 @@ import net.kyori.indra.IndraPublishingPlugin import net.kyori.indra.IndraCheckstylePlugin import net.kyori.indra.IndraPlugin -import net.kyori.indra.repository.sonatypeSnapshots plugins { id("net.kyori.indra") @@ -13,7 +12,7 @@ plugins { } group = "broccolai.tags" -version = "1.3.0-SNAPSHOT" +version = "2.0.0" subprojects { apply() @@ -22,7 +21,8 @@ subprojects { repositories { mavenCentral() - sonatypeSnapshots() + sonatype.ossSnapshots() + sonatype.s01Snapshots() maven("https://papermc.io/repo/repository/maven-public/") maven("https://repo.extendedclip.com/content/repositories/placeholderapi/") maven("https://jitpack.io") @@ -42,6 +42,8 @@ subprojects { ci(true) publishing(true) } + + checkstyle("10.12.4") } processResources { diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts deleted file mode 100644 index bed38d2..0000000 --- a/buildSrc/build.gradle.kts +++ /dev/null @@ -1,12 +0,0 @@ -plugins { - `kotlin-dsl` -} - -repositories { - mavenCentral() - gradlePluginPortal() -} - -dependencies { - implementation("gradle.plugin.com.github.jengelman.gradle.plugins", "shadow", "7.0.0") -} diff --git a/buildSrc/src/main/kotlin/Configurations.kt b/buildSrc/src/main/kotlin/Configurations.kt deleted file mode 100644 index cc969e8..0000000 --- a/buildSrc/src/main/kotlin/Configurations.kt +++ /dev/null @@ -1,55 +0,0 @@ -import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar -import org.gradle.api.Project -import org.gradle.kotlin.dsl.apply -import org.gradle.kotlin.dsl.invoke -import org.gradle.kotlin.dsl.withType - -fun Project.setupShadowJar() { - apply() - - tasks { - withType { - - dependencies { - exclude(dependency("com.google.guava:")) - exclude(dependency("com.google.errorprone:")) - exclude(dependency("org.checkerframework:")) - } - - relocate( - rootProject.group, - "com.github.benmanes.caffeine", - "com.typesafe.config", - "com.zaxxer.hikari", - "com.google.inject", - "org.antlr", - "org.jdbi", - "org.aopalliance", - "org.spongepowered.configurate", - "io.leangen.geantyref", - "cloud.commandframework", - "net.kyori.event", - "net.kyori.coffee", - "org.objectweb.asm", - "org.flyway", - "broccolai.corn" - ) - - archiveFileName.set(project.name + ".jar") - minimize() - } - - getByName("build") { - dependsOn(withType()) - } - } -} - -private fun ShadowJar.relocate(group: Any, vararg dependencies: String) { - dependencies.forEach { - val split = it.split('.') - val name = split.last() - relocate(it, "$group.dependencies.$name") - } -} diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts deleted file mode 100644 index 18bbcad..0000000 --- a/bukkit/build.gradle.kts +++ /dev/null @@ -1,22 +0,0 @@ -plugins { - id("xyz.jpenilla.run-paper") version "1.0.6" -} - -setupShadowJar() - -dependencies { - api(project(":tags-core")) - - compileOnly(libs.paper.api) - compileOnly(libs.papi) - compileOnly(libs.vault) - - api(libs.cloud.paper) - api(libs.cloud.extras) -} - -tasks { - runServer { - minecraftVersion("1.19") - } -} diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitConsoleCommandUser.java b/bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitConsoleCommandUser.java deleted file mode 100644 index 517f2a1..0000000 --- a/bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitConsoleCommandUser.java +++ /dev/null @@ -1,24 +0,0 @@ -package broccolai.tags.bukkit.commands.context; - -import broccolai.tags.api.model.user.impl.ConsoleTagsUser; -import net.kyori.adventure.audience.Audience; -import org.bukkit.command.CommandSender; -import org.checkerframework.checker.nullness.qual.NonNull; - -import java.util.UUID; - -public final class BukkitConsoleCommandUser extends BukkitCommandUser { - - public BukkitConsoleCommandUser( - final @NonNull CommandSender source, - final @NonNull Audience audience - ) { - super(source, audience); - } - - @Override - public UUID uuid() { - return ConsoleTagsUser.UUID; - } - -} diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitPlayerCommandUser.java b/bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitPlayerCommandUser.java deleted file mode 100644 index 486ed5c..0000000 --- a/bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitPlayerCommandUser.java +++ /dev/null @@ -1,26 +0,0 @@ -package broccolai.tags.bukkit.commands.context; - -import net.kyori.adventure.audience.Audience; -import org.bukkit.entity.Player; -import org.checkerframework.checker.nullness.qual.NonNull; - -import java.util.UUID; - -public final class BukkitPlayerCommandUser extends BukkitCommandUser { - - private final Player player; - - public BukkitPlayerCommandUser( - final @NonNull Player player, - final @NonNull Audience audience - ) { - super(player, audience); - this.player = player; - } - - @Override - public UUID uuid() { - return this.player.getUniqueId(); - } - -} diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/integrations/VaultIntegration.java b/bukkit/src/main/java/broccolai/tags/bukkit/integrations/VaultIntegration.java deleted file mode 100644 index f5c39ef..0000000 --- a/bukkit/src/main/java/broccolai/tags/bukkit/integrations/VaultIntegration.java +++ /dev/null @@ -1,55 +0,0 @@ -package broccolai.tags.bukkit.integrations; - -import broccolai.tags.api.events.EventListener; -import broccolai.tags.api.events.event.TagChangeEvent; -import broccolai.tags.api.events.event.UserLoginEvent; -import broccolai.tags.api.model.tag.Tag; -import broccolai.tags.api.model.user.TagsUser; -import broccolai.tags.api.service.TagsService; -import com.google.inject.Inject; -import com.google.inject.Singleton; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import net.kyori.event.PostOrders; -import net.kyori.event.method.annotation.PostOrder; -import net.kyori.event.method.annotation.Subscribe; -import net.milkbowl.vault.chat.Chat; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.checkerframework.checker.nullness.qual.NonNull; - -@Singleton -public final class VaultIntegration implements EventListener { - - private static final LegacyComponentSerializer LEGACY = LegacyComponentSerializer.builder() - .hexColors() - .character(LegacyComponentSerializer.SECTION_CHAR) - .build(); - - private final Chat chat; - private final TagsService tagsService; - - @Inject - public VaultIntegration( - final @NonNull Chat chat, - final @NonNull TagsService tagsService - ) { - this.chat = chat; - this.tagsService = tagsService; - } - - @Subscribe - public void onUserLogin(final @NonNull UserLoginEvent event) { - TagsUser user = event.user(); - Tag tag = this.tagsService.load(user); - - this.chat.setPlayerPrefix(null, Bukkit.getPlayer(user.uuid()), LEGACY.serialize(tag.component())); - } - - @Subscribe - @PostOrder(PostOrders.LATE) - public void onTagChange(final @NonNull TagChangeEvent event) { - Player player = Bukkit.getPlayer(event.user().uuid()); - this.chat.setPlayerPrefix(null, player, LEGACY.serialize(event.tag().component())); - } - -} diff --git a/bukkit/src/main/resources/queries/save-user.sql b/bukkit/src/main/resources/queries/save-user.sql deleted file mode 100644 index 1c22a02..0000000 --- a/bukkit/src/main/resources/queries/save-user.sql +++ /dev/null @@ -1,3 +0,0 @@ -INSERT -OR REPLACE INTO tags_users(uuid, currentTag) -VALUES(:uuid, :currentTag); diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 82b35e8..3723d21 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -18,4 +18,4 @@ dependencies { api(libs.cloud.core) api(libs.event.asm) api(libs.coffee) -} +} \ No newline at end of file diff --git a/core/src/main/java/broccolai/tags/core/TagsPlugin.java b/core/src/main/java/broccolai/tags/core/TagsPlugin.java index a03a554..573c7ff 100644 --- a/core/src/main/java/broccolai/tags/core/TagsPlugin.java +++ b/core/src/main/java/broccolai/tags/core/TagsPlugin.java @@ -15,6 +15,7 @@ import com.google.inject.Injector; import com.google.inject.Singleton; import com.zaxxer.hikari.HikariDataSource; +import java.util.Collection; import org.checkerframework.checker.nullness.qual.NonNull; @Singleton @@ -43,7 +44,7 @@ public void start() { public void commands( final @NonNull CommandManager<@NonNull CommandUser> commandManager, - final @NonNull Class[] commands + final @NonNull Collection> commands ) { for (final @NonNull Class commandClass : commands) { this.injector.getInstance(commandClass).register(commandManager); diff --git a/core/src/main/java/broccolai/tags/core/commands/TagsAdminCommand.java b/core/src/main/java/broccolai/tags/core/commands/TagsAdminCommand.java index 5caad74..f1ea167 100644 --- a/core/src/main/java/broccolai/tags/core/commands/TagsAdminCommand.java +++ b/core/src/main/java/broccolai/tags/core/commands/TagsAdminCommand.java @@ -1,7 +1,7 @@ package broccolai.tags.core.commands; import broccolai.tags.api.events.event.TagChangeEvent; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.api.service.EventService; import broccolai.tags.api.service.MessageService; @@ -14,9 +14,8 @@ import cloud.commandframework.CommandManager; import cloud.commandframework.context.CommandContext; import com.google.inject.Inject; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.Collection; +import org.checkerframework.checker.nullness.qual.NonNull; public final class TagsAdminCommand implements PluginCommand { @@ -83,7 +82,7 @@ public void register( private void handleGive(final @NonNull CommandContext context) { CommandUser sender = context.getSender(); TagsUser target = context.get("target"); - Tag tag = context.get("tag"); + ConstructedTag tag = context.get("tag"); this.permissionService.grant(target, tag); sender.sendMessage(this.messageService.commandAdminGive(tag, target)); @@ -92,7 +91,7 @@ private void handleGive(final @NonNull CommandContext context) { private void handleRemove(final @NonNull CommandContext context) { CommandUser sender = context.getSender(); TagsUser target = context.get("target"); - Tag tag = context.get("tag"); + ConstructedTag tag = context.get("tag"); this.permissionService.remove(target, tag); sender.sendMessage(this.messageService.commandAdminRemove(tag, target)); @@ -100,7 +99,7 @@ private void handleRemove(final @NonNull CommandContext context) { private void handleList(final @NonNull CommandContext context) { CommandUser sender = context.getSender(); - Collection tags = context.getOptional("target") + Collection tags = context.getOptional("target") .map(this.tagsService::allTags) .orElse(this.tagsService.allTags()); @@ -110,7 +109,7 @@ private void handleList(final @NonNull CommandContext context) { private void handleSet(final @NonNull CommandContext context) { CommandUser sender = context.getSender(); TagsUser target = context.get("target"); - Tag tag = context.get("tag"); + ConstructedTag tag = context.get("tag"); TagChangeEvent event = new TagChangeEvent(target, tag); this.eventService.post(event); diff --git a/core/src/main/java/broccolai/tags/core/commands/TagsCommand.java b/core/src/main/java/broccolai/tags/core/commands/TagsCommand.java index 8b0ea55..09bb96d 100644 --- a/core/src/main/java/broccolai/tags/core/commands/TagsCommand.java +++ b/core/src/main/java/broccolai/tags/core/commands/TagsCommand.java @@ -1,9 +1,8 @@ package broccolai.tags.core.commands; -import broccolai.tags.api.events.event.TagChangeEvent; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; -import broccolai.tags.api.service.EventService; +import broccolai.tags.api.service.ActionService; import broccolai.tags.api.service.MessageService; import broccolai.tags.api.service.TagsService; import broccolai.tags.api.service.UserService; @@ -14,9 +13,8 @@ import cloud.commandframework.CommandManager; import cloud.commandframework.context.CommandContext; import com.google.inject.Inject; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.Collection; +import org.checkerframework.checker.nullness.qual.NonNull; public final class TagsCommand implements PluginCommand { @@ -24,7 +22,7 @@ public final class TagsCommand implements PluginCommand { private final @NonNull MessageService messageService; private final @NonNull UserService userService; private final @NonNull TagsService tagsService; - private final @NonNull EventService eventService; + private final @NonNull ActionService actionService; @Inject public TagsCommand( @@ -32,13 +30,13 @@ public TagsCommand( final @NonNull MessageService messageService, final @NonNull UserService userService, final @NonNull TagsService tagsService, - final @NonNull EventService eventService + final @NonNull ActionService actionService ) { this.argumentFactory = argumentFactory; this.messageService = messageService; this.userService = userService; this.tagsService = tagsService; - this.eventService = eventService; + this.actionService = actionService; } @Override @@ -71,12 +69,11 @@ public void register( private void handleSelect(final @NonNull CommandContext context) { CommandUser sender = context.getSender(); TagsUser user = this.userService.get(sender.uuid()); - Tag tag = context.get("tag"); + ConstructedTag tag = context.get("tag"); - TagChangeEvent event = new TagChangeEvent(user, tag); - this.eventService.post(event); + boolean success = this.actionService.select(user, tag); - if (!event.cancelled()) { + if (success) { sender.sendMessage(this.messageService.commandSelect(tag)); } } @@ -84,14 +81,14 @@ private void handleSelect(final @NonNull CommandContext context) { private void handleList(final @NonNull CommandContext context) { CommandUser sender = context.getSender(); TagsUser user = this.userService.get(sender.uuid()); - Collection tags = this.tagsService.allTags(user); + Collection tags = this.tagsService.allTags(user); sender.sendMessage(this.messageService.commandList(tags)); } private void handlePreview(final @NonNull CommandContext context) { CommandUser sender = context.getSender(); - Tag tag = context.get("tag"); + ConstructedTag tag = context.get("tag"); sender.sendMessage(this.messageService.commandInfo(tag)); } diff --git a/core/src/main/java/broccolai/tags/core/commands/arguments/TagArgument.java b/core/src/main/java/broccolai/tags/core/commands/arguments/TagArgument.java index fb6e6a6..dd71087 100644 --- a/core/src/main/java/broccolai/tags/core/commands/arguments/TagArgument.java +++ b/core/src/main/java/broccolai/tags/core/commands/arguments/TagArgument.java @@ -1,7 +1,7 @@ package broccolai.tags.core.commands.arguments; import broccolai.corn.core.Lists; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.api.service.PermissionService; import broccolai.tags.api.service.TagsService; @@ -15,14 +15,13 @@ import cloud.commandframework.exceptions.parsing.NoInputProvidedException; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Queue; +import org.checkerframework.checker.nullness.qual.NonNull; -public class TagArgument extends CommandArgument<@NonNull CommandUser, @NonNull Tag> { +public class TagArgument extends CommandArgument<@NonNull CommandUser, @NonNull ConstructedTag> { @AssistedInject public TagArgument( @@ -32,10 +31,10 @@ public TagArgument( final @Assisted("name") @NonNull String name, final @Assisted("mode") @NonNull TagParserMode mode ) { - super(true, name, new TagParser(permissionService, tagsService, userService, mode), Tag.class); + super(true, name, new TagParser(permissionService, tagsService, userService, mode), ConstructedTag.class); } - public static final class TagParser implements ArgumentParser<@NonNull CommandUser, Tag> { + public static final class TagParser implements ArgumentParser<@NonNull CommandUser, ConstructedTag> { private final @NonNull PermissionService permissionService; private final @NonNull TagsService tagsService; @@ -55,7 +54,7 @@ public TagParser( } @Override - public @NonNull ArgumentParseResult parse( + public @NonNull ArgumentParseResult parse( final @NonNull CommandContext<@NonNull CommandUser> commandContext, final @NonNull Queue inputQueue ) { @@ -65,7 +64,7 @@ public TagParser( return ArgumentParseResult.failure(new NoInputProvidedException(TagParser.class, commandContext)); } - Tag tag = this.tagsService.load(input); + ConstructedTag tag = this.tagsService.load(input); if (tag == null) { return ArgumentParseResult.failure(new TagArgumentException(input)); @@ -88,7 +87,6 @@ public TagParser( user = commandContext.get("target"); } - if (!this.permissionService.has(user, tag)) { return ArgumentParseResult.failure(new TagArgumentException(input)); } @@ -104,7 +102,7 @@ public TagParser( final @NonNull String input ) { if (this.mode == TagParserMode.ANY || this.mode == TagParserMode.NON_SECRET) { - Collection tags = new ArrayList<>(this.tagsService.allTags()); + Collection tags = new ArrayList<>(this.tagsService.allTags()); if (this.mode == TagParserMode.NON_SECRET) { CommandUser self = commandContext.getSender(); @@ -113,7 +111,7 @@ public TagParser( tags.removeIf(tag -> !(this.permissionService.has(user, tag) || tag.secret())); } - return Lists.map(this.tagsService.allTags(), Tag::name); + return Lists.map(this.tagsService.allTags(), ConstructedTag::name); } final TagsUser target; @@ -125,7 +123,7 @@ public TagParser( target = commandContext.get("target"); } - return Lists.map(this.tagsService.allTags(target), Tag::name); + return Lists.map(this.tagsService.allTags(target), ConstructedTag::name); } } diff --git a/core/src/main/java/broccolai/tags/core/commands/arguments/UserArgument.java b/core/src/main/java/broccolai/tags/core/commands/arguments/UserArgument.java index ebe6c6d..121cd6a 100644 --- a/core/src/main/java/broccolai/tags/core/commands/arguments/UserArgument.java +++ b/core/src/main/java/broccolai/tags/core/commands/arguments/UserArgument.java @@ -10,10 +10,9 @@ import cloud.commandframework.exceptions.parsing.NoInputProvidedException; import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.AssistedInject; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.List; import java.util.Queue; +import org.checkerframework.checker.nullness.qual.NonNull; public class UserArgument extends CommandArgument<@NonNull CommandUser, @NonNull TagsUser> { @@ -35,7 +34,6 @@ public UserParser(final @NonNull UserService userService) { } @Override - @SuppressWarnings("deprecation") public @NonNull ArgumentParseResult parse( final @NonNull CommandContext<@NonNull CommandUser> commandContext, final @NonNull Queue inputQueue diff --git a/core/src/main/java/broccolai/tags/core/commands/arguments/modes/TagParserMode.java b/core/src/main/java/broccolai/tags/core/commands/arguments/modes/TagParserMode.java index 7207010..772e3f3 100644 --- a/core/src/main/java/broccolai/tags/core/commands/arguments/modes/TagParserMode.java +++ b/core/src/main/java/broccolai/tags/core/commands/arguments/modes/TagParserMode.java @@ -4,5 +4,6 @@ public enum TagParserMode { SELF, TARGET, NON_SECRET, - ANY, + ANY + } diff --git a/core/src/main/java/broccolai/tags/core/commands/context/CommandUser.java b/core/src/main/java/broccolai/tags/core/commands/context/CommandUser.java index 2f715bc..28d37de 100644 --- a/core/src/main/java/broccolai/tags/core/commands/context/CommandUser.java +++ b/core/src/main/java/broccolai/tags/core/commands/context/CommandUser.java @@ -1,10 +1,9 @@ package broccolai.tags.core.commands.context; +import java.util.UUID; import net.kyori.adventure.audience.ForwardingAudience; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.UUID; - public interface CommandUser extends ForwardingAudience.Single { UUID uuid(); diff --git a/core/src/main/java/broccolai/tags/core/config/LocaleConfiguration.java b/core/src/main/java/broccolai/tags/core/config/LocaleConfiguration.java index af7df59..676c722 100644 --- a/core/src/main/java/broccolai/tags/core/config/LocaleConfiguration.java +++ b/core/src/main/java/broccolai/tags/core/config/LocaleConfiguration.java @@ -11,7 +11,6 @@ import org.spongepowered.configurate.objectmapping.meta.Setting; import org.spongepowered.configurate.serialize.SerializationException; -@SuppressWarnings("FieldMayBeFinal") @ConfigSerializable public final class LocaleConfiguration implements Configuration { @@ -23,6 +22,10 @@ public final class LocaleConfiguration implements Configuration { @Comment("Locales for command feedback related messages") public FeedbackLocaleConfiguration commands = new FeedbackLocaleConfiguration(); + @Setting + @Comment("Locales for menu related translations") + public MenuLocaleConfiguration menu = new MenuLocaleConfiguration(); + @ConfigSerializable public static final class FeedbackLocaleConfiguration { @@ -83,6 +86,20 @@ public static final class ErrorLocaleConfiguration { } + @ConfigSerializable + public static final class MenuLocaleConfiguration { + + @Setting + public LocaleEntry title = new BasicLocaleEntry("Tags Menu"); + + @Setting + public LocaleEntry equip = new BasicLocaleEntry("Left click to equip"); + + @Setting + public LocaleEntry currentlyEquipped = new BasicLocaleEntry("Currently Equipped"); + + } + //region Configurate private static final @NonNull ObjectMapper MAPPER; diff --git a/core/src/main/java/broccolai/tags/core/config/MainConfiguration.java b/core/src/main/java/broccolai/tags/core/config/MainConfiguration.java index 8ff3a88..8e2e9a7 100644 --- a/core/src/main/java/broccolai/tags/core/config/MainConfiguration.java +++ b/core/src/main/java/broccolai/tags/core/config/MainConfiguration.java @@ -1,6 +1,8 @@ package broccolai.tags.core.config; +import broccolai.tags.api.model.tag.TagDisplayInformation; import com.google.inject.Singleton; +import java.util.List; import org.checkerframework.checker.nullness.qual.NonNull; import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.ScopedConfigurationNode; @@ -10,9 +12,6 @@ import org.spongepowered.configurate.objectmapping.meta.Setting; import org.spongepowered.configurate.serialize.SerializationException; -import java.util.ArrayList; -import java.util.List; - @ConfigSerializable @Singleton @NonNull @@ -27,14 +26,35 @@ public final class MainConfiguration implements Configuration { @Setting @Comment( - "Potential tags for players to obtain. \n" - + "Increment id for each new tag, if you remove a tag, treat the config as if it's id is still there. \n" - + "Permissions will use this id as it's reference. \n" - + "The name attribute should be a simple one word phrase for selecting tags through commands." + """ + Potential tags for players to obtain. + Increment id for each new tag, if you remove a tag, treat the config as if it's id is still there. + Permissions will use this id as it's reference. + The name attribute should be a simple one word phrase for selecting tags through commands. + + Tag configuration is described as followed: + id -> the unique numerical id for tags + name -> the unique name for a tag to be used in a command + component -> the component to be rendered in chat / menu first line + reason -> how a player could obtain the tag + display-information: + material -> the material id to use for the menu representation + custom-model-data -> the custom model id to use on items, optionally + """ ) - public List tags = new ArrayList() {{ - this.add(new TagConfiguration(1, "example", false, "example", "Acquired by playing for an hour")); - }}; + public List tags = List.of( + new TagConfiguration( + 1, + "example", + false, + "example", + "Acquired by playing for an hour", + new TagDisplayInformation( + "stick", + 5 + ) + ) + ); //region Configurate private static final @NonNull ObjectMapper MAPPER; diff --git a/core/src/main/java/broccolai/tags/core/config/StorageConfiguration.java b/core/src/main/java/broccolai/tags/core/config/StorageConfiguration.java index ec80c36..19680b0 100644 --- a/core/src/main/java/broccolai/tags/core/config/StorageConfiguration.java +++ b/core/src/main/java/broccolai/tags/core/config/StorageConfiguration.java @@ -9,7 +9,7 @@ public class StorageConfiguration { @Setting - @Comment("Storage method. Current options are: LUCKPERMS, SQLITE") - public StorageMethod storageMethod = StorageMethod.LUCKPERMS; + @Comment("Storage method. Current options are: LUCKPERMS, H2") + public StorageMethod storageMethod = StorageMethod.H2; } diff --git a/core/src/main/java/broccolai/tags/core/config/TagConfiguration.java b/core/src/main/java/broccolai/tags/core/config/TagConfiguration.java index 9b26229..17db0d9 100644 --- a/core/src/main/java/broccolai/tags/core/config/TagConfiguration.java +++ b/core/src/main/java/broccolai/tags/core/config/TagConfiguration.java @@ -1,8 +1,8 @@ package broccolai.tags.core.config; +import broccolai.tags.api.model.tag.TagDisplayInformation; import org.checkerframework.checker.nullness.qual.NonNull; import org.spongepowered.configurate.objectmapping.ConfigSerializable; -import org.spongepowered.configurate.objectmapping.meta.Comment; import org.spongepowered.configurate.objectmapping.meta.Setting; @ConfigSerializable @@ -10,34 +10,43 @@ public final class TagConfiguration { @Setting - @Comment("Tags unique id") public int id; @Setting - @Comment("Readable name for players") public String name; @Setting - @Comment("Whether to hide the tag from public info") - public boolean secret = false; + public boolean secret; @Setting - @Comment("MiniMessage component to display") public String component; @Setting - @Comment("How to obtain this tag, can be null") - public String reason = null; + public String reason; + + @Setting + public TagDisplayInformation displayInformation = new TagDisplayInformation( + "stick", + 0 + ); public TagConfiguration() { } - public TagConfiguration(final int id, final String name, final boolean secret, final String component, final String reason) { + public TagConfiguration( + final int id, + final String name, + final boolean secret, + final String component, + final String reason, + final TagDisplayInformation displayInformation + ) { this.id = id; this.name = name; this.secret = secret; this.component = component; this.reason = reason; + this.displayInformation = displayInformation; } } diff --git a/core/src/main/java/broccolai/tags/core/config/serializers/LocaleEntrySerializer.java b/core/src/main/java/broccolai/tags/core/config/serializers/LocaleEntrySerializer.java index de598f7..1cb306c 100644 --- a/core/src/main/java/broccolai/tags/core/config/serializers/LocaleEntrySerializer.java +++ b/core/src/main/java/broccolai/tags/core/config/serializers/LocaleEntrySerializer.java @@ -2,13 +2,12 @@ import broccolai.tags.core.model.locale.LocaleEntry; import broccolai.tags.core.model.locale.impl.BasicLocaleEntry; +import java.lang.reflect.Type; import org.checkerframework.checker.nullness.qual.Nullable; import org.spongepowered.configurate.ConfigurationNode; import org.spongepowered.configurate.serialize.SerializationException; import org.spongepowered.configurate.serialize.TypeSerializer; -import java.lang.reflect.Type; - public final class LocaleEntrySerializer implements TypeSerializer { public static final LocaleEntrySerializer INSTANCE = new LocaleEntrySerializer(); diff --git a/core/src/main/java/broccolai/tags/core/data/StorageMethod.java b/core/src/main/java/broccolai/tags/core/data/StorageMethod.java index ac4901e..7e8cbe7 100644 --- a/core/src/main/java/broccolai/tags/core/data/StorageMethod.java +++ b/core/src/main/java/broccolai/tags/core/data/StorageMethod.java @@ -1,12 +1,12 @@ package broccolai.tags.core.data; import broccolai.tags.api.service.DataService; +import broccolai.tags.core.service.data.H2DataService; import broccolai.tags.core.service.data.LPDataService; -import broccolai.tags.core.service.data.SQLDataService; import org.checkerframework.checker.nullness.qual.NonNull; public enum StorageMethod { - SQLITE(SQLDataService.class), + H2(H2DataService.class), LUCKPERMS(LPDataService.class); private final Class clazz; diff --git a/core/src/main/java/broccolai/tags/core/data/jdbi/UserMapper.java b/core/src/main/java/broccolai/tags/core/data/jdbi/UserMapper.java index f36ae2b..b676dba 100644 --- a/core/src/main/java/broccolai/tags/core/data/jdbi/UserMapper.java +++ b/core/src/main/java/broccolai/tags/core/data/jdbi/UserMapper.java @@ -2,15 +2,14 @@ import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.api.model.user.impl.PlayerTagsUser; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; import org.checkerframework.checker.nullness.qual.NonNull; import org.jdbi.v3.core.mapper.ColumnMapper; import org.jdbi.v3.core.mapper.RowMapper; import org.jdbi.v3.core.statement.StatementContext; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.UUID; - public final class UserMapper implements RowMapper { @Override diff --git a/core/src/main/java/broccolai/tags/core/inject/ConfigurationModule.java b/core/src/main/java/broccolai/tags/core/inject/ConfigurationModule.java index 6e8a699..141a222 100644 --- a/core/src/main/java/broccolai/tags/core/inject/ConfigurationModule.java +++ b/core/src/main/java/broccolai/tags/core/inject/ConfigurationModule.java @@ -8,6 +8,8 @@ import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Singleton; +import java.io.File; +import java.io.IOException; import net.kyori.coffee.functional.function.exceptional.Function2E; import org.checkerframework.checker.nullness.qual.NonNull; import org.spongepowered.configurate.CommentedConfigurationNode; @@ -19,9 +21,6 @@ import org.spongepowered.configurate.transformation.ConfigurationTransformation; import org.spongepowered.configurate.transformation.TransformAction; -import java.io.File; -import java.io.IOException; - public final class ConfigurationModule extends AbstractModule { @Provides @@ -49,9 +48,7 @@ public final class ConfigurationModule extends AbstractModule { File file = new File(folder, "locale.conf"); try { - return this.configuration(file, (loader, node) -> { - return LocaleConfiguration.loadFrom(node); - }); + return this.configuration(file, (loader, node) -> LocaleConfiguration.loadFrom(node)); } catch (IOException e) { throw new RuntimeException(e); } diff --git a/core/src/main/java/broccolai/tags/core/inject/PluginModule.java b/core/src/main/java/broccolai/tags/core/inject/PluginModule.java index 6b8db23..6216ff7 100644 --- a/core/src/main/java/broccolai/tags/core/inject/PluginModule.java +++ b/core/src/main/java/broccolai/tags/core/inject/PluginModule.java @@ -9,11 +9,13 @@ import com.google.inject.Singleton; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import org.checkerframework.checker.nullness.qual.NonNull; import org.jdbi.v3.core.Jdbi; -import java.io.File; - public final class PluginModule extends AbstractModule { @Provides @@ -21,12 +23,17 @@ public final class PluginModule extends AbstractModule { public @NonNull HikariDataSource provideDataSource( final @NonNull File folder, final @NonNull MainConfiguration configuration - ) { + ) throws IOException { HikariConfig hikariConfig = new HikariConfig(); - if (configuration.storage.storageMethod == StorageMethod.SQLITE) { - File file = new File(folder, "tags.db"); - hikariConfig.setJdbcUrl("jdbc:sqlite:" + file); + //todo(josh): cleanup + if (configuration.storage.storageMethod == StorageMethod.H2) { + Path file = folder.toPath().resolve("storage.db"); + if (!Files.exists(file)) { + Files.createFile(file); + } + hikariConfig.setDriverClassName("org.h2.Driver"); + hikariConfig.setJdbcUrl("jdbc:h2:" + file.toAbsolutePath() + ";MODE=MySQL;DATABASE_TO_LOWER=TRUE"); } hikariConfig.setMaximumPoolSize(10); diff --git a/core/src/main/java/broccolai/tags/core/inject/ServiceModule.java b/core/src/main/java/broccolai/tags/core/inject/ServiceModule.java index fa3165a..9ff15f4 100644 --- a/core/src/main/java/broccolai/tags/core/inject/ServiceModule.java +++ b/core/src/main/java/broccolai/tags/core/inject/ServiceModule.java @@ -1,13 +1,15 @@ package broccolai.tags.core.inject; +import broccolai.tags.api.service.ActionService; import broccolai.tags.api.service.DataService; import broccolai.tags.api.service.EventService; import broccolai.tags.api.service.MessageService; import broccolai.tags.api.service.TagsService; import broccolai.tags.core.config.MainConfiguration; import broccolai.tags.core.data.StorageMethod; +import broccolai.tags.core.service.action.EventActionService; +import broccolai.tags.core.service.data.H2DataService; import broccolai.tags.core.service.data.LPDataService; -import broccolai.tags.core.service.data.SQLDataService; import broccolai.tags.core.service.event.ASMEventService; import broccolai.tags.core.service.message.MiniMessageService; import broccolai.tags.core.service.tags.MappedTagsService; @@ -26,6 +28,7 @@ protected void configure() { this.bind(MessageService.class).to(MiniMessageService.class); this.bind(TagsService.class).to(MappedTagsService.class); this.bind(EventService.class).to(ASMEventService.class); + this.bind(ActionService.class).to(EventActionService.class); } @Provides @@ -53,7 +56,7 @@ public DataService providesDataService( .load() .migrate(); - return injector.getInstance(SQLDataService.class); + return injector.getInstance(H2DataService.class); } } diff --git a/core/src/main/java/broccolai/tags/core/platform/TagsPlatform.java b/core/src/main/java/broccolai/tags/core/platform/TagsPlatform.java index 6ab34a4..cc6ffac 100644 --- a/core/src/main/java/broccolai/tags/core/platform/TagsPlatform.java +++ b/core/src/main/java/broccolai/tags/core/platform/TagsPlatform.java @@ -14,15 +14,15 @@ public interface TagsPlatform { @NonNull Module @NonNull [] STANDARD_MODULES = new Module[]{ - new ConfigurationModule(), - new PluginModule(), - new CloudArgumentFactoryModule(), - new ServiceModule() + new ConfigurationModule(), + new PluginModule(), + new CloudArgumentFactoryModule(), + new ServiceModule() }; @NonNull Class[] COMMANDS = ArrayUtilities.create( - TagsCommand.class, - TagsAdminCommand.class + TagsCommand.class, + TagsAdminCommand.class ); } diff --git a/core/src/main/java/broccolai/tags/core/service/action/EventActionService.java b/core/src/main/java/broccolai/tags/core/service/action/EventActionService.java new file mode 100644 index 0000000..5fd1195 --- /dev/null +++ b/core/src/main/java/broccolai/tags/core/service/action/EventActionService.java @@ -0,0 +1,33 @@ +package broccolai.tags.core.service.action; + +import broccolai.tags.api.events.event.TagChangeEvent; +import broccolai.tags.api.model.tag.ConstructedTag; +import broccolai.tags.api.model.user.TagsUser; +import broccolai.tags.api.service.ActionService; +import broccolai.tags.api.service.EventService; +import com.google.inject.Inject; +import org.checkerframework.checker.nullness.qual.NonNull; + +public final class EventActionService implements ActionService { + + private final EventService eventService; + + @Inject + public EventActionService(final @NonNull EventService eventService) { + this.eventService = eventService; + } + + @Override + public boolean select(final @NonNull TagsUser user, final @NonNull ConstructedTag tag) { + TagChangeEvent event = new TagChangeEvent(user, tag); + this.eventService.post(event); + + return !event.cancelled(); + } + + @Override + public void remove(final @NonNull TagsUser user) { + + } + +} diff --git a/core/src/main/java/broccolai/tags/core/service/data/SQLDataService.java b/core/src/main/java/broccolai/tags/core/service/data/H2DataService.java similarity index 93% rename from core/src/main/java/broccolai/tags/core/service/data/SQLDataService.java rename to core/src/main/java/broccolai/tags/core/service/data/H2DataService.java index 84724ed..70ac5dd 100644 --- a/core/src/main/java/broccolai/tags/core/service/data/SQLDataService.java +++ b/core/src/main/java/broccolai/tags/core/service/data/H2DataService.java @@ -6,21 +6,20 @@ import broccolai.tags.core.util.ResourceReader; import com.google.inject.Inject; import com.google.inject.Singleton; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.jdbi.v3.core.Jdbi; - import java.util.Optional; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.jdbi.v3.core.Jdbi; @Singleton -public final class SQLDataService implements DataService { +public final class H2DataService implements DataService { private static final String PATH = "queries/"; private final @NonNull Jdbi jdbi; @Inject - public SQLDataService(final @NonNull Jdbi jdbi) { + public H2DataService(final @NonNull Jdbi jdbi) { this.jdbi = jdbi; } diff --git a/core/src/main/java/broccolai/tags/core/service/data/LPDataService.java b/core/src/main/java/broccolai/tags/core/service/data/LPDataService.java index 2f90ddf..4c15e37 100644 --- a/core/src/main/java/broccolai/tags/core/service/data/LPDataService.java +++ b/core/src/main/java/broccolai/tags/core/service/data/LPDataService.java @@ -3,22 +3,20 @@ import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.api.model.user.impl.PlayerTagsUser; import broccolai.tags.api.service.DataService; +import java.util.Optional; +import java.util.UUID; import net.luckperms.api.LuckPerms; import net.luckperms.api.LuckPermsProvider; import net.luckperms.api.model.user.User; import net.luckperms.api.node.types.MetaNode; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.Optional; -import java.util.UUID; - public final class LPDataService implements DataService { private static final String CURRENT_TAG_NODE = "current-tag"; private final LuckPerms luckPerms = LuckPermsProvider.get(); - @Override public @NonNull Optional<@NonNull TagsUser> loadUser( final @NonNull UUID uniqueId @@ -47,7 +45,7 @@ public final class LPDataService implements DataService { public void saveUser(final @NonNull TagsUser user) { Optional potentialId = user.current(); - if (!potentialId.isPresent()) { + if (potentialId.isEmpty()) { return; } diff --git a/core/src/main/java/broccolai/tags/core/service/message/MiniMessageService.java b/core/src/main/java/broccolai/tags/core/service/message/MiniMessageService.java index 20ed729..ce1aed5 100644 --- a/core/src/main/java/broccolai/tags/core/service/message/MiniMessageService.java +++ b/core/src/main/java/broccolai/tags/core/service/message/MiniMessageService.java @@ -1,19 +1,18 @@ package broccolai.tags.core.service.message; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.api.service.MessageService; import broccolai.tags.api.service.UserService; import broccolai.tags.core.config.LocaleConfiguration; import com.google.inject.Inject; import com.google.inject.Singleton; +import java.util.Collection; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.Collection; - @Singleton public final class MiniMessageService implements MessageService { @@ -22,8 +21,8 @@ public final class MiniMessageService implements MessageService { @Inject public MiniMessageService( - final @NonNull LocaleConfiguration locale, - final @NonNull UserService userService + final @NonNull LocaleConfiguration locale, + final @NonNull UserService userService ) { this.locale = locale; this.userService = userService; @@ -31,95 +30,95 @@ public MiniMessageService( @Override public TagResolver prefix() { - return Placeholder.component("prefix", this.locale.prefix.asComponent()); + return TagResolver.resolver("prefix", Tag.selfClosingInserting(this.locale.prefix.asComponent())); } @Override - public Component commandSelect(final @NonNull Tag tag) { - TagResolver tagComponent = Placeholder.component("tag", tag.component()); + public Component commandSelect(final @NonNull ConstructedTag tag) { + TagResolver tagComponent = TagResolver.resolver("tag", Tag.selfClosingInserting(tag.component())); return this.locale.commands.player.select.asComponent(this.prefix(), tagComponent); } @Override - public Component commandList(final @NonNull Collection tags) { + public Component commandList(final @NonNull Collection tags) { Component component = this.locale.commands.player.list.asComponent(this.prefix()); - for (Tag tag : tags) { - TagResolver nameTagResolver = Placeholder.unparsed("name", tag.name()); - TagResolver tagComponent = Placeholder.component("tag", tag.component()); + for (ConstructedTag tag : tags) { + TagResolver nameTemplate = TagResolver.resolver("name", Tag.preProcessParsed(tag.name())); + TagResolver tagComponent = TagResolver.resolver("tag", Tag.selfClosingInserting(tag.component())); - component = component.append(this.locale.commands.player.listEntry.asComponent(nameTagResolver, tagComponent)); + component = component.append(this.locale.commands.player.listEntry.asComponent(nameTemplate, tagComponent)); } return component; } @Override - public Component commandInfo(final @NonNull Tag tag) { - TagResolver nameTagResolver = Placeholder.unparsed("name", tag.name()); - TagResolver tagTagResolver = Placeholder.component("tag", tag.component()); - TagResolver reasonTagResolver = Placeholder.parsed("reason", tag.reason()); + public Component commandInfo(final @NonNull ConstructedTag tag) { + TagResolver nameTemplate = TagResolver.resolver("name", Tag.preProcessParsed(tag.name())); + TagResolver tagTemplate = TagResolver.resolver("tag", Tag.selfClosingInserting(tag.component())); + TagResolver reasonTemplate = TagResolver.resolver("reason", Tag.preProcessParsed(tag.reason())); - return this.locale.commands.player.info.asComponent(this.prefix(), nameTagResolver, tagTagResolver, reasonTagResolver); + return this.locale.commands.player.info.asComponent(this.prefix(), nameTemplate, tagTemplate, reasonTemplate); } @Override public Component commandAdminGive( - final @NonNull Tag tag, - final @NonNull TagsUser target + final @NonNull ConstructedTag tag, + final @NonNull TagsUser target ) { - TagResolver tagComponent = Placeholder.component("tag", tag.component()); - TagResolver targetComponent = Placeholder.unparsed("target", this.nameFromUser(target)); + TagResolver tagComponent = TagResolver.resolver("tag", Tag.selfClosingInserting(tag.component())); + TagResolver targetComponent = TagResolver.resolver("target", Tag.preProcessParsed(this.nameFromUser(target))); return this.locale.commands.admin.give.asComponent(this.prefix(), tagComponent, targetComponent); } @Override public Component commandAdminRemove( - final @NonNull Tag tag, - final @NonNull TagsUser target + final @NonNull ConstructedTag tag, + final @NonNull TagsUser target ) { - TagResolver tagComponent = Placeholder.component("tag", tag.component()); - TagResolver targetComponent = Placeholder.unparsed("target", this.nameFromUser(target)); + TagResolver tagComponent = TagResolver.resolver("tag", Tag.selfClosingInserting(tag.component())); + TagResolver targetComponent = TagResolver.resolver("target", Tag.preProcessParsed(this.nameFromUser(target))); return this.locale.commands.admin.remove.asComponent(this.prefix(), tagComponent, targetComponent); } @Override - public Component commandAdminList(final @NonNull Collection tags) { + public Component commandAdminList(final @NonNull Collection tags) { Component component = this.locale.commands.admin.list.asComponent(this.prefix()); - for (Tag tag : tags) { - TagResolver nameTagResolver = Placeholder.unparsed("name", tag.name()); - TagResolver tagTagResolver = Placeholder.component("tag", tag.component()); + for (ConstructedTag tag : tags) { + TagResolver nameTemplate = TagResolver.resolver("name", Tag.preProcessParsed(tag.name())); + TagResolver tagTemplate = TagResolver.resolver("tag", Tag.selfClosingInserting(tag.component())); - component = component.append(this.locale.commands.admin.listEntry.asComponent(nameTagResolver, tagTagResolver)); + component = component.append(this.locale.commands.admin.listEntry.asComponent(nameTemplate, tagTemplate)); } return component; } @Override - public Component commandAdminSet(@NonNull final Tag tag, @NonNull final TagsUser target) { - TagResolver tagTagResolver = Placeholder.component("tag", tag.component()); - TagResolver targetTagResolver = Placeholder.unparsed("target", this.nameFromUser(target)); + public Component commandAdminSet(@NonNull final ConstructedTag tag, @NonNull final TagsUser target) { + TagResolver tagTemplate = TagResolver.resolver("tag", Tag.selfClosingInserting(tag.component())); + TagResolver targetTemplate = TagResolver.resolver("target", Tag.preProcessParsed(this.nameFromUser(target))); - return this.locale.commands.admin.set.asComponent(this.prefix(), tagTagResolver, targetTagResolver); + return this.locale.commands.admin.set.asComponent(this.prefix(), tagTemplate, targetTemplate); } @Override public Component commandErrorUserNotFound(final @NonNull String input) { - TagResolver inputTagResolver = Placeholder.parsed("input", input); + TagResolver inputTemplate = TagResolver.resolver("input", Tag.preProcessParsed(input)); - return this.locale.commands.error.userNotFound.asComponent(this.prefix(), inputTagResolver); + return this.locale.commands.error.userNotFound.asComponent(this.prefix(), inputTemplate); } @Override public Component commandErrorTagNotFound(final @NonNull String input) { - TagResolver inputTagResolver = Placeholder.parsed("input", input); + TagResolver inputTemplate = TagResolver.resolver("input", Tag.preProcessParsed(input)); - return this.locale.commands.error.tagNotFound.asComponent(this.prefix(), inputTagResolver); + return this.locale.commands.error.tagNotFound.asComponent(this.prefix(), inputTemplate); } //todo: Add user to TagUser object? diff --git a/core/src/main/java/broccolai/tags/core/service/tags/MappedTagsService.java b/core/src/main/java/broccolai/tags/core/service/tags/MappedTagsService.java index 24745b5..d6303eb 100644 --- a/core/src/main/java/broccolai/tags/core/service/tags/MappedTagsService.java +++ b/core/src/main/java/broccolai/tags/core/service/tags/MappedTagsService.java @@ -1,6 +1,7 @@ package broccolai.tags.core.service.tags; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; +import broccolai.tags.api.model.tag.TagDisplayInformation; import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.api.service.PermissionService; import broccolai.tags.api.service.TagsService; @@ -8,12 +9,6 @@ import broccolai.tags.core.config.TagConfiguration; import com.google.inject.Inject; import com.google.inject.Singleton; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.MiniMessage; -import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; -import org.jetbrains.annotations.NotNull; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -22,14 +17,19 @@ import java.util.Map; import java.util.Optional; import java.util.TreeMap; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; +import org.jetbrains.annotations.NotNull; @Singleton public final class MappedTagsService implements TagsService { private static final MiniMessage MINI = MiniMessage.miniMessage(); - private final @NonNull Map idToTags = new HashMap<>(); - private final @NonNull Map nameToTags = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + private final @NonNull Map idToTags = new HashMap<>(); + private final @NonNull Map nameToTags = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); private final @NonNull PermissionService permissionService; private final int defaultId; @@ -43,12 +43,12 @@ public MappedTagsService( this.defaultId = mainConfiguration.defaultTag; for (TagConfiguration config : mainConfiguration.tags) { - this.create(config.id, config.name, config.secret, config.component, config.reason); + this.create(config.id, config.name, config.secret, config.component, config.reason, config.displayInformation); } } @Override - public @NotNull Tag defaultTag() { + public @NotNull ConstructedTag defaultTag() { return this.load(this.defaultId); } @@ -58,29 +58,30 @@ public void create( final @NonNull String name, final boolean secret, final @NonNull String componentString, - final @NonNull String reason + final @NonNull String reason, + final @Nullable TagDisplayInformation displayInformation ) { Component component = MINI.deserialize(componentString); - Tag tag = new Tag(id, name, secret, component, reason); + ConstructedTag tag = new ConstructedTag(id, name, secret, component, reason, displayInformation); this.idToTags.put(id, tag); this.nameToTags.put(name.toLowerCase(), tag); } @Override - public @Nullable Tag load(final int id) { + public @Nullable ConstructedTag load(final int id) { return this.idToTags.get(id); } @Override - public @Nullable Tag load(final @NonNull String name) { + public @Nullable ConstructedTag load(final @NonNull String name) { return this.nameToTags.get(name); } @Override - public @NonNull Tag load(final @NonNull TagsUser user) { - Optional current = user.current() + public @NonNull ConstructedTag load(final @NonNull TagsUser user) { + Optional current = user.current() .map(this::load) .filter(tag -> this.permissionService.has(user, tag)); @@ -93,7 +94,7 @@ public void create( Collections.reverse(keys); for (int index : keys) { - Tag tag = this.idToTags.get(index); + ConstructedTag tag = this.idToTags.get(index); if (this.permissionService.has(user, tag)) { return tag; } @@ -103,13 +104,13 @@ public void create( } @Override - public @NonNull Collection allTags() { + public @NonNull Collection allTags() { return Collections.unmodifiableCollection(this.idToTags.values()); } @Override - public @NonNull Collection allTags(final @NonNull TagsUser user) { - List filtered = new ArrayList<>(this.idToTags.values()); + public @NonNull Collection allTags(final @NonNull TagsUser user) { + List filtered = new ArrayList<>(this.idToTags.values()); filtered.removeIf(tag -> !this.permissionService.has(user, tag)); return Collections.unmodifiableCollection(filtered); diff --git a/core/src/main/java/broccolai/tags/core/service/user/PartialUserService.java b/core/src/main/java/broccolai/tags/core/service/user/PartialUserService.java index f70856e..f47adef 100644 --- a/core/src/main/java/broccolai/tags/core/service/user/PartialUserService.java +++ b/core/src/main/java/broccolai/tags/core/service/user/PartialUserService.java @@ -2,7 +2,6 @@ import broccolai.tags.api.model.user.TagsUser; import cloud.commandframework.services.types.PartialResultService; - import java.util.UUID; public interface PartialUserService extends PartialResultService { diff --git a/core/src/main/java/broccolai/tags/core/service/user/PipelineUserService.java b/core/src/main/java/broccolai/tags/core/service/user/PipelineUserService.java index ed92969..b8ba83c 100644 --- a/core/src/main/java/broccolai/tags/core/service/user/PipelineUserService.java +++ b/core/src/main/java/broccolai/tags/core/service/user/PipelineUserService.java @@ -8,12 +8,11 @@ import cloud.commandframework.services.ServicePipeline; import com.google.inject.Injector; import io.leangen.geantyref.TypeToken; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; public abstract class PipelineUserService implements UserService { diff --git a/core/src/main/java/broccolai/tags/core/service/user/UserServiceContext.java b/core/src/main/java/broccolai/tags/core/service/user/UserServiceContext.java index 6d02eff..a9ed60f 100644 --- a/core/src/main/java/broccolai/tags/core/service/user/UserServiceContext.java +++ b/core/src/main/java/broccolai/tags/core/service/user/UserServiceContext.java @@ -2,10 +2,9 @@ import broccolai.tags.api.model.user.TagsUser; import cloud.commandframework.services.ChunkedRequestContext; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.Collection; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; final class UserServiceContext extends ChunkedRequestContext { diff --git a/core/src/main/java/broccolai/tags/core/service/user/partials/UserCacheService.java b/core/src/main/java/broccolai/tags/core/service/user/partials/UserCacheService.java index d37e05d..23bb4d1 100644 --- a/core/src/main/java/broccolai/tags/core/service/user/partials/UserCacheService.java +++ b/core/src/main/java/broccolai/tags/core/service/user/partials/UserCacheService.java @@ -8,14 +8,13 @@ import com.google.common.cache.CacheBuilder; import com.google.inject.Inject; import com.google.inject.Singleton; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.io.Closeable; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.function.Consumer; +import org.checkerframework.checker.nullness.qual.NonNull; @Singleton public final class UserCacheService implements PartialUserService, Consumer>, Closeable { @@ -29,7 +28,7 @@ public UserCacheService(final @NonNull DataService dataService) { this.dataService = dataService; this.uuidCache = CacheBuilder.newBuilder() .maximumSize(100) - .removalListener((notification) -> this.dataService.saveUser(notification.getValue())) + .removalListener(notification -> this.dataService.saveUser(notification.getValue())) .build(); } diff --git a/core/src/main/java/broccolai/tags/core/service/user/partials/UserCreateService.java b/core/src/main/java/broccolai/tags/core/service/user/partials/UserCreateService.java index c2f1e13..36ceb97 100644 --- a/core/src/main/java/broccolai/tags/core/service/user/partials/UserCreateService.java +++ b/core/src/main/java/broccolai/tags/core/service/user/partials/UserCreateService.java @@ -3,12 +3,11 @@ import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.api.model.user.impl.PlayerTagsUser; import broccolai.tags.core.service.user.PartialUserService; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; public final class UserCreateService implements PartialUserService { diff --git a/core/src/main/java/broccolai/tags/core/service/user/partials/UserSQLService.java b/core/src/main/java/broccolai/tags/core/service/user/partials/UserSQLService.java index e3afda5..a214411 100644 --- a/core/src/main/java/broccolai/tags/core/service/user/partials/UserSQLService.java +++ b/core/src/main/java/broccolai/tags/core/service/user/partials/UserSQLService.java @@ -5,12 +5,11 @@ import broccolai.tags.core.service.user.PartialUserService; import com.google.inject.Inject; import com.google.inject.Singleton; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; +import org.checkerframework.checker.nullness.qual.NonNull; @Singleton public final class UserSQLService implements PartialUserService { diff --git a/core/src/main/java/broccolai/tags/core/subscribers/TagChangeSubscriber.java b/core/src/main/java/broccolai/tags/core/subscribers/TagChangeSubscriber.java index 5d39d6d..8b5fd81 100644 --- a/core/src/main/java/broccolai/tags/core/subscribers/TagChangeSubscriber.java +++ b/core/src/main/java/broccolai/tags/core/subscribers/TagChangeSubscriber.java @@ -11,8 +11,8 @@ public final class TagChangeSubscriber implements EventListener { @Subscribe @PostOrder(PostOrders.LAST) - public void onTagChance(final @NonNull TagChangeEvent event) { - event.user().setCurrent(event.tag()); + public void onTagChange(final @NonNull TagChangeEvent event) { + event.user().current(event.tag()); } } diff --git a/core/src/main/java/broccolai/tags/core/util/ArrayUtilities.java b/core/src/main/java/broccolai/tags/core/util/ArrayUtilities.java index 214aeb7..2c373a4 100644 --- a/core/src/main/java/broccolai/tags/core/util/ArrayUtilities.java +++ b/core/src/main/java/broccolai/tags/core/util/ArrayUtilities.java @@ -1,12 +1,10 @@ package broccolai.tags.core.util; -import com.google.inject.Module; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.util.ArrayDeque; import java.util.Arrays; import java.util.Collection; import java.util.Deque; +import org.checkerframework.checker.nullness.qual.NonNull; public final class ArrayUtilities { @@ -19,10 +17,11 @@ private ArrayUtilities() { return entries; } - public static Collection merge(final @NonNull Module[] initial, final @NonNull Module... extra) { - Deque modules = new ArrayDeque<>(Arrays.asList(initial)); + @SafeVarargs + public static Collection merge(final @NonNull T[] initial, final @NonNull T... extra) { + Deque modules = new ArrayDeque<>(Arrays.asList(initial)); - for (final Module module : extra) { + for (final T module : extra) { modules.addFirst(module); } diff --git a/core/src/main/java/broccolai/tags/core/util/FormatingUtilites.java b/core/src/main/java/broccolai/tags/core/util/FormatingUtilites.java new file mode 100644 index 0000000..3a1ad9a --- /dev/null +++ b/core/src/main/java/broccolai/tags/core/util/FormatingUtilites.java @@ -0,0 +1,34 @@ +package broccolai.tags.core.util; + +import java.util.ArrayList; +import java.util.List; + +public final class FormatingUtilites { + + public static List splitString(String input, int maxLength) { + List lines = new ArrayList<>(); + StringBuilder currentLine = new StringBuilder(); + + String[] words = input.split(" "); + + for (String word : words) { + if (currentLine.length() + word.length() + 1 <= maxLength) { + if (!currentLine.isEmpty()) { + currentLine.append(" "); + } + currentLine.append(word); + } else { + lines.add(currentLine.toString()); + currentLine = new StringBuilder(word); + } + } + + lines.add(currentLine.toString()); + + return lines; + } + + private FormatingUtilites() { + } + +} diff --git a/core/src/main/java/broccolai/tags/core/util/ResourceReader.java b/core/src/main/java/broccolai/tags/core/util/ResourceReader.java index edead6e..b1ac044 100644 --- a/core/src/main/java/broccolai/tags/core/util/ResourceReader.java +++ b/core/src/main/java/broccolai/tags/core/util/ResourceReader.java @@ -1,12 +1,11 @@ package broccolai.tags.core.util; import com.google.common.io.CharStreams; -import org.checkerframework.checker.nullness.qual.NonNull; - import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; +import org.checkerframework.checker.nullness.qual.NonNull; public final class ResourceReader { diff --git a/gradle/libs.versions.conf b/gradle/libs.versions.conf index 92b70f4..7e233cb 100644 --- a/gradle/libs.versions.conf +++ b/gradle/libs.versions.conf @@ -4,21 +4,23 @@ metadata = { } plugins = { - "net.kyori.indra" = "2.1.1" - "net.kyori.indra.publishing" = "2.1.1" - "net.kyori.indra.checkstyle" = "2.1.1" + "net.kyori.indra" = "3.1.3" + "net.kyori.indra.publishing" = "3.1.3" + "net.kyori.indra.checkstyle" = "3.1.3" "ca.stellardrift.opinionated" = "5.0.1" - "com.github.ben-manes.versions" = "0.42.0" - "com.github.johnrengelman.shadow" = "7.1.2" - "net.ltgt.errorprone" = "2.0.2" + "com.github.ben-manes.versions" = "0.49.0" + "com.github.johnrengelman.shadow" = "8.1.1" + "net.ltgt.errorprone" = "3.1.0" "xyz.jpenilla.run-paper" = "1.0.6" "com.adarshr.test-logger" = "3.2.0" + "xyz.jpenilla.gremlin-gradle" = "0.0.1-SNAPSHOT" } versions = { # Tooling checker-qual = "3.22.0" errorprone = "2.13.1" + gremlin = "0.0.1-SNAPSHOT" # Testing truth = "1.1.3" @@ -28,39 +30,41 @@ versions = { # Google guava = "31.1-jre" gson = "2.9.0" - guice = "5.1.0" + guice = "7.0.0" # Incendo http4j = "1.3" - cloud = "1.7.0" + cloud = "1.8.4" + interfaces = "1.0.0-SNAPSHOT" # Kyori - adventure = "4.11.0" + adventure = "4.14.0" moonshine = "2.0.4" coffee = "1.0.0-SNAPSHOT" event = "4.0.0-SNAPSHOT" # Storage - jdbi = "3.30.0" + jdbi = "3.41.3" hikari = "5.0.1" - flyway = "9.0.1" - h2 = "2.1.212" + flyway = "10.0.0" + h2 = "2.2.224" configurate = "4.1.2" # Misc - corn = "3.1.0" + corn = "3.2.0" slf4j = "1.7.30" caffeine = "3.1.0" + stylecheck = "0.2.1" # Bukkit - paper-api = "1.19-R0.1-SNAPSHOT" + paper-api = "1.20.2-R0.1-SNAPSHOT" paper-lib = "1.0.6" # Velocity velocity = "1.1.8" # Plugin APIs - papi = "2.11.2" + papi = "2.11.5" vault = "1.7.1" luckperms = "5.4" } @@ -69,6 +73,7 @@ dependencies = { # Tooling checker-qual = {group = "org.checkerframework", name = "checker-qual", version.ref = "checker-qual"} errorprone = {group = "com.google.errorprone", name = "error_prone_core", version.ref = "errorprone"} + gremlin = {group = "xyz.jpenilla", name = "gremlin-runtime", version.ref = "gremlin"} # Google guava = {group = "com.google.guava", name = "guava", version.ref = "guava"} @@ -82,6 +87,7 @@ dependencies = { cloud-paper = {group = "cloud.commandframework", name = "cloud-paper", version.ref = "cloud"} cloud-velocity = {group = "cloud.commandframework", name = "cloud-velocity", version.ref = "cloud"} cloud-extras = {group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud"} + interfaces-paper = {group = "org.incendo.interfaces", name = "interfaces-paper", version.ref = "interfaces"} # Kyori adventure-api = {group = "net.kyori", name = "adventure-api", version.ref = "adventure"} @@ -104,8 +110,10 @@ dependencies = { # Misc corn-misc = {group = "broccolai.corn", name = "corn-misc", version.ref = "corn"} corn-context = {group = "broccolai.corn", name = "corn-context", version.ref = "corn"} + corn-minecraft-paper = {group = "broccolai.corn", name = "corn-minecraft-paper", version.ref = "corn"} slf4j = {group = "org.slf4j", name = "slf4j-simple", version.ref = "slf4j"} caffeine = {group = "com.github.ben-manes.caffeine", name = "caffeine", version.ref = "caffeine"} + stylecheck = {group = "ca.stellardrift", name = "stylecheck", version.ref = "stylecheck"} # Bukkit paper-api = {group = "io.papermc.paper", name = "paper-api", version.ref = "paper-api"} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8049c68..e411586 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts new file mode 100644 index 0000000..d166946 --- /dev/null +++ b/paper/build.gradle.kts @@ -0,0 +1,74 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +plugins { + id("xyz.jpenilla.run-paper") version "2.2.0" + id("com.github.johnrengelman.shadow") + id("xyz.jpenilla.gremlin-gradle") +} + +repositories { + maven("https://repo.jpenilla.xyz/snapshots/") +} + +fun DependencyHandler.runtimeDownloadApi(dependencyNotation: Any) { + api(dependencyNotation) + runtimeDownload(dependencyNotation) +} + +dependencies { + runtimeDownloadApi(projects.tagsCore) + + compileOnly(libs.paper.api) + compileOnly(libs.papi) + compileOnly(libs.vault) + + runtimeDownloadApi(libs.cloud.paper) + runtimeDownloadApi(libs.cloud.extras) + runtimeDownloadApi(libs.corn.minecraft.paper) + + runtimeDownloadApi(libs.interfaces.paper) + + runtimeDownloadApi(libs.h2) +} + +configurations.runtimeDownload { + exclude("io.papermc.paper") + exclude("net.kyori", "adventure-api") + exclude("net.kyori", "adventure-text-minimessage") + exclude("net.kyori", "adventure-text-serializer-plain") + exclude("org.slf4j", "slf4j-api") + exclude("org.ow2.asm") +} + +tasks { + runServer { + minecraftVersion("1.20.2") + downloadPlugins { + url("https://github.com/MilkBowl/Vault/releases/download/1.7.3/Vault.jar") + } + } + + withType { + dependencies { + include(project(":tags-core")) + include(project(":tags-api")) + include(dependency(libs.gremlin.get().toString())) + } + + relocate("xyz.jpenilla.gremlin", "broccolai.tags.lib.xyz.jpenilla.gremlin") + + archiveFileName.set(project.name + ".jar") + } + + build { + dependsOn(shadowJar) + } + + writeDependencies { + repos.set(listOf( + "https://repo.papermc.io/repository/maven-public/", + "https://repo.broccol.ai/releases", + "https://oss.sonatype.org/content/repositories/snapshots/", + )) + } +} diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/BukkitTagsPlatform.java b/paper/src/main/java/broccolai/tags/paper/PaperTagsPlatform.java similarity index 65% rename from bukkit/src/main/java/broccolai/tags/bukkit/BukkitTagsPlatform.java rename to paper/src/main/java/broccolai/tags/paper/PaperTagsPlatform.java index f85478e..69deb02 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/BukkitTagsPlatform.java +++ b/paper/src/main/java/broccolai/tags/paper/PaperTagsPlatform.java @@ -1,22 +1,22 @@ -package broccolai.tags.bukkit; +package broccolai.tags.paper; -import broccolai.tags.api.events.EventListener; -import broccolai.tags.api.service.EventService; import broccolai.tags.api.service.MessageService; -import broccolai.tags.bukkit.commands.context.BukkitCommandUser; -import broccolai.tags.bukkit.commands.context.BukkitConsoleCommandUser; -import broccolai.tags.bukkit.commands.context.BukkitPlayerCommandUser; -import broccolai.tags.bukkit.inject.PlatformModule; -import broccolai.tags.bukkit.inject.VaultModule; -import broccolai.tags.bukkit.integrations.PapiIntegration; -import broccolai.tags.bukkit.integrations.VaultIntegration; -import broccolai.tags.bukkit.listeners.PlayerListener; import broccolai.tags.core.TagsPlugin; +import broccolai.tags.core.commands.PluginCommand; import broccolai.tags.core.commands.arguments.TagArgument; import broccolai.tags.core.commands.arguments.UserArgument; import broccolai.tags.core.commands.context.CommandUser; import broccolai.tags.core.platform.TagsPlatform; import broccolai.tags.core.util.ArrayUtilities; +import broccolai.tags.paper.commands.PaperTagsCommand; +import broccolai.tags.paper.commands.context.PaperCommandUser; +import broccolai.tags.paper.commands.context.PaperConsoleCommandUser; +import broccolai.tags.paper.commands.context.PaperPlayerCommandUser; +import broccolai.tags.paper.inject.PlatformModule; +import broccolai.tags.paper.inject.VaultModule; +import broccolai.tags.paper.integrations.BasicIntegration; +import broccolai.tags.paper.integrations.PapiIntegration; +import broccolai.tags.paper.listeners.PlayerListener; import cloud.commandframework.CommandManager; import cloud.commandframework.bukkit.CloudBukkitCapabilities; import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator; @@ -24,6 +24,7 @@ import cloud.commandframework.paper.PaperCommandManager; import com.google.inject.Guice; import com.google.inject.Injector; +import java.util.Collection; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; @@ -32,15 +33,18 @@ import org.bukkit.plugin.java.JavaPlugin; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.interfaces.paper.PaperInterfaceListeners; -public final class BukkitTagsPlatform extends JavaPlugin implements TagsPlatform { +public final class PaperTagsPlatform extends JavaPlugin implements TagsPlatform { - private static final @NonNull Class[] BUKKIT_LISTENERS = ArrayUtilities.create( - PlayerListener.class + private static final @NonNull Class[] PAPER_LISTENERS = ArrayUtilities.create( + PlayerListener.class, + BasicIntegration.class ); - private static final @NonNull Class[] LISTENERS = ArrayUtilities.create( - VaultIntegration.class + private static final @NonNull Collection> PAPER_COMMANDS = ArrayUtilities.merge( + COMMANDS, + PaperTagsCommand.class ); private @MonotonicNonNull TagsPlugin plugin; @@ -49,6 +53,8 @@ public final class BukkitTagsPlatform extends JavaPlugin implements TagsPlatform public void onEnable() { this.getDataFolder().mkdirs(); + PaperInterfaceListeners.install(this); + Injector injector = Guice.createInjector(ArrayUtilities.merge( STANDARD_MODULES, new PlatformModule(this), @@ -58,7 +64,7 @@ public void onEnable() { this.plugin = injector.getInstance(TagsPlugin.class); this.plugin.start(); - CommandManager commandManager = this.getCommandManager( + CommandManager commandManager = this.commandManager( injector.getInstance(MessageService.class) ); @@ -66,20 +72,14 @@ public void onEnable() { injector.getInstance(PapiIntegration.class).register(); } - EventService eventService = injector.getInstance(EventService.class); - for (final Class listener : LISTENERS) { - eventService.register(injector.getInstance(listener)); - } - - for (final Class bukkitListener : BUKKIT_LISTENERS) { + for (final Class paperListener : PAPER_LISTENERS) { this.getServer().getPluginManager().registerEvents( - injector.getInstance(bukkitListener), + injector.getInstance(paperListener), this ); } - - this.plugin.commands(commandManager, COMMANDS); + this.plugin.commands(commandManager, PAPER_COMMANDS); } @Override @@ -87,15 +87,15 @@ public void onDisable() { this.plugin.shutdown(); } - private CommandManager getCommandManager( + private CommandManager commandManager( final @NonNull MessageService messageService ) { try { PaperCommandManager commandManager = new PaperCommandManager<>( this, - AsynchronousCommandExecutionCoordinator.newBuilder().build(), - BukkitTagsPlatform::from, - user -> user.cast().sender() + AsynchronousCommandExecutionCoordinator.builder().build(), + PaperTagsPlatform::from, + user -> user.cast().sender() ); if (commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { @@ -108,7 +108,7 @@ private CommandManager getCommandManager( new MinecraftExceptionHandler() .withDefaultHandlers() - .apply(commandManager, (e) -> e); + .apply(commandManager, e -> e); commandManager.registerExceptionHandler(UserArgument.UserArgumentException.class, (user, ex) -> { user.sendMessage(messageService.commandErrorUserNotFound(ex.input())); @@ -126,9 +126,9 @@ private CommandManager getCommandManager( private static CommandUser from(final @NonNull CommandSender sender) { if (sender instanceof ConsoleCommandSender console) { - return new BukkitConsoleCommandUser(console, console); + return new PaperConsoleCommandUser(console); } else if (sender instanceof Player player) { - return new BukkitPlayerCommandUser(player, player); + return new PaperPlayerCommandUser(player); } return null; diff --git a/paper/src/main/java/broccolai/tags/paper/commands/PaperTagsCommand.java b/paper/src/main/java/broccolai/tags/paper/commands/PaperTagsCommand.java new file mode 100644 index 0000000..4b0dcd3 --- /dev/null +++ b/paper/src/main/java/broccolai/tags/paper/commands/PaperTagsCommand.java @@ -0,0 +1,80 @@ +package broccolai.tags.paper.commands; + +import broccolai.corn.paper.item.PaperItemBuilder; +import broccolai.tags.api.model.tag.ConstructedTag; +import broccolai.tags.api.model.tag.TagDisplayInformation; +import broccolai.tags.api.model.user.TagsUser; +import broccolai.tags.api.service.UserService; +import broccolai.tags.core.commands.PluginCommand; +import broccolai.tags.core.commands.arguments.modes.TagParserMode; +import broccolai.tags.core.commands.context.CommandUser; +import broccolai.tags.core.factory.CloudArgumentFactory; +import broccolai.tags.paper.commands.context.PaperPlayerCommandUser; +import broccolai.tags.paper.menu.TagsMenuFactory; +import cloud.commandframework.Command; +import cloud.commandframework.CommandManager; +import cloud.commandframework.context.CommandContext; +import com.google.inject.Inject; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.interfaces.paper.PlayerViewer; + +public final class PaperTagsCommand implements PluginCommand { + + private final UserService userService; + private final CloudArgumentFactory argumentFactory; + private final TagsMenuFactory tagsMenuFactory; + + @Inject + public PaperTagsCommand( + final @NonNull UserService userService, + final @NonNull CloudArgumentFactory argumentFactory, + final @NonNull TagsMenuFactory tagsMenuFactory + ) { + this.userService = userService; + this.argumentFactory = argumentFactory; + this.tagsMenuFactory = tagsMenuFactory; + } + + @Override + public void register(@NonNull final CommandManager<@NonNull CommandUser> commandManager) { + Command.Builder tagsCommand = commandManager.commandBuilder("tags"); + + commandManager.command(tagsCommand + .literal("test-item") + .permission("tags.command.admin.test-item") + .argument(this.argumentFactory.tag("tag", TagParserMode.SELF)) + .handler(this::handleTestItem) + ); + + commandManager.command(tagsCommand + .literal("menu") + .permission("tags.command.user.menu") + .handler(this::handleMenu) + ); + } + + private void handleTestItem(final @NonNull CommandContext context) { + ConstructedTag tag = context.get("tag"); + TagDisplayInformation displayInformation = tag.displayInformation(); + + Material material = Material.matchMaterial(displayInformation.material()); + + ItemStack item = PaperItemBuilder + .ofType(material) + .customModelData(displayInformation.customModelData()) + .build(); + + PaperPlayerCommandUser user = context.getSender().cast(); + user.player().getInventory().addItem(item); + } + + private void handleMenu(final @NonNull CommandContext context) { + PaperPlayerCommandUser sender = context.getSender().cast(); + TagsUser user = this.userService.get(sender.uuid()); + + this.tagsMenuFactory.create(user).open(PlayerViewer.of(sender.player())); + } + +} diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitCommandUser.java b/paper/src/main/java/broccolai/tags/paper/commands/context/PaperCommandUser.java similarity index 58% rename from bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitCommandUser.java rename to paper/src/main/java/broccolai/tags/paper/commands/context/PaperCommandUser.java index dd7d86e..81e50f5 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/commands/context/BukkitCommandUser.java +++ b/paper/src/main/java/broccolai/tags/paper/commands/context/PaperCommandUser.java @@ -1,18 +1,16 @@ -package broccolai.tags.bukkit.commands.context; +package broccolai.tags.paper.commands.context; import broccolai.tags.core.commands.context.CommandUser; import net.kyori.adventure.audience.Audience; import org.bukkit.command.CommandSender; import org.checkerframework.checker.nullness.qual.NonNull; -public abstract class BukkitCommandUser implements CommandUser { +public abstract class PaperCommandUser implements CommandUser { private final CommandSender source; - private final Audience audience; - public BukkitCommandUser(final @NonNull CommandSender source, final @NonNull Audience audience) { + public PaperCommandUser(final @NonNull CommandSender source) { this.source = source; - this.audience = audience; } public final @NonNull CommandSender sender() { @@ -21,7 +19,7 @@ public BukkitCommandUser(final @NonNull CommandSender source, final @NonNull Aud @Override public final @NonNull Audience audience() { - return this.audience; + return this.source; } } diff --git a/paper/src/main/java/broccolai/tags/paper/commands/context/PaperConsoleCommandUser.java b/paper/src/main/java/broccolai/tags/paper/commands/context/PaperConsoleCommandUser.java new file mode 100644 index 0000000..8907b55 --- /dev/null +++ b/paper/src/main/java/broccolai/tags/paper/commands/context/PaperConsoleCommandUser.java @@ -0,0 +1,19 @@ +package broccolai.tags.paper.commands.context; + +import broccolai.tags.api.model.user.impl.ConsoleTagsUser; +import java.util.UUID; +import org.bukkit.command.CommandSender; +import org.checkerframework.checker.nullness.qual.NonNull; + +public final class PaperConsoleCommandUser extends PaperCommandUser { + + public PaperConsoleCommandUser(final @NonNull CommandSender source) { + super(source); + } + + @Override + public UUID uuid() { + return ConsoleTagsUser.UUID; + } + +} diff --git a/paper/src/main/java/broccolai/tags/paper/commands/context/PaperPlayerCommandUser.java b/paper/src/main/java/broccolai/tags/paper/commands/context/PaperPlayerCommandUser.java new file mode 100644 index 0000000..92360c6 --- /dev/null +++ b/paper/src/main/java/broccolai/tags/paper/commands/context/PaperPlayerCommandUser.java @@ -0,0 +1,27 @@ +package broccolai.tags.paper.commands.context; + +import java.util.UUID; +import org.bukkit.entity.Player; +import org.checkerframework.checker.nullness.qual.NonNull; + +public final class PaperPlayerCommandUser extends PaperCommandUser { + + private final Player player; + + public PaperPlayerCommandUser( + final @NonNull Player player + ) { + super(player); + this.player = player; + } + + @Override + public UUID uuid() { + return this.player.getUniqueId(); + } + + public @NonNull Player player() { + return this.player; + } + +} diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/inject/PlatformModule.java b/paper/src/main/java/broccolai/tags/paper/inject/PlatformModule.java similarity index 50% rename from bukkit/src/main/java/broccolai/tags/bukkit/inject/PlatformModule.java rename to paper/src/main/java/broccolai/tags/paper/inject/PlatformModule.java index 24f470e..6fb16a6 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/inject/PlatformModule.java +++ b/paper/src/main/java/broccolai/tags/paper/inject/PlatformModule.java @@ -1,24 +1,24 @@ -package broccolai.tags.bukkit.inject; +package broccolai.tags.paper.inject; import broccolai.tags.api.service.PermissionService; import broccolai.tags.api.service.TaskService; import broccolai.tags.api.service.UserService; -import broccolai.tags.bukkit.BukkitTagsPlatform; -import broccolai.tags.bukkit.service.BukkitPermissionService; -import broccolai.tags.bukkit.service.BukkitPipelineUserService; -import broccolai.tags.bukkit.service.BukkitTaskService; import broccolai.tags.core.platform.TagsPlatform; +import broccolai.tags.paper.PaperTagsPlatform; +import broccolai.tags.paper.service.PaperPermissionService; +import broccolai.tags.paper.service.PaperPipelineUserService; +import broccolai.tags.paper.service.PaperTaskService; import com.google.inject.AbstractModule; +import java.io.File; import org.bukkit.plugin.Plugin; import org.checkerframework.checker.nullness.qual.NonNull; - -import java.io.File; +import org.slf4j.Logger; public final class PlatformModule extends AbstractModule { - private final @NonNull BukkitTagsPlatform plugin; + private final @NonNull PaperTagsPlatform plugin; - public PlatformModule(final @NonNull BukkitTagsPlatform plugin) { + public PlatformModule(final @NonNull PaperTagsPlatform plugin) { this.plugin = plugin; } @@ -27,9 +27,10 @@ protected void configure() { this.bind(Plugin.class).toInstance(this.plugin); this.bind(TagsPlatform.class).toInstance(this.plugin); this.bind(File.class).toInstance(this.plugin.getDataFolder()); - this.bind(TaskService.class).to(BukkitTaskService.class); - this.bind(UserService.class).to(BukkitPipelineUserService.class); - this.bind(PermissionService.class).to(BukkitPermissionService.class); + this.bind(Logger.class).toInstance(this.plugin.getSLF4JLogger()); + this.bind(TaskService.class).to(PaperTaskService.class); + this.bind(UserService.class).to(PaperPipelineUserService.class); + this.bind(PermissionService.class).to(PaperPermissionService.class); } } diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/inject/VaultModule.java b/paper/src/main/java/broccolai/tags/paper/inject/VaultModule.java similarity index 64% rename from bukkit/src/main/java/broccolai/tags/bukkit/inject/VaultModule.java rename to paper/src/main/java/broccolai/tags/paper/inject/VaultModule.java index e0b0240..4fca5c1 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/inject/VaultModule.java +++ b/paper/src/main/java/broccolai/tags/paper/inject/VaultModule.java @@ -1,9 +1,8 @@ -package broccolai.tags.bukkit.inject; +package broccolai.tags.paper.inject; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Singleton; -import net.milkbowl.vault.chat.Chat; import net.milkbowl.vault.permission.Permission; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.RegisteredServiceProvider; @@ -11,18 +10,6 @@ public final class VaultModule extends AbstractModule { - @Provides - @Singleton - private Chat provideChat(final @NonNull Plugin plugin) { - RegisteredServiceProvider rsp = plugin.getServer().getServicesManager().getRegistration(Chat.class); - - if (rsp == null) { - throw new RuntimeException(); - } - - return rsp.getProvider(); - } - @Provides @Singleton private Permission providePermission(final @NonNull Plugin plugin) { diff --git a/paper/src/main/java/broccolai/tags/paper/integrations/BasicIntegration.java b/paper/src/main/java/broccolai/tags/paper/integrations/BasicIntegration.java new file mode 100644 index 0000000..037bdcd --- /dev/null +++ b/paper/src/main/java/broccolai/tags/paper/integrations/BasicIntegration.java @@ -0,0 +1,33 @@ +package broccolai.tags.paper.integrations; + +import broccolai.tags.api.model.tag.ConstructedTag; +import broccolai.tags.api.service.TagsService; +import broccolai.tags.api.service.UserService; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import io.papermc.paper.event.player.AsyncChatEvent; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.checkerframework.checker.nullness.qual.NonNull; + +@Singleton +public final class BasicIntegration implements Listener { + + private final UserService userService; + private final TagsService tagsService; + + @Inject + public BasicIntegration(final @NonNull UserService userService, final @NonNull TagsService tagsService) { + this.userService = userService; + this.tagsService = tagsService; + } + + @EventHandler + public void onChat(final @NonNull AsyncChatEvent event) { + event.renderer((source, name, message, viewer) -> { + ConstructedTag tag = this.tagsService.load(this.userService.get(source.getUniqueId())); + return message.replaceText(builder -> builder.matchLiteral("%tag%").replacement(tag.component())); + }); + } + +} diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/integrations/PapiIntegration.java b/paper/src/main/java/broccolai/tags/paper/integrations/PapiIntegration.java similarity index 87% rename from bukkit/src/main/java/broccolai/tags/bukkit/integrations/PapiIntegration.java rename to paper/src/main/java/broccolai/tags/paper/integrations/PapiIntegration.java index 8821c99..4445a94 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/integrations/PapiIntegration.java +++ b/paper/src/main/java/broccolai/tags/paper/integrations/PapiIntegration.java @@ -1,6 +1,6 @@ -package broccolai.tags.bukkit.integrations; +package broccolai.tags.paper.integrations; -import broccolai.tags.api.model.tag.Tag; +import broccolai.tags.api.model.tag.ConstructedTag; import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.api.service.TagsService; import broccolai.tags.api.service.UserService; @@ -48,8 +48,8 @@ public String getVersion() { public String onRequest(final @NonNull OfflinePlayer player, final @NonNull String identifier) { TagsUser user = this.userService.get(player.getUniqueId()); - if (identifier.equalsIgnoreCase("current")) { - Tag tag = this.tagsService.load(user); + if ("current".equalsIgnoreCase(identifier)) { + ConstructedTag tag = this.tagsService.load(user); return LEGACY.serialize(tag.component()); } diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/listeners/PlayerListener.java b/paper/src/main/java/broccolai/tags/paper/listeners/PlayerListener.java similarity index 96% rename from bukkit/src/main/java/broccolai/tags/bukkit/listeners/PlayerListener.java rename to paper/src/main/java/broccolai/tags/paper/listeners/PlayerListener.java index a62bc3c..0e30f0f 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/listeners/PlayerListener.java +++ b/paper/src/main/java/broccolai/tags/paper/listeners/PlayerListener.java @@ -1,4 +1,4 @@ -package broccolai.tags.bukkit.listeners; +package broccolai.tags.paper.listeners; import broccolai.tags.api.events.event.UserLoginEvent; import broccolai.tags.api.model.user.TagsUser; @@ -6,9 +6,7 @@ import broccolai.tags.api.service.TaskService; import broccolai.tags.api.service.UserService; import com.google.inject.Inject; - import java.util.UUID; - import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; diff --git a/paper/src/main/java/broccolai/tags/paper/menu/TagsMenuFactory.java b/paper/src/main/java/broccolai/tags/paper/menu/TagsMenuFactory.java new file mode 100644 index 0000000..0f99daa --- /dev/null +++ b/paper/src/main/java/broccolai/tags/paper/menu/TagsMenuFactory.java @@ -0,0 +1,184 @@ +package broccolai.tags.paper.menu; + +import broccolai.corn.paper.item.PaperItemBuilder; +import broccolai.tags.api.model.tag.ConstructedTag; +import broccolai.tags.api.model.user.TagsUser; +import broccolai.tags.api.service.ActionService; +import broccolai.tags.api.service.TagsService; +import broccolai.tags.core.config.LocaleConfiguration; +import broccolai.tags.core.util.FormatingUtilites; +import com.google.inject.Inject; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.incendo.interfaces.core.click.ClickHandler; +import org.incendo.interfaces.core.transform.InterfaceProperty; +import org.incendo.interfaces.core.transform.types.PaginatedTransform; +import org.incendo.interfaces.core.util.Vector2; +import org.incendo.interfaces.core.view.InterfaceView; +import org.incendo.interfaces.paper.PlayerViewer; +import org.incendo.interfaces.paper.element.ItemStackElement; +import org.incendo.interfaces.paper.pane.ChestPane; +import org.incendo.interfaces.paper.type.ChestInterface; +import org.slf4j.Logger; + +public final class TagsMenuFactory { + + private static final ItemStackElement BOTTOM_BAR_ELEMENT = new ItemStackElement<>( + PaperItemBuilder.ofType(Material.WHITE_STAINED_GLASS_PANE) + .name(Component.empty()) + .build(), + ClickHandler.cancel() + ); + + private static final ItemStack BACK_ITEM = PaperItemBuilder + .ofType(Material.RED_STAINED_GLASS_PANE) + .name(Component.text("Previous Page")) + .build(); + + private static final ItemStack FORWARD_ITEM = PaperItemBuilder + .ofType(Material.GREEN_STAINED_GLASS_PANE) + .name(Component.text("Next Page")) + .build(); + + private final Logger logger; + private final TagsService tagsService; + private final ActionService actionService; + private final LocaleConfiguration.MenuLocaleConfiguration locale; + + @Inject + public TagsMenuFactory( + final @NonNull Logger logger, + final @NonNull TagsService tagsService, + final @NonNull ActionService actionService, + final @NonNull LocaleConfiguration locale + ) { + this.logger = logger; + this.tagsService = tagsService; + this.actionService = actionService; + this.locale = locale.menu; + } + + public ChestInterface create(final @NonNull TagsUser user) { + InterfaceProperty refreshProperty = InterfaceProperty.of(UUID.randomUUID()); + var tagTransform = this.createTagTransform(user, refreshProperty); + + return ChestInterface.builder() + .title(this.locale.title.asComponent()) + .rows(4) + .cancelClicksInPlayerInventory(true) + .addTransform(this::createFillTransform) + .addTransform(tagTransform, tagTransform.pageProperty(), refreshProperty) + .build(); + } + + private ChestPane createFillTransform(ChestPane pane, InterfaceView view) { + ChestPane result = pane; + + for (int i = 0; i < 9; i++) { + result = result.element(BOTTOM_BAR_ELEMENT, i, 3); + } + + return result; + } + + private PaginatedTransform, ChestPane, PlayerViewer> createTagTransform( + final @NonNull TagsUser user, + final @NonNull InterfaceProperty refreshProperty + ) { + PaginatedTransform, ChestPane, PlayerViewer> transform = new PaginatedTransform<>( + Vector2.at(0, 0), + Vector2.at(8, 2), + () -> this.createTagElements(user, refreshProperty) + ); + + transform.backwardElement(Vector2.at(0, 3), unused -> { + return ItemStackElement.of(BACK_ITEM, ctx -> { + transform.previousPage(); + ctx.cancel(true); + }); + }); + + transform.forwardElement(Vector2.at(8, 3), unused -> { + return ItemStackElement.of(FORWARD_ITEM, ctx -> { + transform.nextPage(); + ctx.cancel(true); + }); + }); + + return transform; + } + + private List> createTagElements( + final @NonNull TagsUser user, + final @NonNull InterfaceProperty refreshProperty + ) { + return this.tagsService.allTags(user) + .stream() + .map(tag -> this.createTagElement(user, tag, refreshProperty)) + .toList(); + } + + private ItemStackElement createTagElement( + final @NonNull TagsUser user, + final @NonNull ConstructedTag tag, + final @NonNull InterfaceProperty refreshProperty + ) { + Material material = this.matchMaterialOrDefault(tag.displayInformation().material()); + ItemStack item = PaperItemBuilder.ofType(material) + .name(tag.component()) + .lore(this.createTagLore(user, tag)) + .build(); + + return ItemStackElement.of(item, ctx -> { + ctx.cancel(true); + this.actionService.select(user, tag); + refreshProperty.set(UUID.randomUUID()); + }); + } + + private List createTagLore(final @NonNull TagsUser user, final @NonNull ConstructedTag tag) { + List result = new ArrayList<>(); + + result.addAll(this.formatTagReason(tag.reason())); + + result.add(Component.empty()); + + if (this.userHasTagEquipped(user, tag)) { + result.add(this.locale.currentlyEquipped.asComponent()); + } else { + result.add(this.locale.equip.asComponent()); + } + + return result; + } + + private List formatTagReason(final @NonNull String reason) { + return FormatingUtilites.splitString(reason, 30) + .stream() + .map(text -> Component.text(text, NamedTextColor.WHITE)) + .collect(Collectors.toList()); + } + + private Material matchMaterialOrDefault(final @NonNull String input) { + Material material = Material.matchMaterial(input); + + if (material == null) { + this.logger.warn("material {} does not exist", input); + material = Material.POTATO; + } + + return material; + } + + private boolean userHasTagEquipped(final @NonNull TagsUser user, final @NonNull ConstructedTag tag) { + return user.current().isPresent() && user.current().get() == tag.id(); + } + +} diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitPermissionService.java b/paper/src/main/java/broccolai/tags/paper/service/PaperPermissionService.java similarity index 85% rename from bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitPermissionService.java rename to paper/src/main/java/broccolai/tags/paper/service/PaperPermissionService.java index 30e9547..c36a854 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitPermissionService.java +++ b/paper/src/main/java/broccolai/tags/paper/service/PaperPermissionService.java @@ -1,4 +1,4 @@ -package broccolai.tags.bukkit.service; +package broccolai.tags.paper.service; import broccolai.tags.api.model.Permissible; import broccolai.tags.api.model.user.TagsUser; @@ -9,12 +9,12 @@ import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.NonNull; -public final class BukkitPermissionService implements PermissionService { +public final class PaperPermissionService implements PermissionService { private final @NonNull Permission permission; @Inject - public BukkitPermissionService(final @NonNull Permission permission) { + public PaperPermissionService(final @NonNull Permission permission) { this.permission = permission; } diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitPipelineUserService.java b/paper/src/main/java/broccolai/tags/paper/service/PaperPipelineUserService.java similarity index 81% rename from bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitPipelineUserService.java rename to paper/src/main/java/broccolai/tags/paper/service/PaperPipelineUserService.java index 2d73e8f..daf7846 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitPipelineUserService.java +++ b/paper/src/main/java/broccolai/tags/paper/service/PaperPipelineUserService.java @@ -1,27 +1,25 @@ -package broccolai.tags.bukkit.service; +package broccolai.tags.paper.service; import broccolai.corn.core.Lists; import broccolai.tags.api.model.user.TagsUser; import broccolai.tags.core.service.user.PipelineUserService; import com.google.inject.Inject; import com.google.inject.Injector; +import java.util.List; +import java.util.Objects; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.NonNull; -import java.util.List; -import java.util.Objects; - -public final class BukkitPipelineUserService extends PipelineUserService { +public final class PaperPipelineUserService extends PipelineUserService { @Inject - public BukkitPipelineUserService(final @NonNull Injector injector) { + public PaperPipelineUserService(final @NonNull Injector injector) { super(injector); } @Override - @SuppressWarnings("deprecation") public @NonNull TagsUser get(final @NonNull String username) { return this.get(Bukkit.getOfflinePlayer(username).getUniqueId()); } diff --git a/bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitTaskService.java b/paper/src/main/java/broccolai/tags/paper/service/PaperTaskService.java similarity index 78% rename from bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitTaskService.java rename to paper/src/main/java/broccolai/tags/paper/service/PaperTaskService.java index 0fa1a6b..844774f 100644 --- a/bukkit/src/main/java/broccolai/tags/bukkit/service/BukkitTaskService.java +++ b/paper/src/main/java/broccolai/tags/paper/service/PaperTaskService.java @@ -1,4 +1,4 @@ -package broccolai.tags.bukkit.service; +package broccolai.tags.paper.service; import broccolai.tags.api.service.TaskService; import com.google.inject.Inject; @@ -6,12 +6,12 @@ import org.bukkit.plugin.Plugin; import org.checkerframework.checker.nullness.qual.NonNull; -public final class BukkitTaskService implements TaskService { +public final class PaperTaskService implements TaskService { private final @NonNull Plugin plugin; @Inject - public BukkitTaskService(final @NonNull Plugin plugin) { + public PaperTaskService(final @NonNull Plugin plugin) { this.plugin = plugin; } diff --git a/bukkit/src/main/resources/plugin.yml b/paper/src/main/resources/paper-plugin.yml similarity index 66% rename from bukkit/src/main/resources/plugin.yml rename to paper/src/main/resources/paper-plugin.yml index d6de61a..2f2a88a 100644 --- a/bukkit/src/main/resources/plugin.yml +++ b/paper/src/main/resources/paper-plugin.yml @@ -1,9 +1,15 @@ name : Tags version : $version -main : broccolai.tags.bukkit.BukkitTagsPlatform -api-version : 1.19 -depend : [ Vault ] -softdepend : [ PlaceholderAPI, EssentialsChat, Essentials ] +main : broccolai.tags.paper.PaperTagsPlatform +loader: broccolai.tags.lib.xyz.jpenilla.gremlin.runtime.platformsupport.DefaultsPaperPluginLoader +api-version : '1.20' +dependencies: + server: + Vault: + load: BEFORE + required: true + join-classpath: true +softdepend : [ PlaceholderAPI ] permissions : tags.user : default : true diff --git a/bukkit/src/main/resources/queries/migrations/V1__create_tables.sql b/paper/src/main/resources/queries/migrations/V1__create_tables.sql similarity index 100% rename from bukkit/src/main/resources/queries/migrations/V1__create_tables.sql rename to paper/src/main/resources/queries/migrations/V1__create_tables.sql diff --git a/paper/src/main/resources/queries/save-user.sql b/paper/src/main/resources/queries/save-user.sql new file mode 100644 index 0000000..a2ecae0 --- /dev/null +++ b/paper/src/main/resources/queries/save-user.sql @@ -0,0 +1,2 @@ +REPLACE INTO tags_users(uuid, currentTag) +VALUES(:uuid, :currentTag); diff --git a/bukkit/src/main/resources/queries/select-user.sql b/paper/src/main/resources/queries/select-user.sql similarity index 100% rename from bukkit/src/main/resources/queries/select-user.sql rename to paper/src/main/resources/queries/select-user.sql diff --git a/settings.gradle.kts b/settings.gradle.kts index a216619..7d61a8a 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,11 +1,17 @@ +pluginManagement { + repositories { + gradlePluginPortal() + maven("https://repo.jpenilla.xyz/snapshots/") + } +} + plugins { - id("ca.stellardrift.polyglot-version-catalogs") version "5.0.0" + id("ca.stellardrift.polyglot-version-catalogs") version "6.0.0" } rootProject.name = "tags" - -use("api", "core", "bukkit") +use("api", "core", "paper") fun use(vararg names: String) { for (name in names) { @@ -13,3 +19,5 @@ fun use(vararg names: String) { project(":$name").name = "${rootProject.name}-$name" } } + +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")