From 985a5840e0a405ca2c042a9cd9527bf4826bcf47 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 12 Apr 2024 21:15:58 +0100 Subject: [PATCH 01/43] chore: Start rewrite --- build-logic/build.gradle.kts | 11 + build-logic/settings.gradle.kts | 15 + .../src/main/kotlin/gui.base.gradle.kts | 45 +++ .../src/main/kotlin/gui.parent.gradle.kts | 4 + build.gradle.kts | 48 +-- bukkit/build.gradle.kts | 12 + core/build.gradle.kts | 104 +---- .../main/java/dev/triumphteam/gui/Gui.java | 6 + .../triumphteam/gui/element/GuiElement.java | 4 + .../java/dev/triumphteam/gui/value/Value.java | 4 + fabric/build.gradle.kts | 19 - gradle/libs.versions.toml | 32 ++ gradle/wrapper/gradle-wrapper.properties | 2 +- kotlin/build.gradle.kts | 19 - old-core/build.gradle.kts | 107 ++++++ .../gui/builder/gui/BaseGuiBuilder.java | 0 .../gui/builder/gui/PaginatedBuilder.java | 0 .../gui/builder/gui/ScrollingBuilder.java | 0 .../gui/builder/gui/SimpleBuilder.java | 0 .../gui/builder/gui/StorageBuilder.java | 0 .../gui/builder/item/BannerBuilder.java | 0 .../gui/builder/item/BaseItemBuilder.java | 0 .../gui/builder/item/BookBuilder.java | 0 .../gui/builder/item/FireworkBuilder.java | 0 .../gui/builder/item/ItemBuilder.java | 0 .../gui/builder/item/MapBuilder.java | 0 .../gui/builder/item/SkullBuilder.java | 0 .../triumphteam/gui/components/GuiAction.java | 0 .../triumphteam/gui/components/GuiPage.java | 0 .../triumphteam/gui/components/GuiType.java | 0 .../gui/components/InteractionModifier.java | 0 .../gui/components/ScrollType.java | 0 .../gui/components/Serializable.java | 0 .../components/exception/GuiException.java | 0 .../gui/components/nbt/LegacyNbt.java | 0 .../gui/components/nbt/NbtWrapper.java | 0 .../triumphteam/gui/components/nbt/Pdc.java | 0 .../gui/components/util/GuiFiller.java | 0 .../gui/components/util/ItemNbt.java | 0 .../gui/components/util/Legacy.java | 0 .../gui/components/util/SkullUtil.java | 0 .../gui/components/util/VersionHelper.java | 0 .../dev/triumphteam/gui/guis/BaseGui.java | 0 .../java/dev/triumphteam/gui/guis/Gui.java | 0 .../dev/triumphteam/gui/guis/GuiItem.java | 0 .../dev/triumphteam/gui/guis/GuiListener.java | 0 .../gui/guis/InteractionModifierListener.java | 0 .../triumphteam/gui/guis/PaginatedGui.java | 0 .../gui/guis/PersistentPaginatedGui.java | 357 ++++++++++++++++++ .../triumphteam/gui/guis/ScrollingGui.java | 0 .../dev/triumphteam/gui/guis/StorageGui.java | 0 settings.gradle.kts | 27 +- 52 files changed, 623 insertions(+), 193 deletions(-) create mode 100644 build-logic/build.gradle.kts create mode 100644 build-logic/settings.gradle.kts create mode 100644 build-logic/src/main/kotlin/gui.base.gradle.kts create mode 100644 build-logic/src/main/kotlin/gui.parent.gradle.kts create mode 100644 bukkit/build.gradle.kts create mode 100644 core/src/main/java/dev/triumphteam/gui/Gui.java create mode 100644 core/src/main/java/dev/triumphteam/gui/element/GuiElement.java create mode 100644 core/src/main/java/dev/triumphteam/gui/value/Value.java delete mode 100644 fabric/build.gradle.kts create mode 100644 gradle/libs.versions.toml delete mode 100644 kotlin/build.gradle.kts create mode 100644 old-core/build.gradle.kts rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/GuiAction.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/GuiPage.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/GuiType.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/ScrollType.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/Serializable.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/util/Legacy.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/guis/BaseGui.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/guis/Gui.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/guis/GuiItem.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/guis/GuiListener.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java (100%) create mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/PersistentPaginatedGui.java rename {core => old-core}/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java (100%) rename {core => old-core}/src/main/java/dev/triumphteam/gui/guis/StorageGui.java (100%) diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts new file mode 100644 index 00000000..8999fb75 --- /dev/null +++ b/build-logic/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + `kotlin-dsl` +} + +dependencies { + // Hack to allow version catalog inside convention plugins + implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location)) + + // Bundled plugins + implementation(libs.bundles.build) +} diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 00000000..d6c5922e --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,15 @@ +rootProject.name = "build-logic" + +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + gradlePluginPortal() + mavenCentral() + } + + versionCatalogs { + register("libs") { + from(files("../gradle/libs.versions.toml")) // include from parent project + } + } +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/gui.base.gradle.kts b/build-logic/src/main/kotlin/gui.base.gradle.kts new file mode 100644 index 00000000..049402f0 --- /dev/null +++ b/build-logic/src/main/kotlin/gui.base.gradle.kts @@ -0,0 +1,45 @@ +import org.gradle.accessors.dm.LibrariesForLibs + +// Hack which exposes `libs` to this convention plugin +val libs = the() + +plugins { + `java-library` + kotlin("jvm") + id("com.github.hierynomus.license") +} + +repositories { + mavenCentral() +} + +dependencies { + compileOnlyApi(libs.annotations) +} + + +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + withSourcesJar() + withJavadocJar() +} + +kotlin { + explicitApi() +} + +license { + header = rootProject.file("LICENSE") + encoding = "UTF-8" + useDefaultMappings = true + + include("**/*.kt") + include("**/*.java") +} + +tasks { + withType { + options.encoding = "UTF-8" + options.compilerArgs.add("-parameters") + } +} diff --git a/build-logic/src/main/kotlin/gui.parent.gradle.kts b/build-logic/src/main/kotlin/gui.parent.gradle.kts new file mode 100644 index 00000000..a8b3fb23 --- /dev/null +++ b/build-logic/src/main/kotlin/gui.parent.gradle.kts @@ -0,0 +1,4 @@ +plugins { + `java-library` + kotlin("jvm") +} diff --git a/build.gradle.kts b/build.gradle.kts index 0db7c0b3..8627a0b9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,49 +1,3 @@ plugins { - id("java-library") - id("com.github.hierynomus.license") version "0.16.1" -} - -allprojects { - repositories { - mavenLocal() - mavenCentral() - maven("https://repo.papermc.io/repository/maven-public/") - } -} - -subprojects { - - apply { - plugin("java-library") - plugin("com.github.hierynomus.license") - } - - group = "dev.triumphteam" - version = "3.1.7" - - dependencies { - compileOnly("org.jetbrains:annotations:21.0.1") - compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") - - val adventureVersion = "4.14.0" - api("net.kyori:adventure-api:$adventureVersion") - api("net.kyori:adventure-text-serializer-legacy:$adventureVersion") - api("net.kyori:adventure-text-serializer-gson:$adventureVersion") - } - - license { - header = rootProject.file("LICENSE") - encoding = "UTF-8" - mapping("java", "JAVADOC_STYLE") - include("**/*.java") - } - - tasks { - withType { - sourceCompatibility = "1.8" - targetCompatibility = "1.8" - options.encoding = "UTF-8" - } - } - + id("gui.parent") } diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts new file mode 100644 index 00000000..57b1dfd9 --- /dev/null +++ b/bukkit/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("gui.base") +} + +repositories { + maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") +} + +dependencies { + api(projects.triumphGuiCore) + api(libs.spigot) +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index e2c57f88..7314ccac 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,106 +1,8 @@ plugins { - `maven-publish` - signing + id("gui.base") } repositories { - mavenCentral() - maven("https://libraries.minecraft.net/") -} - -dependencies { - compileOnly("com.mojang:authlib:1.5.25") -} - -val javaComponent: SoftwareComponent = components["java"] - -tasks { - - val sourcesJar by creating(Jar::class) { - archiveClassifier.set("sources") - from(sourceSets.main.get().allSource) - } - - val javadocJar by creating(Jar::class) { - dependsOn.add(javadoc) - archiveClassifier.set("javadoc") - from(javadoc) - } - - publishing { - publications { - create("maven") { - from(javaComponent) - artifact(sourcesJar) - artifact(javadocJar) - versionMapping { - usage("java-api") { - fromResolutionOf("runtimeClasspath") - } - usage("java-runtime") { - fromResolutionResult() - } - } - pom { - name.set("Triumph GUI") - description.set("Library for easy creation of GUIs for Bukkit plugins.") - url.set("https://github.com/TriumphTeam/triumph-gui") - - licenses { - license { - name.set("MIT License") - url.set("http://www.opensource.org/licenses/mit-license.php") - } - } - - developers { - developer { - id.set("matt") - name.set("Mateus Moreira") - organization.set("TriumphTeam") - organizationUrl.set("https://github.com/TriumphTeam") - } - } - - scm { - connection.set("scm:git:git://github.com/TriumphTeam/triumph-gui.git") - developerConnection.set("scm:git:ssh://github.com:TriumphTeam/triumph-gui.git") - url.set("https://github.com/TriumphTeam/triumph-gui") - } - } - } - } - - repositories { - maven { - if (version.toString().contains("SNAPSHOT")) { - credentials { - username = System.getenv("REPO_USER") - password = System.getenv("REPO_PASS") - } - - url = uri("https://repo.mattstudios.me/artifactory/public-snapshot/") - return@maven - } - - credentials { - username = System.getenv("SONATYPE_USER") - password = System.getenv("SONATYPE_PASSWORD") - } - - url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") - } - } - - } - - signing { - /*useGpgCmd() - val signingKey = System.getenv("GPG_KEY") - val signingPassword = System.getenv("GPG_PASS") - val secretKey = System.getenv("GPG_SECRET_KEY") - useInMemoryPgpKeys(signingKey, secretKey, signingPassword)*/ - sign(publishing.publications["maven"]) - } - + maven("https://papermc.io/repo/repository/maven-public/") + maven("https://repo.triumphteam.dev/snapshots/") } diff --git a/core/src/main/java/dev/triumphteam/gui/Gui.java b/core/src/main/java/dev/triumphteam/gui/Gui.java new file mode 100644 index 00000000..52804f4f --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/Gui.java @@ -0,0 +1,6 @@ +package dev.triumphteam.gui; + +public interface Gui

{ + + +} diff --git a/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java b/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java new file mode 100644 index 00000000..22d01647 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java @@ -0,0 +1,4 @@ +package dev.triumphteam.gui.element; + +public interface GuiElement { +} diff --git a/core/src/main/java/dev/triumphteam/gui/value/Value.java b/core/src/main/java/dev/triumphteam/gui/value/Value.java new file mode 100644 index 00000000..895437e1 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/value/Value.java @@ -0,0 +1,4 @@ +package dev.triumphteam.gui.value; + +public interface Value { +} diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts deleted file mode 100644 index 1ef76787..00000000 --- a/fabric/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -plugins { - kotlin("jvm") version "1.4.32" -} - -dependencies { - implementation(project(":triumph-gui")) - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") -} - -tasks { - withType { - kotlinOptions { - jvmTarget = "1.8" - javaParameters = true - } - } -} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..f1534ab8 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,32 @@ +[versions] +# kotlin +kotlin = "1.8.10" +coroutines = "1.6.4" + +license = "0.16.1" + +# Core +annotations = "23.0.0" + +# Minecraft +spigot = "1.18.2-R0.1-SNAPSHOT" + +[libraries] +# Core +annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" } + +# Minecraft +spigot = { module = "org.spigotmc:spigot-api", version.ref = "spigot" } + +# Kotlin +coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } + +# build +build-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +build-license = { module = "gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin", version.ref = "license" } + +[bundles] +build = [ + "build-kotlin", + "build-license", +] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e411586a..e1bef7e8 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-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kotlin/build.gradle.kts b/kotlin/build.gradle.kts deleted file mode 100644 index 692f0a39..00000000 --- a/kotlin/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -plugins { - kotlin("jvm") version "1.9.10" -} - -dependencies { - implementation(project(":triumph-gui")) - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") -} - -tasks { - withType { - kotlinOptions { - jvmTarget = "1.8" - javaParameters = true - } - } -} diff --git a/old-core/build.gradle.kts b/old-core/build.gradle.kts new file mode 100644 index 00000000..7d83eddd --- /dev/null +++ b/old-core/build.gradle.kts @@ -0,0 +1,107 @@ +plugins { + `maven-publish` + signing +} + +repositories { + mavenCentral() + maven("https://repo.mattstudios.me/artifactory/public/") + maven("https://libraries.minecraft.net/") +} + +dependencies { + compileOnly("com.mojang:authlib:1.5.21") +} + +val javaComponent: SoftwareComponent = components["java"] + +tasks { + + val sourcesJar by creating(Jar::class) { + archiveClassifier.set("sources") + from(sourceSets.main.get().allSource) + } + + val javadocJar by creating(Jar::class) { + dependsOn.add(javadoc) + archiveClassifier.set("javadoc") + from(javadoc) + } + + publishing { + publications { + create("maven") { + from(javaComponent) + artifact(sourcesJar) + artifact(javadocJar) + versionMapping { + usage("java-api") { + fromResolutionOf("runtimeClasspath") + } + usage("java-runtime") { + fromResolutionResult() + } + } + pom { + name.set("Triumph GUI") + description.set("Library for easy creation of GUIs for Bukkit plugins.") + url.set("https://github.com/TriumphTeam/triumph-gui") + + licenses { + license { + name.set("MIT License") + url.set("http://www.opensource.org/licenses/mit-license.php") + } + } + + developers { + developer { + id.set("matt") + name.set("Mateus Moreira") + organization.set("TriumphTeam") + organizationUrl.set("https://github.com/TriumphTeam") + } + } + + scm { + connection.set("scm:git:git://github.com/TriumphTeam/triumph-gui.git") + developerConnection.set("scm:git:ssh://github.com:TriumphTeam/triumph-gui.git") + url.set("https://github.com/TriumphTeam/triumph-gui") + } + } + } + } + + repositories { + maven { + if (version.toString().contains("SNAPSHOT")) { + credentials { + username = System.getenv("REPO_USER") + password = System.getenv("REPO_PASS") + } + + url = uri("https://repo.triumphteam.dev/snapshots/") + return@maven + } + + credentials { + username = System.getenv("SONATYPE_USER") + password = System.getenv("SONATYPE_PASSWORD") + } + + url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") + } + } + + } + + signing { + /*useGpgCmd() + val signingKey = System.getenv("GPG_KEY") + val signingPassword = System.getenv("GPG_PASS") + val secretKey = System.getenv("GPG_SECRET_KEY") + useInMemoryPgpKeys(signingKey, secretKey, signingPassword)*/ + sign(publishing.publications["maven"]) + } + +} diff --git a/core/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java rename to old-core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/GuiAction.java b/old-core/src/main/java/dev/triumphteam/gui/components/GuiAction.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/GuiAction.java rename to old-core/src/main/java/dev/triumphteam/gui/components/GuiAction.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/GuiPage.java b/old-core/src/main/java/dev/triumphteam/gui/components/GuiPage.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/GuiPage.java rename to old-core/src/main/java/dev/triumphteam/gui/components/GuiPage.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/GuiType.java b/old-core/src/main/java/dev/triumphteam/gui/components/GuiType.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/GuiType.java rename to old-core/src/main/java/dev/triumphteam/gui/components/GuiType.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java b/old-core/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java rename to old-core/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/ScrollType.java b/old-core/src/main/java/dev/triumphteam/gui/components/ScrollType.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/ScrollType.java rename to old-core/src/main/java/dev/triumphteam/gui/components/ScrollType.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/Serializable.java b/old-core/src/main/java/dev/triumphteam/gui/components/Serializable.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/Serializable.java rename to old-core/src/main/java/dev/triumphteam/gui/components/Serializable.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java b/old-core/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java rename to old-core/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java b/old-core/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java rename to old-core/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java b/old-core/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java rename to old-core/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java b/old-core/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java rename to old-core/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java rename to old-core/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java rename to old-core/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/util/Legacy.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/Legacy.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/util/Legacy.java rename to old-core/src/main/java/dev/triumphteam/gui/components/util/Legacy.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java rename to old-core/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java diff --git a/core/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java rename to old-core/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java diff --git a/core/src/main/java/dev/triumphteam/gui/guis/BaseGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/BaseGui.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/guis/BaseGui.java rename to old-core/src/main/java/dev/triumphteam/gui/guis/BaseGui.java diff --git a/core/src/main/java/dev/triumphteam/gui/guis/Gui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/Gui.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/guis/Gui.java rename to old-core/src/main/java/dev/triumphteam/gui/guis/Gui.java diff --git a/core/src/main/java/dev/triumphteam/gui/guis/GuiItem.java b/old-core/src/main/java/dev/triumphteam/gui/guis/GuiItem.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/guis/GuiItem.java rename to old-core/src/main/java/dev/triumphteam/gui/guis/GuiItem.java diff --git a/core/src/main/java/dev/triumphteam/gui/guis/GuiListener.java b/old-core/src/main/java/dev/triumphteam/gui/guis/GuiListener.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/guis/GuiListener.java rename to old-core/src/main/java/dev/triumphteam/gui/guis/GuiListener.java diff --git a/core/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java b/old-core/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java rename to old-core/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java diff --git a/core/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java rename to old-core/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/PersistentPaginatedGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/PersistentPaginatedGui.java new file mode 100644 index 00000000..e207b6a1 --- /dev/null +++ b/old-core/src/main/java/dev/triumphteam/gui/guis/PersistentPaginatedGui.java @@ -0,0 +1,357 @@ +/** + * MIT License + * + * Copyright (c) 2021 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package dev.triumphteam.gui.guis; + +import dev.triumphteam.gui.components.Serializable; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * GUI that does not clear it's items once it's closed + */ +@SuppressWarnings("unused") +class PersistentPaginatedGui extends PaginatedGui implements Serializable { + + // Contains all the pages + private final List pages = new ArrayList<>(); + + // Used for page serialization + private final YamlConfiguration yamlConfiguration = new YamlConfiguration(); + + /** + * Main constructor of the Persistent GUI + * + * @param rows The rows the GUI should have + * @param pageSize The pageSize + * @param title The GUI's title + * @param pages How many pages will be used + */ + public PersistentPaginatedGui(final int rows, final int pageSize, @NotNull final String title, final int pages) { + super(rows, pageSize, title); + + if (pages <= 0) { + this.pages.add(new Page()); + return; + } + + for (int i = 0; i < pages; i++) { + this.pages.add(new Page()); + } + + } + + /** + * Alternative constructor with only title + * + * @param title The GUI's title + */ + public PersistentPaginatedGui(@NotNull final String title) { + this(1, title); + } + + /** + * Alternative constructor with only rows and title + * + * @param rows The rows the GUI should have + * @param title The GUI's title + */ + public PersistentPaginatedGui(final int rows, @NotNull final String title) { + this(rows, 0, title, 1); + } + + /** + * Alternative constructor with only title and pages + * + * @param title The GUI's title + * @param pages How many pages will be used + */ + public PersistentPaginatedGui(@NotNull final String title, final int pages) { + this(1, 0, title, pages); + } + + /** + * Alternative constructor with only rows, title and pages + * + * @param rows The rows the GUI should have + * @param title The GUI's title + * @param pages How many pages will be used + */ + public PersistentPaginatedGui(final int rows, @NotNull final String title, final int pages) { + this(rows, 0, title, pages); + } + + /** + * Adds {@link ItemStack} to the inventory straight, not the GUI + * + * @param items Varargs with {@link ItemStack}s + * @return An immutable {@link Map} with the left overs + */ + @NotNull + public Map<@NotNull Integer, @NotNull ItemStack> addItem(@NotNull final ItemStack... items) { + return addItem(1, items); + } + + /** + * Adds {@link ItemStack} to the inventory straight, not the GUI + * + * @param page To which page it should be added + * @param items Varargs with {@link ItemStack}s + * @return An immutable {@link Map} with the left overs + */ + @NotNull + public Map<@NotNull Integer, @NotNull ItemStack> addItem(final int page, @NotNull final ItemStack... items) { + int finalPage = page; + if (page <= 0 || page > pages.size()) finalPage = 1; + + return Collections.unmodifiableMap(getInventory().addItem(items)); + } + + /** + * Overrides {@link BaseGui#open(HumanEntity)} to use the paginated populator instead + * + * @param player The {@link HumanEntity} to open the GUI to + */ + @Override + public void open(@NotNull final HumanEntity player) { + open(player, 1); + } + + /** + * Specific open method for the Paginated GUI + * + * @param player The {@link HumanEntity} to open it to + * @param openPage The specific page to open at + */ + public void open(@NotNull final HumanEntity player, final int openPage) { + if (player.isSleeping()) return; + + if (openPage < pages.size() || openPage > 0) setPageNum(openPage - 1); + getInventory().clear(); + + populateGui(); + + if (getPageSize() == 0) setPageSize(calculatePageSize()); + + pages.get(getPageNum()).populatePage(getInventory()); + + player.openInventory(getInventory()); + } + + /** + * Goes to the next page if possible + */ + public boolean next() { + if (getPageNum() + 1 >= pages.size()) return false; + + savePage(); + + setPageNum(getPageNum() + 1); + updatePage(); + return true; + } + + /** + * Goes to the previous page if possible + */ + public boolean previous() { + if (getPageNum() - 1 < 0) return false; + + savePage(); + + setPageNum(getPageNum() - 1); + updatePage(); + return true; + } + + /** + * Gets the current page number + * + * @return The current page number + */ + @Override + public int getCurrentPageNum() { + return getPageNum() + 1; + } + + /** + * Updates the page content + */ + @Override + void updatePage() { + clearPage(); + populatePage(); + } + + /** + * Clears the current page + */ + @Override + void clearPage() { + for (int i = 0; i < getInventory().getSize(); i++) { + final ItemStack itemStack = getInventory().getItem(i); + if (itemStack == null) continue; + if (getGuiItems().get(i) != null) continue; + + getInventory().setItem(i, null); + } + } + + /** + * Saves the current page, used by the {@link GuiListener} + */ + void savePage() { + pages.get(getPageNum()).savePage(getInventory(), getGuiItems()); + } + + /** + * Populates the inventory with the page items + */ + private void populatePage() { + // Adds the paginated items to the page + pages.get(getPageNum()).populatePage(getInventory()); + } + + /** + * Encodes the GUI into a list of strings, each string representing a page + * + * @return A {@link List} of page items encoded into a string + */ + @NotNull + @Override + public List encodeGui() { + final int inventorySize = getInventory().getSize(); + final List pageItems = new ArrayList<>(); + + for (final Page page : pages) { + yamlConfiguration.set("inventory", page.getContent(inventorySize)); + //pageItems.add(Base64.encodeBase64String(yamlConfiguration.saveToString().getBytes())); + } + + return pageItems; + } + + /** + * Decodes the {@link List} of strings into a usable inventory + * + * @param encodedItem The {@link List} to decode + */ + @Override + public void decodeGui(@NotNull final List encodedItem) { + for (int i = 0; i < pages.size(); i++) { + final Page page = pages.get(i); + //yamlConfiguration.loadFromString(new String(Base64.decodeBase64(encodedItem.get(i)))); + //noinspection unchecked + final List content = (List) yamlConfiguration.get("inventory"); + if (content == null) continue; + page.loadPageContent(content, getInventory().getSize()); + } + } + + /** + * Private class for holding all the page interactions + */ + private static class Page { + + // Map that contains all the page items and their slot + private final Map pageItems = new LinkedHashMap<>(); + + /** + * Adds all the items from the page to the {@link Inventory} + * + * @param inventory The given {@link Inventory} to use + */ + private void populatePage(@NotNull final Inventory inventory) { + // Adds the paginated items to the page + for (Map.Entry entry : pageItems.entrySet()) { + inventory.setItem(entry.getKey(), entry.getValue()); + } + } + + /** + * Saves the current page and any modifications that was done to it + * + * @param inventory The given {@link Inventory} to use + * @param guiItems The gui items map just to check if the current item is or not a gui item, to not add it + */ + private void savePage(@NotNull final Inventory inventory, @NotNull Map guiItems) { + for (int i = 0; i < inventory.getSize(); i++) { + final ItemStack itemStack = inventory.getItem(i); + + // Removes the item if it was removed + if (itemStack == null) { + pageItems.remove(i); + continue; + } + + // Skips gui items + if (guiItems.get(i) != null) continue; + + pageItems.put(i, itemStack); + } + } + + /** + * Turns the map into an array of {@link ItemStack} so it can be serialized + * + * @param inventorySize The inventory size + * @return An array of {@link ItemStack} + */ + @NotNull + private ItemStack[] getContent(final int inventorySize) { + final ItemStack[] content = new ItemStack[inventorySize]; + for (int i = 0; i < inventorySize; i++) { + content[i] = pageItems.get(i); + } + return content; + } + + /** + * Loads the list of items into the page + * + * @param items The list of {@link ItemStack} + * @param inventorySize The inventory size + */ + private void loadPageContent(@NotNull final List items, final int inventorySize) { + // Cleans the page to avoid problems + pageItems.clear(); + for (int i = 0; i < inventorySize; i++) { + final ItemStack item = items.get(i); + if (item == null) continue; + + pageItems.put(i, item); + } + } + + } + +} diff --git a/core/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java rename to old-core/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java diff --git a/core/src/main/java/dev/triumphteam/gui/guis/StorageGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/StorageGui.java similarity index 100% rename from core/src/main/java/dev/triumphteam/gui/guis/StorageGui.java rename to old-core/src/main/java/dev/triumphteam/gui/guis/StorageGui.java diff --git a/settings.gradle.kts b/settings.gradle.kts index f4b738d8..b450db03 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,9 +1,24 @@ +dependencyResolutionManagement { + includeBuild("build-logic") + repositories.gradlePluginPortal() +} + +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + rootProject.name = "triumph-gui" -include("core") -findProject(":core")?.name = "triumph-gui" +listOf("core", "bukkit").forEach(::includeProject) + +fun includeProject(name: String) { + include(name) { + this.name = "${rootProject.name}-$name" + } +} + +fun include(name: String, block: ProjectDescriptor.() -> Unit) { + include(name) + project(":$name").apply(block) +} -listOf("kotlin").forEach { - include(it) - findProject(":$it")?.name = "triumph-gui-$it" -} \ No newline at end of file +//include("fabric-test") +// include("test-plugin") From 265d5546d8280763d425976eb0a017cdb342e4e8 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 14 Apr 2024 17:09:29 +0100 Subject: [PATCH 02/43] feature: API design proposal --- .../java/dev/triumphteam/gui/bukkit/Gui.java | 27 +++++++++ .../dev/triumphteam/gui/bukkit/GuiView.java | 48 ++++++++++++++++ .../gui/bukkit/builder/GuiBuilder.java | 14 +++++ .../java/dev/triumphteam/gui/BaseGui.java | 9 +++ .../java/dev/triumphteam/gui/BaseGuiView.java | 55 +++++++++++++++++++ .../main/java/dev/triumphteam/gui/Gui.java | 6 -- .../gui/builder/BaseGuiBuilder.java | 28 ++++++++++ .../gui/component/FinalComponent.java | 9 +++ .../gui/component/GuiComponent.java | 15 +++++ .../gui/component/GuiComponentProcessor.java | 6 ++ .../gui/component/GuiComponentRenderer.java | 14 +++++ .../component/SimpleGuiComponentRenderer.java | 42 ++++++++++++++ .../triumphteam/gui/container/Container.java | 17 ++++++ .../gui/exception/GuiException.java | 10 ++++ .../java/dev/triumphteam/gui/slot/Slot.java | 8 +++ .../triumphteam/gui/state/SimpleState.java | 35 ++++++++++++ .../java/dev/triumphteam/gui/state/State.java | 18 ++++++ .../dev/triumphteam/gui/state/StateMap.java | 20 +++++++ .../java/dev/triumphteam/gui/value/Value.java | 4 -- settings.gradle.kts | 2 +- 20 files changed, 376 insertions(+), 11 deletions(-) create mode 100644 bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java create mode 100644 bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java create mode 100644 bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java create mode 100644 core/src/main/java/dev/triumphteam/gui/BaseGui.java create mode 100644 core/src/main/java/dev/triumphteam/gui/BaseGuiView.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/Gui.java create mode 100644 core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/GuiComponentProcessor.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/GuiComponentRenderer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponentRenderer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/container/Container.java create mode 100644 core/src/main/java/dev/triumphteam/gui/exception/GuiException.java create mode 100644 core/src/main/java/dev/triumphteam/gui/slot/Slot.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/SimpleState.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/State.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/StateMap.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/value/Value.java diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java new file mode 100644 index 00000000..7994edfc --- /dev/null +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java @@ -0,0 +1,27 @@ +package dev.triumphteam.gui.bukkit; + +import dev.triumphteam.gui.BaseGui; +import dev.triumphteam.gui.component.SimpleGuiComponentRenderer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public final class Gui implements BaseGui { + + private final List> componentRenderers; + + public Gui( + final @NotNull List> componentRenderers + ) { + this.componentRenderers = componentRenderers; + } + + @Override + public @NotNull GuiView open(final @NotNull Player player, final @Nullable GuiView parent) { + final var view = new GuiView(player, parent); + view.open(); + return view; + } +} diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java new file mode 100644 index 00000000..caddae57 --- /dev/null +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java @@ -0,0 +1,48 @@ +package dev.triumphteam.gui.bukkit; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.component.FinalComponent; +import dev.triumphteam.gui.container.Container; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public final class GuiView extends BaseGuiView implements InventoryHolder { + + private final Inventory inventory; + + public GuiView( + final @NotNull Player player, + final @Nullable GuiView parent, + final @NotNull List> componentRenderers + ) { + super(player, parent, componentRenderers); + this.inventory = Bukkit.createInventory(this, 6, "Gui"); + } + + @Override + public void open() { + getViewer().openInventory(inventory); + } + + @Override + public void close() { + + } + + @NotNull + @Override + public Inventory getInventory() { + return inventory; + } + + @Override + protected void populateInventory(final @NotNull Container container) { + inventory.addItem() + } +} diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java new file mode 100644 index 00000000..c321bf7d --- /dev/null +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java @@ -0,0 +1,14 @@ +package dev.triumphteam.gui.bukkit.builder; + +import dev.triumphteam.gui.builder.BaseGuiBuilder; +import dev.triumphteam.gui.bukkit.Gui; +import dev.triumphteam.gui.bukkit.GuiView; +import org.bukkit.entity.Player; + +public final class GuiBuilder extends BaseGuiBuilder { + + @Override + public Gui build() { + return new Gui(componentRenderers); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGui.java b/core/src/main/java/dev/triumphteam/gui/BaseGui.java new file mode 100644 index 00000000..a8e20035 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/BaseGui.java @@ -0,0 +1,9 @@ +package dev.triumphteam.gui; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface BaseGui> { + + @NotNull V open(final @NotNull P player, final @Nullable V parent); +} diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java b/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java new file mode 100644 index 00000000..073f6251 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java @@ -0,0 +1,55 @@ +package dev.triumphteam.gui; + +import dev.triumphteam.gui.component.FinalComponent; +import dev.triumphteam.gui.container.Container; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public abstract class BaseGuiView> { + + private final P viewer; + private final V parent; + private final List> components; + + public BaseGuiView( + final @NotNull P viewer, + final V parent, + final List> components + ) { + this.viewer = viewer; + this.parent = parent; + this.components = components; + } + + public @NotNull P getViewer() { + return viewer; + } + + public @Nullable V getParent() { + return parent; + } + + public abstract void open(); + + public abstract void close(); + + protected void setup() { + components.forEach(renderer -> { + renderer.states().forEach(state -> { + state.addListener(this, () -> { + renderComponent(renderer); + }); + }); + }); + } + + private void renderComponent(final @NotNull FinalComponent component) { + final var container = new Container(); + //noinspection unchecked + component.component().render(container, viewer, (V) this); + } + + protected abstract void populateInventory(final @NotNull Container container); +} diff --git a/core/src/main/java/dev/triumphteam/gui/Gui.java b/core/src/main/java/dev/triumphteam/gui/Gui.java deleted file mode 100644 index 52804f4f..00000000 --- a/core/src/main/java/dev/triumphteam/gui/Gui.java +++ /dev/null @@ -1,6 +0,0 @@ -package dev.triumphteam.gui; - -public interface Gui

{ - - -} diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java new file mode 100644 index 00000000..df3d362d --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -0,0 +1,28 @@ +package dev.triumphteam.gui.builder; + +import dev.triumphteam.gui.BaseGui; +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.component.GuiComponentRenderer; +import dev.triumphteam.gui.component.SimpleGuiComponentRenderer; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +@SuppressWarnings({"unchecked", "UnusedReturnValue"}) +public abstract class BaseGuiBuilder, P, G extends BaseGui, V extends BaseGuiView> { + + protected final List> componentRenderers = new ArrayList<>(); + + @Contract("_ -> this") + public @NotNull B component(final @NotNull Consumer<@NotNull GuiComponentRenderer<@NotNull P, @NotNull V>> renderer) { + final var componentRenderer = new SimpleGuiComponentRenderer(); + renderer.accept(componentRenderer); + componentRenderers.add(componentRenderer); + return (B) this; + } + + public abstract G build(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java b/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java new file mode 100644 index 00000000..5cee0c7b --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java @@ -0,0 +1,9 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.state.State; + +import java.util.List; + +public record FinalComponent>(List> states, GuiComponent component) { +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java new file mode 100644 index 00000000..094666d3 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java @@ -0,0 +1,15 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.container.Container; +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface GuiComponent> { + + void render( + final @NotNull Container container, + final @NotNull P player, + final @NotNull V view + ); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProcessor.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProcessor.java new file mode 100644 index 00000000..6a160e31 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProcessor.java @@ -0,0 +1,6 @@ +package dev.triumphteam.gui.component; + +public interface GuiComponentProcessor { + + // void render(final @NotNull GuiComponentRenderer

component, final @NotNull I inventory); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRenderer.java new file mode 100644 index 00000000..dab301e4 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRenderer.java @@ -0,0 +1,14 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.state.State; +import org.jetbrains.annotations.NotNull; + +public interface GuiComponentRenderer> { + + State state(final int value); + + State state(final @NotNull State state); + + void render(final @NotNull GuiComponent component); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponentRenderer.java new file mode 100644 index 00000000..b87bd4de --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponentRenderer.java @@ -0,0 +1,42 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.exception.GuiException; +import dev.triumphteam.gui.state.SimpleState; +import dev.triumphteam.gui.state.State; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public final class SimpleGuiComponentRenderer> implements GuiComponentRenderer { + + private final List> states = new ArrayList<>(); + private GuiComponent component = null; + + @Override + public State state(final int value) { + final var state = new SimpleState<>(value); + states.add(state); + return state; + } + + @Override + public State state(final @NotNull State state) { + states.add(state); + return state; + } + + @Override + public void render(final @NotNull GuiComponent component) { + this.component = component; + } + + public @NotNull FinalComponent createComponent() { + if (component == null) { + throw new GuiException("TODO"); + } + + return new FinalComponent<>(states, component); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/container/Container.java b/core/src/main/java/dev/triumphteam/gui/container/Container.java new file mode 100644 index 00000000..fc0751b2 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/container/Container.java @@ -0,0 +1,17 @@ +package dev.triumphteam.gui.container; + +import dev.triumphteam.gui.element.GuiElement; +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +public final class Container { + + private final Map backing = new HashMap<>(100); + + public void set(final @NotNull Slot slot, final @NotNull GuiElement guiElement) { + backing.put(slot, guiElement); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/exception/GuiException.java b/core/src/main/java/dev/triumphteam/gui/exception/GuiException.java new file mode 100644 index 00000000..f3bc47fe --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/exception/GuiException.java @@ -0,0 +1,10 @@ +package dev.triumphteam.gui.exception; + +import org.jetbrains.annotations.NotNull; + +public final class GuiException extends RuntimeException { + + public GuiException(final @NotNull String message) { + super(message); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java new file mode 100644 index 00000000..9df0d685 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java @@ -0,0 +1,8 @@ +package dev.triumphteam.gui.slot; + +public record Slot(int row, int col) { + + public int asRealSlot() { + return 0; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java b/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java new file mode 100644 index 00000000..67951573 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java @@ -0,0 +1,35 @@ +package dev.triumphteam.gui.state; + +import dev.triumphteam.gui.BaseGuiView; +import org.jetbrains.annotations.NotNull; + +public final class SimpleState implements State { + + private final StateMap stateMap = new StateMap(); + private T value; + + public SimpleState(final T value) { + this.value = value; + } + + @Override + public T getValue() { + return value; + } + + @Override + public void setValue(final T value) { + this.value = value; + force(); + } + + @Override + public void force() { + stateMap.run(); + } + + @Override + public void addListener(final @NotNull BaseGuiView view, final @NotNull Runnable runnable) { + stateMap.put(view, runnable); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/State.java b/core/src/main/java/dev/triumphteam/gui/state/State.java new file mode 100644 index 00000000..32f5ec98 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/State.java @@ -0,0 +1,18 @@ +package dev.triumphteam.gui.state; + +import dev.triumphteam.gui.BaseGuiView; +import org.jetbrains.annotations.NotNull; + +public interface State { + + T getValue(); + + void setValue(final T value); + + void force(); + + void addListener( + final @NotNull BaseGuiView view, + final @NotNull Runnable runnable + ); +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/StateMap.java b/core/src/main/java/dev/triumphteam/gui/state/StateMap.java new file mode 100644 index 00000000..24b9428b --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/StateMap.java @@ -0,0 +1,20 @@ +package dev.triumphteam.gui.state; + +import dev.triumphteam.gui.BaseGuiView; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; +import java.util.WeakHashMap; + +public final class StateMap { + + private final Map, Runnable> backing = new WeakHashMap<>(); + + public void put(final @NotNull BaseGuiView view, final @NotNull Runnable runnable) { + backing.put(view, runnable); + } + + public void run() { + backing.forEach((inventoryInterface, runnable) -> runnable.run()); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/value/Value.java b/core/src/main/java/dev/triumphteam/gui/value/Value.java deleted file mode 100644 index 895437e1..00000000 --- a/core/src/main/java/dev/triumphteam/gui/value/Value.java +++ /dev/null @@ -1,4 +0,0 @@ -package dev.triumphteam.gui.value; - -public interface Value { -} diff --git a/settings.gradle.kts b/settings.gradle.kts index b450db03..60c97c5c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,4 +21,4 @@ fun include(name: String, block: ProjectDescriptor.() -> Unit) { } //include("fabric-test") -// include("test-plugin") +include("test-plugin") From fd01d5c9ee1f33cd60fd1ae5ba0b26e0ae68939c Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 14 Apr 2024 17:11:17 +0100 Subject: [PATCH 03/43] chore: Yeet old code --- old-core/build.gradle.kts | 107 -- .../gui/builder/gui/BaseGuiBuilder.java | 315 ----- .../gui/builder/gui/PaginatedBuilder.java | 70 -- .../gui/builder/gui/ScrollingBuilder.java | 96 -- .../gui/builder/gui/SimpleBuilder.java | 87 -- .../gui/builder/gui/StorageBuilder.java | 55 - .../gui/builder/item/BannerBuilder.java | 197 ---- .../gui/builder/item/BaseItemBuilder.java | 709 ----------- .../gui/builder/item/BookBuilder.java | 181 --- .../gui/builder/item/FireworkBuilder.java | 124 -- .../gui/builder/item/ItemBuilder.java | 268 ----- .../gui/builder/item/MapBuilder.java | 133 --- .../gui/builder/item/SkullBuilder.java | 168 --- .../triumphteam/gui/components/GuiAction.java | 38 - .../triumphteam/gui/components/GuiPage.java | 27 - .../triumphteam/gui/components/GuiType.java | 56 - .../gui/components/InteractionModifier.java | 44 - .../gui/components/ScrollType.java | 36 - .../gui/components/Serializable.java | 36 - .../components/exception/GuiException.java | 30 - .../gui/components/nbt/LegacyNbt.java | 313 ----- .../gui/components/nbt/NbtWrapper.java | 72 -- .../triumphteam/gui/components/nbt/Pdc.java | 112 -- .../gui/components/util/GuiFiller.java | 247 ---- .../gui/components/util/ItemNbt.java | 97 -- .../gui/components/util/Legacy.java | 43 - .../gui/components/util/SkullUtil.java | 112 -- .../gui/components/util/VersionHelper.java | 166 --- .../dev/triumphteam/gui/guis/BaseGui.java | 1032 ----------------- .../java/dev/triumphteam/gui/guis/Gui.java | 178 --- .../dev/triumphteam/gui/guis/GuiItem.java | 140 --- .../dev/triumphteam/gui/guis/GuiListener.java | 175 --- .../gui/guis/InteractionModifierListener.java | 255 ---- .../triumphteam/gui/guis/PaginatedGui.java | 498 -------- .../gui/guis/PersistentPaginatedGui.java | 357 ------ .../triumphteam/gui/guis/ScrollingGui.java | 316 ----- .../dev/triumphteam/gui/guis/StorageGui.java | 108 -- 37 files changed, 6998 deletions(-) delete mode 100644 old-core/build.gradle.kts delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/GuiAction.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/GuiPage.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/GuiType.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/ScrollType.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/Serializable.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/util/Legacy.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/BaseGui.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/Gui.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/GuiItem.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/GuiListener.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/PersistentPaginatedGui.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java delete mode 100644 old-core/src/main/java/dev/triumphteam/gui/guis/StorageGui.java diff --git a/old-core/build.gradle.kts b/old-core/build.gradle.kts deleted file mode 100644 index 7d83eddd..00000000 --- a/old-core/build.gradle.kts +++ /dev/null @@ -1,107 +0,0 @@ -plugins { - `maven-publish` - signing -} - -repositories { - mavenCentral() - maven("https://repo.mattstudios.me/artifactory/public/") - maven("https://libraries.minecraft.net/") -} - -dependencies { - compileOnly("com.mojang:authlib:1.5.21") -} - -val javaComponent: SoftwareComponent = components["java"] - -tasks { - - val sourcesJar by creating(Jar::class) { - archiveClassifier.set("sources") - from(sourceSets.main.get().allSource) - } - - val javadocJar by creating(Jar::class) { - dependsOn.add(javadoc) - archiveClassifier.set("javadoc") - from(javadoc) - } - - publishing { - publications { - create("maven") { - from(javaComponent) - artifact(sourcesJar) - artifact(javadocJar) - versionMapping { - usage("java-api") { - fromResolutionOf("runtimeClasspath") - } - usage("java-runtime") { - fromResolutionResult() - } - } - pom { - name.set("Triumph GUI") - description.set("Library for easy creation of GUIs for Bukkit plugins.") - url.set("https://github.com/TriumphTeam/triumph-gui") - - licenses { - license { - name.set("MIT License") - url.set("http://www.opensource.org/licenses/mit-license.php") - } - } - - developers { - developer { - id.set("matt") - name.set("Mateus Moreira") - organization.set("TriumphTeam") - organizationUrl.set("https://github.com/TriumphTeam") - } - } - - scm { - connection.set("scm:git:git://github.com/TriumphTeam/triumph-gui.git") - developerConnection.set("scm:git:ssh://github.com:TriumphTeam/triumph-gui.git") - url.set("https://github.com/TriumphTeam/triumph-gui") - } - } - } - } - - repositories { - maven { - if (version.toString().contains("SNAPSHOT")) { - credentials { - username = System.getenv("REPO_USER") - password = System.getenv("REPO_PASS") - } - - url = uri("https://repo.triumphteam.dev/snapshots/") - return@maven - } - - credentials { - username = System.getenv("SONATYPE_USER") - password = System.getenv("SONATYPE_PASSWORD") - } - - url = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") - } - } - - } - - signing { - /*useGpgCmd() - val signingKey = System.getenv("GPG_KEY") - val signingPassword = System.getenv("GPG_PASS") - val secretKey = System.getenv("GPG_SECRET_KEY") - useInMemoryPgpKeys(signingKey, secretKey, signingPassword)*/ - sign(publishing.publications["maven"]) - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java deleted file mode 100644 index 2c3872d4..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/BaseGuiBuilder.java +++ /dev/null @@ -1,315 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.gui; - -import dev.triumphteam.gui.components.InteractionModifier; -import dev.triumphteam.gui.components.exception.GuiException; -import dev.triumphteam.gui.guis.BaseGui; -import net.kyori.adventure.text.Component; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.EnumSet; -import java.util.Set; -import java.util.function.Consumer; - -/** - * The base for all the GUI builders this is due to some limitations - * where some builders will have unique features based on the GUI type - * - * @param The Type of {@link BaseGui} - */ -@SuppressWarnings("unchecked") -public abstract class BaseGuiBuilder> { - - private Component title = null; - private int rows = 1; - private final EnumSet interactionModifiers = EnumSet.noneOf(InteractionModifier.class); - - private Consumer consumer; - - /** - * Sets the rows for the GUI - * This will only work on CHEST {@link dev.triumphteam.gui.components.GuiType} - * - * @param rows The amount of rows - * @return The builder - */ - @NotNull - @Contract("_ -> this") - public B rows(final int rows) { - this.rows = rows; - return (B) this; - } - - /** - * Sets the title for the GUI - * This will be either a Component or a String - * - * @param title The GUI title - * @return The builder - */ - @NotNull - @Contract("_ -> this") - public B title(@NotNull final Component title) { - this.title = title; - return (B) this; - } - - /** - * Disable item placement inside the GUI - * - * @return The builder - * @since 3.0.0 - * @author SecretX - */ - @NotNull - @Contract(" -> this") - public B disableItemPlace() { - interactionModifiers.add(InteractionModifier.PREVENT_ITEM_PLACE); - return (B) this; - } - - /** - * Disable item retrieval inside the GUI - * - * @return The builder - * @since 3.0.0 - * @author SecretX - */ - @NotNull - @Contract(" -> this") - public B disableItemTake() { - interactionModifiers.add(InteractionModifier.PREVENT_ITEM_TAKE); - return (B) this; - } - - /** - * Disable item swap inside the GUI - * - * @return The builder - * @since 3.0.0 - * @author SecretX - */ - @NotNull - @Contract(" -> this") - public B disableItemSwap() { - interactionModifiers.add(InteractionModifier.PREVENT_ITEM_SWAP); - return (B) this; - } - - /** - * Disable item drop inside the GUI - * - * @return The builder - * @since 3.0.3 - */ - @NotNull - @Contract(" -> this") - public B disableItemDrop() { - interactionModifiers.add(InteractionModifier.PREVENT_ITEM_DROP); - return (B) this; - } - - /** - * Disable other GUI actions - * This option pretty much disables creating a clone stack of the item - * - * @return The builder - * @since 3.0.4 - */ - @NotNull - @Contract(" -> this") - public B disableOtherActions() { - interactionModifiers.add(InteractionModifier.PREVENT_OTHER_ACTIONS); - return (B) this; - } - - /** - * Disable all the modifications of the GUI, making it immutable by player interaction - * - * @return The builder - * @since 3.0.0 - * @author SecretX - */ - @NotNull - @Contract(" -> this") - public B disableAllInteractions() { - interactionModifiers.addAll(InteractionModifier.VALUES); - return (B) this; - } - - /** - * Allows item placement inside the GUI - * - * @return The builder - * @since 3.0.0 - * @author SecretX - */ - @NotNull - @Contract(" -> this") - public B enableItemPlace() { - interactionModifiers.remove(InteractionModifier.PREVENT_ITEM_PLACE); - return (B) this; - } - - /** - * Allow items to be taken from the GUI - * - * @return The builder - * @since 3.0.0 - * @author SecretX - */ - @NotNull - @Contract(" -> this") - public B enableItemTake() { - interactionModifiers.remove(InteractionModifier.PREVENT_ITEM_TAKE); - return (B) this; - } - - /** - * Allows item swap inside the GUI - * - * @return The builder - * @since 3.0.0 - * @author SecretX - */ - @NotNull - @Contract(" -> this") - public B enableItemSwap() { - interactionModifiers.remove(InteractionModifier.PREVENT_ITEM_SWAP); - return (B) this; - } - - /** - * Allows item drop inside the GUI - * - * @return The builder - * @since 3.0.3 - */ - @NotNull - @Contract(" -> this") - public B enableItemDrop() { - interactionModifiers.remove(InteractionModifier.PREVENT_ITEM_DROP); - return (B) this; - } - - /** - * Enable other GUI actions - * This option pretty much enables creating a clone stack of the item - * - * @return The builder - * @since 3.0.4 - */ - @NotNull - @Contract(" -> this") - public B enableOtherActions() { - interactionModifiers.remove(InteractionModifier.PREVENT_OTHER_ACTIONS); - return (B) this; - } - - /** - * Enable all modifications of the GUI, making it completely mutable by player interaction - * - * @return The builder - * @since 3.0.0 - * @author SecretX - */ - @NotNull - @Contract(" -> this") - public B enableAllInteractions() { - interactionModifiers.clear(); - return (B) this; - } - - /** - * Applies anything to the GUI once it's created - * Can be pretty useful for setting up small things like default actions - * - * @param consumer A {@link Consumer} that passes the built GUI - * @return The builder - */ - @NotNull - @Contract("_ -> this") - public B apply(@NotNull final Consumer consumer) { - this.consumer = consumer; - return (B) this; - } - - /** - * Creates the given GuiBase - * Has to be abstract because each GUI are different - * - * @return The new {@link BaseGui} - */ - @NotNull - @Contract(" -> new") - public abstract G create(); - - /** - * Getter for the title - * - * @return The current title - */ - @NotNull - protected Component getTitle() { - if (title == null) { - throw new GuiException("GUI title is missing!"); - } - - return title; - } - - /** - * Getter for the rows - * - * @return The amount of rows - */ - protected int getRows() { - return rows; - } - - /** - * Getter for the consumer - * - * @return The consumer - */ - @Nullable - protected Consumer getConsumer() { - return consumer; - } - - - /** - * Getter for the set of interaction modifiers - * @return The set of {@link InteractionModifier} - * @since 3.0.0 - * @author SecretX - */ - @NotNull - protected Set getModifiers() { - return interactionModifiers; - } -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java deleted file mode 100644 index deea0f6d..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/PaginatedBuilder.java +++ /dev/null @@ -1,70 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.gui; - -import dev.triumphteam.gui.components.util.Legacy; -import dev.triumphteam.gui.guis.PaginatedGui; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Consumer; - -/** - * GUI builder for creating a {@link PaginatedGui} - */ -public class PaginatedBuilder extends BaseGuiBuilder { - - private int pageSize = 0; - - /** - * Sets the desirable page size, most of the time this isn't needed - * - * @param pageSize The amount of free slots that page items should occupy - * @return The current builder - */ - @NotNull - @Contract("_ -> this") - public PaginatedBuilder pageSize(final int pageSize) { - this.pageSize = pageSize; - return this; - } - - /** - * Creates a new {@link PaginatedGui} - * - * @return A new {@link PaginatedGui} - */ - @NotNull - @Override - @Contract(" -> new") - public PaginatedGui create() { - final PaginatedGui gui = new PaginatedGui(getRows(), pageSize, Legacy.SERIALIZER.serialize(getTitle()), getModifiers()); - - final Consumer consumer = getConsumer(); - if (consumer != null) consumer.accept(gui); - - return gui; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java deleted file mode 100644 index 4d5ea332..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/ScrollingBuilder.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.gui; - -import dev.triumphteam.gui.components.ScrollType; -import dev.triumphteam.gui.components.util.Legacy; -import dev.triumphteam.gui.guis.ScrollingGui; -import net.kyori.adventure.text.Component; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Consumer; - -/** - * The simple GUI builder is used for creating a {@link ScrollingGui} that uses {@link Component} for title - * TODO This class needs more work to remove the redundant pageSize since it's the same as the paginated builder - */ -public final class ScrollingBuilder extends BaseGuiBuilder { - - private ScrollType scrollType; - private int pageSize = 0; - - /** - * Main constructor - * - * @param scrollType The {@link ScrollType} to default to - */ - public ScrollingBuilder(@NotNull final ScrollType scrollType) { - this.scrollType = scrollType; - } - - /** - * Sets the {@link ScrollType} to be used - * - * @param scrollType Either horizontal or vertical scrolling - * @return The current builder - */ - @NotNull - @Contract("_ -> this") - public ScrollingBuilder scrollType(@NotNull final ScrollType scrollType) { - this.scrollType = scrollType; - return this; - } - - /** - * Sets the desirable page size, most of the times this isn't needed - * - * @param pageSize The amount of free slots that page items should occupy - * @return The current builder - */ - @NotNull - @Contract("_ -> this") - public ScrollingBuilder pageSize(final int pageSize) { - this.pageSize = pageSize; - return this; - } - - /** - * Creates a new {@link ScrollingGui} - * - * @return A new {@link ScrollingGui} - */ - @NotNull - @Override - @Contract(" -> new") - public ScrollingGui create() { - final ScrollingGui gui = new ScrollingGui(getRows(), pageSize, Legacy.SERIALIZER.serialize(getTitle()), scrollType, getModifiers()); - - final Consumer consumer = getConsumer(); - if (consumer != null) consumer.accept(gui); - - return gui; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java deleted file mode 100644 index 8dc98b67..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/SimpleBuilder.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.gui; - -import dev.triumphteam.gui.components.GuiType; -import dev.triumphteam.gui.components.util.Legacy; -import dev.triumphteam.gui.guis.Gui; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Consumer; - -/** - * The simple GUI builder is used for creating a {@link Gui} - */ -public final class SimpleBuilder extends BaseGuiBuilder { - - private GuiType guiType; - - /** - * Main constructor - * - * @param guiType The {@link GuiType} to default to - */ - public SimpleBuilder(@NotNull final GuiType guiType) { - this.guiType = guiType; - } - - /** - * Sets the {@link GuiType} to use on the GUI - * This method is unique to the simple GUI - * - * @param guiType The {@link GuiType} - * @return The current builder - */ - @NotNull - @Contract("_ -> this") - public SimpleBuilder type(@NotNull final GuiType guiType) { - this.guiType = guiType; - return this; - } - - /** - * Creates a new {@link Gui} - * - * @return A new {@link Gui} - */ - @NotNull - @Override - @Contract(" -> new") - public Gui create() { - final Gui gui; - final String title = Legacy.SERIALIZER.serialize(getTitle()); - if (guiType == null || guiType == GuiType.CHEST) { - gui = new Gui(getRows(), title, getModifiers()); - } else { - gui = new Gui(guiType, title, getModifiers()); - } - - final Consumer consumer = getConsumer(); - if (consumer != null) consumer.accept(gui); - - return gui; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java deleted file mode 100644 index f160514a..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/gui/StorageBuilder.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.gui; - -import dev.triumphteam.gui.components.util.Legacy; -import dev.triumphteam.gui.guis.StorageGui; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.function.Consumer; - -/** - * The simple GUI builder is used for creating a {@link StorageGui} - */ -public final class StorageBuilder extends BaseGuiBuilder { - - /** - * Creates a new {@link StorageGui} - * - * @return A new {@link StorageGui} - */ - @NotNull - @Override - @Contract(" -> new") - public StorageGui create() { - final StorageGui gui = new StorageGui(getRows(), Legacy.SERIALIZER.serialize(getTitle()), getModifiers()); - - final Consumer consumer = getConsumer(); - if (consumer != null) consumer.accept(gui); - - return gui; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java deleted file mode 100644 index fc6045d6..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/item/BannerBuilder.java +++ /dev/null @@ -1,197 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.item; - -import dev.triumphteam.gui.components.exception.GuiException; -import dev.triumphteam.gui.components.util.VersionHelper; -import org.bukkit.DyeColor; -import org.bukkit.Material; -import org.bukkit.Tag; -import org.bukkit.block.banner.Pattern; -import org.bukkit.block.banner.PatternType; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BannerMeta; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; - -/** - * Item builder for banners only - * - * @author GabyTM https://github.com/iGabyTM - * @since 3.0.1 - */ -@SuppressWarnings("unused") -public final class BannerBuilder extends BaseItemBuilder { - - private static final Material DEFAULT_BANNER; - private static final EnumSet BANNERS; - - static { - if (VersionHelper.IS_ITEM_LEGACY) { - DEFAULT_BANNER = Material.valueOf("BANNER"); - BANNERS = EnumSet.of(Material.valueOf("BANNER")); - } else { - DEFAULT_BANNER = Material.WHITE_BANNER; - BANNERS = EnumSet.copyOf(Tag.BANNERS.getValues()); - } - } - - BannerBuilder() { - super(new ItemStack(DEFAULT_BANNER)); - } - - BannerBuilder(@NotNull ItemStack itemStack) { - super(itemStack); - if (!BANNERS.contains(itemStack.getType())) { - throw new GuiException("BannerBuilder requires the material to be a banner!"); - } - } - - /** - * Sets the base color for this banner - * - * @param color the base color - * @return {@link BannerBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BannerBuilder baseColor(@NotNull final DyeColor color) { - final BannerMeta bannerMeta = (BannerMeta) getMeta(); - - bannerMeta.setBaseColor(color); - setMeta(bannerMeta); - return this; - } - - /** - * Adds a new pattern on top of the existing patterns - * - * @param color the pattern color - * @param pattern the pattern type - * @return {@link BannerBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_, _ -> this") - public BannerBuilder pattern(@NotNull final DyeColor color, @NotNull final PatternType pattern) { - final BannerMeta bannerMeta = (BannerMeta) getMeta(); - - bannerMeta.addPattern(new Pattern(color, pattern)); - setMeta(bannerMeta); - return this; - } - - /** - * Adds new patterns on top of the existing patterns - * - * @param pattern the patterns - * @return {@link BannerBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BannerBuilder pattern(@NotNull final Pattern... pattern) { - return pattern(Arrays.asList(pattern)); - } - - /** - * Adds new patterns on top of the existing patterns - * - * @param patterns the patterns - * @return {@link BannerBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BannerBuilder pattern(@NotNull final List patterns) { - final BannerMeta bannerMeta = (BannerMeta) getMeta(); - - for (final Pattern it : patterns) { - bannerMeta.addPattern(it); - } - - setMeta(bannerMeta); - return this; - } - - /** - * Sets the pattern at the specified index - * - * @param index the index - * @param color the pattern color - * @param pattern the pattern type - * @return {@link BannerBuilder} - * @throws IndexOutOfBoundsException when index is not in [0, {@link BannerMeta#numberOfPatterns()}) range - * @since 3.0.1 - */ - @NotNull - @Contract("_, _, _ -> this") - public BannerBuilder pattern(final int index, @NotNull final DyeColor color, @NotNull final PatternType pattern) { - return pattern(index, new Pattern(color, pattern)); - } - - /** - * Sets the pattern at the specified index - * - * @param index the index - * @param pattern the new pattern - * @return {@link BannerBuilder} - * @throws IndexOutOfBoundsException when index is not in [0, {@link BannerMeta#numberOfPatterns()}) range - * @since 3.0.1 - */ - @NotNull - @Contract("_, _ -> this") - public BannerBuilder pattern(final int index, @NotNull final Pattern pattern) { - final BannerMeta bannerMeta = (BannerMeta) getMeta(); - - bannerMeta.setPattern(index, pattern); - setMeta(bannerMeta); - return this; - } - - /** - * Sets the patterns used on this banner - * - * @param patterns the new list of patterns - * @return {@link BannerBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BannerBuilder setPatterns(@NotNull List<@NotNull Pattern> patterns) { - final BannerMeta bannerMeta = (BannerMeta) getMeta(); - - bannerMeta.setPatterns(patterns); - setMeta(bannerMeta); - return this; - } - - // TODO add shield() - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java deleted file mode 100644 index 568c773f..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/item/BaseItemBuilder.java +++ /dev/null @@ -1,709 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.item; - -import com.google.common.base.Preconditions; -import dev.triumphteam.gui.components.GuiAction; -import dev.triumphteam.gui.components.exception.GuiException; -import dev.triumphteam.gui.components.util.ItemNbt; -import dev.triumphteam.gui.components.util.Legacy; -import dev.triumphteam.gui.components.util.VersionHelper; -import dev.triumphteam.gui.guis.GuiItem; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import org.bukkit.Bukkit; -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.ItemFlag; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.LeatherArmorMeta; -import org.bukkit.persistence.PersistentDataContainer; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -/** - * Contains all the common methods for the future ItemBuilders - * - * @param The ItemBuilder type so the methods can cast to the subtype - */ -@SuppressWarnings("unchecked") -public abstract class BaseItemBuilder> { - - private static final EnumSet LEATHER_ARMOR = EnumSet.of( - Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS - ); - - private static final GsonComponentSerializer GSON = GsonComponentSerializer.gson(); - private static final Field DISPLAY_NAME_FIELD; - private static final Field LORE_FIELD; - - static { - try { - final Class metaClass = VersionHelper.craftClass("inventory.CraftMetaItem"); - - DISPLAY_NAME_FIELD = metaClass.getDeclaredField("displayName"); - DISPLAY_NAME_FIELD.setAccessible(true); - - LORE_FIELD = metaClass.getDeclaredField("lore"); - LORE_FIELD.setAccessible(true); - } catch (NoSuchFieldException | ClassNotFoundException exception) { - exception.printStackTrace(); - throw new GuiException("Could not retrieve displayName nor lore field for ItemBuilder."); - } - } - - private ItemStack itemStack; - private ItemMeta meta; - - protected BaseItemBuilder(@NotNull final ItemStack itemStack) { - Preconditions.checkNotNull(itemStack, "Item can't be null!"); - - this.itemStack = itemStack; - meta = itemStack.hasItemMeta() ? itemStack.getItemMeta() : Bukkit.getItemFactory().getItemMeta(itemStack.getType()); - } - - /** - * Sets the display name of the item using {@link Component} - * - * @param name The {@link Component} name - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B name(@NotNull final Component name) { - if (meta == null) return (B) this; - - if (VersionHelper.IS_COMPONENT_LEGACY) { - meta.setDisplayName(Legacy.SERIALIZER.serialize(name)); - return (B) this; - } - - try { - DISPLAY_NAME_FIELD.set(meta, GSON.serialize(name)); - } catch (IllegalAccessException exception) { - exception.printStackTrace(); - } - - return (B) this; - } - - /** - * Sets the amount of items - * - * @param amount the amount of items - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B amount(final int amount) { - itemStack.setAmount(amount); - return (B) this; - } - - /** - * Set the lore lines of an item - * - * @param lore Lore lines as varargs - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B lore(@Nullable final Component @NotNull ... lore) { - return lore(Arrays.asList(lore)); - } - - /** - * Set the lore lines of an item - * - * @param lore A {@link List} with the lore lines - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B lore(@NotNull final List<@Nullable Component> lore) { - if (meta == null) return (B) this; - - if (VersionHelper.IS_COMPONENT_LEGACY) { - meta.setLore(lore.stream().filter(Objects::nonNull).map(Legacy.SERIALIZER::serialize).collect(Collectors.toList())); - return (B) this; - } - - final List jsonLore = lore.stream().filter(Objects::nonNull).map(GSON::serialize).collect(Collectors.toList()); - - try { - LORE_FIELD.set(meta, jsonLore); - } catch (IllegalAccessException exception) { - exception.printStackTrace(); - } - - return (B) this; - } - - /** - * Consumer for freely adding to the lore - * - * @param lore A {@link Consumer} with the {@link List} of lore {@link Component} - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B lore(@NotNull final Consumer> lore) { - if (meta == null) return (B) this; - - List components; - if (VersionHelper.IS_COMPONENT_LEGACY) { - final List stringLore = meta.getLore(); - components = (stringLore == null) ? new ArrayList<>() : stringLore.stream().map(Legacy.SERIALIZER::deserialize).collect(Collectors.toList()); - } else { - try { - final List jsonLore = (List) LORE_FIELD.get(meta); - // The field is null by default ._. - components = (jsonLore == null) ? new ArrayList<>() : jsonLore.stream().map(GSON::deserialize).collect(Collectors.toList()); - } catch (IllegalAccessException exception) { - components = new ArrayList<>(); - exception.printStackTrace(); - } - } - - lore.accept(components); - return lore(components); - } - - /** - * Enchants the {@link ItemStack} - * - * @param enchantment The {@link Enchantment} to add - * @param level The level of the {@link Enchantment} - * @param ignoreLevelRestriction If should or not ignore it - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_, _, _ -> this") - public B enchant(@NotNull final Enchantment enchantment, final int level, final boolean ignoreLevelRestriction) { - meta.addEnchant(enchantment, level, ignoreLevelRestriction); - return (B) this; - } - - /** - * Enchants the {@link ItemStack} - * - * @param enchantment The {@link Enchantment} to add - * @param level The level of the {@link Enchantment} - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_, _ -> this") - public B enchant(@NotNull final Enchantment enchantment, final int level) { - return enchant(enchantment, level, true); - } - - /** - * Enchants the {@link ItemStack} - * - * @param enchantment The {@link Enchantment} to add - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B enchant(@NotNull final Enchantment enchantment) { - return enchant(enchantment, 1, true); - } - - /** - * Enchants the {@link ItemStack} with the specified map where the value - * is the level of the key's enchantment - * - * @param enchantments Enchantments to add - * @param ignoreLevelRestriction If level restriction should be ignored - * @return {@link ItemBuilder} - * @since 3.1.2 - */ - @NotNull - @Contract("_, _ -> this") - public B enchant(@NotNull final Map enchantments, final boolean ignoreLevelRestriction) { - enchantments.forEach((enchantment, level) -> this.enchant(enchantment, level, ignoreLevelRestriction)); - return (B) this; - } - - /** - * Enchants the {@link ItemStack} with the specified map where the value - * is the level of the key's enchantment - * - * @param enchantments Enchantments to add - * @return {@link ItemBuilder} - * @since 3.1.2 - */ - @NotNull - @Contract("_ -> this") - public B enchant(@NotNull final Map enchantments) { - return enchant(enchantments, true); - } - - /** - * Disenchants a certain {@link Enchantment} from the {@link ItemStack} - * - * @param enchantment The {@link Enchantment} to remove - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B disenchant(@NotNull final Enchantment enchantment) { - itemStack.removeEnchantment(enchantment); - return (B) this; - } - - /** - * Add an {@link ItemFlag} to the item - * - * @param flags The {@link ItemFlag} to add - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B flags(@NotNull final ItemFlag... flags) { - meta.addItemFlags(flags); - return (B) this; - } - - /** - * Makes the {@link ItemStack} unbreakable - * - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract(" -> this") - public B unbreakable() { - return unbreakable(true); - } - - /** - * Sets the item as unbreakable - * - * @param unbreakable If should or not be unbreakable - * @return {@link ItemBuilder} - */ - @NotNull - @Contract("_ -> this") - public B unbreakable(boolean unbreakable) { - if (VersionHelper.IS_UNBREAKABLE_LEGACY) { - return setNbt("Unbreakable", unbreakable); - } - - meta.setUnbreakable(unbreakable); - return (B) this; - } - - /** - * Makes the {@link ItemStack} glow - * - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract(" -> this") - public B glow() { - return glow(true); - } - - /** - * Adds or removes the {@link ItemStack} glow - * - * @param glow Should the item glow - * @return {@link ItemBuilder} - */ - @NotNull - @Contract("_ -> this") - public B glow(boolean glow) { - if (glow) { - meta.addEnchant(Enchantment.LURE, 1, false); - meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); - return (B) this; - } - - for (final Enchantment enchantment : meta.getEnchants().keySet()) { - meta.removeEnchant(enchantment); - } - - return (B) this; - } - - /** - * Consumer for applying {@link PersistentDataContainer} to the item - * This method will only work on versions above 1.14 - * - * @param consumer The {@link Consumer} with the PDC - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B pdc(@NotNull final Consumer consumer) { - consumer.accept(meta.getPersistentDataContainer()); - return (B) this; - } - - /** - * Sets the custom model data of the item - * Added in 1.13 - * - * @param modelData The custom model data from the resource pack - * @return {@link ItemBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> this") - public B model(final int modelData) { - if (VersionHelper.IS_CUSTOM_MODEL_DATA) { - meta.setCustomModelData(modelData); - } - - return (B) this; - } - - /** - * Color an {@link org.bukkit.inventory.ItemStack} - * - * @param color color - * @return {@link B} - * @see org.bukkit.inventory.meta.LeatherArmorMeta#setColor(Color) - * @see org.bukkit.inventory.meta.MapMeta#setColor(Color) - * @since 3.0.3 - */ - @NotNull - @Contract("_ -> this") - public B color(@NotNull final Color color) { - if (LEATHER_ARMOR.contains(itemStack.getType())) { - final LeatherArmorMeta leatherArmorMeta = (LeatherArmorMeta) getMeta(); - - leatherArmorMeta.setColor(color); - setMeta(leatherArmorMeta); - } - - return (B) this; - } - - /** - * Sets NBT tag to the {@link ItemStack} - * - * @param key The NBT key - * @param value The NBT value - * @return {@link ItemBuilder} - */ - @NotNull - @Contract("_, _ -> this") - public B setNbt(@NotNull final String key, @NotNull final String value) { - itemStack.setItemMeta(meta); - itemStack = ItemNbt.setString(itemStack, key, value); - meta = itemStack.getItemMeta(); - return (B) this; - } - - /** - * Sets NBT tag to the {@link ItemStack} - * - * @param key The NBT key - * @param value The NBT value - * @return {@link ItemBuilder} - */ - @NotNull - @Contract("_, _ -> this") - public B setNbt(@NotNull final String key, final boolean value) { - itemStack.setItemMeta(meta); - itemStack = ItemNbt.setBoolean(itemStack, key, value); - meta = itemStack.getItemMeta(); - return (B) this; - } - - /** - * Removes NBT tag from the {@link ItemStack} - * - * @param key The NBT key - * @return {@link ItemBuilder} - */ - @NotNull - @Contract("_ -> this") - public B removeNbt(@NotNull final String key) { - itemStack.setItemMeta(meta); - itemStack = ItemNbt.removeTag(itemStack, key); - meta = itemStack.getItemMeta(); - return (B) this; - } - - /** - * Builds the item into {@link ItemStack} - * - * @return The fully built {@link ItemStack} - */ - @NotNull - public ItemStack build() { - itemStack.setItemMeta(meta); - return itemStack; - } - - /** - * Creates a {@link GuiItem} instead of an {@link ItemStack} - * - * @return A {@link GuiItem} with no {@link GuiAction} - */ - @NotNull - @Contract(" -> new") - public GuiItem asGuiItem() { - return new GuiItem(build()); - } - - /** - * Creates a {@link GuiItem} instead of an {@link ItemStack} - * - * @param action The {@link GuiAction} to apply to the item - * @return A {@link GuiItem} with {@link GuiAction} - */ - @NotNull - @Contract("_ -> new") - public GuiItem asGuiItem(@NotNull final GuiAction action) { - return new GuiItem(build(), action); - } - - /** - * Package private getter for extended builders - * - * @return The ItemStack - */ - @NotNull - protected ItemStack getItemStack() { - return itemStack; - } - - /** - * Package private setter for the extended builders - * - * @param itemStack The ItemStack - */ - protected void setItemStack(@NotNull final ItemStack itemStack) { - this.itemStack = itemStack; - } - - /** - * Package private getter for extended builders - * - * @return The ItemMeta - */ - @NotNull - protected ItemMeta getMeta() { - return meta; - } - - /** - * Package private setter for the extended builders - * - * @param meta The ItemMeta - */ - protected void setMeta(@NotNull final ItemMeta meta) { - this.meta = meta; - } - - // DEPRECATED, TO BE REMOVED METHODS - // TODO Remove deprecated methods - - /** - * Set display name of the item - * - * @param name the display name of the item - * @return {@link ItemBuilder} - * @deprecated In favor of {@link BaseItemBuilder#name(Component)}, will be removed in 3.0.1 - */ - @Deprecated - public B setName(@NotNull final String name) { - getMeta().setDisplayName(name); - return (B) this; - } - - /** - * Sets the amount of items - * - * @param amount the amount of items - * @return {@link ItemBuilder} - * @deprecated In favor of {@link BaseItemBuilder#amount(int)}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public B setAmount(final int amount) { - getItemStack().setAmount(amount); - return (B) this; - } - - /** - * Add lore lines of an item - * - * @param lore the lore lines to add - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#lore(Consumer)}, will be removed in 3.0.1 - */ - @Deprecated - public B addLore(@NotNull final String... lore) { - return addLore(Arrays.asList(lore)); - } - - /** - * Set lore lines of an item - * - * @param lore A {@link List} with the lore lines to add - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#lore(Consumer)}, will be removed in 3.0.1 - */ - @Deprecated - public B addLore(@NotNull final List lore) { - final List newLore = getMeta().hasLore() ? getMeta().getLore() : new ArrayList<>(); - - newLore.addAll(lore); - return setLore(newLore); - } - - /** - * Set the lore lines of an item - * - * @param lore the lore lines to set - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#lore(Component...)}, will be removed in 3.0.1 - */ - @Deprecated - public B setLore(@NotNull final String... lore) { - return setLore(Arrays.asList(lore)); - } - - /** - * Set the lore lines of an item - * - * @param lore A {@link List} with the lore lines - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#lore(List)}, will be removed in 3.0.1 - */ - @Deprecated - public B setLore(@NotNull final List lore) { - getMeta().setLore(lore); - return (B) this; - } - - /** - * Add enchantment to an item - * - * @param enchantment the {@link Enchantment} to add - * @param level the level of the {@link Enchantment} - * @param ignoreLevelRestriction If should or not ignore it - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#enchant(Enchantment, int, boolean)}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public B addEnchantment(@NotNull final Enchantment enchantment, final int level, final boolean ignoreLevelRestriction) { - getMeta().addEnchant(enchantment, level, ignoreLevelRestriction); - return (B) this; - } - - /** - * Add enchantment to an item - * - * @param enchantment the {@link Enchantment} to add - * @param level the level of the {@link Enchantment} - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#enchant(Enchantment, int)}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public B addEnchantment(@NotNull final Enchantment enchantment, final int level) { - return addEnchantment(enchantment, level, true); - } - - /** - * Add enchantment to an item - * - * @param enchantment the {@link Enchantment} to add - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#enchant(Enchantment)}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public B addEnchantment(@NotNull final Enchantment enchantment) { - return addEnchantment(enchantment, 1, true); - } - - /** - * Removes a certain {@link Enchantment} from the item - * - * @param enchantment The {@link Enchantment} to remove - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#disenchant(Enchantment)}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public B removeEnchantment(@NotNull final Enchantment enchantment) { - getItemStack().removeEnchantment(enchantment); - return (B) this; - } - - /** - * Add a custom {@link ItemFlag} to the item - * - * @param flags the {@link ItemFlag} to add - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#flags(ItemFlag...)}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public B addItemFlags(@NotNull final ItemFlag... flags) { - getMeta().addItemFlags(flags); - return (B) this; - } - - /** - * Sets the item as unbreakable - * - * @param unbreakable If should or not be unbreakable - * @return {@link ItemBuilder} - * @deprecated In favor of {@link ItemBuilder#unbreakable()}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public B setUnbreakable(boolean unbreakable) { - return unbreakable(unbreakable); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java deleted file mode 100644 index 278f8087..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/item/BookBuilder.java +++ /dev/null @@ -1,181 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.item; - -import dev.triumphteam.gui.components.exception.GuiException; -import dev.triumphteam.gui.components.util.Legacy; -import net.kyori.adventure.text.Component; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.BookMeta; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.EnumSet; -import java.util.List; - -/** - * Item builder for {@link Material#WRITTEN_BOOK} and {@link Material#WRITTEN_BOOK} only - * - * @author GabyTM https://github.com/iGabyTM - * @since 3.0.1 - */ -public class BookBuilder extends BaseItemBuilder { - - private static final EnumSet BOOKS = EnumSet.of(Material.WRITABLE_BOOK, Material.WRITTEN_BOOK); - - BookBuilder(@NotNull ItemStack itemStack) { - super(itemStack); - if (!BOOKS.contains(itemStack.getType())) { - throw new GuiException("BookBuilder requires the material to be a WRITABLE_BOOK/WRITTEN_BOOK!"); - } - } - - /** - * Sets the author of the book. Removes author when given null. - * - * @param author the author to set - * @return {@link BookBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BookBuilder author(@Nullable final Component author) { - final BookMeta bookMeta = (BookMeta) getMeta(); - - if (author == null) { - bookMeta.setAuthor(null); - setMeta(bookMeta); - return this; - } - - bookMeta.setAuthor(Legacy.SERIALIZER.serialize(author)); - setMeta(bookMeta); - return this; - } - - /** - * Sets the generation of the book. Removes generation when given null. - * - * @param generation the generation to set - * @return {@link BookBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BookBuilder generation(@Nullable final BookMeta.Generation generation) { - final BookMeta bookMeta = (BookMeta) getMeta(); - - bookMeta.setGeneration(generation); - setMeta(bookMeta); - return this; - } - - /** - * Adds new pages to the end of the book. Up to a maximum of 50 pages with - * 256 characters per page. - * - * @param pages list of pages - * @return {@link BookBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BookBuilder page(@NotNull final Component... pages) { - return page(Arrays.asList(pages)); - } - - /** - * Adds new pages to the end of the book. Up to a maximum of 50 pages with - * 256 characters per page. - * - * @param pages list of pages - * @return {@link BookBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BookBuilder page(@NotNull final List pages) { - final BookMeta bookMeta = (BookMeta) getMeta(); - - for (final Component page : pages) { - bookMeta.addPage(Legacy.SERIALIZER.serialize(page)); - } - - setMeta(bookMeta); - return this; - } - - /** - * Sets the specified page in the book. Pages of the book must be - * contiguous. - *

- * The data can be up to 256 characters in length, additional characters - * are truncated. - *

- * Pages are 1-indexed. - * - * @param page the page number to set, in range [1, {@link BookMeta#getPageCount()}] - * @param data the data to set for that page - * @return {@link BookBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_, _ -> this") - public BookBuilder page(final int page, @NotNull final Component data) { - final BookMeta bookMeta = (BookMeta) getMeta(); - - bookMeta.setPage(page, Legacy.SERIALIZER.serialize(data)); - setMeta(bookMeta); - return this; - } - - /** - * Sets the title of the book. - *

- * Limited to 32 characters. Removes title when given null. - * - * @param title the title to set - * @return {@link BookBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public BookBuilder title(@Nullable Component title) { - final BookMeta bookMeta = (BookMeta) getMeta(); - - if (title == null) { - bookMeta.setTitle(null); - setMeta(bookMeta); - return this; - } - - bookMeta.setTitle(Legacy.SERIALIZER.serialize(title)); - setMeta(bookMeta); - return this; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java deleted file mode 100644 index a99aa69e..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/item/FireworkBuilder.java +++ /dev/null @@ -1,124 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.item; - -import dev.triumphteam.gui.components.exception.GuiException; -import org.bukkit.FireworkEffect; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.FireworkEffectMeta; -import org.bukkit.inventory.meta.FireworkMeta; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.List; - -/** - * Item builder for {@link Material#FIREWORK_ROCKET} and {@link Material#FIREWORK_ROCKET} only - * - * @author GabyTM https://github.com/iGabyTM - * @since 3.0.1 - */ -public class FireworkBuilder extends BaseItemBuilder { - - private static final Material STAR = Material.FIREWORK_STAR; - private static final Material ROCKET = Material.FIREWORK_ROCKET; - - FireworkBuilder(@NotNull final ItemStack itemStack) { - super(itemStack); - if (itemStack.getType() != STAR && itemStack.getType() != ROCKET) { - throw new GuiException("FireworkBuilder requires the material to be a FIREWORK_STAR/FIREWORK_ROCKET!"); - } - } - - /** - * Add several firework effects to this firework. - * - * @param effects effects to add - * @return {@link FireworkBuilder} - * @throws IllegalArgumentException If effects is null - * @throws IllegalArgumentException If any effect is null (may be thrown after changes have occurred) - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public FireworkBuilder effect(@NotNull final FireworkEffect... effects) { - return effect(Arrays.asList(effects)); - } - - /** - * Add several firework effects to this firework. - * - * @param effects effects to add - * @return {@link FireworkBuilder} - * @throws IllegalArgumentException If effects is null - * @throws IllegalArgumentException If any effect is null (may be thrown after changes have occurred) - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public FireworkBuilder effect(@NotNull final List effects) { - if (effects.isEmpty()) { - return this; - } - - if (getItemStack().getType() == STAR) { - final FireworkEffectMeta effectMeta = (FireworkEffectMeta) getMeta(); - - effectMeta.setEffect(effects.get(0)); - setMeta(effectMeta); - return this; - } - - final FireworkMeta fireworkMeta = (FireworkMeta) getMeta(); - - fireworkMeta.addEffects(effects); - setMeta(fireworkMeta); - return this; - } - - /** - * Sets the approximate power of the firework. Each level of power is half - * a second of flight time. - * - * @param power the power of the firework, from 0-128 - * @return {@link FireworkBuilder} - * @throws IllegalArgumentException if {@literal height<0 or height>128} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public FireworkBuilder power(final int power) { - if (getItemStack().getType() == ROCKET) { - final FireworkMeta fireworkMeta = (FireworkMeta) getMeta(); - - fireworkMeta.setPower(power); - setMeta(fireworkMeta); - } - - return this; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java deleted file mode 100644 index a0bd942b..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/item/ItemBuilder.java +++ /dev/null @@ -1,268 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.item; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import dev.triumphteam.gui.components.util.SkullUtil; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.lang.reflect.Field; -import java.util.UUID; - -/** - * Main ItemBuilder - */ -public class ItemBuilder extends BaseItemBuilder { - - /** - * Constructor of the item builder - * - * @param itemStack The {@link ItemStack} of the item - */ - ItemBuilder(@NotNull final ItemStack itemStack) { - super(itemStack); - } - - /** - * Main method to create {@link ItemBuilder} - * - * @param itemStack The {@link ItemStack} you want to edit - * @return A new {@link ItemBuilder} - */ - @NotNull - @Contract("_ -> new") - public static ItemBuilder from(@NotNull final ItemStack itemStack) { - return new ItemBuilder(itemStack); - } - - - /** - * Alternative method to create {@link ItemBuilder} - * - * @param material The {@link Material} you want to create an item from - * @return A new {@link ItemBuilder} - */ - @NotNull - @Contract("_ -> new") - public static ItemBuilder from(@NotNull final Material material) { - return new ItemBuilder(new ItemStack(material)); - } - - /** - * Method for creating a {@link BannerBuilder} which will have BANNER specific methods - * - * @return A new {@link BannerBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract(" -> new") - public static BannerBuilder banner() { - return new BannerBuilder(); - } - - /** - * Method for creating a {@link BannerBuilder} which will have BANNER specific methods - * - * @param itemStack An existing BANNER {@link ItemStack} - * @return A new {@link BannerBuilder} - * @throws dev.triumphteam.gui.components.exception.GuiException if the item is not a BANNER - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> new") - public static BannerBuilder banner(@NotNull final ItemStack itemStack) { - return new BannerBuilder(itemStack); - } - - /** - * Method for creating a {@link BookBuilder} which will have {@link Material#WRITABLE_BOOK} / - * {@link Material#WRITTEN_BOOK} specific methods - * - * @param itemStack an existing {@link Material#WRITABLE_BOOK} / {@link Material#WRITTEN_BOOK} {@link ItemStack} - * @return A new {@link FireworkBuilder} - * @throws dev.triumphteam.gui.components.exception.GuiException if the item type is not {@link Material#WRITABLE_BOOK} - * or {@link Material#WRITTEN_BOOK} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> new") - public static BookBuilder book(@NotNull final ItemStack itemStack) { - return new BookBuilder(itemStack); - } - - /** - * Method for creating a {@link FireworkBuilder} which will have {@link Material#FIREWORK_ROCKET} specific methods - * - * @return A new {@link FireworkBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract(" -> new") - public static FireworkBuilder firework() { - return new FireworkBuilder(new ItemStack(Material.FIREWORK_ROCKET)); - } - - /** - * Method for creating a {@link FireworkBuilder} which will have {@link Material#FIREWORK_ROCKET} specific methods - * - * @param itemStack an existing {@link Material#FIREWORK_ROCKET} {@link ItemStack} - * @return A new {@link FireworkBuilder} - * @throws dev.triumphteam.gui.components.exception.GuiException if the item type is not {@link Material#FIREWORK_ROCKET} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> new") - public static FireworkBuilder firework(@NotNull final ItemStack itemStack) { - return new FireworkBuilder(itemStack); - } - - /** - * Method for creating a {@link MapBuilder} which will have {@link Material#MAP} specific methods - * - * @return A new {@link MapBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract(" -> new") - public static MapBuilder map() { - return new MapBuilder(); - } - - /** - * Method for creating a {@link MapBuilder} which will have @link Material#MAP} specific methods - * - * @param itemStack An existing {@link Material#MAP} {@link ItemStack} - * @return A new {@link MapBuilder} - * @throws dev.triumphteam.gui.components.exception.GuiException if the item type is not {@link Material#MAP} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> new") - public static MapBuilder map(@NotNull final ItemStack itemStack) { - return new MapBuilder(itemStack); - } - - /** - * Method for creating a {@link SkullBuilder} which will have PLAYER_HEAD specific methods - * - * @return A new {@link SkullBuilder} - */ - @NotNull - @Contract(" -> new") - public static SkullBuilder skull() { - return new SkullBuilder(); - } - - /** - * Method for creating a {@link SkullBuilder} which will have PLAYER_HEAD specific methods - * - * @param itemStack An existing PLAYER_HEAD {@link ItemStack} - * @return A new {@link SkullBuilder} - * @throws dev.triumphteam.gui.components.exception.GuiException if the item is not a player head - */ - @NotNull - @Contract("_ -> new") - public static SkullBuilder skull(@NotNull final ItemStack itemStack) { - return new SkullBuilder(itemStack); - } - - /** - * Method for creating a {@link FireworkBuilder} which will have {@link Material#FIREWORK_STAR} specific methods - * - * @return A new {@link FireworkBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract(" -> new") - public static FireworkBuilder star() { - return new FireworkBuilder(new ItemStack(Material.FIREWORK_STAR)); - } - - /** - * Method for creating a {@link FireworkBuilder} which will have {@link Material#FIREWORK_STAR} specific methods - * - * @param itemStack an existing {@link Material#FIREWORK_STAR} {@link ItemStack} - * @return A new {@link FireworkBuilder} - * @throws dev.triumphteam.gui.components.exception.GuiException if the item type is not {@link Material#FIREWORK_STAR} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> new") - public static FireworkBuilder star(@NotNull final ItemStack itemStack) { - return new FireworkBuilder(itemStack); - } - - /** - * Sets the skull texture - * - * @param texture The base64 texture - * @return {@link ItemBuilder} - * @deprecated In favor of {@link SkullBuilder#texture(String)}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public ItemBuilder setSkullTexture(@NotNull final String texture) { - if (!SkullUtil.isPlayerSkull(getItemStack())) return this; - - final SkullMeta skullMeta = (SkullMeta) getMeta(); - final GameProfile profile = new GameProfile(UUID.randomUUID(), null); - profile.getProperties().put("textures", new Property("textures", texture)); - final Field profileField; - - try { - profileField = skullMeta.getClass().getDeclaredField("profile"); - profileField.setAccessible(true); - profileField.set(skullMeta, profile); - } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException ex) { - ex.printStackTrace(); - } - - setMeta(skullMeta); - return this; - } - - /** - * Sets skull owner via bukkit methods - * - * @param player {@link OfflinePlayer} to set skull of - * @return {@link ItemBuilder} - * @deprecated In favor of {@link SkullBuilder#owner(OfflinePlayer)}, nothing changed just the name, will be removed in 3.0.1 - */ - @Deprecated - public ItemBuilder setSkullOwner(@NotNull final OfflinePlayer player) { - if (!SkullUtil.isPlayerSkull(getItemStack())) return this; - - final SkullMeta skullMeta = (SkullMeta) getMeta(); - skullMeta.setOwningPlayer(player); - - setMeta(skullMeta); - return this; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java deleted file mode 100644 index 082c56ac..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/item/MapBuilder.java +++ /dev/null @@ -1,133 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.item; - -import dev.triumphteam.gui.components.exception.GuiException; -import org.bukkit.Color; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.MapMeta; -import org.bukkit.map.MapView; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * Item builder for {@link Material#MAP} only - * - * @author GabyTM https://github.com/iGabyTM - * @since 3.0.1 - */ -public class MapBuilder extends BaseItemBuilder { - - private static final Material MAP = Material.MAP; - - MapBuilder() { - super(new ItemStack(MAP)); - } - - MapBuilder(@NotNull ItemStack itemStack) { - super(itemStack); - if (itemStack.getType() != MAP) { - throw new GuiException("MapBuilder requires the material to be a MAP!"); - } - } - - /** - * Sets the map color. A custom map color will alter the display of the map - * in an inventory slot. - * - * @param color the color to set - * @return {@link MapBuilder} - * @since 3.0.1 - */ - @NotNull - @Override - @Contract("_ -> this") - public MapBuilder color(@Nullable final Color color) { - final MapMeta mapMeta = (MapMeta) getMeta(); - - mapMeta.setColor(color); - setMeta(mapMeta); - return this; - } - - /** - * Sets the location name. A custom map color will alter the display of the - * map in an inventory slot. - * - * @param name the name to set - * @return {@link MapMeta} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public MapBuilder locationName(@Nullable final String name) { - final MapMeta mapMeta = (MapMeta) getMeta(); - - mapMeta.setLocationName(name); - setMeta(mapMeta); - return this; - } - - /** - * Sets if this map is scaling or not. - * - * @param scaling true to scale - * @return {@link MapMeta} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public MapBuilder scaling(final boolean scaling) { - final MapMeta mapMeta = (MapMeta) getMeta(); - - mapMeta.setScaling(scaling); - setMeta(mapMeta); - return this; - } - - /** - * Sets the associated map. This is used to determine what map is displayed. - * - *

- * The implementation may allow null to clear the associated map, but - * this is not required and is liable to generate a new (undefined) map when - * the item is first used. - * - * @param view the map to set - * @return {@link MapBuilder} - * @since 3.0.1 - */ - @NotNull - @Contract("_ -> this") - public MapBuilder view(@NotNull final MapView view) { - final MapMeta mapMeta = (MapMeta) getMeta(); - - mapMeta.setMapView(view); - setMeta(mapMeta); - return this; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java b/old-core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java deleted file mode 100644 index f6cec8cb..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/builder/item/SkullBuilder.java +++ /dev/null @@ -1,168 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.builder.item; - -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.properties.Property; -import dev.triumphteam.gui.components.exception.GuiException; -import dev.triumphteam.gui.components.util.SkullUtil; -import dev.triumphteam.gui.components.util.VersionHelper; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; -import org.bukkit.profile.PlayerProfile; -import org.bukkit.profile.PlayerTextures; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.lang.reflect.Field; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.UUID; - -/** - * New builder for skull only, created to separate the specific features for skulls - * Soon I'll add more useful features to this builder - */ -public final class SkullBuilder extends BaseItemBuilder { - - private static final Field PROFILE_FIELD; - - static { - Field field; - - try { - final SkullMeta skullMeta = (SkullMeta) SkullUtil.skull().getItemMeta(); - field = skullMeta.getClass().getDeclaredField("profile"); - field.setAccessible(true); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - field = null; - } - - PROFILE_FIELD = field; - } - - SkullBuilder() { - super(SkullUtil.skull()); - } - - SkullBuilder(final @NotNull ItemStack itemStack) { - super(itemStack); - if (!SkullUtil.isPlayerSkull(itemStack)) { - throw new GuiException("SkullBuilder requires the material to be a PLAYER_HEAD/SKULL_ITEM!"); - } - } - - /** - * Sets the skull texture using a BASE64 string - * - * @param texture The base64 texture - * @param profileId The unique id of the profile - * @return {@link SkullBuilder} - */ - @NotNull - @Contract("_, _ -> this") - public SkullBuilder texture(@NotNull final String texture, @NotNull final UUID profileId) { - if (!SkullUtil.isPlayerSkull(getItemStack())) return this; - - if (VersionHelper.IS_PLAYER_PROFILE_API) { - final String textureUrl = SkullUtil.getSkinUrl(texture); - - if (textureUrl == null) { - return this; - } - - final SkullMeta skullMeta = (SkullMeta) getMeta(); - final PlayerProfile profile = Bukkit.createPlayerProfile(profileId, ""); - final PlayerTextures textures = profile.getTextures(); - - try { - textures.setSkin(new URL(textureUrl)); - } catch (MalformedURLException e) { - e.printStackTrace(); - return this; - } - - profile.setTextures(textures); - skullMeta.setOwnerProfile(profile); - setMeta(skullMeta); - return this; - } - - if (PROFILE_FIELD == null) { - return this; - } - - final SkullMeta skullMeta = (SkullMeta) getMeta(); - final GameProfile profile = new GameProfile(profileId, ""); - profile.getProperties().put("textures", new Property("textures", texture)); - - try { - PROFILE_FIELD.set(skullMeta, profile); - } catch (IllegalArgumentException | IllegalAccessException ex) { - ex.printStackTrace(); - } - - setMeta(skullMeta); - return this; - } - - /** - * Sets the skull texture using a BASE64 string - * - * @param texture The base64 texture - * @return {@link SkullBuilder} - */ - @NotNull - @Contract("_ -> this") - public SkullBuilder texture(@NotNull final String texture) { - return texture(texture, UUID.randomUUID()); - } - - /** - * Sets skull owner via bukkit methods - * - * @param player {@link OfflinePlayer} to set skull of - * @return {@link SkullBuilder} - */ - @NotNull - @Contract("_ -> this") - public SkullBuilder owner(@NotNull final OfflinePlayer player) { - if (!SkullUtil.isPlayerSkull(getItemStack())) return this; - - final SkullMeta skullMeta = (SkullMeta) getMeta(); - - if (VersionHelper.IS_SKULL_OWNER_LEGACY) { - skullMeta.setOwner(player.getName()); - } else { - skullMeta.setOwningPlayer(player); - } - - setMeta(skullMeta); - return this; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/GuiAction.java b/old-core/src/main/java/dev/triumphteam/gui/components/GuiAction.java deleted file mode 100644 index 7ba5c7b2..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/GuiAction.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components; - -import org.bukkit.event.Event; - -@FunctionalInterface -public interface GuiAction { - - /** - * Executes the event passed to it - * - * @param event Inventory action - */ - void execute(final T event); - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/GuiPage.java b/old-core/src/main/java/dev/triumphteam/gui/components/GuiPage.java deleted file mode 100644 index 05b54a41..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/GuiPage.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components; - -public final class GuiPage { -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/GuiType.java b/old-core/src/main/java/dev/triumphteam/gui/components/GuiType.java deleted file mode 100644 index a2443060..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/GuiType.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components; - -import org.bukkit.event.inventory.InventoryType; -import org.jetbrains.annotations.NotNull; - -// TODO COMMENTS -public enum GuiType { - - CHEST(InventoryType.CHEST, 9), - WORKBENCH(InventoryType.WORKBENCH, 9), - HOPPER(InventoryType.HOPPER, 5), - DISPENSER(InventoryType.DISPENSER, 8), - BREWING(InventoryType.BREWING, 4); - - @NotNull - private final InventoryType inventoryType; - private final int limit; - - GuiType(@NotNull final InventoryType inventoryType, final int limit) { - this.inventoryType = inventoryType; - this.limit = limit; - } - - @NotNull - public InventoryType getInventoryType() { - return inventoryType; - } - - public int getLimit() { - return limit; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java b/old-core/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java deleted file mode 100644 index 2a1597cc..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/InteractionModifier.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components; - -import java.util.Collections; -import java.util.EnumSet; -import java.util.Set; - -/** - * Used to control what kind of interaction can happen inside a GUI - * - * @since 3.0.0 - * @author SecretX - */ -public enum InteractionModifier { - PREVENT_ITEM_PLACE, - PREVENT_ITEM_TAKE, - PREVENT_ITEM_SWAP, - PREVENT_ITEM_DROP, - PREVENT_OTHER_ACTIONS; - - public static final Set VALUES = Collections.unmodifiableSet(EnumSet.allOf(InteractionModifier.class)); -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/ScrollType.java b/old-core/src/main/java/dev/triumphteam/gui/components/ScrollType.java deleted file mode 100644 index 6ffa597d..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/ScrollType.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components; - -import dev.triumphteam.gui.guis.ScrollingGui; - -/** - * Possible Scroll types for the {@link ScrollingGui} - */ -public enum ScrollType { - - HORIZONTAL, - VERTICAL - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/Serializable.java b/old-core/src/main/java/dev/triumphteam/gui/components/Serializable.java deleted file mode 100644 index dc3516b0..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/Serializable.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components; - -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public interface Serializable { - - List encodeGui(); - - void decodeGui(@NotNull final List gui); - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java b/old-core/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java deleted file mode 100644 index dbf38b93..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/exception/GuiException.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.exception; - -public final class GuiException extends RuntimeException { - public GuiException(String message) { - super(message); - } -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java b/old-core/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java deleted file mode 100644 index 31863fdd..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/nbt/LegacyNbt.java +++ /dev/null @@ -1,313 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.nbt; - -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Objects; - -/** - * Class to set / get NBT tags from items. - * I hate this class. - */ -public final class LegacyNbt implements NbtWrapper { - - public static final String PACKAGE_NAME = Bukkit.getServer().getClass().getPackage().getName(); - public static final String NMS_VERSION = PACKAGE_NAME.substring(PACKAGE_NAME.lastIndexOf(46) + 1); - - private static Method getStringMethod; - private static Method setStringMethod; - private static Method setBooleanMethod; - private static Method hasTagMethod; - private static Method getTagMethod; - private static Method setTagMethod; - private static Method removeTagMethod; - private static Method asNMSCopyMethod; - private static Method asBukkitCopyMethod; - - private static Constructor nbtCompoundConstructor; - - static { - try { - getStringMethod = Objects.requireNonNull(getNMSClass("NBTTagCompound")).getMethod("getString", String.class); - removeTagMethod = Objects.requireNonNull(getNMSClass("NBTTagCompound")).getMethod("remove", String.class); - setStringMethod = Objects.requireNonNull(getNMSClass("NBTTagCompound")).getMethod("setString", String.class, String.class); - setBooleanMethod = Objects.requireNonNull(getNMSClass("NBTTagCompound")).getMethod("setBoolean", String.class, boolean.class); - hasTagMethod = Objects.requireNonNull(getNMSClass("ItemStack")).getMethod("hasTag"); - getTagMethod = Objects.requireNonNull(getNMSClass("ItemStack")).getMethod("getTag"); - setTagMethod = Objects.requireNonNull(getNMSClass("ItemStack")).getMethod("setTag", getNMSClass("NBTTagCompound")); - nbtCompoundConstructor = Objects.requireNonNull(getNMSClass("NBTTagCompound")).getDeclaredConstructor(); - asNMSCopyMethod = Objects.requireNonNull(getCraftItemStackClass()).getMethod("asNMSCopy", ItemStack.class); - asBukkitCopyMethod = Objects.requireNonNull(getCraftItemStackClass()).getMethod("asBukkitCopy", getNMSClass("ItemStack")); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } - } - - /** - * Sets an NBT tag to the an {@link ItemStack}. - * - * @param itemStack The current {@link ItemStack} to be set. - * @param key The NBT key to use. - * @param value The tag value to set. - * @return An {@link ItemStack} that has NBT set. - */ - @Override - public ItemStack setString(@NotNull final ItemStack itemStack, final String key, final String value) { - if (itemStack.getType() == Material.AIR) return itemStack; - - Object nmsItemStack = asNMSCopy(itemStack); - Object itemCompound = hasTag(nmsItemStack) ? getTag(nmsItemStack) : newNBTTagCompound(); - - setString(itemCompound, key, value); - setTag(nmsItemStack, itemCompound); - - return asBukkitCopy(nmsItemStack); - } - - /** - * Removes a tag from an {@link ItemStack}. - * - * @param itemStack The current {@link ItemStack} to be remove. - * @param key The NBT key to remove. - * @return An {@link ItemStack} that has the tag removed. - */ - @Override - public ItemStack removeTag(@NotNull final ItemStack itemStack, final String key) { - if (itemStack.getType() == Material.AIR) return itemStack; - - Object nmsItemStack = asNMSCopy(itemStack); - Object itemCompound = hasTag(nmsItemStack) ? getTag(nmsItemStack) : newNBTTagCompound(); - - remove(itemCompound, key); - setTag(nmsItemStack, itemCompound); - - return asBukkitCopy(nmsItemStack); - } - - /** - * Sets a boolean to the {@link ItemStack}. - * Mainly used for setting an item to be unbreakable on older versions. - * - * @param itemStack The {@link ItemStack} to set the boolean to. - * @param key The key to use. - * @param value The boolean value. - * @return An {@link ItemStack} with a boolean value set. - */ - @Override - public ItemStack setBoolean(@NotNull final ItemStack itemStack, final String key, final boolean value) { - if (itemStack.getType() == Material.AIR) return itemStack; - - Object nmsItemStack = asNMSCopy(itemStack); - Object itemCompound = hasTag(nmsItemStack) ? getTag(nmsItemStack) : newNBTTagCompound(); - - setBoolean(itemCompound, key, value); - setTag(nmsItemStack, itemCompound); - - return asBukkitCopy(nmsItemStack); - } - - /** - * Gets the NBT tag based on a given key. - * - * @param itemStack The {@link ItemStack} to get from. - * @param key The key to look for. - * @return The tag that was stored in the {@link ItemStack}. - */ - @Nullable - @Override - public String getString(@NotNull final ItemStack itemStack, final String key) { - if (itemStack.getType() == Material.AIR) return null; - - Object nmsItemStack = asNMSCopy(itemStack); - Object itemCompound = hasTag(nmsItemStack) ? getTag(nmsItemStack) : newNBTTagCompound(); - - return getString(itemCompound, key); - } - - /** - * Mimics the itemCompound#setString method. - * - * @param itemCompound The ItemCompound. - * @param key The key to add. - * @param value The value to add. - */ - private static void setString(final Object itemCompound, final String key, final String value) { - try { - setStringMethod.invoke(itemCompound, key, value); - } catch (IllegalAccessException | InvocationTargetException ignored) { - } - } - - private static void setBoolean(final Object itemCompound, final String key, final boolean value) { - try { - setBooleanMethod.invoke(itemCompound, key, value); - } catch (IllegalAccessException | InvocationTargetException ignored) { - } - } - - /** - * Mimics the itemCompound#remove method. - * - * @param itemCompound The ItemCompound. - * @param key The key to remove. - */ - private static void remove(final Object itemCompound, final String key) { - try { - removeTagMethod.invoke(itemCompound, key); - } catch (IllegalAccessException | InvocationTargetException ignored) { - } - } - - /** - * Mimics the itemCompound#getString method. - * - * @param itemCompound The ItemCompound. - * @param key The key to get from. - * @return A string with the value from the key. - */ - private static String getString(final Object itemCompound, final String key) { - try { - return (String) getStringMethod.invoke(itemCompound, key); - } catch (IllegalAccessException | InvocationTargetException e) { - return null; - } - } - - /** - * Mimics the nmsItemStack#hasTag method. - * - * @param nmsItemStack the NMS ItemStack to check from. - * @return True or false depending if it has tag or not. - */ - private static boolean hasTag(final Object nmsItemStack) { - try { - return (boolean) hasTagMethod.invoke(nmsItemStack); - } catch (IllegalAccessException | InvocationTargetException e) { - return false; - } - } - - /** - * Mimics the nmsItemStack#getTag method. - * - * @param nmsItemStack The NMS ItemStack to get from. - * @return The tag compound. - */ - public static Object getTag(final Object nmsItemStack) { - try { - return getTagMethod.invoke(nmsItemStack); - } catch (IllegalAccessException | InvocationTargetException e) { - return null; - } - } - - /** - * Mimics the nmsItemStack#setTag method. - * - * @param nmsItemStack the NMS ItemStack to set the tag to. - * @param itemCompound The item compound to set. - */ - private static void setTag(final Object nmsItemStack, final Object itemCompound) { - try { - setTagMethod.invoke(nmsItemStack, itemCompound); - } catch (IllegalAccessException | InvocationTargetException ignored) { - } - } - - /** - * Mimics the new NBTTagCompound instantiation. - * - * @return The new NBTTagCompound. - */ - private static Object newNBTTagCompound() { - try { - return nbtCompoundConstructor.newInstance(); - } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { - return null; - } - } - - /** - * Mimics the CraftItemStack#asNMSCopy method. - * - * @param itemStack The ItemStack to make NMS copy. - * @return An NMS copy of the ItemStack. - */ - public static Object asNMSCopy(final ItemStack itemStack) { - try { - return asNMSCopyMethod.invoke(null, itemStack); - } catch (IllegalAccessException | InvocationTargetException e) { - return null; - } - } - - /** - * Mimics the CraftItemStack#asBukkitCopy method. - * - * @param nmsItemStack The NMS ItemStack to turn into {@link ItemStack}. - * @return The new {@link ItemStack}. - */ - public static ItemStack asBukkitCopy(final Object nmsItemStack) { - try { - return (ItemStack) asBukkitCopyMethod.invoke(null, nmsItemStack); - } catch (IllegalAccessException | InvocationTargetException e) { - return null; - } - } - - /** - * Gets the NMS class from class name. - * - * @return The NMS class. - */ - private static Class getNMSClass(final String className) { - try { - return Class.forName("net.minecraft.server." + NMS_VERSION + "." + className); - } catch (ClassNotFoundException e) { - return null; - } - } - - /** - * Gets the NMS craft {@link ItemStack} class from class name. - * - * @return The NMS craft {@link ItemStack} class. - */ - private static Class getCraftItemStackClass() { - try { - return Class.forName("org.bukkit.craftbukkit." + NMS_VERSION + ".inventory.CraftItemStack"); - } catch (ClassNotFoundException e) { - return null; - } - } - -} \ No newline at end of file diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java b/old-core/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java deleted file mode 100644 index 6562ffaa..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/nbt/NbtWrapper.java +++ /dev/null @@ -1,72 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.nbt; - -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public interface NbtWrapper { - - /** - * Sets an String NBT tag to the an {@link ItemStack}. - * - * @param itemStack The current {@link ItemStack} to be set. - * @param key The NBT key to use. - * @param value The tag value to set. - * @return An {@link ItemStack} that has NBT set. - */ - ItemStack setString(@NotNull final ItemStack itemStack, final String key, final String value); - - /** - * Removes a tag from an {@link ItemStack}. - * - * @param itemStack The current {@link ItemStack} to be remove. - * @param key The NBT key to remove. - * @return An {@link ItemStack} that has the tag removed. - */ - ItemStack removeTag(@NotNull final ItemStack itemStack, final String key); - - /** - * Sets a boolean to the {@link ItemStack}. - * Mainly used for setting an item to be unbreakable on older versions. - * - * @param itemStack The {@link ItemStack} to set the boolean to. - * @param key The key to use. - * @param value The boolean value. - * @return An {@link ItemStack} with a boolean value set. - */ - ItemStack setBoolean(@NotNull final ItemStack itemStack, final String key, final boolean value); - - /** - * Gets the NBT tag based on a given key. - * - * @param itemStack The {@link ItemStack} to get from. - * @param key The key to look for. - * @return The tag that was stored in the {@link ItemStack}. - */ - @Nullable - String getString(@NotNull final ItemStack itemStack, final String key); - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java b/old-core/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java deleted file mode 100644 index 8f75fb02..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/nbt/Pdc.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.nbt; - -import org.bukkit.NamespacedKey; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataType; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -/** - * Wrapper for compatibility with {@link LegacyNbt}. - * This ideally wouldn't need exist, but legacy. - */ -public final class Pdc implements NbtWrapper { - - /** - * Plugin instance required for the {@link NamespacedKey}. - */ - private static final Plugin PLUGIN = JavaPlugin.getProvidingPlugin(Pdc.class); - - /** - * Sets an String NBT tag to the an {@link ItemStack}. - * - * @param itemStack The current {@link ItemStack} to be set. - * @param key The NBT key to use. - * @param value The tag value to set. - * @return An {@link ItemStack} that has NBT set. - */ - @Override - public ItemStack setString(@NotNull final ItemStack itemStack, final String key, final String value) { - final ItemMeta meta = itemStack.getItemMeta(); - if (meta == null) return itemStack; - meta.getPersistentDataContainer().set(new NamespacedKey(PLUGIN, key), PersistentDataType.STRING, value); - itemStack.setItemMeta(meta); - return itemStack; - } - - /** - * Removes a tag from an {@link ItemStack}. - * - * @param itemStack The current {@link ItemStack} to be remove. - * @param key The NBT key to remove. - * @return An {@link ItemStack} that has the tag removed. - */ - @Override - public ItemStack removeTag(@NotNull final ItemStack itemStack, final String key) { - final ItemMeta meta = itemStack.getItemMeta(); - if (meta == null) return itemStack; - meta.getPersistentDataContainer().remove(new NamespacedKey(PLUGIN, key)); - itemStack.setItemMeta(meta); - return itemStack; - } - - /** - * Sets a boolean to the {@link ItemStack}. - * Mainly used for setting an item to be unbreakable on older versions. - * - * @param itemStack The {@link ItemStack} to set the boolean to. - * @param key The key to use. - * @param value The boolean value. - * @return An {@link ItemStack} with a boolean value set. - */ - @Override - public ItemStack setBoolean(@NotNull final ItemStack itemStack, final String key, final boolean value) { - final ItemMeta meta = itemStack.getItemMeta(); - if (meta == null) return itemStack; - meta.getPersistentDataContainer().set(new NamespacedKey(PLUGIN, key), PersistentDataType.BYTE, value ? (byte) 1 : 0); - itemStack.setItemMeta(meta); - return itemStack; - } - - /** - * Gets the NBT tag based on a given key. - * - * @param itemStack The {@link ItemStack} to get from. - * @param key The key to look for. - * @return The tag that was stored in the {@link ItemStack}. - */ - @Nullable - @Override - public String getString(@NotNull final ItemStack itemStack, final String key) { - final ItemMeta meta = itemStack.getItemMeta(); - if (meta == null) return null; - return meta.getPersistentDataContainer().get(new NamespacedKey(PLUGIN, key), PersistentDataType.STRING); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java deleted file mode 100644 index b75c0090..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/util/GuiFiller.java +++ /dev/null @@ -1,247 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.util; - -import dev.triumphteam.gui.components.GuiType; -import dev.triumphteam.gui.components.exception.GuiException; -import dev.triumphteam.gui.guis.BaseGui; -import dev.triumphteam.gui.guis.GuiItem; -import dev.triumphteam.gui.guis.PaginatedGui; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * TODO fix comments - */ -public final class GuiFiller { - - private final BaseGui gui; - - public GuiFiller(final BaseGui gui) { - this.gui = gui; - } - - /** - * Fills top portion of the GUI - * - * @param guiItem GuiItem - */ - public void fillTop(@NotNull final GuiItem guiItem) { - fillTop(Collections.singletonList(guiItem)); - } - - /** - * Fills top portion of the GUI with alternation - * - * @param guiItems List of GuiItems - */ - public void fillTop(@NotNull final List guiItems) { - final List items = repeatList(guiItems); - for (int i = 0; i < 9; i++) { - if (!gui.getGuiItems().containsKey(i)) gui.setItem(i, items.get(i)); - } - } - - /** - * Fills bottom portion of the GUI - * - * @param guiItem GuiItem - */ - public void fillBottom(@NotNull final GuiItem guiItem) { - fillBottom(Collections.singletonList(guiItem)); - } - - /** - * Fills bottom portion of the GUI with alternation - * - * @param guiItems GuiItem - */ - public void fillBottom(@NotNull final List guiItems) { - final int rows = gui.getRows(); - final List items = repeatList(guiItems); - for (int i = 9; i > 0; i--) { - if (gui.getGuiItems().get((rows * 9) - i) == null) { - gui.setItem((rows * 9) - i, items.get(i)); - } - } - } - - /** - * Fills the outside section of the GUI with a GuiItem - * - * @param guiItem GuiItem - */ - public void fillBorder(@NotNull final GuiItem guiItem) { - fillBorder(Collections.singletonList(guiItem)); - } - - /** - * Fill empty slots with Multiple GuiItems, goes through list and starts again - * - * @param guiItems GuiItem - */ - public void fillBorder(@NotNull final List guiItems) { - final int rows = gui.getRows(); - if (rows <= 2) return; - - final List items = repeatList(guiItems); - - for (int i = 0; i < rows * 9; i++) { - if ((i <= 8) - || (i >= (rows * 9) - 8) && (i <= (rows * 9) - 2) - || i % 9 == 0 - || i % 9 == 8) - gui.setItem(i, items.get(i)); - - } - } - - /** - * Fills rectangle from points within the GUI - * - * @param rowFrom Row point 1 - * @param colFrom Col point 1 - * @param rowTo Row point 2 - * @param colTo Col point 2 - * @param guiItem Item to fill with - * @author Harolds - */ - public void fillBetweenPoints(final int rowFrom, final int colFrom, final int rowTo, final int colTo, @NotNull final GuiItem guiItem) { - fillBetweenPoints(rowFrom, colFrom, rowTo, colTo, Collections.singletonList(guiItem)); - } - - /** - * Fills rectangle from points within the GUI - * - * @param rowFrom Row point 1 - * @param colFrom Col point 1 - * @param rowTo Row point 2 - * @param colTo Col point 2 - * @param guiItems Item to fill with - * @author Harolds - */ - public void fillBetweenPoints(final int rowFrom, final int colFrom, final int rowTo, final int colTo, @NotNull final List guiItems) { - final int minRow = Math.min(rowFrom, rowTo); - final int maxRow = Math.max(rowFrom, rowTo); - final int minCol = Math.min(colFrom, colTo); - final int maxCol = Math.max(colFrom, colTo); - - final int rows = gui.getRows(); - final List items = repeatList(guiItems); - - for (int row = 1; row <= rows; row++) { - for (int col = 1; col <= 9; col++) { - final int slot = getSlotFromRowCol(row, col); - if (!((row >= minRow && row <= maxRow) && (col >= minCol && col <= maxCol))) - continue; - - gui.setItem(slot, items.get(slot)); - } - } - } - - /** - * Sets an GuiItem to fill up the entire inventory where there is no other item - * - * @param guiItem The item to use as fill - */ - public void fill(@NotNull final GuiItem guiItem) { - fill(Collections.singletonList(guiItem)); - } - - /** - * Fill empty slots with Multiple GuiItems, goes through list and starts again - * - * @param guiItems GuiItem - */ - public void fill(@NotNull final List guiItems) { - if (gui instanceof PaginatedGui) { - throw new GuiException("Full filling a GUI is not supported in a Paginated GUI!"); - } - - final GuiType type = gui.guiType(); - - final int fill; - if (type == GuiType.CHEST) { - fill = gui.getRows() * type.getLimit(); - } else { - fill = type.getLimit(); - } - - final List items = repeatList(guiItems); - for (int i = 0; i < fill; i++) { - if (gui.getGuiItems().get(i) == null) gui.setItem(i, items.get(i)); - } - } - - /** - * Fills specified side of the GUI with a GuiItem - * - * @param guiItems GuiItem - */ - public void fillSide(@NotNull final Side side, @NotNull final List guiItems) { - switch (side) { - case LEFT: - this.fillBetweenPoints(1, 1, gui.getRows(), 1, guiItems); - case RIGHT: - this.fillBetweenPoints(1, 9, gui.getRows(), 9, guiItems); - case BOTH: - this.fillBetweenPoints(1, 1, gui.getRows(), 1, guiItems); - this.fillBetweenPoints(1, 9, gui.getRows(), 9, guiItems); - } - } - - /** - * Repeats a list of items. Allows for alternating items - * Stores references to existing objects -> Does not create new objects - * - * @param guiItems List of items to repeat - * @return New list - */ - private List repeatList(@NotNull final List guiItems) { - final List repeated = new ArrayList<>(); - Collections.nCopies(gui.getRows() * 9, guiItems).forEach(repeated::addAll); - return repeated; - } - - /** - * Gets the slot from the row and col passed - * - * @param row The row - * @param col The col - * @return The new slot - */ - private int getSlotFromRowCol(final int row, final int col) { - return (col + (row - 1) * 9) - 1; - } - - public enum Side { - LEFT, - RIGHT, - BOTH - } -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java deleted file mode 100644 index 1c034d83..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/util/ItemNbt.java +++ /dev/null @@ -1,97 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.util; - -import dev.triumphteam.gui.components.nbt.LegacyNbt; -import dev.triumphteam.gui.components.nbt.NbtWrapper; -import dev.triumphteam.gui.components.nbt.Pdc; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -/** - * Ideally this wouldn't need to be an util, but because of the {@link LegacyNbt} it makes it easier. Legacy.. - * Will use the PDC wrapper if version is higher than 1.14 - */ -public final class ItemNbt { - - private static final NbtWrapper nbt = selectNbt(); - - /** - * Sets an NBT tag to the an {@link ItemStack}. - * - * @param itemStack The current {@link ItemStack} to be set. - * @param key The NBT key to use. - * @param value The tag value to set. - * @return An {@link ItemStack} that has NBT set. - */ - public static ItemStack setString(@NotNull final ItemStack itemStack, @NotNull final String key, @NotNull final String value) { - return nbt.setString(itemStack, key, value); - } - - /** - * Gets the NBT tag based on a given key. - * - * @param itemStack The {@link ItemStack} to get from. - * @param key The key to look for. - * @return The tag that was stored in the {@link ItemStack}. - */ - public static String getString(@NotNull final ItemStack itemStack, @NotNull final String key) { - return nbt.getString(itemStack, key); - } - - /** - * Sets a boolean to the {@link ItemStack}. - * Mainly used for setting an item to be unbreakable on older versions. - * - * @param itemStack The {@link ItemStack} to set the boolean to. - * @param key The key to use. - * @param value The boolean value. - * @return An {@link ItemStack} with a boolean value set. - */ - public static ItemStack setBoolean(@NotNull final ItemStack itemStack, @NotNull final String key, final boolean value) { - return nbt.setBoolean(itemStack, key, value); - } - - /** - * Removes a tag from an {@link ItemStack}. - * - * @param itemStack The current {@link ItemStack} to be remove. - * @param key The NBT key to remove. - * @return An {@link ItemStack} that has the tag removed. - */ - public static ItemStack removeTag(@NotNull final ItemStack itemStack, @NotNull final String key) { - return nbt.removeTag(itemStack, key); - } - - /** - * Selects which {@link NbtWrapper} to use based on server version. - * - * @return A {@link NbtWrapper} implementation, {@link Pdc} if version is higher than 1.14 and {@link LegacyNbt} if not. - */ - private static NbtWrapper selectNbt() { - if (VersionHelper.IS_PDC_VERSION) return new Pdc(); - return new LegacyNbt(); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/util/Legacy.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/Legacy.java deleted file mode 100644 index e955eaa5..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/util/Legacy.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.util; - -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; - -public final class Legacy { - - /** - * Since old versions and fucking spigot don't use the components, I use the serializer - * with the stupid format to guarantee compatibility - */ - public static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder() - .hexColors() - .useUnusualXRepeatedCharacterHexFormat() - .build(); - - private Legacy() { - throw new UnsupportedOperationException("Class should not be instantiated!"); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java deleted file mode 100644 index 36a10f7b..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/util/SkullUtil.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.util; - -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import org.bukkit.Material; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.Base64; - -public final class SkullUtil { - - /** - * The main SKULL material for the version - */ - private static final Material SKULL = getSkullMaterial(); - private static final Gson GSON = new Gson(); - - /** - * Gets the correct {@link Material} for the version - * - * @return The correct SKULL {@link Material} - */ - private static Material getSkullMaterial() { - if (VersionHelper.IS_ITEM_LEGACY) { - return Material.valueOf("SKULL_ITEM"); - } - - return Material.PLAYER_HEAD; - } - - /** - * Create a player skull - * - * @return player skull - */ - @SuppressWarnings("deprecation") - public static ItemStack skull() { - return VersionHelper.IS_ITEM_LEGACY ? new ItemStack(SKULL, 1, (short) 3) : new ItemStack(SKULL); - } - - /** - * Checks if an {@link ItemStack} is a player skull - * - * @param item item to check - * @return whether the item is a player skull - */ - @SuppressWarnings("deprecation") - public static boolean isPlayerSkull(@NotNull final ItemStack item) { - if (VersionHelper.IS_ITEM_LEGACY) { - return item.getType() == SKULL && item.getDurability() == (short) 3; - } - - return item.getType() == SKULL; - } - - /** - * Decode a base64 string and extract the url of the skin. Example: - *
- * - Base64: {@code eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGNlYjE3MDhkNTQwNGVmMzI2MTAzZTdiNjA1NTljOTE3OGYzZGNlNzI5MDA3YWM5YTBiNDk4YmRlYmU0NjEwNyJ9fX0=} - *
- * - JSON: {@code {"textures":{"SKIN":{"url":"http://textures.minecraft.net/texture/dceb1708d5404ef326103e7b60559c9178f3dce729007ac9a0b498bdebe46107"}}}} - *
- * - Result: {@code http://textures.minecraft.net/texture/dceb1708d5404ef326103e7b60559c9178f3dce729007ac9a0b498bdebe46107} - * @param base64Texture the texture - * @return the url of the texture if found, otherwise {@code null} - */ - public static String getSkinUrl(String base64Texture) { - final String decoded = new String(Base64.getDecoder().decode(base64Texture)); - final JsonObject object = GSON.fromJson(decoded, JsonObject.class); - - final JsonElement textures = object.get("textures"); - - if (textures == null) { - return null; - } - - final JsonElement skin = textures.getAsJsonObject().get("SKIN"); - - if (skin == null) { - return null; - } - - final JsonElement url = skin.getAsJsonObject().get("url"); - return url == null ? null : url.getAsString(); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java b/old-core/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java deleted file mode 100644 index 27eb0607..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/components/util/VersionHelper.java +++ /dev/null @@ -1,166 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.components.util; - -import com.google.common.primitives.Ints; -import dev.triumphteam.gui.components.exception.GuiException; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.jetbrains.annotations.NotNull; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Class for detecting server version for legacy support :( - */ -public final class VersionHelper { - - private static final String NMS_VERSION = getNmsVersion(); - - // Unbreakable change - private static final int V1_11 = 1110; - // Material and components on items change - private static final int V1_13 = 1130; - // PDC and customModelData - private static final int V1_14 = 1140; - // Paper adventure changes - private static final int V1_16_5 = 1165; - // SkullMeta#setOwningPlayer was added - private static final int V1_12_1 = 1121; - // PlayerProfile API - private static final int V1_20_1 = 1201; - - private static final int CURRENT_VERSION = getCurrentVersion(); - - private static final boolean IS_PAPER = checkPaper(); - - /** - * Checks if the version supports Components or not - * Spigot always false - */ - public static final boolean IS_COMPONENT_LEGACY = CURRENT_VERSION < V1_16_5; - - /** - * Checks if the version is lower than 1.13 due to the item changes - */ - public static final boolean IS_ITEM_LEGACY = CURRENT_VERSION < V1_13; - - /** - * Checks if the version supports the {@link org.bukkit.inventory.meta.ItemMeta#setUnbreakable(boolean)} method - */ - public static final boolean IS_UNBREAKABLE_LEGACY = CURRENT_VERSION < V1_11; - - /** - * Checks if the version supports {@link org.bukkit.persistence.PersistentDataContainer} - */ - public static final boolean IS_PDC_VERSION = CURRENT_VERSION >= V1_14; - - /** - * Checks if the version doesn't have {@link org.bukkit.inventory.meta.SkullMeta#setOwningPlayer(OfflinePlayer)} and - * {@link org.bukkit.inventory.meta.SkullMeta#setOwner(String)} should be used instead - */ - public static final boolean IS_SKULL_OWNER_LEGACY = CURRENT_VERSION < V1_12_1; - - /** - * Checks if the version has {@link org.bukkit.inventory.meta.ItemMeta#setCustomModelData(Integer)} - */ - public static final boolean IS_CUSTOM_MODEL_DATA = CURRENT_VERSION >= V1_14; - - /** - * Checks if the version has {@link org.bukkit.profile.PlayerProfile} - */ - public static final boolean IS_PLAYER_PROFILE_API = CURRENT_VERSION >= V1_20_1; - - /** - * Checks if the server is Folia - */ - public static final boolean IS_FOLIA = checkFolia(); - - /** - * Check if the server has access to the Paper API - * Taken from PaperLib - * - * @return True if on Paper server (or forks), false anything else - */ - private static boolean checkPaper() { - try { - Class.forName("com.destroystokyo.paper.PaperConfig"); - return true; - } catch (ClassNotFoundException ignored) { - return false; - } - } - - /** - * Check if the server has access to the Folia API - * Taken from Folia - * - * @return True if on Folia server (or forks), false anything else - */ - private static boolean checkFolia() { - try { - Class.forName("io.papermc.paper.threadedregions.RegionizedServer"); - return true; - } catch (ClassNotFoundException ignored) { - return false; - } - } - - /** - * Gets the current server version - * - * @return A protocol like number representing the version, for example 1.16.5 - 1165 - */ - private static int getCurrentVersion() { - // No need to cache since will only run once - final Matcher matcher = Pattern.compile("(?\\d+\\.\\d+)(?\\.\\d+)?").matcher(Bukkit.getBukkitVersion()); - - final StringBuilder stringBuilder = new StringBuilder(); - if (matcher.find()) { - stringBuilder.append(matcher.group("version").replace(".", "")); - final String patch = matcher.group("patch"); - if (patch == null) stringBuilder.append("0"); - else stringBuilder.append(patch.replace(".", "")); - } - - //noinspection UnstableApiUsage - final Integer version = Ints.tryParse(stringBuilder.toString()); - - // Should never fail - if (version == null) throw new GuiException("Could not retrieve server version!"); - - return version; - } - - private static String getNmsVersion() { - final String version = Bukkit.getServer().getClass().getPackage().getName(); - return version.substring(version.lastIndexOf('.') + 1); - } - - public static Class craftClass(@NotNull final String name) throws ClassNotFoundException { - return Class.forName("org.bukkit.craftbukkit." + NMS_VERSION + "." + name); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/BaseGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/BaseGui.java deleted file mode 100644 index 34ebc581..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/BaseGui.java +++ /dev/null @@ -1,1032 +0,0 @@ -/** - * MIT License - *

- * Copyright (c) 2021 TriumphTeam - *

- * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - *

- * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - *

- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import dev.triumphteam.gui.components.GuiAction; -import dev.triumphteam.gui.components.GuiType; -import dev.triumphteam.gui.components.InteractionModifier; -import dev.triumphteam.gui.components.exception.GuiException; -import dev.triumphteam.gui.components.util.GuiFiller; -import dev.triumphteam.gui.components.util.Legacy; -import dev.triumphteam.gui.components.util.VersionHelper; -import net.kyori.adventure.text.Component; -import org.bukkit.Bukkit; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.inventory.InventoryDragEvent; -import org.bukkit.event.inventory.InventoryOpenEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - - -/** - * Base class that every GUI extends. - * Contains all the basics for the GUI to work. - * Main and simplest implementation of this is {@link Gui}. - */ -@SuppressWarnings("unused") -public abstract class BaseGui implements InventoryHolder { - - // The plugin instance for registering the event and for the close delay. - private static final Plugin plugin = JavaPlugin.getProvidingPlugin(BaseGui.class); - - // Registering the listener class. - static { - Bukkit.getPluginManager().registerEvents(new GuiListener(), plugin); - // TODO might join these two - Bukkit.getPluginManager().registerEvents(new InteractionModifierListener(), plugin); - } - - // Gui filler. - private final GuiFiller filler = new GuiFiller(this); - // Contains all items the GUI will have. - private final Map guiItems; - // Actions for specific slots. - private final Map> slotActions; - // Interaction modifiers. - private final Set interactionModifiers; - // Main inventory. - private Inventory inventory; - // title - private String title; - private int rows = 1; - // Gui type, defaults to chest. - private GuiType guiType = GuiType.CHEST; - // Action to execute when clicking on any item. - private GuiAction defaultClickAction; - // Action to execute when clicking on the top part of the GUI only. - private GuiAction defaultTopClickAction; - // Action to execute when clicking on the player Inventory. - private GuiAction playerInventoryAction; - // Action to execute when dragging the item on the GUI. - private GuiAction dragAction; - // Action to execute when GUI closes. - private GuiAction closeGuiAction; - // Action to execute when GUI opens. - private GuiAction openGuiAction; - // Action to execute when clicked outside the GUI. - private GuiAction outsideClickAction; - - // Whether the GUI is updating. - private boolean updating; - - // Whether should run the actions from the close and open methods. - private boolean runCloseAction = true; - private boolean runOpenAction = true; - - /** - * The main constructor, using {@link String}. - * - * @param rows The amount of rows to use. - * @param title The GUI title using {@link String}. - * @param interactionModifiers Modifiers to select which interactions are allowed. - * @since 3.0.0. - */ - public BaseGui(final int rows, @NotNull final String title, @NotNull final Set interactionModifiers) { - int finalRows = rows; - if (!(rows >= 1 && rows <= 6)) finalRows = 1; - this.rows = finalRows; - this.interactionModifiers = safeCopyOf(interactionModifiers); - this.title = title; - int inventorySize = this.rows * 9; - this.inventory = Bukkit.createInventory(this, inventorySize, title); - this.slotActions = new LinkedHashMap<>(inventorySize); - this.guiItems = new LinkedHashMap<>(inventorySize); - } - - /** - * Alternative constructor that takes {@link GuiType} instead of rows number. - * - * @param guiType The {@link GuiType} to use. - * @param title The GUI title using {@link String}. - * @param interactionModifiers Modifiers to select which interactions are allowed. - * @since 3.0.0 - */ - public BaseGui(@NotNull final GuiType guiType, @NotNull final String title, @NotNull final Set interactionModifiers) { - this.guiType = guiType; - this.interactionModifiers = safeCopyOf(interactionModifiers); - this.title = title; - int inventorySize = guiType.getLimit(); - this.inventory = Bukkit.createInventory(this, guiType.getInventoryType(), title); - this.slotActions = new LinkedHashMap<>(inventorySize); - this.guiItems = new LinkedHashMap<>(inventorySize); - } - - /** - * Legacy constructor that takes rows and title. - * - * @param rows The amount of rows the GUI should have. - * @param title The GUI title. - * @deprecated In favor of {@link BaseGui#BaseGui(int, String, Set)}. - */ - @Deprecated - public BaseGui(final int rows, @NotNull final String title) { - int finalRows = rows; - if (!(rows >= 1 && rows <= 6)) finalRows = 1; - this.rows = finalRows; - this.interactionModifiers = EnumSet.noneOf(InteractionModifier.class); - this.title = title; - - inventory = Bukkit.createInventory(this, this.rows * 9, title); - slotActions = new LinkedHashMap<>(); - guiItems = new LinkedHashMap<>(); - } - - /** - * Alternative constructor that takes {@link GuiType} instead of rows number. - * - * @param guiType The {@link GuiType} to use. - * @param title The GUI title. - * @deprecated In favor of {@link BaseGui#BaseGui(GuiType, String, Set)}. - */ - @Deprecated - public BaseGui(@NotNull final GuiType guiType, @NotNull final String title) { - this.guiType = guiType; - this.interactionModifiers = EnumSet.noneOf(InteractionModifier.class); - this.title = title; - - inventory = Bukkit.createInventory(this, this.guiType.getInventoryType(), title); - slotActions = new LinkedHashMap<>(); - guiItems = new LinkedHashMap<>(); - } - - /** - * Copy a set into an EnumSet, required because {@link EnumSet#copyOf(EnumSet)} throws an exception if the collection passed as argument is empty. - * - * @param set The set to be copied. - * @return An EnumSet with the provided elements from the original set. - */ - @NotNull - private Set safeCopyOf(@NotNull final Set set) { - if (set.isEmpty()) return EnumSet.noneOf(InteractionModifier.class); - else return EnumSet.copyOf(set); - } - - /** - * Gets the GUI's title as string. - * - * @return The GUI's title. - */ - @NotNull - @Deprecated - public String getTitle() { - return title; - } - - /** - * Gets the GUI title as a {@link Component}. - * - * @return The GUI title {@link Component}. - */ - @NotNull - public Component title() { - return Legacy.SERIALIZER.deserialize(title); - } - - /** - * Sets the {@link GuiItem} to a specific slot on the GUI. - * - * @param slot The GUI slot. - * @param guiItem The {@link GuiItem} to add to the slot. - */ - public void setItem(final int slot, @NotNull final GuiItem guiItem) { - validateSlot(slot); - guiItems.put(slot, guiItem); - } - - /** - * Removes the given {@link GuiItem} from the GUI. - * - * @param item The item to remove. - */ - public void removeItem(@NotNull final GuiItem item) { - final Optional> entry = guiItems.entrySet() - .stream() - .filter(it -> it.getValue().equals(item)) - .findFirst(); - - entry.ifPresent(it -> { - guiItems.remove(it.getKey()); - inventory.remove(it.getValue().getItemStack()); - }); - } - - /** - * Removes the given {@link ItemStack} from the GUI. - * - * @param item The item to remove. - */ - public void removeItem(@NotNull final ItemStack item) { - final Optional> entry = guiItems.entrySet() - .stream() - .filter(it -> it.getValue().getItemStack().equals(item)) - .findFirst(); - - entry.ifPresent(it -> { - guiItems.remove(it.getKey()); - inventory.remove(item); - }); - } - - /** - * Removes the {@link GuiItem} in the specific slot. - * - * @param slot The GUI slot. - */ - public void removeItem(final int slot) { - validateSlot(slot); - guiItems.remove(slot); - inventory.setItem(slot, null); - } - - /** - * Alternative {@link #removeItem(int)} with cols and rows. - * - * @param row The row. - * @param col The column. - */ - public void removeItem(final int row, final int col) { - removeItem(getSlotFromRowCol(row, col)); - } - - /** - * Alternative {@link #setItem(int, GuiItem)} to set item that takes a {@link List} of slots instead. - * - * @param slots The slots in which the item should go. - * @param guiItem The {@link GuiItem} to add to the slots. - */ - public void setItem(@NotNull final List slots, @NotNull final GuiItem guiItem) { - for (final int slot : slots) { - setItem(slot, guiItem); - } - } - - /** - * Alternative {@link #setItem(int, GuiItem)} to set item that uses ROWS and COLUMNS instead of slots. - * - * @param row The GUI row number. - * @param col The GUI column number. - * @param guiItem The {@link GuiItem} to add to the slot. - */ - public void setItem(final int row, final int col, @NotNull final GuiItem guiItem) { - setItem(getSlotFromRowCol(row, col), guiItem); - } - - /** - * Adds {@link GuiItem}s to the GUI without specific slot. - * It'll set the item to the next empty slot available. - * - * @param items Varargs for specifying the {@link GuiItem}s. - */ - public void addItem(@NotNull final GuiItem... items) { - this.addItem(false, items); - } - - /** - * Adds {@link GuiItem}s to the GUI without specific slot. - * It'll set the item to the next empty slot available. - * - * @param items Varargs for specifying the {@link GuiItem}s. - * @param expandIfFull If true, expands the gui if it is full - * and there are more items to be added - */ - public void addItem(final boolean expandIfFull, @NotNull final GuiItem... items) { - final List notAddedItems = new ArrayList<>(); - - for (final GuiItem guiItem : items) { - for (int slot = 0; slot < rows * 9; slot++) { - if (guiItems.get(slot) != null) { - if (slot == rows * 9 - 1) { - notAddedItems.add(guiItem); - } - continue; - } - - guiItems.put(slot, guiItem); - break; - } - } - - if (!expandIfFull || this.rows >= 6 || - notAddedItems.isEmpty() || - (this.guiType != null && this.guiType != GuiType.CHEST)) { - return; - } - - this.rows++; - this.inventory = Bukkit.createInventory(this, this.rows * 9, this.title); - this.update(); - this.addItem(true, notAddedItems.toArray(new GuiItem[0])); - } - - /** - * Adds a {@link GuiAction} for when clicking on a specific slot. - * See {@link InventoryClickEvent}. - * - * @param slot The slot that will trigger the {@link GuiAction}. - * @param slotAction {@link GuiAction} to resolve when clicking on specific slots. - */ - public void addSlotAction(final int slot, @Nullable final GuiAction<@NotNull InventoryClickEvent> slotAction) { - validateSlot(slot); - slotActions.put(slot, slotAction); - } - - /** - * Alternative method for {@link #addSlotAction(int, GuiAction)} to add a {@link GuiAction} to a specific slot using ROWS and COLUMNS instead of slots. - * See {@link InventoryClickEvent}. - * - * @param row The row of the slot. - * @param col The column of the slot. - * @param slotAction {@link GuiAction} to resolve when clicking on the slot. - */ - public void addSlotAction(final int row, final int col, @Nullable final GuiAction<@NotNull InventoryClickEvent> slotAction) { - addSlotAction(getSlotFromRowCol(row, col), slotAction); - } - - /** - * Gets a specific {@link GuiItem} on the slot. - * - * @param slot The slot of the item. - * @return The {@link GuiItem} on the introduced slot or {@code null} if doesn't exist. - */ - @Nullable - public GuiItem getGuiItem(final int slot) { - return guiItems.get(slot); - } - - /** - * Checks whether or not the GUI is updating. - * - * @return Whether the GUI is updating or not. - */ - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - public boolean isUpdating() { - return updating; - } - - /** - * Sets the updating status of the GUI. - * - * @param updating Sets the GUI to the updating status. - */ - public void setUpdating(final boolean updating) { - this.updating = updating; - } - - /** - * Opens the GUI for a {@link HumanEntity}. - * - * @param player The {@link HumanEntity} to open the GUI to. - */ - public void open(@NotNull final HumanEntity player) { - if (player.isSleeping()) return; - - inventory.clear(); - populateGui(); - player.openInventory(inventory); - } - - /** - * Closes the GUI with a {@code 2 tick} delay (to prevent items from being taken from the {@link Inventory}). - * - * @param player The {@link HumanEntity} to close the GUI to. - */ - public void close(@NotNull final HumanEntity player) { - close(player, true); - } - - /** - * Closes the GUI with a {@code 2 tick} delay (to prevent items from being taken from the {@link Inventory}). - * - * @param player The {@link HumanEntity} to close the GUI to. - * @param runCloseAction If should or not run the close action. - */ - public void close(@NotNull final HumanEntity player, final boolean runCloseAction) { - if (VersionHelper.IS_FOLIA) { - player.getScheduler().runDelayed(plugin, task -> { - this.runCloseAction = runCloseAction; - player.closeInventory(); - this.runCloseAction = true; - }, null, 2L); - return; - } - - Bukkit.getScheduler().runTaskLater(plugin, () -> { - this.runCloseAction = runCloseAction; - player.closeInventory(); - this.runCloseAction = true; - }, 2L); - } - - /** - * Updates the GUI for all the {@link Inventory} views. - */ - public void update() { - inventory.clear(); - populateGui(); - for (HumanEntity viewer : new ArrayList<>(inventory.getViewers())) ((Player) viewer).updateInventory(); - } - - /** - * Updates the title of the GUI. - * This method may cause LAG if used on a loop. - * - * @param title The title to set. - * @return The GUI for easier use when declaring, works like a builder. - */ - @Contract("_ -> this") - @NotNull - public BaseGui updateTitle(@NotNull final String title) { - updating = true; - - final List viewers = new ArrayList<>(inventory.getViewers()); - - inventory = Bukkit.createInventory(this, inventory.getSize(), title); - - for (final HumanEntity player : viewers) { - open(player); - } - - updating = false; - this.title = title; - return this; - } - - /** - * Updates the specified item in the GUI at runtime, without creating a new {@link GuiItem}. - * - * @param slot The slot of the item to update. - * @param itemStack The {@link ItemStack} to replace in the original one in the {@link GuiItem}. - */ - public void updateItem(final int slot, @NotNull final ItemStack itemStack) { - final GuiItem guiItem = guiItems.get(slot); - - if (guiItem == null) { - updateItem(slot, new GuiItem(itemStack)); - return; - } - - guiItem.setItemStack(itemStack); - updateItem(slot, guiItem); - } - - /** - * Alternative {@link #updateItem(int, ItemStack)} that takes ROWS and COLUMNS instead of slots. - * - * @param row The row of the slot. - * @param col The columns of the slot. - * @param itemStack The {@link ItemStack} to replace in the original one in the {@link GuiItem}. - */ - public void updateItem(final int row, final int col, @NotNull final ItemStack itemStack) { - updateItem(getSlotFromRowCol(row, col), itemStack); - } - - /** - * Alternative {@link #updateItem(int, ItemStack)} but creates a new {@link GuiItem}. - * - * @param slot The slot of the item to update. - * @param item The {@link GuiItem} to replace in the original. - */ - public void updateItem(final int slot, @NotNull final GuiItem item) { - guiItems.put(slot, item); - inventory.setItem(slot, item.getItemStack()); - } - - /** - * Alternative {@link #updateItem(int, GuiItem)} that takes ROWS and COLUMNS instead of slots. - * - * @param row The row of the slot. - * @param col The columns of the slot. - * @param item The {@link GuiItem} to replace in the original. - */ - public void updateItem(final int row, final int col, @NotNull final GuiItem item) { - updateItem(getSlotFromRowCol(row, col), item); - } - - /** - * Disable item placement inside the GUI. - * - * @return The BaseGui. - * @author SecretX. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> this") - public BaseGui disableItemPlace() { - interactionModifiers.add(InteractionModifier.PREVENT_ITEM_PLACE); - return this; - } - - /** - * Disable item retrieval inside the GUI. - * - * @return The BaseGui. - * @author SecretX. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> this") - public BaseGui disableItemTake() { - interactionModifiers.add(InteractionModifier.PREVENT_ITEM_TAKE); - return this; - } - - /** - * Disable item swap inside the GUI. - * - * @return The BaseGui. - * @author SecretX. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> this") - public BaseGui disableItemSwap() { - interactionModifiers.add(InteractionModifier.PREVENT_ITEM_SWAP); - return this; - } - - /** - * Disable item drop inside the GUI - * - * @return The BaseGui - * @since 3.0.3. - */ - @NotNull - @Contract(" -> this") - public BaseGui disableItemDrop() { - interactionModifiers.add(InteractionModifier.PREVENT_ITEM_DROP); - return this; - } - - /** - * Disable other GUI actions - * This option pretty much disables creating a clone stack of the item - * - * @return The BaseGui - * @since 3.0.4 - */ - @NotNull - @Contract(" -> this") - public BaseGui disableOtherActions() { - interactionModifiers.add(InteractionModifier.PREVENT_OTHER_ACTIONS); - return this; - } - - /** - * Disable all the modifications of the GUI, making it immutable by player interaction. - * - * @return The BaseGui. - * @author SecretX. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> this") - public BaseGui disableAllInteractions() { - interactionModifiers.addAll(InteractionModifier.VALUES); - return this; - } - - /** - * Allows item placement inside the GUI. - * - * @return The BaseGui. - * @author SecretX. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> this") - public BaseGui enableItemPlace() { - interactionModifiers.remove(InteractionModifier.PREVENT_ITEM_PLACE); - return this; - } - - /** - * Allow items to be taken from the GUI. - * - * @return The BaseGui. - * @author SecretX. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> this") - public BaseGui enableItemTake() { - interactionModifiers.remove(InteractionModifier.PREVENT_ITEM_TAKE); - return this; - } - - /** - * Allows item swap inside the GUI. - * - * @return The BaseGui. - * @author SecretX. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> this") - public BaseGui enableItemSwap() { - interactionModifiers.remove(InteractionModifier.PREVENT_ITEM_SWAP); - return this; - } - - /** - * Allows item drop inside the GUI - * - * @return The BaseGui - * @since 3.0.3 - */ - @NotNull - @Contract(" -> this") - public BaseGui enableItemDrop() { - interactionModifiers.remove(InteractionModifier.PREVENT_ITEM_DROP); - return this; - } - - /** - * Enable other GUI actions - * This option pretty much enables creating a clone stack of the item - * - * @return The BaseGui - * @since 3.0.4 - */ - @NotNull - @Contract(" -> this") - public BaseGui enableOtherActions() { - interactionModifiers.remove(InteractionModifier.PREVENT_OTHER_ACTIONS); - return this; - } - - /** - * Enable all modifications of the GUI, making it completely mutable by player interaction. - * - * @return The BaseGui. - * @author SecretX. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> this") - public BaseGui enableAllInteractions() { - interactionModifiers.clear(); - return this; - } - - public boolean allInteractionsDisabled() { - return interactionModifiers.size() == InteractionModifier.VALUES.size(); - } - - /** - * Check if item placement is allowed inside this GUI. - * - * @return True if item placement is allowed for this GUI. - * @author SecretX. - * @since 3.0.0. - */ - public boolean canPlaceItems() { - return !interactionModifiers.contains(InteractionModifier.PREVENT_ITEM_PLACE); - } - - /** - * Check if item retrieval is allowed inside this GUI. - * - * @return True if item retrieval is allowed inside this GUI. - * @author SecretX. - * @since 3.0.0. - */ - public boolean canTakeItems() { - return !interactionModifiers.contains(InteractionModifier.PREVENT_ITEM_TAKE); - } - - /** - * Check if item swap is allowed inside this GUI. - * - * @return True if item swap is allowed for this GUI. - * @author SecretX. - * @since 3.0.0. - */ - public boolean canSwapItems() { - return !interactionModifiers.contains(InteractionModifier.PREVENT_ITEM_SWAP); - } - - /** - * Check if item drop is allowed inside this GUI - * - * @return True if item drop is allowed for this GUI - * @since 3.0.3 - */ - public boolean canDropItems() { - return !interactionModifiers.contains(InteractionModifier.PREVENT_ITEM_DROP); - } - - /** - * Check if any other actions are allowed in this GUI - * - * @return True if other actions are allowed - * @since 3.0.4 - */ - public boolean allowsOtherActions() { - return !interactionModifiers.contains(InteractionModifier.PREVENT_OTHER_ACTIONS); - } - - /** - * Gets the {@link GuiFiller} that it's used for filling up the GUI in specific ways. - * - * @return The {@link GuiFiller}. - */ - @NotNull - public GuiFiller getFiller() { - return filler; - } - - /** - * Gets an immutable {@link Map} with all the GUI items. - * - * @return The {@link Map} with all the {@link #guiItems}. - */ - @NotNull - public Map<@NotNull Integer, @NotNull GuiItem> getGuiItems() { - return guiItems; - } - - /** - * Gets the main {@link Inventory} of this GUI. - * - * @return Gets the {@link Inventory} from the holder. - */ - @NotNull - @Override - public Inventory getInventory() { - return inventory; - } - - /** - * Sets the new inventory of the GUI. - * - * @param inventory The new inventory. - */ - public void setInventory(@NotNull final Inventory inventory) { - this.inventory = inventory; - } - - /** - * Gets the amount of {@link #rows}. - * - * @return The {@link #rows} of the GUI. - */ - public int getRows() { - return rows; - } - - /** - * Gets the {@link GuiType} in use. - * - * @return The {@link GuiType}. - */ - @NotNull - public GuiType guiType() { - return guiType; - } - - /** - * Gets the default click resolver. - */ - @Nullable - GuiAction getDefaultClickAction() { - return defaultClickAction; - } - - /** - * Sets the {@link GuiAction} of a default click on any item. - * See {@link InventoryClickEvent}. - * - * @param defaultClickAction {@link GuiAction} to resolve when any item is clicked. - */ - public void setDefaultClickAction(@Nullable final GuiAction<@NotNull InventoryClickEvent> defaultClickAction) { - this.defaultClickAction = defaultClickAction; - } - - /** - * Gets the default top click resolver. - */ - @Nullable - GuiAction getDefaultTopClickAction() { - return defaultTopClickAction; - } - - /** - * Sets the {@link GuiAction} of a default click on any item on the top part of the GUI. - * Top inventory being for example chests etc, instead of the {@link Player} inventory. - * See {@link InventoryClickEvent}. - * - * @param defaultTopClickAction {@link GuiAction} to resolve when clicking on the top inventory. - */ - public void setDefaultTopClickAction(@Nullable final GuiAction<@NotNull InventoryClickEvent> defaultTopClickAction) { - this.defaultTopClickAction = defaultTopClickAction; - } - - /** - * Gets the player inventory action. - */ - @Nullable - GuiAction getPlayerInventoryAction() { - return playerInventoryAction; - } - - public void setPlayerInventoryAction(@Nullable final GuiAction<@NotNull InventoryClickEvent> playerInventoryAction) { - this.playerInventoryAction = playerInventoryAction; - } - - /** - * Gets the default drag resolver. - */ - @Nullable - GuiAction getDragAction() { - return dragAction; - } - - /** - * Sets the {@link GuiAction} of a default drag action. - * See {@link InventoryDragEvent}. - * - * @param dragAction {@link GuiAction} to resolve. - */ - public void setDragAction(@Nullable final GuiAction<@NotNull InventoryDragEvent> dragAction) { - this.dragAction = dragAction; - } - - /** - * Gets the close gui resolver. - */ - @Nullable - GuiAction getCloseGuiAction() { - return closeGuiAction; - } - - /** - * Sets the {@link GuiAction} to run once the inventory is closed. - * See {@link InventoryCloseEvent}. - * - * @param closeGuiAction {@link GuiAction} to resolve when the inventory is closed. - */ - public void setCloseGuiAction(@Nullable final GuiAction<@NotNull InventoryCloseEvent> closeGuiAction) { - this.closeGuiAction = closeGuiAction; - } - - /** - * Gets the open gui resolver. - */ - @Nullable - GuiAction getOpenGuiAction() { - return openGuiAction; - } - - /** - * Sets the {@link GuiAction} to run when the GUI opens. - * See {@link InventoryOpenEvent}. - * - * @param openGuiAction {@link GuiAction} to resolve when opening the inventory. - */ - public void setOpenGuiAction(@Nullable final GuiAction<@NotNull InventoryOpenEvent> openGuiAction) { - this.openGuiAction = openGuiAction; - } - - /** - * Gets the resolver for the outside click. - */ - @Nullable - GuiAction getOutsideClickAction() { - return outsideClickAction; - } - - /** - * Sets the {@link GuiAction} to run when clicking on the outside of the inventory. - * See {@link InventoryClickEvent}. - * - * @param outsideClickAction {@link GuiAction} to resolve when clicking outside of the inventory. - */ - public void setOutsideClickAction(@Nullable final GuiAction<@NotNull InventoryClickEvent> outsideClickAction) { - this.outsideClickAction = outsideClickAction; - } - - /** - * Gets the action for the specified slot. - * - * @param slot The slot clicked. - */ - @Nullable - GuiAction getSlotAction(final int slot) { - return slotActions.get(slot); - } - - /** - * Populates the GUI with it's items. - */ - void populateGui() { - for (final Map.Entry entry : guiItems.entrySet()) { - inventory.setItem(entry.getKey(), entry.getValue().getItemStack()); - } - } - - boolean shouldRunCloseAction() { - return runCloseAction; - } - - boolean shouldRunOpenAction() { - return runOpenAction; - } - - /** - * Gets the slot from the row and column passed. - * - * @param row The row. - * @param col The column. - * @return The slot needed. - */ - int getSlotFromRowCol(final int row, final int col) { - return (col + (row - 1) * 9) - 1; - } - - /* - TODO fix this part, find a better solution for using Paper - protected Inventory createRowedInventory(@NotNull final Component title) { - if (VersionHelper.IS_COMPONENT_LEGACY) { - return Bukkit.createInventory(this, this.rows * 9, Legacy.SERIALIZER.serialize(title)); - } - - return inventory = Bukkit.createInventory(this, this.rows * 9, title); - } - - private Inventory createTypedInventory(@NotNull final Component title) { - final InventoryType inventoryType = guiType.getInventoryType(); - if (VersionHelper.IS_COMPONENT_LEGACY) { - return Bukkit.createInventory(this, inventoryType, Legacy.SERIALIZER.serialize(title)); - } - - return Bukkit.createInventory(this, inventoryType, title); - }*/ - - /** - * Checks if the slot introduces is a valid slot. - * - * @param slot The slot to check. - */ - private void validateSlot(final int slot) { - final int limit = guiType.getLimit(); - - if (guiType == GuiType.CHEST) { - if (slot < 0 || slot >= rows * limit) throwInvalidSlot(slot); - return; - } - - if (slot < 0 || slot > limit) throwInvalidSlot(slot); - } - - /** - * Throws an exception if the slot is invalid. - * - * @param slot The specific slot to display in the error message. - */ - private void throwInvalidSlot(final int slot) { - if (guiType == GuiType.CHEST) { - throw new GuiException("Slot " + slot + " is not valid for the gui type - " + guiType.name() + " and rows - " + rows + "!"); - } - - throw new GuiException("Slot " + slot + " is not valid for the gui type - " + guiType.name() + "!"); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/Gui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/Gui.java deleted file mode 100644 index 68135533..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/Gui.java +++ /dev/null @@ -1,178 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import dev.triumphteam.gui.builder.gui.PaginatedBuilder; -import dev.triumphteam.gui.builder.gui.ScrollingBuilder; -import dev.triumphteam.gui.builder.gui.SimpleBuilder; -import dev.triumphteam.gui.builder.gui.StorageBuilder; -import dev.triumphteam.gui.components.GuiType; -import dev.triumphteam.gui.components.InteractionModifier; -import dev.triumphteam.gui.components.ScrollType; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import java.util.Set; - -/** - * Standard GUI implementation of {@link BaseGui} - */ -public class Gui extends BaseGui { - - /** - * Main constructor for the GUI - * - * @param rows The amount of rows the GUI should have - * @param title The GUI's title using {@link String} - * @param interactionModifiers A set containing the {@link InteractionModifier} this GUI should use - * @author SecretX - * @since 3.0.3 - */ - public Gui(final int rows, @NotNull final String title, @NotNull final Set interactionModifiers) { - super(rows, title, interactionModifiers); - } - - /** - * Alternative constructor that takes both a {@link GuiType} and a set of {@link InteractionModifier} - * - * @param guiType The {@link GuiType} to be used - * @param title The GUI's title using {@link String} - * @param interactionModifiers A set containing the {@link InteractionModifier} this GUI should use - * @author SecretX - * @since 3.0.3 - */ - public Gui(@NotNull final GuiType guiType, @NotNull final String title, @NotNull final Set interactionModifiers) { - super(guiType, title, interactionModifiers); - } - - /** - * Old main constructor for the GUI - * - * @param rows The amount of rows the GUI should have - * @param title The GUI's title - * @deprecated In favor of {@link Gui#Gui(int, String, Set)} - */ - @Deprecated - public Gui(final int rows, @NotNull final String title) { - super(rows, title); - } - - /** - * Alternative constructor that defaults to 1 row - * - * @param title The GUI's title - * @deprecated In favor of {@link Gui#Gui(int, String, Set)} - */ - @Deprecated - public Gui(@NotNull final String title) { - super(1, title); - } - - /** - * Main constructor that takes a {@link GuiType} instead of rows - * - * @param guiType The {@link GuiType} to be used - * @param title The GUI's title - * @deprecated In favor of {@link Gui#Gui(GuiType, String, Set)} - */ - @Deprecated - public Gui(@NotNull final GuiType guiType, @NotNull final String title) { - super(guiType, title); - } - - /** - * Creates a {@link SimpleBuilder} to build a {@link dev.triumphteam.gui.guis.Gui} - * - * @param type The {@link GuiType} to be used - * @return A {@link SimpleBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> new") - public static SimpleBuilder gui(@NotNull final GuiType type) { - return new SimpleBuilder(type); - } - - /** - * Creates a {@link SimpleBuilder} with CHEST as the {@link GuiType} - * - * @return A CHEST {@link SimpleBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract(" -> new") - public static SimpleBuilder gui() { - return gui(GuiType.CHEST); - } - - /** - * Creates a {@link StorageBuilder}. - * - * @return A CHEST {@link StorageBuilder}. - * @since 3.0.0. - */ - @NotNull - @Contract(" -> new") - public static StorageBuilder storage() { - return new StorageBuilder(); - } - - /** - * Creates a {@link PaginatedBuilder} to build a {@link dev.triumphteam.gui.guis.PaginatedGui} - * - * @return A {@link PaginatedBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract(" -> new") - public static PaginatedBuilder paginated() { - return new PaginatedBuilder(); - } - - /** - * Creates a {@link ScrollingBuilder} to build a {@link dev.triumphteam.gui.guis.ScrollingGui} - * - * @param scrollType The {@link ScrollType} to be used by the GUI - * @return A {@link ScrollingBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract("_ -> new") - public static ScrollingBuilder scrolling(@NotNull final ScrollType scrollType) { - return new ScrollingBuilder(scrollType); - } - - /** - * Creates a {@link ScrollingBuilder} with VERTICAL as the {@link ScrollType} - * - * @return A vertical {@link SimpleBuilder} - * @since 3.0.0 - */ - @NotNull - @Contract(" -> new") - public static ScrollingBuilder scrolling() { - return scrolling(ScrollType.VERTICAL); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/GuiItem.java b/old-core/src/main/java/dev/triumphteam/gui/guis/GuiItem.java deleted file mode 100644 index cf700384..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/GuiItem.java +++ /dev/null @@ -1,140 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import com.google.common.base.Preconditions; -import dev.triumphteam.gui.components.GuiAction; -import dev.triumphteam.gui.components.util.ItemNbt; -import org.bukkit.Material; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.UUID; - -/** - * GuiItem represents the {@link ItemStack} on the {@link Inventory} - */ -@SuppressWarnings("unused") -public class GuiItem { - - // Action to do when clicking on the item - private GuiAction action; - - // The ItemStack of the GuiItem - private ItemStack itemStack; - - // Random UUID to identify the item when clicking - private final UUID uuid = UUID.randomUUID(); - - /** - * Main constructor of the GuiItem - * - * @param itemStack The {@link ItemStack} to be used - * @param action The {@link GuiAction} to run when clicking on the Item - */ - public GuiItem(@NotNull final ItemStack itemStack, @Nullable final GuiAction<@NotNull InventoryClickEvent> action) { - Preconditions.checkNotNull(itemStack, "The ItemStack for the GUI Item cannot be null!"); - - this.action = action; - - // Sets the UUID to an NBT tag to be identifiable later - this.itemStack = ItemNbt.setString(itemStack.clone(), "mf-gui", uuid.toString()); - } - - /** - * Secondary constructor with no action - * - * @param itemStack The ItemStack to be used - */ - public GuiItem(@NotNull final ItemStack itemStack) { - this(itemStack, null); - } - - /** - * Alternate constructor that takes {@link Material} instead of an {@link ItemStack} but without a {@link GuiAction} - * - * @param material The {@link Material} to be used when invoking class - */ - public GuiItem(@NotNull final Material material) { - this(new ItemStack(material), null); - } - - /** - * Alternate constructor that takes {@link Material} instead of an {@link ItemStack} - * - * @param material The {@code Material} to be used when invoking class - * @param action The {@link GuiAction} should be passed on {@link InventoryClickEvent} - */ - public GuiItem(@NotNull final Material material, @Nullable final GuiAction<@NotNull InventoryClickEvent> action) { - this(new ItemStack(material), action); - } - - /** - * Replaces the {@link ItemStack} of the GUI Item - * - * @param itemStack The new {@link ItemStack} - */ - public void setItemStack(@NotNull final ItemStack itemStack) { - Preconditions.checkNotNull(itemStack, "The ItemStack for the GUI Item cannot be null!"); - this.itemStack = ItemNbt.setString(itemStack.clone(), "mf-gui", uuid.toString()); - } - - /** - * Replaces the {@link GuiAction} of the current GUI Item - * - * @param action The new {@link GuiAction} to set - */ - public void setAction(@Nullable final GuiAction<@NotNull InventoryClickEvent> action) { - this.action = action; - } - - /** - * Gets the GuiItem's {@link ItemStack} - * - * @return The {@link ItemStack} - */ - @NotNull - public ItemStack getItemStack() { - return itemStack; - } - - /** - * Gets the random {@link UUID} that was generated when the GuiItem was made - */ - @NotNull - UUID getUuid() { - return uuid; - } - - /** - * Gets the {@link GuiAction} to do when the player clicks on it - */ - @Nullable - GuiAction getAction() { - return action; - } -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/GuiListener.java b/old-core/src/main/java/dev/triumphteam/gui/guis/GuiListener.java deleted file mode 100644 index ce4d7428..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/GuiListener.java +++ /dev/null @@ -1,175 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import dev.triumphteam.gui.components.GuiAction; -import dev.triumphteam.gui.components.util.ItemNbt; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; -import org.bukkit.event.inventory.InventoryDragEvent; -import org.bukkit.event.inventory.InventoryOpenEvent; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Nullable; - -public final class GuiListener implements Listener { - - /** - * Handles what happens when a player clicks on the GUI - * - * @param event The InventoryClickEvent - */ - @EventHandler - public void onGuiClick(final InventoryClickEvent event) { - if (!(event.getInventory().getHolder() instanceof BaseGui)) return; - - // Gui - final BaseGui gui = (BaseGui) event.getInventory().getHolder(); - - // Executes the outside click action - final GuiAction outsideClickAction = gui.getOutsideClickAction(); - if (outsideClickAction != null && event.getClickedInventory() == null) { - outsideClickAction.execute(event); - return; - } - - if (event.getClickedInventory() == null) return; - - // Default click action and checks weather or not there is a default action and executes it - final GuiAction defaultTopClick = gui.getDefaultTopClickAction(); - if (defaultTopClick != null && event.getClickedInventory().getType() != InventoryType.PLAYER) { - defaultTopClick.execute(event); - } - - // Default click action and checks weather or not there is a default action and executes it - final GuiAction playerInventoryClick = gui.getPlayerInventoryAction(); - if (playerInventoryClick != null && event.getClickedInventory().getType() == InventoryType.PLAYER) { - playerInventoryClick.execute(event); - } - - // Default click action and checks weather or not there is a default action and executes it - final GuiAction defaultClick = gui.getDefaultClickAction(); - if (defaultClick != null) defaultClick.execute(event); - - // Slot action and checks weather or not there is a slot action and executes it - final GuiAction slotAction = gui.getSlotAction(event.getSlot()); - if (slotAction != null && event.getClickedInventory().getType() != InventoryType.PLAYER) { - slotAction.execute(event); - } - - GuiItem guiItem; - - // Checks whether it's a paginated gui or not - if (gui instanceof PaginatedGui) { - final PaginatedGui paginatedGui = (PaginatedGui) gui; - - // Gets the gui item from the added items or the page items - guiItem = paginatedGui.getGuiItem(event.getSlot()); - if (guiItem == null) guiItem = paginatedGui.getPageItem(event.getSlot()); - - } else { - // The clicked GUI Item - guiItem = gui.getGuiItem(event.getSlot()); - } - - if (!isGuiItem(event.getCurrentItem(), guiItem)) return; - - // Executes the action of the item - final GuiAction itemAction = guiItem.getAction(); - if (itemAction != null) itemAction.execute(event); - } - - /** - * Handles what happens when a player clicks on the GUI - * - * @param event The InventoryClickEvent - */ - @EventHandler - public void onGuiDrag(final InventoryDragEvent event) { - if (!(event.getInventory().getHolder() instanceof BaseGui)) return; - - // Gui - final BaseGui gui = (BaseGui) event.getInventory().getHolder(); - - // Default click action and checks weather or not there is a default action and executes it - final GuiAction dragAction = gui.getDragAction(); - if (dragAction != null) dragAction.execute(event); - } - - /** - * Handles what happens when the GUI is closed - * - * @param event The InventoryCloseEvent - */ - @EventHandler - public void onGuiClose(final InventoryCloseEvent event) { - if (!(event.getInventory().getHolder() instanceof BaseGui)) return; - - // GUI - final BaseGui gui = (BaseGui) event.getInventory().getHolder(); - - // The GUI action for closing - final GuiAction closeAction = gui.getCloseGuiAction(); - - // Checks if there is or not an action set and executes it - if (closeAction != null && !gui.isUpdating() && gui.shouldRunCloseAction()) closeAction.execute(event); - } - - /** - * Handles what happens when the GUI is opened - * - * @param event The InventoryOpenEvent - */ - @EventHandler - public void onGuiOpen(final InventoryOpenEvent event) { - if (!(event.getInventory().getHolder() instanceof BaseGui)) return; - - // GUI - final BaseGui gui = (BaseGui) event.getInventory().getHolder(); - - // The GUI action for opening - final GuiAction openAction = gui.getOpenGuiAction(); - - // Checks if there is or not an action set and executes it - if (openAction != null && !gui.isUpdating()) openAction.execute(event); - } - - /** - * Checks if the item is or not a GUI item - * - * @param currentItem The current item clicked - * @param guiItem The GUI item in the slot - * @return Whether it is or not a GUI item - */ - private boolean isGuiItem(@Nullable final ItemStack currentItem, @Nullable final GuiItem guiItem) { - if (currentItem == null || guiItem == null) return false; - // Checks whether the Item is truly a GUI Item - final String nbt = ItemNbt.getString(currentItem, "mf-gui"); - if (nbt == null) return false; - return nbt.equals(guiItem.getUuid().toString()); - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java b/old-core/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java deleted file mode 100644 index e40d8a5a..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/InteractionModifierListener.java +++ /dev/null @@ -1,255 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import com.google.common.base.Preconditions; -import org.bukkit.event.Event; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.inventory.InventoryAction; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryDragEvent; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; - -import java.util.Collections; -import java.util.EnumSet; -import java.util.Set; - -/** - * Listener that apply default GUI {@link dev.triumphteam.gui.components.InteractionModifier InteractionModifier}s to all GUIs - * - * @author SecretX - * @since 3.0.0 - */ -public final class InteractionModifierListener implements Listener { - - /** - * Handles any click on GUIs, applying all {@link dev.triumphteam.gui.components.InteractionModifier InteractionModifier} as required - * - * @param event The InventoryClickEvent - * @author SecretX - * @since 3.0.0 - */ - @EventHandler - public void onGuiClick(final InventoryClickEvent event) { - if (!(event.getInventory().getHolder() instanceof BaseGui)) return; - - // Gui - final BaseGui gui = (BaseGui) event.getInventory().getHolder(); - - if (gui.allInteractionsDisabled()) { - event.setCancelled(true); - event.setResult(Event.Result.DENY); - return; - } - - // if player is trying to do a disabled action, cancel it - if ((!gui.canPlaceItems() && isPlaceItemEvent(event)) || (!gui.canTakeItems() && isTakeItemEvent(event)) || (!gui.canSwapItems() && isSwapItemEvent(event)) || (!gui.canDropItems() && isDropItemEvent(event)) || (!gui.allowsOtherActions() && isOtherEvent(event))) { - event.setCancelled(true); - event.setResult(Event.Result.DENY); - } - } - - /** - * Handles any item drag on GUIs, applying all {@link dev.triumphteam.gui.components.InteractionModifier InteractionModifier} as required - * - * @param event The InventoryDragEvent - * @author SecretX - * @since 3.0.0 - */ - @EventHandler - public void onGuiDrag(final InventoryDragEvent event) { - if (!(event.getInventory().getHolder() instanceof BaseGui)) return; - - // Gui - final BaseGui gui = (BaseGui) event.getInventory().getHolder(); - - if (gui.allInteractionsDisabled()) { - event.setCancelled(true); - event.setResult(Event.Result.DENY); - return; - } - - // if players are allowed to place items on the GUI, or player is not dragging on GUI, return - if (gui.canPlaceItems() || !isDraggingOnGui(event)) return; - - // cancel the interaction - event.setCancelled(true); - event.setResult(Event.Result.DENY); - } - - /** - * Checks if what is happening on the {@link InventoryClickEvent} is take an item from the GUI - * - * @param event The InventoryClickEvent - * @return True if the {@link InventoryClickEvent} is for taking an item from the GUI - * @author SecretX - * @since 3.0.0 - */ - private boolean isTakeItemEvent(final InventoryClickEvent event) { - Preconditions.checkNotNull(event, "event cannot be null"); - - final Inventory inventory = event.getInventory(); - final Inventory clickedInventory = event.getClickedInventory(); - final InventoryAction action = event.getAction(); - - // magic logic, simplified version of https://paste.helpch.at/tizivomeco.cpp - if (clickedInventory != null && clickedInventory.getType() == InventoryType.PLAYER || inventory.getType() == InventoryType.PLAYER) { - return false; - } - - return action == InventoryAction.MOVE_TO_OTHER_INVENTORY || isTakeAction(action); - } - - /** - * Checks if what is happening on the {@link InventoryClickEvent} is place an item on the GUI - * - * @param event The InventoryClickEvent - * @return True if the {@link InventoryClickEvent} is for placing an item from the GUI - * @author SecretX - * @since 3.0.0 - */ - private boolean isPlaceItemEvent(final InventoryClickEvent event) { - Preconditions.checkNotNull(event, "event cannot be null"); - - final Inventory inventory = event.getInventory(); - final Inventory clickedInventory = event.getClickedInventory(); - final InventoryAction action = event.getAction(); - - // shift click on item in player inventory - if (action == InventoryAction.MOVE_TO_OTHER_INVENTORY - && clickedInventory != null && clickedInventory.getType() == InventoryType.PLAYER - && inventory.getType() != clickedInventory.getType()) { - return true; - } - - // normal click on gui empty slot with item on cursor - return isPlaceAction(action) - && (clickedInventory == null || clickedInventory.getType() != InventoryType.PLAYER) - && inventory.getType() != InventoryType.PLAYER; - } - - /** - * Checks if what is happening on the {@link InventoryClickEvent} is swap any item with an item from the GUI - * - * @param event The InventoryClickEvent - * @return True if the {@link InventoryClickEvent} is for swapping any item with an item from the GUI - * @author SecretX - * @since 3.0.0 - */ - private boolean isSwapItemEvent(final InventoryClickEvent event) { - Preconditions.checkNotNull(event, "event cannot be null"); - - final Inventory inventory = event.getInventory(); - final Inventory clickedInventory = event.getClickedInventory(); - final InventoryAction action = event.getAction(); - - return isSwapAction(action) - && (clickedInventory == null || clickedInventory.getType() != InventoryType.PLAYER) - && inventory.getType() != InventoryType.PLAYER; - } - - private boolean isDropItemEvent(final InventoryClickEvent event) { - Preconditions.checkNotNull(event, "event cannot be null"); - - final Inventory inventory = event.getInventory(); - final Inventory clickedInventory = event.getClickedInventory(); - final InventoryAction action = event.getAction(); - - return isDropAction(action) - && (clickedInventory != null || inventory.getType() != InventoryType.PLAYER); - } - - private boolean isOtherEvent(final InventoryClickEvent event) { - Preconditions.checkNotNull(event, "event cannot be null"); - - final Inventory inventory = event.getInventory(); - final Inventory clickedInventory = event.getClickedInventory(); - final InventoryAction action = event.getAction(); - - return isOtherAction(action) - && (clickedInventory != null || inventory.getType() != InventoryType.PLAYER); - } - - /** - * Checks if any item is being dragged on the GUI - * - * @param event The InventoryDragEvent - * @return True if the {@link InventoryDragEvent} is for dragging an item inside the GUI - * @author SecretX - * @since 3.0.0 - */ - private boolean isDraggingOnGui(final InventoryDragEvent event) { - Preconditions.checkNotNull(event, "event cannot be null"); - final int topSlots = event.getView().getTopInventory().getSize(); - // is dragging on any top inventory slot - return event.getRawSlots().stream().anyMatch(slot -> slot < topSlots); - } - - private boolean isTakeAction(final InventoryAction action) { - Preconditions.checkNotNull(action, "action cannot be null"); - return ITEM_TAKE_ACTIONS.contains(action); - } - - private boolean isPlaceAction(final InventoryAction action) { - Preconditions.checkNotNull(action, "action cannot be null"); - return ITEM_PLACE_ACTIONS.contains(action); - } - - private boolean isSwapAction(final InventoryAction action) { - Preconditions.checkNotNull(action, "action cannot be null"); - return ITEM_SWAP_ACTIONS.contains(action); - } - - private boolean isDropAction(final InventoryAction action) { - Preconditions.checkNotNull(action, "action cannot be null"); - return ITEM_DROP_ACTIONS.contains(action); - } - - private boolean isOtherAction(final InventoryAction action) { - Preconditions.checkNotNull(action, "action cannot be null"); - return action == InventoryAction.CLONE_STACK || action == InventoryAction.UNKNOWN; - } - - /** - * Holds all the actions that should be considered "take" actions - */ - private static final Set ITEM_TAKE_ACTIONS = Collections.unmodifiableSet(EnumSet.of(InventoryAction.PICKUP_ONE, InventoryAction.PICKUP_SOME, InventoryAction.PICKUP_HALF, InventoryAction.PICKUP_ALL, InventoryAction.COLLECT_TO_CURSOR, InventoryAction.HOTBAR_SWAP, InventoryAction.MOVE_TO_OTHER_INVENTORY)); - - /** - * Holds all the actions that should be considered "place" actions - */ - private static final Set ITEM_PLACE_ACTIONS = Collections.unmodifiableSet(EnumSet.of(InventoryAction.PLACE_ONE, InventoryAction.PLACE_SOME, InventoryAction.PLACE_ALL)); - - /** - * Holds all actions relating to swapping items - */ - private static final Set ITEM_SWAP_ACTIONS = Collections.unmodifiableSet(EnumSet.of(InventoryAction.HOTBAR_SWAP, InventoryAction.SWAP_WITH_CURSOR, InventoryAction.HOTBAR_MOVE_AND_READD)); - - /** - * Holds all actions relating to dropping items - */ - private static final Set ITEM_DROP_ACTIONS = Collections.unmodifiableSet(EnumSet.of(InventoryAction.DROP_ONE_SLOT, InventoryAction.DROP_ALL_SLOT, InventoryAction.DROP_ONE_CURSOR, InventoryAction.DROP_ALL_CURSOR)); -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java deleted file mode 100644 index 6ea2c0a9..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/PaginatedGui.java +++ /dev/null @@ -1,498 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import dev.triumphteam.gui.components.InteractionModifier; -import org.bukkit.Bukkit; -import org.bukkit.entity.HumanEntity; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -/** - * GUI that allows you to have multiple pages - */ -@SuppressWarnings("unused") -public class PaginatedGui extends BaseGui { - - // List with all the page items - private final List pageItems = new ArrayList<>(); - // Saves the current page items and it's slot - private final Map currentPage; - - private int pageSize; - private int pageNum = 1; - - /** - * Main constructor to provide a way to create PaginatedGui - * - * @param rows The amount of rows the GUI should have - * @param pageSize The page size. - * @param title The GUI's title using {@link String} - * @param interactionModifiers A set containing what {@link InteractionModifier} this GUI should have - * @author SecretX - * @since 3.0.3 - */ - public PaginatedGui(final int rows, final int pageSize, @NotNull final String title, @NotNull final Set interactionModifiers) { - super(rows, title, interactionModifiers); - this.pageSize = pageSize; - int inventorySize = rows * 9; - this.currentPage = new LinkedHashMap<>(inventorySize); - } - - /** - * Old main constructor of the PaginatedGui - * - * @param rows The rows the GUI should have - * @param pageSize The pageSize - * @param title The GUI's title - * @deprecated In favor of {@link PaginatedGui#PaginatedGui(int, int, String, Set)} - */ - @Deprecated - public PaginatedGui(final int rows, final int pageSize, @NotNull final String title) { - super(rows, title); - this.pageSize = pageSize; - int inventorySize = rows * 9; - this.currentPage = new LinkedHashMap<>(inventorySize); - } - - /** - * Alternative constructor that doesn't require the {@link #pageSize} to be defined - * - * @param rows The rows the GUI should have - * @param title The GUI's title - * @deprecated In favor of {@link PaginatedGui#PaginatedGui(int, int, String, Set)} - */ - @Deprecated - public PaginatedGui(final int rows, @NotNull final String title) { - this(rows, 0, title); - } - - /** - * Alternative constructor that only requires title - * - * @param title The GUI's title - * @deprecated In favor of {@link PaginatedGui#PaginatedGui(int, int, String, Set)} - */ - @Deprecated - public PaginatedGui(@NotNull final String title) { - this(2, title); - } - - /** - * Sets the page size - * - * @param pageSize The new page size - * @return The GUI for easier use when declaring, works like a builder - */ - public BaseGui setPageSize(final int pageSize) { - this.pageSize = pageSize; - return this; - } - - /** - * Adds an {@link GuiItem} to the next available slot in the page area - * - * @param item The {@link GuiItem} to add to the page - */ - public void addItem(@NotNull final GuiItem item) { - pageItems.add(item); - } - - /** - * Overridden {@link BaseGui#addItem(GuiItem...)} to add the items to the page instead - * - * @param items Varargs for specifying the {@link GuiItem}s - */ - @Override - public void addItem(@NotNull final GuiItem... items) { - pageItems.addAll(Arrays.asList(items)); - } - - /** - * Overridden {@link BaseGui#update()} to use the paginated open - */ - @Override - public void update() { - getInventory().clear(); - populateGui(); - - updatePage(); - } - - /** - * Updates the page {@link GuiItem} on the slot in the page - * Can get the slot from {@link InventoryClickEvent#getSlot()} - * - * @param slot The slot of the item to update - * @param itemStack The new {@link ItemStack} - */ - public void updatePageItem(final int slot, @NotNull final ItemStack itemStack) { - if (!currentPage.containsKey(slot)) return; - final GuiItem guiItem = currentPage.get(slot); - guiItem.setItemStack(itemStack); - getInventory().setItem(slot, guiItem.getItemStack()); - } - - /** - * Alternative {@link #updatePageItem(int, ItemStack)} that uses ROWS and COLUMNS instead - * - * @param row The row of the slot - * @param col The columns of the slot - * @param itemStack The new {@link ItemStack} - */ - public void updatePageItem(final int row, final int col, @NotNull final ItemStack itemStack) { - updateItem(getSlotFromRowCol(row, col), itemStack); - } - - /** - * Alternative {@link #updatePageItem(int, ItemStack)} that uses {@link GuiItem} instead - * - * @param slot The slot of the item to update - * @param item The new ItemStack - */ - public void updatePageItem(final int slot, @NotNull final GuiItem item) { - if (!currentPage.containsKey(slot)) return; - // Gets the old item and its index on the main items list - final GuiItem oldItem = currentPage.get(slot); - final int index = pageItems.indexOf(currentPage.get(slot)); - - // Updates both lists and inventory - currentPage.put(slot, item); - pageItems.set(index, item); - getInventory().setItem(slot, item.getItemStack()); - } - - /** - * Alternative {@link #updatePageItem(int, GuiItem)} that uses ROWS and COLUMNS instead - * - * @param row The row of the slot - * @param col The columns of the slot - * @param item The new {@link GuiItem} - */ - public void updatePageItem(final int row, final int col, @NotNull final GuiItem item) { - updateItem(getSlotFromRowCol(row, col), item); - } - - /** - * Removes a given {@link GuiItem} from the page. - * - * @param item The {@link GuiItem} to remove. - */ - public void removePageItem(@NotNull final GuiItem item) { - pageItems.remove(item); - updatePage(); - } - - /** - * Removes a given {@link ItemStack} from the page. - * - * @param item The {@link ItemStack} to remove. - */ - public void removePageItem(@NotNull final ItemStack item) { - final Optional guiItem = pageItems.stream().filter(it -> it.getItemStack().equals(item)).findFirst(); - guiItem.ifPresent(this::removePageItem); - } - - /** - * Overrides {@link BaseGui#open(HumanEntity)} to use the paginated populator instead - * - * @param player The {@link HumanEntity} to open the GUI to - */ - @Override - public void open(@NotNull final HumanEntity player) { - open(player, 1); - } - - /** - * Specific open method for the Paginated GUI - * Uses {@link #populatePage()} - * - * @param player The {@link HumanEntity} to open it to - * @param openPage The specific page to open at - */ - public void open(@NotNull final HumanEntity player, final int openPage) { - if (player.isSleeping()) return; - if (openPage <= getPagesNum() || openPage > 0) pageNum = openPage; - - getInventory().clear(); - currentPage.clear(); - - populateGui(); - - if (pageSize == 0) pageSize = calculatePageSize(); - - populatePage(); - - player.openInventory(getInventory()); - } - - /** - * Overrides {@link BaseGui#updateTitle(String)} to use the paginated populator instead - * Updates the title of the GUI - * This method may cause LAG if used on a loop - * - * @param title The title to set - * @return The GUI for easier use when declaring, works like a builder - */ - @Override - @NotNull - public BaseGui updateTitle(@NotNull final String title) { - setUpdating(true); - - final List viewers = new ArrayList<>(getInventory().getViewers()); - - setInventory(Bukkit.createInventory(this, getInventory().getSize(), title)); - - for (final HumanEntity player : viewers) { - open(player, getPageNum()); - } - - setUpdating(false); - - return this; - } - - /** - * Gets an immutable {@link Map} with all the current pages items - * - * @return The {@link Map} with all the {@link #currentPage} - */ - @NotNull - public Map<@NotNull Integer, @NotNull GuiItem> getCurrentPageItems() { - return Collections.unmodifiableMap(currentPage); - } - - /** - * Gets an immutable {@link List} with all the page items added to the GUI - * - * @return The {@link List} with all the {@link #pageItems} - */ - @NotNull - public List<@NotNull GuiItem> getPageItems() { - return Collections.unmodifiableList(pageItems); - } - - - /** - * Gets the current page number - * - * @return The current page number - */ - public int getCurrentPageNum() { - return pageNum; - } - - /** - * Gets the next page number - * - * @return The next page number or {@link #pageNum} if no next is present - */ - public int getNextPageNum() { - if (pageNum + 1 > getPagesNum()) return pageNum; - return pageNum + 1; - } - - /** - * Gets the previous page number - * - * @return The previous page number or {@link #pageNum} if no previous is present - */ - public int getPrevPageNum() { - if (pageNum - 1 == 0) return pageNum; - return pageNum - 1; - } - - /** - * Goes to the next page - * - * @return False if there is no next page. - */ - public boolean next() { - if (pageNum + 1 > getPagesNum()) return false; - - pageNum++; - updatePage(); - return true; - } - - /** - * Goes to the previous page if possible - * - * @return False if there is no previous page. - */ - public boolean previous() { - if (pageNum - 1 == 0) return false; - - pageNum--; - updatePage(); - return true; - } - - /** - * Gets the page item for the GUI listener - * - * @param slot The slot to get - * @return The GuiItem on that slot - */ - GuiItem getPageItem(final int slot) { - return currentPage.get(slot); - } - - /** - * Gets the items in the page - * - * @param givenPage The page to get - * @return A list with all the page items - */ - private List getPageNum(final int givenPage) { - final int page = givenPage - 1; - - final List guiPage = new ArrayList<>(); - - int max = ((page * pageSize) + pageSize); - if (max > pageItems.size()) max = pageItems.size(); - - for (int i = page * pageSize; i < max; i++) { - guiPage.add(pageItems.get(i)); - } - - return guiPage; - } - - /** - * Gets the number of pages the GUI has - * - * @return The pages number - */ - public int getPagesNum() { - return (int) Math.ceil((double) pageItems.size() / pageSize); - } - - /** - * Populates the inventory with the page items - */ - private void populatePage() { - // Adds the paginated items to the page - for (final GuiItem guiItem : getPageNum(pageNum)) { - for (int slot = 0; slot < getRows() * 9; slot++) { - if (getGuiItem(slot) != null || getInventory().getItem(slot) != null) continue; - currentPage.put(slot, guiItem); - getInventory().setItem(slot, guiItem.getItemStack()); - break; - } - } - } - - /** - * Gets the current page items to be used on other gui types - * - * @return The {@link Map} with all the {@link #currentPage} - */ - Map getMutableCurrentPageItems() { - return currentPage; - } - - /** - * Clears the page content - */ - void clearPage() { - for (Map.Entry entry : currentPage.entrySet()) { - getInventory().setItem(entry.getKey(), null); - } - } - - /** - * Clears all previously added page items - */ - public void clearPageItems(final boolean update) { - pageItems.clear(); - if (update) update(); - } - - public void clearPageItems() { - clearPageItems(false); - } - - - /** - * Gets the page size - * - * @return The page size - */ - int getPageSize() { - return pageSize; - } - - /** - * Gets the page number - * - * @return The current page number - */ - int getPageNum() { - return pageNum; - } - - /** - * Sets the page number - * - * @param pageNum Sets the current page to be the specified number - */ - void setPageNum(final int pageNum) { - this.pageNum = pageNum; - } - - /** - * Updates the page content - */ - void updatePage() { - clearPage(); - populatePage(); - } - - /** - * Calculates the size of the give page - * - * @return The page size - */ - int calculatePageSize() { - int counter = 0; - - for (int slot = 0; slot < getRows() * 9; slot++) { - if (getInventory().getItem(slot) == null) counter++; - } - - return counter; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/PersistentPaginatedGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/PersistentPaginatedGui.java deleted file mode 100644 index e207b6a1..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/PersistentPaginatedGui.java +++ /dev/null @@ -1,357 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import dev.triumphteam.gui.components.Serializable; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.HumanEntity; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -/** - * GUI that does not clear it's items once it's closed - */ -@SuppressWarnings("unused") -class PersistentPaginatedGui extends PaginatedGui implements Serializable { - - // Contains all the pages - private final List pages = new ArrayList<>(); - - // Used for page serialization - private final YamlConfiguration yamlConfiguration = new YamlConfiguration(); - - /** - * Main constructor of the Persistent GUI - * - * @param rows The rows the GUI should have - * @param pageSize The pageSize - * @param title The GUI's title - * @param pages How many pages will be used - */ - public PersistentPaginatedGui(final int rows, final int pageSize, @NotNull final String title, final int pages) { - super(rows, pageSize, title); - - if (pages <= 0) { - this.pages.add(new Page()); - return; - } - - for (int i = 0; i < pages; i++) { - this.pages.add(new Page()); - } - - } - - /** - * Alternative constructor with only title - * - * @param title The GUI's title - */ - public PersistentPaginatedGui(@NotNull final String title) { - this(1, title); - } - - /** - * Alternative constructor with only rows and title - * - * @param rows The rows the GUI should have - * @param title The GUI's title - */ - public PersistentPaginatedGui(final int rows, @NotNull final String title) { - this(rows, 0, title, 1); - } - - /** - * Alternative constructor with only title and pages - * - * @param title The GUI's title - * @param pages How many pages will be used - */ - public PersistentPaginatedGui(@NotNull final String title, final int pages) { - this(1, 0, title, pages); - } - - /** - * Alternative constructor with only rows, title and pages - * - * @param rows The rows the GUI should have - * @param title The GUI's title - * @param pages How many pages will be used - */ - public PersistentPaginatedGui(final int rows, @NotNull final String title, final int pages) { - this(rows, 0, title, pages); - } - - /** - * Adds {@link ItemStack} to the inventory straight, not the GUI - * - * @param items Varargs with {@link ItemStack}s - * @return An immutable {@link Map} with the left overs - */ - @NotNull - public Map<@NotNull Integer, @NotNull ItemStack> addItem(@NotNull final ItemStack... items) { - return addItem(1, items); - } - - /** - * Adds {@link ItemStack} to the inventory straight, not the GUI - * - * @param page To which page it should be added - * @param items Varargs with {@link ItemStack}s - * @return An immutable {@link Map} with the left overs - */ - @NotNull - public Map<@NotNull Integer, @NotNull ItemStack> addItem(final int page, @NotNull final ItemStack... items) { - int finalPage = page; - if (page <= 0 || page > pages.size()) finalPage = 1; - - return Collections.unmodifiableMap(getInventory().addItem(items)); - } - - /** - * Overrides {@link BaseGui#open(HumanEntity)} to use the paginated populator instead - * - * @param player The {@link HumanEntity} to open the GUI to - */ - @Override - public void open(@NotNull final HumanEntity player) { - open(player, 1); - } - - /** - * Specific open method for the Paginated GUI - * - * @param player The {@link HumanEntity} to open it to - * @param openPage The specific page to open at - */ - public void open(@NotNull final HumanEntity player, final int openPage) { - if (player.isSleeping()) return; - - if (openPage < pages.size() || openPage > 0) setPageNum(openPage - 1); - getInventory().clear(); - - populateGui(); - - if (getPageSize() == 0) setPageSize(calculatePageSize()); - - pages.get(getPageNum()).populatePage(getInventory()); - - player.openInventory(getInventory()); - } - - /** - * Goes to the next page if possible - */ - public boolean next() { - if (getPageNum() + 1 >= pages.size()) return false; - - savePage(); - - setPageNum(getPageNum() + 1); - updatePage(); - return true; - } - - /** - * Goes to the previous page if possible - */ - public boolean previous() { - if (getPageNum() - 1 < 0) return false; - - savePage(); - - setPageNum(getPageNum() - 1); - updatePage(); - return true; - } - - /** - * Gets the current page number - * - * @return The current page number - */ - @Override - public int getCurrentPageNum() { - return getPageNum() + 1; - } - - /** - * Updates the page content - */ - @Override - void updatePage() { - clearPage(); - populatePage(); - } - - /** - * Clears the current page - */ - @Override - void clearPage() { - for (int i = 0; i < getInventory().getSize(); i++) { - final ItemStack itemStack = getInventory().getItem(i); - if (itemStack == null) continue; - if (getGuiItems().get(i) != null) continue; - - getInventory().setItem(i, null); - } - } - - /** - * Saves the current page, used by the {@link GuiListener} - */ - void savePage() { - pages.get(getPageNum()).savePage(getInventory(), getGuiItems()); - } - - /** - * Populates the inventory with the page items - */ - private void populatePage() { - // Adds the paginated items to the page - pages.get(getPageNum()).populatePage(getInventory()); - } - - /** - * Encodes the GUI into a list of strings, each string representing a page - * - * @return A {@link List} of page items encoded into a string - */ - @NotNull - @Override - public List encodeGui() { - final int inventorySize = getInventory().getSize(); - final List pageItems = new ArrayList<>(); - - for (final Page page : pages) { - yamlConfiguration.set("inventory", page.getContent(inventorySize)); - //pageItems.add(Base64.encodeBase64String(yamlConfiguration.saveToString().getBytes())); - } - - return pageItems; - } - - /** - * Decodes the {@link List} of strings into a usable inventory - * - * @param encodedItem The {@link List} to decode - */ - @Override - public void decodeGui(@NotNull final List encodedItem) { - for (int i = 0; i < pages.size(); i++) { - final Page page = pages.get(i); - //yamlConfiguration.loadFromString(new String(Base64.decodeBase64(encodedItem.get(i)))); - //noinspection unchecked - final List content = (List) yamlConfiguration.get("inventory"); - if (content == null) continue; - page.loadPageContent(content, getInventory().getSize()); - } - } - - /** - * Private class for holding all the page interactions - */ - private static class Page { - - // Map that contains all the page items and their slot - private final Map pageItems = new LinkedHashMap<>(); - - /** - * Adds all the items from the page to the {@link Inventory} - * - * @param inventory The given {@link Inventory} to use - */ - private void populatePage(@NotNull final Inventory inventory) { - // Adds the paginated items to the page - for (Map.Entry entry : pageItems.entrySet()) { - inventory.setItem(entry.getKey(), entry.getValue()); - } - } - - /** - * Saves the current page and any modifications that was done to it - * - * @param inventory The given {@link Inventory} to use - * @param guiItems The gui items map just to check if the current item is or not a gui item, to not add it - */ - private void savePage(@NotNull final Inventory inventory, @NotNull Map guiItems) { - for (int i = 0; i < inventory.getSize(); i++) { - final ItemStack itemStack = inventory.getItem(i); - - // Removes the item if it was removed - if (itemStack == null) { - pageItems.remove(i); - continue; - } - - // Skips gui items - if (guiItems.get(i) != null) continue; - - pageItems.put(i, itemStack); - } - } - - /** - * Turns the map into an array of {@link ItemStack} so it can be serialized - * - * @param inventorySize The inventory size - * @return An array of {@link ItemStack} - */ - @NotNull - private ItemStack[] getContent(final int inventorySize) { - final ItemStack[] content = new ItemStack[inventorySize]; - for (int i = 0; i < inventorySize; i++) { - content[i] = pageItems.get(i); - } - return content; - } - - /** - * Loads the list of items into the page - * - * @param items The list of {@link ItemStack} - * @param inventorySize The inventory size - */ - private void loadPageContent(@NotNull final List items, final int inventorySize) { - // Cleans the page to avoid problems - pageItems.clear(); - for (int i = 0; i < inventorySize; i++) { - final ItemStack item = items.get(i); - if (item == null) continue; - - pageItems.put(i, item); - } - } - - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java deleted file mode 100644 index 38fbae31..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/ScrollingGui.java +++ /dev/null @@ -1,316 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import dev.triumphteam.gui.components.InteractionModifier; -import dev.triumphteam.gui.components.ScrollType; -import org.bukkit.entity.HumanEntity; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -/** - * GUI that allows you to scroll through items - */ -@SuppressWarnings("unused") -public class ScrollingGui extends PaginatedGui { - - private final ScrollType scrollType; - private int scrollSize = 0; - - /** - * Main constructor of the Scrolling GUI - * - * @param rows The rows the GUI should have - * @param pageSize The Page size - * @param title The title using {@link String} - * @param scrollType The {@link ScrollType} - * @param interactionModifiers A set containing the {@link InteractionModifier} this GUI should use - * @since 3.0.3 - * @author SecretX - */ - public ScrollingGui(final int rows, final int pageSize, @NotNull final String title, @NotNull final ScrollType scrollType, @NotNull final Set interactionModifiers) { - super(rows, pageSize, title, interactionModifiers); - - this.scrollType = scrollType; - } - - /** - * Main constructor of the Scrolling GUI - * - * @param rows The rows the GUI should have - * @param pageSize The Page size - * @param title The GUI's title - * @param scrollType The {@link ScrollType} - * @deprecated In favor of {@link ScrollingGui#ScrollingGui(int, int, String, ScrollType, Set)} - */ - @Deprecated - public ScrollingGui(final int rows, final int pageSize, @NotNull final String title, @NotNull final ScrollType scrollType) { - super(rows, pageSize, title); - this.scrollType = scrollType; - } - - /** - * Alternative constructor that doesn't require the {@link ScrollType} - * - * @param rows The rows the GUI should have - * @param pageSize The Page size - * @param title The GUI's title - * @deprecated In favor of {@link ScrollingGui#ScrollingGui(int, int, String, ScrollType, Set)} - */ - @Deprecated - public ScrollingGui(final int rows, final int pageSize, @NotNull final String title) { - this(rows, pageSize, title, ScrollType.VERTICAL); - } - - /** - * Alternative constructor that doesn't require the {@link ScrollType} or page size - * - * @param rows The rows the GUI should have - * @param title The GUI's title - * @deprecated In favor of {@link ScrollingGui#ScrollingGui(int, int, String, ScrollType, Set)} - */ - @Deprecated - public ScrollingGui(final int rows, @NotNull final String title) { - this(rows, 0, title, ScrollType.VERTICAL); - } - - /** - * Alternative constructor that doesn't require the page size - * - * @param rows The rows the GUI should have - * @param title The GUI's title - * @param scrollType The {@link ScrollType} - * @deprecated In favor of {@link ScrollingGui#ScrollingGui(int, int, String, ScrollType, Set)} - */ - @Deprecated - public ScrollingGui(final int rows, @NotNull final String title, @NotNull final ScrollType scrollType) { - this(rows, 0, title, scrollType); - } - - /** - * Alternative constructor that only requires title - * - * @param title The GUI's title - * @deprecated In favor of {@link ScrollingGui#ScrollingGui(int, int, String, ScrollType, Set)} - */ - @Deprecated - public ScrollingGui(@NotNull final String title) { - this(2, title); - } - - /** - * Alternative constructor that doesn't require the rows or page size - * - * @param title The GUI's title - * @param scrollType The {@link ScrollType} - * @deprecated In favor of {@link ScrollingGui#ScrollingGui(int, int, String, ScrollType, Set)} - */ - @Deprecated - public ScrollingGui(@NotNull final String title, @NotNull final ScrollType scrollType) { - this(2, title, scrollType); - } - - /** - * Overrides {@link PaginatedGui#next()} to make it work with the specific scrolls - */ - @Override - public boolean next() { - if (getPageNum() * scrollSize + getPageSize() > getPageItems().size() + scrollSize) return false; - - setPageNum(getPageNum() + 1); - updatePage(); - return true; - } - - /** - * Overrides {@link PaginatedGui#previous()} to make it work with the specific scrolls - */ - @Override - public boolean previous() { - if (getPageNum() - 1 == 0) return false; - - setPageNum(getPageNum() - 1); - updatePage(); - return true; - } - - /** - * Overrides {@link PaginatedGui#open(HumanEntity)} to make it work with the specific scrolls - * - * @param player The {@link HumanEntity} to open the GUI to - */ - @Override - public void open(@NotNull final HumanEntity player) { - open(player, 1); - } - - /** - * Overrides {@link PaginatedGui#open(HumanEntity, int)} to make it work with the specific scrolls - * - * @param player The {@link HumanEntity} to open the GUI to - * @param openPage The page to open on - */ - @Override - public void open(@NotNull final HumanEntity player, final int openPage) { - if (player.isSleeping()) return; - getInventory().clear(); - getMutableCurrentPageItems().clear(); - - populateGui(); - - if (getPageSize() == 0) setPageSize(calculatePageSize()); - if (scrollSize == 0) scrollSize = calculateScrollSize(); - if (openPage > 0 && (openPage * scrollSize + getPageSize() <= getPageItems().size() + scrollSize)) { - setPageNum(openPage); - } - - populatePage(); - - player.openInventory(getInventory()); - } - - /** - * Overrides {@link PaginatedGui#updatePage()} to make it work with the specific scrolls - */ - @Override - void updatePage() { - clearPage(); - populatePage(); - } - - /** - * Fills the page with the items - */ - private void populatePage() { - // Adds the paginated items to the page - for (final GuiItem guiItem : getPage(getPageNum())) { - if (scrollType == ScrollType.HORIZONTAL) { - putItemHorizontally(guiItem); - continue; - } - - putItemVertically(guiItem); - } - } - - /** - * Calculates the size of each scroll - * - * @return The size of he scroll - */ - private int calculateScrollSize() { - int counter = 0; - - if (scrollType == ScrollType.VERTICAL) { - boolean foundCol = false; - - for (int row = 1; row <= getRows(); row++) { - for (int col = 1; col <= 9; col++) { - final int slot = getSlotFromRowCol(row, col); - if (getInventory().getItem(slot) == null) { - if (!foundCol) foundCol = true; - counter++; - } - } - - if (foundCol) return counter; - } - - return counter; - } - - boolean foundRow = false; - - for (int col = 1; col <= 9; col++) { - for (int row = 1; row <= getRows(); row++) { - final int slot = getSlotFromRowCol(row, col); - if (getInventory().getItem(slot) == null) { - if (!foundRow) foundRow = true; - counter++; - } - } - - if (foundRow) return counter; - } - - return counter; - } - - /** - * Puts the item in the GUI for horizontal scrolling - * - * @param guiItem The gui item - */ - private void putItemVertically(final GuiItem guiItem) { - for (int slot = 0; slot < getRows() * 9; slot++) { - if (getGuiItem(slot) != null || getInventory().getItem(slot) != null) continue; - getMutableCurrentPageItems().put(slot, guiItem); - getInventory().setItem(slot, guiItem.getItemStack()); - break; - } - } - - /** - * Puts item into the GUI for vertical scrolling - * - * @param guiItem The gui item - */ - private void putItemHorizontally(final GuiItem guiItem) { - for (int col = 1; col < 10; col++) { - for (int row = 1; row <= getRows(); row++) { - final int slot = getSlotFromRowCol(row, col); - if (getGuiItem(slot) != null || getInventory().getItem(slot) != null) continue; - getMutableCurrentPageItems().put(slot, guiItem); - getInventory().setItem(slot, guiItem.getItemStack()); - return; - } - } - } - - /** - * Gets the items from the current page - * - * @param givenPage The page number - * @return A list with all the items - */ - private List getPage(final int givenPage) { - final int page = givenPage - 1; - final int pageItemsSize = getPageItems().size(); - - final List guiPage = new ArrayList<>(); - - int max = page * scrollSize + getPageSize(); - if (max > pageItemsSize) max = pageItemsSize; - - for (int i = page * scrollSize; i < max; i++) { - guiPage.add(getPageItems().get(i)); - } - - return guiPage; - } - -} diff --git a/old-core/src/main/java/dev/triumphteam/gui/guis/StorageGui.java b/old-core/src/main/java/dev/triumphteam/gui/guis/StorageGui.java deleted file mode 100644 index 9a4e8f82..00000000 --- a/old-core/src/main/java/dev/triumphteam/gui/guis/StorageGui.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2021 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.guis; - -import dev.triumphteam.gui.components.InteractionModifier; -import org.bukkit.entity.HumanEntity; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * GUI that does not clear its items once it's closed - */ -@SuppressWarnings("unused") -public class StorageGui extends BaseGui { - - /** - * Main constructor for the StorageGui - * - * @param rows The amount of rows the GUI should have - * @param title The GUI's title using {@link String} - * @param interactionModifiers A set containing the {@link InteractionModifier} this GUI should use - * @since 3.0.3 - */ - public StorageGui(final int rows, @NotNull final String title, @NotNull final Set interactionModifiers) { - super(rows, title, interactionModifiers); - } - - /** - * Main constructor of the Persistent GUI - * - * @param rows The rows the GUI should have - * @param title The GUI's title - */ - @Deprecated - public StorageGui(final int rows, @NotNull final String title) { - super(rows, title); - } - - /** - * Alternative constructor that does not require rows - * - * @param title The GUI's title - */ - @Deprecated - public StorageGui(@NotNull final String title) { - super(1, title); - } - - /** - * Adds {@link ItemStack} to the inventory straight, not the GUI - * - * @param items Varargs with {@link ItemStack}s - * @return An immutable {@link Map} with the left overs - */ - @NotNull - public Map<@NotNull Integer, @NotNull ItemStack> addItem(@NotNull final ItemStack... items) { - return Collections.unmodifiableMap(getInventory().addItem(items)); - } - - /** - * Adds {@link ItemStack} to the inventory straight, not the GUI - * - * @param items Varargs with {@link ItemStack}s - * @return An immutable {@link Map} with the left overs - */ - public Map<@NotNull Integer, @NotNull ItemStack> addItem(@NotNull final List items) { - return addItem(items.toArray(new ItemStack[0])); - } - - /** - * Overridden {@link BaseGui#open(HumanEntity)} to prevent - * - * @param player The {@link HumanEntity} to open the GUI to - */ - @Override - public void open(@NotNull final HumanEntity player) { - if (player.isSleeping()) return; - populateGui(); - player.openInventory(getInventory()); - } - -} From 2410ff4533591fc3d3321466cf9c2ae0ec544968 Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 21 Apr 2024 14:56:00 +0100 Subject: [PATCH 04/43] feature: Improvements to the component API and starting to document --- bukkit/build.gradle.kts | 8 ++- .../java/dev/triumphteam/gui/bukkit/Gui.java | 22 ++++---- .../gui/bukkit/GuiBukkitListener.java | 30 +++++++++++ .../dev/triumphteam/gui/bukkit/GuiView.java | 25 ++++++---- .../gui/bukkit/builder/GuiBuilder.java | 4 +- .../java/dev/triumphteam/gui/BaseGui.java | 17 +++++-- .../java/dev/triumphteam/gui/BaseGuiView.java | 46 ++++++++--------- .../gui/builder/BaseGuiBuilder.java | 23 +++++---- .../gui/component/FinalComponent.java | 6 ++- .../gui/component/FunctionalGuiComponent.java | 20 ++++++++ .../gui/component/GuiComponent.java | 18 +++---- .../gui/component/GuiComponentBuilder.java | 9 ++++ .../gui/component/GuiComponentRender.java | 13 +++++ .../gui/component/GuiComponentRenderer.java | 14 ------ .../SimpleFunctionalGuiComponent.java | 50 +++++++++++++++++++ .../component/SimpleGuiComponentRenderer.java | 42 ---------------- .../component/builtin/PaginatedComponent.java | 21 ++++++++ .../triumphteam/gui/container/Container.java | 17 ------- .../gui/container/GuiContainer.java | 14 ++++++ .../gui/container/MapBackedContainer.java | 33 ++++++++++++ .../triumphteam/gui/element/GuiElement.java | 4 -- .../dev/triumphteam/gui/item/GuiItem.java | 12 +++++ .../triumphteam/gui/item/ItemClickAction.java | 7 +++ .../triumphteam/gui/item/RenderedItem.java | 4 ++ .../java/dev/triumphteam/gui/slot/Slot.java | 4 +- .../triumphteam/gui/state/MutableState.java | 8 +++ .../triumphteam/gui/state/SimpleState.java | 6 +-- .../java/dev/triumphteam/gui/state/State.java | 32 ++++++++---- gradle/wrapper/gradle-wrapper.properties | 2 +- 29 files changed, 350 insertions(+), 161 deletions(-) create mode 100644 bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/GuiComponentBuilder.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/GuiComponentRender.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/component/GuiComponentRenderer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponentRenderer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/container/Container.java create mode 100644 core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/element/GuiElement.java create mode 100644 core/src/main/java/dev/triumphteam/gui/item/GuiItem.java create mode 100644 core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java create mode 100644 core/src/main/java/dev/triumphteam/gui/item/RenderedItem.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/MutableState.java diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts index 57b1dfd9..ef7da03c 100644 --- a/bukkit/build.gradle.kts +++ b/bukkit/build.gradle.kts @@ -3,10 +3,14 @@ plugins { } repositories { - maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") + maven("https://repo.papermc.io/repository/maven-public/") } dependencies { api(projects.triumphGuiCore) - api(libs.spigot) + compileOnlyApi("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") +} + +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(17)) } diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java index 7994edfc..21c35415 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java @@ -1,27 +1,31 @@ package dev.triumphteam.gui.bukkit; import dev.triumphteam.gui.BaseGui; -import dev.triumphteam.gui.component.SimpleGuiComponentRenderer; +import dev.triumphteam.gui.component.FinalComponent; +import dev.triumphteam.gui.component.SimpleFunctionalGuiComponent; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.List; -public final class Gui implements BaseGui { +public final class Gui implements BaseGui { - private final List> componentRenderers; + private final List> components; + + static { + GuiBukkitListener.register(); + } public Gui( - final @NotNull List> componentRenderers + final @NotNull List> componentRenderers ) { - this.componentRenderers = componentRenderers; + this.components = componentRenderers.stream().map(SimpleFunctionalGuiComponent::createComponent).toList(); } @Override - public @NotNull GuiView open(final @NotNull Player player, final @Nullable GuiView parent) { - final var view = new GuiView(player, parent); + public void open(final @NotNull Player player) { + final var view = new GuiView(player, components); view.open(); - return view; } } diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java new file mode 100644 index 00000000..ca3c64d6 --- /dev/null +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java @@ -0,0 +1,30 @@ +package dev.triumphteam.gui.bukkit; + +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.java.JavaPlugin; + +public final class GuiBukkitListener implements Listener { + + private static final Plugin plugin = JavaPlugin.getProvidingPlugin(GuiBukkitListener.class); + + public static void register() { + Bukkit.getServer().getPluginManager().registerEvents(new GuiBukkitListener(), plugin); + } + + @EventHandler + public void onGuiClick(final InventoryClickEvent event) { + final var holder = event.getInventory().getHolder(); + if (!(holder instanceof final GuiView view)) { + return; + } + + event.setCancelled(true); + final var action = view.getAction(event.getSlot()); + if (action == null) return; + action.click(); + } +} diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java index caddae57..914baa87 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java @@ -2,32 +2,33 @@ import dev.triumphteam.gui.BaseGuiView; import dev.triumphteam.gui.component.FinalComponent; -import dev.triumphteam.gui.container.Container; +import dev.triumphteam.gui.container.MapBackedContainer; +import dev.triumphteam.gui.item.RenderedItem; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.List; -public final class GuiView extends BaseGuiView implements InventoryHolder { +public final class GuiView extends BaseGuiView implements InventoryHolder { private final Inventory inventory; public GuiView( final @NotNull Player player, - final @Nullable GuiView parent, - final @NotNull List> componentRenderers + final @NotNull List> componentRenderers ) { - super(player, parent, componentRenderers); - this.inventory = Bukkit.createInventory(this, 6, "Gui"); + super(player, componentRenderers); + this.inventory = Bukkit.createInventory(this, 54, "Gui"); } @Override public void open() { getViewer().openInventory(inventory); + setup(); } @Override @@ -42,7 +43,13 @@ public Inventory getInventory() { } @Override - protected void populateInventory(final @NotNull Container container) { - inventory.addItem() + protected void populateInventory(final @NotNull MapBackedContainer container) { + inventory.clear(); + container.getBacking().forEach((slot, baseGuiItem) -> { + final var rendered = baseGuiItem.render(); + final var inventorySlot = slot.asRealSlot(); + temporaryCache.put(inventorySlot, new RenderedItem<>(rendered, baseGuiItem.getClickAction())); + inventory.setItem(inventorySlot, rendered); + }); } } diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java index c321bf7d..ea6b1136 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java @@ -2,10 +2,10 @@ import dev.triumphteam.gui.builder.BaseGuiBuilder; import dev.triumphteam.gui.bukkit.Gui; -import dev.triumphteam.gui.bukkit.GuiView; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; -public final class GuiBuilder extends BaseGuiBuilder { +public final class GuiBuilder extends BaseGuiBuilder { @Override public Gui build() { diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGui.java b/core/src/main/java/dev/triumphteam/gui/BaseGui.java index a8e20035..53d5d4bb 100644 --- a/core/src/main/java/dev/triumphteam/gui/BaseGui.java +++ b/core/src/main/java/dev/triumphteam/gui/BaseGui.java @@ -1,9 +1,20 @@ package dev.triumphteam.gui; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -public interface BaseGui> { +/** + * Representation of a simple GUI. + * The GUI itself does nothing other than be a blue-print for multiple {@link BaseGuiView} views, + * for {@link P} players to interact with. + * + * @param

A player. + */ +public interface BaseGui

{ - @NotNull V open(final @NotNull P player, final @Nullable V parent); + /** + * Opens a {@link BaseGuiView} of this GUI for the {@link P} player. + * + * @param player The player to show the view to. + */ + void open(final @NotNull P player); } diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java b/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java index 073f6251..f28ee542 100644 --- a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java @@ -1,25 +1,27 @@ package dev.triumphteam.gui; import dev.triumphteam.gui.component.FinalComponent; -import dev.triumphteam.gui.container.Container; +import dev.triumphteam.gui.container.MapBackedContainer; +import dev.triumphteam.gui.item.ItemClickAction; +import dev.triumphteam.gui.item.RenderedItem; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashMap; import java.util.List; +import java.util.Map; -public abstract class BaseGuiView> { +public abstract class BaseGuiView { + protected final Map> temporaryCache = new HashMap<>(); private final P viewer; - private final V parent; - private final List> components; + private final List> components; public BaseGuiView( final @NotNull P viewer, - final V parent, - final List> components + final List> components ) { this.viewer = viewer; - this.parent = parent; this.components = components; } @@ -27,29 +29,27 @@ public BaseGuiView( return viewer; } - public @Nullable V getParent() { - return parent; - } - public abstract void open(); public abstract void close(); protected void setup() { - components.forEach(renderer -> { - renderer.states().forEach(state -> { - state.addListener(this, () -> { - renderComponent(renderer); - }); - }); - }); + components.forEach(renderer -> renderer.states().forEach(state -> state.addListener(this, () -> renderComponent(renderer)))); + + components.forEach(this::renderComponent); } - private void renderComponent(final @NotNull FinalComponent component) { - final var container = new Container(); - //noinspection unchecked - component.component().render(container, viewer, (V) this); + private void renderComponent(final @NotNull FinalComponent component) { + final var container = new MapBackedContainer(); + component.component().render(container, viewer); + populateInventory(container); } - protected abstract void populateInventory(final @NotNull Container container); + protected abstract void populateInventory(final @NotNull MapBackedContainer container); + + public @Nullable ItemClickAction getAction(final int slot) { + final var item = temporaryCache.get(slot); + if (item == null) return null; + return item.action(); + } } diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index df3d362d..55218a5d 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,28 +1,33 @@ package dev.triumphteam.gui.builder; import dev.triumphteam.gui.BaseGui; -import dev.triumphteam.gui.BaseGuiView; -import dev.triumphteam.gui.component.GuiComponentRenderer; -import dev.triumphteam.gui.component.SimpleGuiComponentRenderer; +import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.GuiComponentBuilder; +import dev.triumphteam.gui.component.SimpleFunctionalGuiComponent; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -import java.util.function.Consumer; @SuppressWarnings({"unchecked", "UnusedReturnValue"}) -public abstract class BaseGuiBuilder, P, G extends BaseGui, V extends BaseGuiView> { +public abstract class BaseGuiBuilder, P, G extends BaseGui

, I> { - protected final List> componentRenderers = new ArrayList<>(); + protected final List> componentRenderers = new ArrayList<>(); @Contract("_ -> this") - public @NotNull B component(final @NotNull Consumer<@NotNull GuiComponentRenderer<@NotNull P, @NotNull V>> renderer) { - final var componentRenderer = new SimpleGuiComponentRenderer(); - renderer.accept(componentRenderer); + public @NotNull B component(final @NotNull GuiComponentBuilder builder) { + final var componentRenderer = new SimpleFunctionalGuiComponent(); + builder.accept(componentRenderer); componentRenderers.add(componentRenderer); return (B) this; } + @Contract("_ -> this") + public @NotNull B component(final @NotNull GuiComponent component) { + // TODO(matt): Yeah + return (B) this; + } + public abstract G build(); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java b/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java index 5cee0c7b..407b5ec5 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java @@ -1,9 +1,11 @@ package dev.triumphteam.gui.component; -import dev.triumphteam.gui.BaseGuiView; import dev.triumphteam.gui.state.State; import java.util.List; -public record FinalComponent>(List> states, GuiComponent component) { +public record FinalComponent( + List> states, + GuiComponentRender component +) { } diff --git a/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java new file mode 100644 index 00000000..381bc900 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java @@ -0,0 +1,20 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.state.MutableState; +import dev.triumphteam.gui.state.State; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface FunctionalGuiComponent { + + @NotNull + State state(final @NotNull State value); + + @NotNull MutableState<@NotNull T> state(final @NotNull T value); + + @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value); + + @NotNull MutableState state(final @NotNull MutableState state); + + void render(final @NotNull GuiComponentRender<@NotNull P, @NotNull I> component); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java index 094666d3..8941f2f6 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java @@ -1,15 +1,15 @@ package dev.triumphteam.gui.component; -import dev.triumphteam.gui.BaseGuiView; -import dev.triumphteam.gui.container.Container; +import dev.triumphteam.gui.container.GuiContainer; +import dev.triumphteam.gui.state.State; import org.jetbrains.annotations.NotNull; -@FunctionalInterface -public interface GuiComponent> { +import java.util.List; - void render( - final @NotNull Container container, - final @NotNull P player, - final @NotNull V view - ); +public interface GuiComponent { + + @NotNull + List<@NotNull State> states(); + + void render(final @NotNull GuiContainer<@NotNull I> container, final @NotNull P player); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentBuilder.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentBuilder.java new file mode 100644 index 00000000..a2a7e7fb --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentBuilder.java @@ -0,0 +1,9 @@ +package dev.triumphteam.gui.component; + +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface GuiComponentBuilder { + + void accept(final @NotNull FunctionalGuiComponent<@NotNull P, @NotNull I> component); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRender.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRender.java new file mode 100644 index 00000000..ef9f41e3 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRender.java @@ -0,0 +1,13 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.container.GuiContainer; +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface GuiComponentRender { + + void render( + final @NotNull GuiContainer container, + final @NotNull P player + ); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRenderer.java deleted file mode 100644 index dab301e4..00000000 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRenderer.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.triumphteam.gui.component; - -import dev.triumphteam.gui.BaseGuiView; -import dev.triumphteam.gui.state.State; -import org.jetbrains.annotations.NotNull; - -public interface GuiComponentRenderer> { - - State state(final int value); - - State state(final @NotNull State state); - - void render(final @NotNull GuiComponent component); -} diff --git a/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java new file mode 100644 index 00000000..52e071e4 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java @@ -0,0 +1,50 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.exception.GuiException; +import dev.triumphteam.gui.state.MutableState; +import dev.triumphteam.gui.state.SimpleState; +import dev.triumphteam.gui.state.State; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public final class SimpleFunctionalGuiComponent implements FunctionalGuiComponent { + + private final List> states = new ArrayList<>(); + private GuiComponentRender component = null; + + @Override + public @NotNull State state(final @NotNull State value) { + return null; + } + + @Override + public @NotNull MutableState<@NotNull T> state(@NotNull final T value) { + return null; + } + + @Override + public @NotNull MutableState<@Nullable T> nullableState(@Nullable final T value) { + return null; + } + + @Override + public @NotNull MutableState state(final @NotNull MutableState state) { + return null; + } + + @Override + public void render(final @NotNull GuiComponentRender component) { + this.component = component; + } + + /*public @NotNull FinalComponent createComponent() { + if (component == null) { + throw new GuiException("TODO"); + } + + return new FinalComponent<>(states, component); + }*/ +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponentRenderer.java deleted file mode 100644 index b87bd4de..00000000 --- a/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponentRenderer.java +++ /dev/null @@ -1,42 +0,0 @@ -package dev.triumphteam.gui.component; - -import dev.triumphteam.gui.BaseGuiView; -import dev.triumphteam.gui.exception.GuiException; -import dev.triumphteam.gui.state.SimpleState; -import dev.triumphteam.gui.state.State; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; - -public final class SimpleGuiComponentRenderer> implements GuiComponentRenderer { - - private final List> states = new ArrayList<>(); - private GuiComponent component = null; - - @Override - public State state(final int value) { - final var state = new SimpleState<>(value); - states.add(state); - return state; - } - - @Override - public State state(final @NotNull State state) { - states.add(state); - return state; - } - - @Override - public void render(final @NotNull GuiComponent component) { - this.component = component; - } - - public @NotNull FinalComponent createComponent() { - if (component == null) { - throw new GuiException("TODO"); - } - - return new FinalComponent<>(states, component); - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java new file mode 100644 index 00000000..34dfd222 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java @@ -0,0 +1,21 @@ +package dev.triumphteam.gui.component.builtin; + +import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.container.GuiContainer; +import dev.triumphteam.gui.state.State; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public final class PaginatedComponent implements GuiComponent { + + @Override + public @NotNull List<@NotNull State> states() { + return List.of(); + } + + @Override + public void render(final @NotNull GuiContainer<@NotNull I> container, @NotNull final P player) { + + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/container/Container.java b/core/src/main/java/dev/triumphteam/gui/container/Container.java deleted file mode 100644 index fc0751b2..00000000 --- a/core/src/main/java/dev/triumphteam/gui/container/Container.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.triumphteam.gui.container; - -import dev.triumphteam.gui.element.GuiElement; -import dev.triumphteam.gui.slot.Slot; -import org.jetbrains.annotations.NotNull; - -import java.util.HashMap; -import java.util.Map; - -public final class Container { - - private final Map backing = new HashMap<>(100); - - public void set(final @NotNull Slot slot, final @NotNull GuiElement guiElement) { - backing.put(slot, guiElement); - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java new file mode 100644 index 00000000..fde61b40 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -0,0 +1,14 @@ +package dev.triumphteam.gui.container; + +import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +public interface GuiContainer { + + void set(final int slot, final @NotNull GuiItem<@NotNull I> guiItem); + + void set(final int row, final int column, final @NotNull GuiItem<@NotNull I> guiItem); + + void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull I> guiItem); +} diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java new file mode 100644 index 00000000..f9c6a786 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -0,0 +1,33 @@ +package dev.triumphteam.gui.container; + +import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +public final class MapBackedContainer implements GuiContainer { + + private final Map> backing = new HashMap<>(100); + + @Override + public void set(final int slot, final @NotNull GuiItem<@NotNull I> guiItem) { + set(new Slot(slot), guiItem); + } + + @Override + public void set(final int row, final int column, final @NotNull GuiItem<@NotNull I> guiItem) { + // TODO(matt): This + set(new Slot(0), guiItem); + } + + @Override + public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull I> guiItem) { + backing.put(slot, guiItem); + } + + public @NotNull Map> getBacking() { + return backing; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java b/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java deleted file mode 100644 index 22d01647..00000000 --- a/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java +++ /dev/null @@ -1,4 +0,0 @@ -package dev.triumphteam.gui.element; - -public interface GuiElement { -} diff --git a/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java new file mode 100644 index 00000000..44b50f13 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java @@ -0,0 +1,12 @@ +package dev.triumphteam.gui.item; + +import org.jetbrains.annotations.NotNull; + +public interface GuiItem { + + @NotNull + I render(); + + @NotNull + ItemClickAction getClickAction(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java b/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java new file mode 100644 index 00000000..a065903b --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java @@ -0,0 +1,7 @@ +package dev.triumphteam.gui.item; + +@FunctionalInterface +public interface ItemClickAction { + + void click(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/item/RenderedItem.java b/core/src/main/java/dev/triumphteam/gui/item/RenderedItem.java new file mode 100644 index 00000000..ed2c4e8a --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/item/RenderedItem.java @@ -0,0 +1,4 @@ +package dev.triumphteam.gui.item; + +public record RenderedItem(I item, ItemClickAction action) { +} diff --git a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java index 9df0d685..62ec751a 100644 --- a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java +++ b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java @@ -1,8 +1,8 @@ package dev.triumphteam.gui.slot; -public record Slot(int row, int col) { +public record Slot(int slot) { public int asRealSlot() { - return 0; + return slot; } } diff --git a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java new file mode 100644 index 00000000..64ec1f1d --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java @@ -0,0 +1,8 @@ +package dev.triumphteam.gui.state; + +public interface MutableState extends State { + + T getValue(); + + void setValue(final T value); +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java b/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java index 67951573..88e8a892 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java @@ -3,7 +3,7 @@ import dev.triumphteam.gui.BaseGuiView; import org.jetbrains.annotations.NotNull; -public final class SimpleState implements State { +public final class SimpleState implements MutableState { private final StateMap stateMap = new StateMap(); private T value; @@ -20,11 +20,11 @@ public T getValue() { @Override public void setValue(final T value) { this.value = value; - force(); + trigger(); } @Override - public void force() { + public void trigger() { stateMap.run(); } diff --git a/core/src/main/java/dev/triumphteam/gui/state/State.java b/core/src/main/java/dev/triumphteam/gui/state/State.java index 32f5ec98..0dc3def8 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/State.java +++ b/core/src/main/java/dev/triumphteam/gui/state/State.java @@ -3,16 +3,28 @@ import dev.triumphteam.gui.BaseGuiView; import org.jetbrains.annotations.NotNull; -public interface State { +/** + * A representation of a "state" in the GUI. + * A state doesn't necessarily need to hold any value. + * Its sole purpose is to trigger updates on the GUI. + */ +public interface State { - T getValue(); + /** + * Trigger a component to re-render. + */ + void trigger(); - void setValue(final T value); - - void force(); - - void addListener( - final @NotNull BaseGuiView view, - final @NotNull Runnable runnable - ); + /** + * Adds a new listener to the state. + * Avoid calling this method manually if you don't know what you are doing, + * this is mostly done internally by the {@link BaseGuiView}. + *

+ * The listener is tied to the lifecycle of the {@link BaseGuiView}, + * so avoid holding the view if it is no longer needed. + * + * @param view The {@link BaseGuiView} which will be handling this state. + * @param listener The listener to be called when a state is triggered. + */ + void addListener(final @NotNull BaseGuiView view, final @NotNull Runnable listener); } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e1bef7e8..48c0a02c 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-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From e9890dbe8fb7a3d98ecc04bbb74e005a0573c703 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 22 Apr 2024 22:31:42 +0100 Subject: [PATCH 05/43] feature: New states! --- .../gui/component/FunctionalGuiComponent.java | 70 ++++++++++++++++- .../SimpleFunctionalGuiComponent.java | 34 ++++++--- .../gui/state/BaseMutableState.java | 53 +++++++++++++ .../triumphteam/gui/state/MutableState.java | 36 +++++++++ .../triumphteam/gui/state/SimpleState.java | 38 +++------- .../java/dev/triumphteam/gui/state/State.java | 4 + .../gui/state/StateListenerContainer.java | 45 +++++++++++ .../dev/triumphteam/gui/state/StateMap.java | 20 ----- .../gui/state/policy/StateMutationPolicy.java | 75 +++++++++++++++++++ 9 files changed, 315 insertions(+), 60 deletions(-) create mode 100644 core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/StateMap.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java diff --git a/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java index 381bc900..3049fd09 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java @@ -1,20 +1,84 @@ package dev.triumphteam.gui.component; +import dev.triumphteam.gui.builder.BaseGuiBuilder; +import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.State; +import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +/** + * Similar to a {@link GuiComponent} this component will take in states and render a component. + * Unlike {@link GuiComponent} it is not meant to be extended upon and is only used by the {@link BaseGuiBuilder}. + * + * @param

The player type. + * @param The item type. + */ public interface FunctionalGuiComponent { + /** + * Associate a {@link State} to the component. + * + * @param state A state. + * @return The same state passed. + */ @NotNull - State state(final @NotNull State value); + State state(final @NotNull State state); + /** + * Create a new state with the given default value. + * + * @param value The default value of the state. + * @param The type of the value. + * @return The newly created {@link MutableState}. + */ @NotNull MutableState<@NotNull T> state(final @NotNull T value); + /** + * Create a new state with the given default value. + * Uses the given {@link StateMutationPolicy} for equivalence check. + * + * @param value The default value of the state. + * @param mutationPolicy The mutation policy to use. + * @param The type of the value. + * @return The newly created {@link MutableState}. + */ + @NotNull MutableState<@NotNull T> state( + final @NotNull T value, + final @NotNull StateMutationPolicy mutationPolicy + ); + + /** + * Create a new state with the given default value. + * In this case, the value is nullable. + * + * @param value The default value of the state. + * @param The type of the value. + * @return The newly created {@link MutableState}. + */ @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value); - @NotNull MutableState state(final @NotNull MutableState state); + /** + * Create a new state with the given default value. + * In this case, the value is nullable. + * Uses the given {@link StateMutationPolicy} for equivalence check. + * + * @param value The default value of the state. + * @param mutationPolicy The mutation policy to use. + * @param The type of the value. + * @return The newly created {@link MutableState}. + */ + @NotNull MutableState<@Nullable T> nullableState( + final @Nullable T value, + final @NotNull StateMutationPolicy mutationPolicy + ); - void render(final @NotNull GuiComponentRender<@NotNull P, @NotNull I> component); + /** + * A component render function. + * The function inside works the same as a normal {@link GuiComponent#render(GuiContainer, Object)} would. + * + * @param render The component render. + */ + void render(final @NotNull GuiComponentRender<@NotNull P, @NotNull I> render); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java index 52e071e4..5566f51f 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java @@ -1,9 +1,9 @@ package dev.triumphteam.gui.component; -import dev.triumphteam.gui.exception.GuiException; import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.SimpleState; import dev.triumphteam.gui.state.State; +import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -12,27 +12,43 @@ public final class SimpleFunctionalGuiComponent implements FunctionalGuiComponent { - private final List> states = new ArrayList<>(); + private final List states = new ArrayList<>(); private GuiComponentRender component = null; @Override - public @NotNull State state(final @NotNull State value) { - return null; + public @NotNull State state(final @NotNull State state) { + states.add(state); + return state; } @Override public @NotNull MutableState<@NotNull T> state(@NotNull final T value) { - return null; + return state(value, StateMutationPolicy.StructuralEquality.INSTANCE); } @Override - public @NotNull MutableState<@Nullable T> nullableState(@Nullable final T value) { - return null; + public @NotNull MutableState<@NotNull T> state( + final @NotNull T value, + final @NotNull StateMutationPolicy mutationPolicy + ) { + var state = new SimpleState<>(value, mutationPolicy); + states.add(state); + return state; } @Override - public @NotNull MutableState state(final @NotNull MutableState state) { - return null; + public @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value) { + return nullableState(value, StateMutationPolicy.StructuralEquality.INSTANCE); + } + + @Override + public @NotNull MutableState<@Nullable T> nullableState( + final @Nullable T value, + final @NotNull StateMutationPolicy mutationPolicy + ) { + var state = new SimpleState<>(value, mutationPolicy); + states.add(state); + return state; } @Override diff --git a/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java b/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java new file mode 100644 index 00000000..a2d29f6f --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java @@ -0,0 +1,53 @@ +package dev.triumphteam.gui.state; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.state.policy.StateMutationPolicy; +import org.jetbrains.annotations.NotNull; + +/** + * Base implementation for a {@link MutableState}. + * The mutability of the value {@link T} is dependent on the given {@link StateMutationPolicy}. + * + * @param The type of the value. + * @see SimpleState + */ +public abstract class BaseMutableState implements MutableState { + + private final StateMutationPolicy mutationPolicy; + private final StateListenerContainer listenerContainer = new StateListenerContainer(); + private T value; + + public BaseMutableState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { + this.value = value; + this.mutationPolicy = mutationPolicy; + } + + @Override + public T getValue() { + return value; + } + + @Override + public void setValue(final T value) { + // Will not mutate value if they are equivalent + if (!mutationPolicy.equivalent(this.value, value)) return; + + this.value = value; + trigger(); + } + + @Override + public @NotNull StateMutationPolicy stateMutationPolicy() { + return mutationPolicy; + } + + @Override + public void trigger() { + listenerContainer.triggerAll(); + } + + @Override + public void addListener(final @NotNull BaseGuiView view, final @NotNull Runnable listener) { + listenerContainer.addListener(view, listener); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java index 64ec1f1d..7f981e39 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java @@ -1,8 +1,44 @@ package dev.triumphteam.gui.state; +import dev.triumphteam.gui.state.policy.StateMutationPolicy; +import org.jetbrains.annotations.NotNull; + +/** + * A representation of a {@link State} that is mutable. + * Modifying value of type {@link T} will trigger the component associated with this state to re-render. + * Setting the value to an equal value as the current, may or may not trigger an update, + * all depending on the implementation of the used {@link MutableState}. + * Same for the nullability of the value. + * + * @param The type the state accepts. + * @see BaseMutableState + * @see SimpleState + */ public interface MutableState extends State { + /** + * Gets the current value of the state. + * The nullability of this value depends on the value passed. + * + * @return The value of the state. + */ T getValue(); + /** + * Set a new value to the state. + * This may or may not trigger a component to re-draw. + * + * @param value The new value of the state. + */ void setValue(final T value); + + /** + * Which mutation policy is used by this state. + * The mutation policy is not used outside the state itself, + * so it can be ignored if not actively used but custom implementations of {@link MutableState}. + * + * @return The used mutation policy. + */ + @NotNull + StateMutationPolicy stateMutationPolicy(); } diff --git a/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java b/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java index 88e8a892..519f2246 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java @@ -1,35 +1,17 @@ package dev.triumphteam.gui.state; -import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; -public final class SimpleState implements MutableState { +/** + * The simplest implementation of {@link MutableState}. + * + * @param The type of the value. + * @see BaseMutableState For the implementation. + */ +public final class SimpleState extends BaseMutableState { - private final StateMap stateMap = new StateMap(); - private T value; - - public SimpleState(final T value) { - this.value = value; - } - - @Override - public T getValue() { - return value; - } - - @Override - public void setValue(final T value) { - this.value = value; - trigger(); - } - - @Override - public void trigger() { - stateMap.run(); - } - - @Override - public void addListener(final @NotNull BaseGuiView view, final @NotNull Runnable runnable) { - stateMap.put(view, runnable); + public SimpleState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { + super(value, mutationPolicy); } } diff --git a/core/src/main/java/dev/triumphteam/gui/state/State.java b/core/src/main/java/dev/triumphteam/gui/state/State.java index 0dc3def8..c7448058 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/State.java +++ b/core/src/main/java/dev/triumphteam/gui/state/State.java @@ -7,6 +7,10 @@ * A representation of a "state" in the GUI. * A state doesn't necessarily need to hold any value. * Its sole purpose is to trigger updates on the GUI. + * + * @see MutableState + * @see BaseMutableState + * @see SimpleState */ public interface State { diff --git a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java new file mode 100644 index 00000000..9e249548 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java @@ -0,0 +1,45 @@ +package dev.triumphteam.gui.state; + +import dev.triumphteam.gui.BaseGuiView; +import org.jetbrains.annotations.NotNull; + +import java.lang.ref.WeakReference; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentHashMap; + +/** + * A map backed container for state listeners. + * This container uses a {@link WeakHashMap}, so instances of the {@link BaseGuiView} can prevent + * values from being garbage collected correctly. + */ +public final class StateListenerContainer { + + private final Set listeners = ConcurrentHashMap.newKeySet(); + + /** + * Adds listener tied to the {@link BaseGuiView} lifecycle. + * + * @param view The view to be used as the reference. + * @param listener The listener to run when a state is triggered. + */ + public void addListener(final @NotNull BaseGuiView view, final @NotNull Runnable listener) { + listeners.add(new Pair(new WeakReference<>(view), listener)); + } + + /** + * Triggers all listeners that this state uses. + */ + public void triggerAll() { + listeners.forEach(pair -> pair.listener.run()); + } + + /** + * Simple pair only used by this class. + * Simply used to hold a weak reference of the view and a listener. + * + * @param weakView The weak reference of view. + * @param listener The listener to run when a state is triggered. + */ + private record Pair(WeakReference> weakView, Runnable listener) {} +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/StateMap.java b/core/src/main/java/dev/triumphteam/gui/state/StateMap.java deleted file mode 100644 index 24b9428b..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/StateMap.java +++ /dev/null @@ -1,20 +0,0 @@ -package dev.triumphteam.gui.state; - -import dev.triumphteam.gui.BaseGuiView; -import org.jetbrains.annotations.NotNull; - -import java.util.Map; -import java.util.WeakHashMap; - -public final class StateMap { - - private final Map, Runnable> backing = new WeakHashMap<>(); - - public void put(final @NotNull BaseGuiView view, final @NotNull Runnable runnable) { - backing.put(view, runnable); - } - - public void run() { - backing.forEach((inventoryInterface, runnable) -> runnable.run()); - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java b/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java new file mode 100644 index 00000000..281433dd --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java @@ -0,0 +1,75 @@ +package dev.triumphteam.gui.state.policy; + +import dev.triumphteam.gui.state.MutableState; +import org.jetbrains.annotations.Nullable; + +/** + * States how a {@link MutableState} handles equality. + * By default, {@link StructuralEquality} is used. + */ +public interface StateMutationPolicy { + + /** + * Checks if the two values are equivalent. + * + * @param a The first value. + * @param b The second value. + * @return Whether or not they are equivalent. + */ + boolean equivalent(final @Nullable Object a, final @Nullable Object b); + + /** + * A {@link StateMutationPolicy} that checks for reference equality. + * This class is a singleton and {@link ReferenceEquality#INSTANCE} should always be the used instance. + */ + final class ReferenceEquality implements StateMutationPolicy { + + public static final StateMutationPolicy INSTANCE = new ReferenceEquality(); + + private ReferenceEquality() { + throw new AssertionError("Should not be instantiated"); + } + + @Override + public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { + return a == b; + } + } + + /** + * A {@link StateMutationPolicy} that checks for structural equality. + * This class is a singleton and {@link StructuralEquality#INSTANCE} should always be the used instance. + */ + final class StructuralEquality implements StateMutationPolicy { + + public static final StateMutationPolicy INSTANCE = new StructuralEquality(); + + private StructuralEquality() { + throw new AssertionError("Should not be instantiated"); + } + + @Override + public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { + if (a == null || b == null) return false; + return a.equals(b); + } + } + + /** + * A {@link StateMutationPolicy} that makes values never be equivalent. + * This class is a singleton and {@link NeverEqual#INSTANCE} should always be the used instance. + */ + final class NeverEqual implements StateMutationPolicy { + + public static final StateMutationPolicy INSTANCE = new NeverEqual(); + + private NeverEqual() { + throw new AssertionError("Should not be instantiated"); + } + + @Override + public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { + return false; + } + } +} From a4295b607f9c52815b5830adfc082198644d13c7 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 23 Apr 2024 21:14:28 +0100 Subject: [PATCH 06/43] chore: Slightly rework components to be more extendable --- bukkit/build.gradle.kts | 2 +- .../java/dev/triumphteam/gui/bukkit/Gui.java | 2 +- .../dev/triumphteam/gui/bukkit/GuiView.java | 5 +- core/build.gradle.kts | 5 +- .../java/dev/triumphteam/gui/BaseGui.java | 4 +- .../java/dev/triumphteam/gui/BaseGuiView.java | 11 ++-- .../java/dev/triumphteam/gui/GuiView.java | 8 +++ .../gui/builder/BaseGuiBuilder.java | 8 +-- .../gui/component/FinalComponent.java | 1 + .../gui/component/GuiComponent.java | 8 +-- .../gui/component/ReactiveGuiComponent.java | 12 +++++ .../component/builtin/PaginatedComponent.java | 4 +- .../FunctionalGuiComponent.java | 8 +-- .../{ => functional}/GuiComponentBuilder.java | 2 +- .../{ => functional}/GuiComponentRender.java | 2 +- .../SimpleFunctionalGuiComponent.java | 11 ++-- .../{ => renderer}/GuiComponentProcessor.java | 2 +- .../gui/container/GuiContainer.java | 8 +-- .../gui/container/MapBackedContainer.java | 18 +++---- .../GuiItem.java => element/GuiElement.java} | 4 +- .../{item => element}/ItemClickAction.java | 2 +- .../gui/{item => element}/RenderedItem.java | 2 +- .../java/dev/triumphteam/gui/slot/Slot.java | 4 -- .../gui/state/BaseMutableState.java | 8 +-- .../triumphteam/gui/state/MutableState.java | 1 + .../java/dev/triumphteam/gui/state/State.java | 11 ++-- .../gui/state/StateListenerContainer.java | 50 +++++++++++-------- .../gui/state/{ => builtin}/SimpleState.java | 4 +- gradle/libs.versions.toml | 6 ++- 29 files changed, 121 insertions(+), 92 deletions(-) create mode 100644 core/src/main/java/dev/triumphteam/gui/GuiView.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java rename core/src/main/java/dev/triumphteam/gui/component/{ => functional}/FunctionalGuiComponent.java (87%) rename core/src/main/java/dev/triumphteam/gui/component/{ => functional}/GuiComponentBuilder.java (80%) rename core/src/main/java/dev/triumphteam/gui/component/{ => functional}/GuiComponentRender.java (84%) rename core/src/main/java/dev/triumphteam/gui/component/{ => functional}/SimpleFunctionalGuiComponent.java (84%) rename core/src/main/java/dev/triumphteam/gui/component/{ => renderer}/GuiComponentProcessor.java (75%) rename core/src/main/java/dev/triumphteam/gui/{item/GuiItem.java => element/GuiElement.java} (64%) rename core/src/main/java/dev/triumphteam/gui/{item => element}/ItemClickAction.java (67%) rename core/src/main/java/dev/triumphteam/gui/{item => element}/RenderedItem.java (64%) rename core/src/main/java/dev/triumphteam/gui/state/{ => builtin}/SimpleState.java (76%) diff --git a/bukkit/build.gradle.kts b/bukkit/build.gradle.kts index ef7da03c..f1497eca 100644 --- a/bukkit/build.gradle.kts +++ b/bukkit/build.gradle.kts @@ -8,7 +8,7 @@ repositories { dependencies { api(projects.triumphGuiCore) - compileOnlyApi("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") + compileOnly(libs.paper) } java { diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java index 21c35415..2cb1b96f 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java @@ -2,7 +2,7 @@ import dev.triumphteam.gui.BaseGui; import dev.triumphteam.gui.component.FinalComponent; -import dev.triumphteam.gui.component.SimpleFunctionalGuiComponent; +import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java index 914baa87..29672eab 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java @@ -1,9 +1,8 @@ package dev.triumphteam.gui.bukkit; -import dev.triumphteam.gui.BaseGuiView; import dev.triumphteam.gui.component.FinalComponent; import dev.triumphteam.gui.container.MapBackedContainer; -import dev.triumphteam.gui.item.RenderedItem; +import dev.triumphteam.gui.element.RenderedItem; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; @@ -13,7 +12,7 @@ import java.util.List; -public final class GuiView extends BaseGuiView implements InventoryHolder { +public final class GuiView extends dev.triumphteam.gui.GuiView implements InventoryHolder { private final Inventory inventory; diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 7314ccac..aac3946e 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -2,7 +2,6 @@ plugins { id("gui.base") } -repositories { - maven("https://papermc.io/repo/repository/maven-public/") - maven("https://repo.triumphteam.dev/snapshots/") +dependencies { + implementation(libs.caffeine) } diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGui.java b/core/src/main/java/dev/triumphteam/gui/BaseGui.java index 53d5d4bb..5d4ec18c 100644 --- a/core/src/main/java/dev/triumphteam/gui/BaseGui.java +++ b/core/src/main/java/dev/triumphteam/gui/BaseGui.java @@ -4,7 +4,7 @@ /** * Representation of a simple GUI. - * The GUI itself does nothing other than be a blue-print for multiple {@link BaseGuiView} views, + * The GUI itself does nothing other than be a blue-print for multiple {@link GuiView} views, * for {@link P} players to interact with. * * @param

A player. @@ -12,7 +12,7 @@ public interface BaseGui

{ /** - * Opens a {@link BaseGuiView} of this GUI for the {@link P} player. + * Opens a {@link GuiView} of this GUI for the {@link P} player. * * @param player The player to show the view to. */ diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java b/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java index f28ee542..8b03a172 100644 --- a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java @@ -2,8 +2,8 @@ import dev.triumphteam.gui.component.FinalComponent; import dev.triumphteam.gui.container.MapBackedContainer; -import dev.triumphteam.gui.item.ItemClickAction; -import dev.triumphteam.gui.item.RenderedItem; +import dev.triumphteam.gui.element.ItemClickAction; +import dev.triumphteam.gui.element.RenderedItem; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -11,9 +11,10 @@ import java.util.List; import java.util.Map; -public abstract class BaseGuiView { +public abstract class BaseGuiView implements GuiView { protected final Map> temporaryCache = new HashMap<>(); + private final P viewer; private final List> components; @@ -29,10 +30,6 @@ public BaseGuiView( return viewer; } - public abstract void open(); - - public abstract void close(); - protected void setup() { components.forEach(renderer -> renderer.states().forEach(state -> state.addListener(this, () -> renderComponent(renderer)))); diff --git a/core/src/main/java/dev/triumphteam/gui/GuiView.java b/core/src/main/java/dev/triumphteam/gui/GuiView.java new file mode 100644 index 00000000..9f17fbee --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/GuiView.java @@ -0,0 +1,8 @@ +package dev.triumphteam.gui; + +public interface GuiView { + + void open(); + + void close(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 55218a5d..96a81fd4 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,9 +1,9 @@ package dev.triumphteam.gui.builder; import dev.triumphteam.gui.BaseGui; -import dev.triumphteam.gui.component.GuiComponent; -import dev.triumphteam.gui.component.GuiComponentBuilder; -import dev.triumphteam.gui.component.SimpleFunctionalGuiComponent; +import dev.triumphteam.gui.component.ReactiveGuiComponent; +import dev.triumphteam.gui.component.functional.GuiComponentBuilder; +import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -24,7 +24,7 @@ public abstract class BaseGuiBuilder, P, G } @Contract("_ -> this") - public @NotNull B component(final @NotNull GuiComponent component) { + public @NotNull B component(final @NotNull ReactiveGuiComponent component) { // TODO(matt): Yeah return (B) this; } diff --git a/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java b/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java index 407b5ec5..6425fdd5 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java @@ -1,5 +1,6 @@ package dev.triumphteam.gui.component; +import dev.triumphteam.gui.component.functional.GuiComponentRender; import dev.triumphteam.gui.state.State; import java.util.List; diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java index 8941f2f6..e399fbfa 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java @@ -1,15 +1,9 @@ package dev.triumphteam.gui.component; import dev.triumphteam.gui.container.GuiContainer; -import dev.triumphteam.gui.state.State; import org.jetbrains.annotations.NotNull; -import java.util.List; - -public interface GuiComponent { - - @NotNull - List<@NotNull State> states(); +public interface GuiComponent extends ReactiveGuiComponent { void render(final @NotNull GuiContainer<@NotNull I> container, final @NotNull P player); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java new file mode 100644 index 00000000..354decee --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java @@ -0,0 +1,12 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.state.State; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface ReactiveGuiComponent { + + @NotNull + List states(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java index 34dfd222..09f01165 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java @@ -1,13 +1,13 @@ package dev.triumphteam.gui.component.builtin; -import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.state.State; import org.jetbrains.annotations.NotNull; import java.util.List; -public final class PaginatedComponent implements GuiComponent { +public final class PaginatedComponent implements ReactiveGuiComponent { @Override public @NotNull List<@NotNull State> states() { diff --git a/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java similarity index 87% rename from core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java rename to core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java index 3049fd09..b1a2af13 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/FunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java @@ -1,6 +1,8 @@ -package dev.triumphteam.gui.component; +package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.builder.BaseGuiBuilder; +import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.State; @@ -9,8 +11,8 @@ import org.jetbrains.annotations.Nullable; /** - * Similar to a {@link GuiComponent} this component will take in states and render a component. - * Unlike {@link GuiComponent} it is not meant to be extended upon and is only used by the {@link BaseGuiBuilder}. + * Similar to a {@link ReactiveGuiComponent} this component will take in states and render a component. + * Unlike {@link ReactiveGuiComponent} it is not meant to be extended upon and is only used by the {@link BaseGuiBuilder}. * * @param

The player type. * @param The item type. diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentBuilder.java b/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentBuilder.java similarity index 80% rename from core/src/main/java/dev/triumphteam/gui/component/GuiComponentBuilder.java rename to core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentBuilder.java index a2a7e7fb..d9620118 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentBuilder.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.component; +package dev.triumphteam.gui.component.functional; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRender.java b/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java similarity index 84% rename from core/src/main/java/dev/triumphteam/gui/component/GuiComponentRender.java rename to core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java index ef9f41e3..b46ef56f 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentRender.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.component; +package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.container.GuiContainer; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java similarity index 84% rename from core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java rename to core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index 5566f51f..8a1f1872 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -1,7 +1,10 @@ -package dev.triumphteam.gui.component; +package dev.triumphteam.gui.component.functional; +import dev.triumphteam.gui.component.FinalComponent; +import dev.triumphteam.gui.component.ReactiveGuiComponent; +import dev.triumphteam.gui.exception.GuiException; import dev.triumphteam.gui.state.MutableState; -import dev.triumphteam.gui.state.SimpleState; +import dev.triumphteam.gui.state.builtin.SimpleState; import dev.triumphteam.gui.state.State; import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; @@ -56,11 +59,11 @@ public void render(final @NotNull GuiComponentRender component) { this.component = component; } - /*public @NotNull FinalComponent createComponent() { + public @NotNull ReactiveGuiComponent asGuiComponent() { if (component == null) { throw new GuiException("TODO"); } return new FinalComponent<>(states, component); - }*/ + } } diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProcessor.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentProcessor.java similarity index 75% rename from core/src/main/java/dev/triumphteam/gui/component/GuiComponentProcessor.java rename to core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentProcessor.java index 6a160e31..9d7681a4 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProcessor.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentProcessor.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.component; +package dev.triumphteam.gui.component.renderer; public interface GuiComponentProcessor { diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java index fde61b40..26361d89 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -1,14 +1,14 @@ package dev.triumphteam.gui.container; -import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.element.GuiElement; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; public interface GuiContainer { - void set(final int slot, final @NotNull GuiItem<@NotNull I> guiItem); + void set(final int slot, final @NotNull GuiElement<@NotNull I> guiElement); - void set(final int row, final int column, final @NotNull GuiItem<@NotNull I> guiItem); + void set(final int row, final int column, final @NotNull GuiElement<@NotNull I> guiElement); - void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull I> guiItem); + void set(final @NotNull Slot slot, final @NotNull GuiElement<@NotNull I> guiElement); } diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index f9c6a786..339da868 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -1,6 +1,6 @@ package dev.triumphteam.gui.container; -import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.element.GuiElement; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; @@ -9,25 +9,25 @@ public final class MapBackedContainer implements GuiContainer { - private final Map> backing = new HashMap<>(100); + private final Map> backing = new HashMap<>(100); @Override - public void set(final int slot, final @NotNull GuiItem<@NotNull I> guiItem) { - set(new Slot(slot), guiItem); + public void set(final int slot, final @NotNull GuiElement<@NotNull I> guiElement) { + set(new Slot(slot), guiElement); } @Override - public void set(final int row, final int column, final @NotNull GuiItem<@NotNull I> guiItem) { + public void set(final int row, final int column, final @NotNull GuiElement<@NotNull I> guiElement) { // TODO(matt): This - set(new Slot(0), guiItem); + set(new Slot(0), guiElement); } @Override - public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull I> guiItem) { - backing.put(slot, guiItem); + public void set(final @NotNull Slot slot, final @NotNull GuiElement<@NotNull I> guiElement) { + backing.put(slot, guiElement); } - public @NotNull Map> getBacking() { + public @NotNull Map> getBacking() { return backing; } } diff --git a/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java b/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java similarity index 64% rename from core/src/main/java/dev/triumphteam/gui/item/GuiItem.java rename to core/src/main/java/dev/triumphteam/gui/element/GuiElement.java index 44b50f13..b912a7be 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java +++ b/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java @@ -1,8 +1,8 @@ -package dev.triumphteam.gui.item; +package dev.triumphteam.gui.element; import org.jetbrains.annotations.NotNull; -public interface GuiItem { +public interface GuiElement { @NotNull I render(); diff --git a/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java b/core/src/main/java/dev/triumphteam/gui/element/ItemClickAction.java similarity index 67% rename from core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java rename to core/src/main/java/dev/triumphteam/gui/element/ItemClickAction.java index a065903b..82f18bb5 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java +++ b/core/src/main/java/dev/triumphteam/gui/element/ItemClickAction.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.item; +package dev.triumphteam.gui.element; @FunctionalInterface public interface ItemClickAction { diff --git a/core/src/main/java/dev/triumphteam/gui/item/RenderedItem.java b/core/src/main/java/dev/triumphteam/gui/element/RenderedItem.java similarity index 64% rename from core/src/main/java/dev/triumphteam/gui/item/RenderedItem.java rename to core/src/main/java/dev/triumphteam/gui/element/RenderedItem.java index ed2c4e8a..b3ef306b 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/RenderedItem.java +++ b/core/src/main/java/dev/triumphteam/gui/element/RenderedItem.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.item; +package dev.triumphteam.gui.element; public record RenderedItem(I item, ItemClickAction action) { } diff --git a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java index 62ec751a..02e4fa0e 100644 --- a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java +++ b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java @@ -1,8 +1,4 @@ package dev.triumphteam.gui.slot; public record Slot(int slot) { - - public int asRealSlot() { - return slot; - } } diff --git a/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java b/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java index a2d29f6f..000ae3d9 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java @@ -1,6 +1,7 @@ package dev.triumphteam.gui.state; -import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.GuiView; +import dev.triumphteam.gui.state.builtin.SimpleState; import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; @@ -13,8 +14,9 @@ */ public abstract class BaseMutableState implements MutableState { - private final StateMutationPolicy mutationPolicy; private final StateListenerContainer listenerContainer = new StateListenerContainer(); + + private final StateMutationPolicy mutationPolicy; private T value; public BaseMutableState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { @@ -47,7 +49,7 @@ public void trigger() { } @Override - public void addListener(final @NotNull BaseGuiView view, final @NotNull Runnable listener) { + public void addListener(final @NotNull GuiView view, final @NotNull Runnable listener) { listenerContainer.addListener(view, listener); } } diff --git a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java index 7f981e39..6296da9c 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java @@ -1,5 +1,6 @@ package dev.triumphteam.gui.state; +import dev.triumphteam.gui.state.builtin.SimpleState; import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/state/State.java b/core/src/main/java/dev/triumphteam/gui/state/State.java index c7448058..29e6bf18 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/State.java +++ b/core/src/main/java/dev/triumphteam/gui/state/State.java @@ -1,6 +1,7 @@ package dev.triumphteam.gui.state; -import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.GuiView; +import dev.triumphteam.gui.state.builtin.SimpleState; import org.jetbrains.annotations.NotNull; /** @@ -22,13 +23,13 @@ public interface State { /** * Adds a new listener to the state. * Avoid calling this method manually if you don't know what you are doing, - * this is mostly done internally by the {@link BaseGuiView}. + * this is mostly done internally by the {@link GuiView}. *

- * The listener is tied to the lifecycle of the {@link BaseGuiView}, + * The listener is tied to the lifecycle of the {@link GuiView}, * so avoid holding the view if it is no longer needed. * - * @param view The {@link BaseGuiView} which will be handling this state. + * @param view The {@link GuiView} which will be handling this state. * @param listener The listener to be called when a state is triggered. */ - void addListener(final @NotNull BaseGuiView view, final @NotNull Runnable listener); + void addListener(final @NotNull GuiView view, final @NotNull Runnable listener); } diff --git a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java index 9e249548..3438a485 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java @@ -1,45 +1,55 @@ package dev.triumphteam.gui.state; -import dev.triumphteam.gui.BaseGuiView; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import dev.triumphteam.gui.GuiView; import org.jetbrains.annotations.NotNull; -import java.lang.ref.WeakReference; -import java.util.Set; -import java.util.WeakHashMap; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Map; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; /** * A map backed container for state listeners. - * This container uses a {@link WeakHashMap}, so instances of the {@link BaseGuiView} can prevent + * This container uses a map with weak keys, so instances of the {@link GuiView} can prevent * values from being garbage collected correctly. */ public final class StateListenerContainer { - private final Set listeners = ConcurrentHashMap.newKeySet(); + /** + * Listeners cache. + * The keys of the map are weak. + * The value of the map is a {@link ConcurrentLinkedQueue}. + */ + private final Map, Queue> listeners = createListenerMap(); /** - * Adds listener tied to the {@link BaseGuiView} lifecycle. + * Creates a map to be used for the listeners. + * + * @return A {@link java.util.concurrent.ConcurrentMap} with weak keys. + */ + private static Map, Queue> createListenerMap() { + final Cache, Queue> cache = Caffeine.newBuilder() + .weakKeys() + .build(); + + return cache.asMap(); + } + + /** + * Adds listener tied to the {@link GuiView} lifecycle. * * @param view The view to be used as the reference. * @param listener The listener to run when a state is triggered. */ - public void addListener(final @NotNull BaseGuiView view, final @NotNull Runnable listener) { - listeners.add(new Pair(new WeakReference<>(view), listener)); + public void addListener(final @NotNull GuiView view, final @NotNull Runnable listener) { + listeners.computeIfAbsent(view, ignored -> new ConcurrentLinkedQueue<>()).add(listener); } /** * Triggers all listeners that this state uses. */ public void triggerAll() { - listeners.forEach(pair -> pair.listener.run()); + listeners.values().forEach(listeners -> listeners.forEach(Runnable::run)); } - - /** - * Simple pair only used by this class. - * Simply used to hold a weak reference of the view and a listener. - * - * @param weakView The weak reference of view. - * @param listener The listener to run when a state is triggered. - */ - private record Pair(WeakReference> weakView, Runnable listener) {} } diff --git a/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java b/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleState.java similarity index 76% rename from core/src/main/java/dev/triumphteam/gui/state/SimpleState.java rename to core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleState.java index 519f2246..e099656a 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/SimpleState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleState.java @@ -1,5 +1,7 @@ -package dev.triumphteam.gui.state; +package dev.triumphteam.gui.state.builtin; +import dev.triumphteam.gui.state.BaseMutableState; +import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f1534ab8..1a62c715 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,16 +7,18 @@ license = "0.16.1" # Core annotations = "23.0.0" +caffeine = "3.1.8" # Minecraft -spigot = "1.18.2-R0.1-SNAPSHOT" +paper = "1.16.5-R0.1-SNAPSHOT" [libraries] # Core annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" } +caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" } # Minecraft -spigot = { module = "org.spigotmc:spigot-api", version.ref = "spigot" } +paper = { module = "org.spigotmc:spigot-api", version.ref = "paper" } # Kotlin coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } From 0e4a428e6a13a1207fd641045f6bf52db4b9538d Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 28 Apr 2024 19:40:15 +0100 Subject: [PATCH 07/43] chore: Making components more extendable --- .../triumphteam/gui/bukkit/BukkitGuiView.java | 58 ++++++++++++++++ .../java/dev/triumphteam/gui/bukkit/Gui.java | 8 +-- .../gui/bukkit/GuiBukkitListener.java | 2 +- .../dev/triumphteam/gui/bukkit/GuiView.java | 54 --------------- .../java/dev/triumphteam/gui/BaseGuiView.java | 66 +++++++++++++------ .../gui/builder/BaseGuiBuilder.java | 4 +- .../gui/component/FinalComponent.java | 12 ---- .../gui/component/GuiComponent.java | 8 +-- .../gui/component/ReactiveGuiComponent.java | 9 +-- .../gui/component/RenderedComponent.java | 13 ++++ .../gui/component/StatefulGuiComponent.java | 12 ++++ .../component/builtin/PaginatedComponent.java | 8 +-- .../functional/FunctionalGuiComponent.java | 13 ++-- .../SimpleFunctionalGuiComponent.java | 23 +++++-- .../renderer/DefaultGuiComponentRenderer.java | 31 +++++++++ .../renderer/GuiComponentProcessor.java | 6 -- .../renderer/GuiComponentRenderer.java | 14 ++++ .../gui/container/GuiContainer.java | 11 ++-- .../gui/container/GuiContainerType.java | 10 +++ .../gui/container/MapBackedContainer.java | 30 ++++++--- .../triumphteam/gui/element/RenderedItem.java | 4 -- .../GuiElement.java => item/GuiItem.java} | 4 +- .../{element => item}/ItemClickAction.java | 2 +- .../triumphteam/gui/item/RenderedGuiItem.java | 6 ++ ...leState.java => AbstractMutableState.java} | 25 ++----- .../triumphteam/gui/state/AbstractState.java | 20 ++++++ .../triumphteam/gui/state/MutableState.java | 6 +- .../java/dev/triumphteam/gui/state/State.java | 6 +- .../gui/state/builtin/EmptyState.java | 5 ++ ...mpleState.java => SimpleMutableState.java} | 8 +-- .../gui/state/policy/StateMutationPolicy.java | 12 ---- gradle/libs.versions.toml | 4 +- 32 files changed, 302 insertions(+), 192 deletions(-) create mode 100644 bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java delete mode 100644 bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentProcessor.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/container/GuiContainerType.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/element/RenderedItem.java rename core/src/main/java/dev/triumphteam/gui/{element/GuiElement.java => item/GuiItem.java} (64%) rename core/src/main/java/dev/triumphteam/gui/{element => item}/ItemClickAction.java (67%) create mode 100644 core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java rename core/src/main/java/dev/triumphteam/gui/state/{BaseMutableState.java => AbstractMutableState.java} (51%) create mode 100644 core/src/main/java/dev/triumphteam/gui/state/AbstractState.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java rename core/src/main/java/dev/triumphteam/gui/state/builtin/{SimpleState.java => SimpleMutableState.java} (55%) diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java new file mode 100644 index 00000000..48177ea9 --- /dev/null +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java @@ -0,0 +1,58 @@ +package dev.triumphteam.gui.bukkit; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.renderer.DefaultGuiComponentRenderer; +import dev.triumphteam.gui.item.RenderedGuiItem; +import dev.triumphteam.gui.slot.Slot; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Map; + +public final class BukkitGuiView extends BaseGuiView implements InventoryHolder { + + private final Inventory inventory; + + public BukkitGuiView( + final @NotNull Player player, + final @NotNull List> components + ) { + // TODO(matt): Renderer from constructor + super(player, components, new DefaultGuiComponentRenderer<>()); + + this.inventory = Bukkit.createInventory(this, 54, "Gui"); + } + + @Override + public void open() { + getViewer().openInventory(inventory); + setup(); + } + + @Override + public void close() { + + } + + @NotNull + @Override + public Inventory getInventory() { + return inventory; + } + + @Override + protected void clearSlot(final @NotNull Slot slot) { + inventory.clear(slot.slot()); + } + + @Override + protected void populateInventory(final @NotNull Map> renderedItems) { + renderedItems.forEach((slot, item) -> inventory.setItem(slot.slot(), item.item())); + } +} diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java index 2cb1b96f..da26aff1 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java @@ -1,7 +1,7 @@ package dev.triumphteam.gui.bukkit; import dev.triumphteam.gui.BaseGui; -import dev.triumphteam.gui.component.FinalComponent; +import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -11,7 +11,7 @@ public final class Gui implements BaseGui { - private final List> components; + private final List> components; static { GuiBukkitListener.register(); @@ -20,12 +20,12 @@ public final class Gui implements BaseGui { public Gui( final @NotNull List> componentRenderers ) { - this.components = componentRenderers.stream().map(SimpleFunctionalGuiComponent::createComponent).toList(); + this.components = componentRenderers.stream().map(SimpleFunctionalGuiComponent::asGuiComponent).toList(); } @Override public void open(final @NotNull Player player) { - final var view = new GuiView(player, components); + final var view = new BukkitGuiView(player, components); view.open(); } } diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java index ca3c64d6..d5a58137 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java @@ -18,7 +18,7 @@ public static void register() { @EventHandler public void onGuiClick(final InventoryClickEvent event) { final var holder = event.getInventory().getHolder(); - if (!(holder instanceof final GuiView view)) { + if (!(holder instanceof final BukkitGuiView view)) { return; } diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java deleted file mode 100644 index 29672eab..00000000 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiView.java +++ /dev/null @@ -1,54 +0,0 @@ -package dev.triumphteam.gui.bukkit; - -import dev.triumphteam.gui.component.FinalComponent; -import dev.triumphteam.gui.container.MapBackedContainer; -import dev.triumphteam.gui.element.RenderedItem; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public final class GuiView extends dev.triumphteam.gui.GuiView implements InventoryHolder { - - private final Inventory inventory; - - public GuiView( - final @NotNull Player player, - final @NotNull List> componentRenderers - ) { - super(player, componentRenderers); - this.inventory = Bukkit.createInventory(this, 54, "Gui"); - } - - @Override - public void open() { - getViewer().openInventory(inventory); - setup(); - } - - @Override - public void close() { - - } - - @NotNull - @Override - public Inventory getInventory() { - return inventory; - } - - @Override - protected void populateInventory(final @NotNull MapBackedContainer container) { - inventory.clear(); - container.getBacking().forEach((slot, baseGuiItem) -> { - final var rendered = baseGuiItem.render(); - final var inventorySlot = slot.asRealSlot(); - temporaryCache.put(inventorySlot, new RenderedItem<>(rendered, baseGuiItem.getClickAction())); - inventory.setItem(inventorySlot, rendered); - }); - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java b/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java index 8b03a172..852469d4 100644 --- a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java @@ -1,29 +1,35 @@ package dev.triumphteam.gui; -import dev.triumphteam.gui.component.FinalComponent; -import dev.triumphteam.gui.container.MapBackedContainer; -import dev.triumphteam.gui.element.ItemClickAction; -import dev.triumphteam.gui.element.RenderedItem; +import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.RenderedComponent; +import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; +import dev.triumphteam.gui.item.ItemClickAction; +import dev.triumphteam.gui.item.RenderedGuiItem; +import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; public abstract class BaseGuiView implements GuiView { - protected final Map> temporaryCache = new HashMap<>(); - private final P viewer; - private final List> components; + private final List> components; + private final GuiComponentRenderer renderer; + + private final Map, RenderedComponent> renderedComponents = new ConcurrentHashMap<>(); + private final Map componentClickActions = new ConcurrentHashMap<>(); public BaseGuiView( final @NotNull P viewer, - final List> components + final @NotNull List<@NotNull GuiComponent> components, + final @NotNull GuiComponentRenderer renderer ) { this.viewer = viewer; this.components = components; + this.renderer = renderer; } public @NotNull P getViewer() { @@ -31,22 +37,44 @@ public BaseGuiView( } protected void setup() { - components.forEach(renderer -> renderer.states().forEach(state -> state.addListener(this, () -> renderComponent(renderer)))); + components.forEach(component -> { + // Add listener to used states + component.states().forEach(state -> { + state.addListener(this, () -> renderer.renderComponent(viewer, component, this)); + }); - components.forEach(this::renderComponent); + // Then render component + renderer.renderComponent(viewer, component, this); + }); } - private void renderComponent(final @NotNull FinalComponent component) { - final var container = new MapBackedContainer(); - component.component().render(container, viewer); - populateInventory(container); + public void completeRendered(final @NotNull RenderedComponent renderedComponent) { + var ownerComponent = renderedComponent.component(); + // Check if component was already rendered before + var existing = renderedComponents.get(ownerComponent); + if (existing != null) { + // Clear its uses + existing.renderedItems().forEach((slot, ignored) -> { + clearSlot(slot); + componentClickActions.remove(slot); + }); + } + + renderedComponents.put(ownerComponent, renderedComponent); + + final var renderedItems = renderedComponent.renderedItems(); + renderedItems.forEach((slot, renderedItem) -> { + componentClickActions.put(slot, renderedItem.action()); + }); + + populateInventory(renderedItems); } - protected abstract void populateInventory(final @NotNull MapBackedContainer container); + protected abstract void clearSlot(final @NotNull Slot slot); + + protected abstract void populateInventory(final @NotNull Map> renderedItems); public @Nullable ItemClickAction getAction(final int slot) { - final var item = temporaryCache.get(slot); - if (item == null) return null; - return item.action(); + return componentClickActions.get(new Slot(slot)); } } diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 96a81fd4..798ffaa5 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,7 +1,7 @@ package dev.triumphteam.gui.builder; import dev.triumphteam.gui.BaseGui; -import dev.triumphteam.gui.component.ReactiveGuiComponent; +import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.functional.GuiComponentBuilder; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import org.jetbrains.annotations.Contract; @@ -24,7 +24,7 @@ public abstract class BaseGuiBuilder, P, G } @Contract("_ -> this") - public @NotNull B component(final @NotNull ReactiveGuiComponent component) { + public @NotNull B component(final @NotNull GuiComponent component) { // TODO(matt): Yeah return (B) this; } diff --git a/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java b/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java deleted file mode 100644 index 6425fdd5..00000000 --- a/core/src/main/java/dev/triumphteam/gui/component/FinalComponent.java +++ /dev/null @@ -1,12 +0,0 @@ -package dev.triumphteam.gui.component; - -import dev.triumphteam.gui.component.functional.GuiComponentRender; -import dev.triumphteam.gui.state.State; - -import java.util.List; - -public record FinalComponent( - List> states, - GuiComponentRender component -) { -} diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java index e399fbfa..42de287c 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java @@ -1,9 +1,3 @@ package dev.triumphteam.gui.component; -import dev.triumphteam.gui.container.GuiContainer; -import org.jetbrains.annotations.NotNull; - -public interface GuiComponent extends ReactiveGuiComponent { - - void render(final @NotNull GuiContainer<@NotNull I> container, final @NotNull P player); -} +public interface GuiComponent {} diff --git a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java index 354decee..88a7a1b3 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java @@ -1,12 +1,9 @@ package dev.triumphteam.gui.component; -import dev.triumphteam.gui.state.State; +import dev.triumphteam.gui.container.GuiContainer; import org.jetbrains.annotations.NotNull; -import java.util.List; +public interface ReactiveGuiComponent extends StatefulGuiComponent { -public interface ReactiveGuiComponent { - - @NotNull - List states(); + void render(final @NotNull GuiContainer<@NotNull I> container, final @NotNull P player); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java new file mode 100644 index 00000000..08015c16 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java @@ -0,0 +1,13 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.item.RenderedGuiItem; +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +public record RenderedComponent( + @NotNull GuiComponent component, + Map> renderedItems +) { +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java new file mode 100644 index 00000000..4e40a1cc --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java @@ -0,0 +1,12 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.state.State; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface StatefulGuiComponent extends GuiComponent { + + @NotNull + List states(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java index 09f01165..84df7458 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java @@ -1,21 +1,17 @@ package dev.triumphteam.gui.component.builtin; -import dev.triumphteam.gui.component.ReactiveGuiComponent; -import dev.triumphteam.gui.container.GuiContainer; +import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.state.State; import org.jetbrains.annotations.NotNull; import java.util.List; -public final class PaginatedComponent implements ReactiveGuiComponent { +public final class PaginatedComponent implements GuiComponent { @Override public @NotNull List<@NotNull State> states() { return List.of(); } - @Override - public void render(final @NotNull GuiContainer<@NotNull I> container, @NotNull final P player) { - } } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java index b1a2af13..0636fa91 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java @@ -1,8 +1,8 @@ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.builder.BaseGuiBuilder; -import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.ReactiveGuiComponent; +import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.State; @@ -11,14 +11,17 @@ import org.jetbrains.annotations.Nullable; /** - * Similar to a {@link ReactiveGuiComponent} this component will take in states and render a component. - * Unlike {@link ReactiveGuiComponent} it is not meant to be extended upon and is only used by the {@link BaseGuiBuilder}. + * Similar to a {@link GuiComponent} this component will take in states and render a component. + * Unlike {@link GuiComponent} it is not meant to be extended upon and is only used by the {@link BaseGuiBuilder}. * * @param

The player type. * @param The item type. */ public interface FunctionalGuiComponent { + @NotNull + State state(); + /** * Associate a {@link State} to the component. * @@ -26,7 +29,7 @@ public interface FunctionalGuiComponent { * @return The same state passed. */ @NotNull - State state(final @NotNull State state); + S state(final @NotNull S state); /** * Create a new state with the given default value. @@ -78,7 +81,7 @@ public interface FunctionalGuiComponent { /** * A component render function. - * The function inside works the same as a normal {@link GuiComponent#render(GuiContainer, Object)} would. + * The function inside works the same as a normal {@link ReactiveGuiComponent#render(GuiContainer, Object)} would. * * @param render The component render. */ diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index 8a1f1872..efee765c 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -1,11 +1,12 @@ package dev.triumphteam.gui.component.functional; -import dev.triumphteam.gui.component.FinalComponent; import dev.triumphteam.gui.component.ReactiveGuiComponent; +import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.exception.GuiException; import dev.triumphteam.gui.state.MutableState; -import dev.triumphteam.gui.state.builtin.SimpleState; import dev.triumphteam.gui.state.State; +import dev.triumphteam.gui.state.builtin.SimpleMutableState; import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -34,7 +35,7 @@ public final class SimpleFunctionalGuiComponent implements FunctionalGuiCo final @NotNull T value, final @NotNull StateMutationPolicy mutationPolicy ) { - var state = new SimpleState<>(value, mutationPolicy); + var state = new SimpleMutableState<>(value, mutationPolicy); states.add(state); return state; } @@ -49,7 +50,7 @@ public final class SimpleFunctionalGuiComponent implements FunctionalGuiCo final @Nullable T value, final @NotNull StateMutationPolicy mutationPolicy ) { - var state = new SimpleState<>(value, mutationPolicy); + var state = new SimpleMutableState<>(value, mutationPolicy); states.add(state); return state; } @@ -59,11 +60,21 @@ public void render(final @NotNull GuiComponentRender component) { this.component = component; } - public @NotNull ReactiveGuiComponent asGuiComponent() { + public @NotNull GuiComponent asGuiComponent() { if (component == null) { throw new GuiException("TODO"); } - return new FinalComponent<>(states, component); + return new ReactiveGuiComponent<>() { + @Override + public void render(final @NotNull GuiContainer<@NotNull I> container, @NotNull final P player) { + component.render(container, player); + } + + @Override + public @NotNull List states() { + return states; + } + }; } } diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java new file mode 100644 index 00000000..04184372 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java @@ -0,0 +1,31 @@ +package dev.triumphteam.gui.component.renderer; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.component.ReactiveGuiComponent; +import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.RenderedComponent; +import dev.triumphteam.gui.container.MapBackedContainer; +import org.jetbrains.annotations.NotNull; + +public final class DefaultGuiComponentRenderer implements GuiComponentRenderer { + + @Override + public void renderComponent( + final @NotNull P player, + final @NotNull GuiComponent component, + final @NotNull BaseGuiView view + ) { + + final var container = new MapBackedContainer(); + + if (component instanceof ReactiveGuiComponent) { + ((ReactiveGuiComponent) component).render(container, player); + } + + final var renderedItems = container.complete(); + final var renderedComponent = new RenderedComponent<>(component, renderedItems); + + // Complete rendered back in the view + view.completeRendered(renderedComponent); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentProcessor.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentProcessor.java deleted file mode 100644 index 9d7681a4..00000000 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentProcessor.java +++ /dev/null @@ -1,6 +0,0 @@ -package dev.triumphteam.gui.component.renderer; - -public interface GuiComponentProcessor { - - // void render(final @NotNull GuiComponentRenderer

component, final @NotNull I inventory); -} diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java new file mode 100644 index 00000000..258b5c21 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java @@ -0,0 +1,14 @@ +package dev.triumphteam.gui.component.renderer; + +import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.component.GuiComponent; +import org.jetbrains.annotations.NotNull; + +public interface GuiComponentRenderer { + + void renderComponent( + final @NotNull P player, + final @NotNull GuiComponent component, + final @NotNull BaseGuiView view + ); +} diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java index 26361d89..cbd54e12 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -1,14 +1,17 @@ package dev.triumphteam.gui.container; -import dev.triumphteam.gui.element.GuiElement; +import dev.triumphteam.gui.item.GuiItem; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; public interface GuiContainer { - void set(final int slot, final @NotNull GuiElement<@NotNull I> guiElement); + @NotNull + GuiContainerType containerType(); - void set(final int row, final int column, final @NotNull GuiElement<@NotNull I> guiElement); + void set(final int slot, final @NotNull GuiItem<@NotNull I> guiItem); - void set(final @NotNull Slot slot, final @NotNull GuiElement<@NotNull I> guiElement); + void set(final int row, final int column, final @NotNull GuiItem<@NotNull I> guiItem); + + void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull I> guiItem); } diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainerType.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainerType.java new file mode 100644 index 00000000..8d55ad2d --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainerType.java @@ -0,0 +1,10 @@ +package dev.triumphteam.gui.container; + +public enum GuiContainerType { + + CHEST, + CHEST_COMBINED, + + ; + +} diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index 339da868..13c95be0 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -1,33 +1,43 @@ package dev.triumphteam.gui.container; -import dev.triumphteam.gui.element.GuiElement; +import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.item.RenderedGuiItem; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; +import java.util.Collections; import java.util.HashMap; import java.util.Map; public final class MapBackedContainer implements GuiContainer { - private final Map> backing = new HashMap<>(100); + private final Map> backing = new HashMap<>(100); @Override - public void set(final int slot, final @NotNull GuiElement<@NotNull I> guiElement) { - set(new Slot(slot), guiElement); + public @NotNull GuiContainerType containerType() { + return null; } @Override - public void set(final int row, final int column, final @NotNull GuiElement<@NotNull I> guiElement) { + public void set(final int slot, final @NotNull GuiItem<@NotNull I> guiItem) { + set(new Slot(slot), guiItem); + } + + @Override + public void set(final int row, final int column, final @NotNull GuiItem<@NotNull I> guiItem) { // TODO(matt): This - set(new Slot(0), guiElement); + set(new Slot(0), guiItem); } @Override - public void set(final @NotNull Slot slot, final @NotNull GuiElement<@NotNull I> guiElement) { - backing.put(slot, guiElement); + public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull I> guiItem) { + // Render item + final var renderedItem = new RenderedGuiItem<>(guiItem.render(), guiItem.getClickAction()); + // Add rendered to backing + backing.put(slot, renderedItem); } - public @NotNull Map> getBacking() { - return backing; + public @NotNull Map> complete() { + return Collections.unmodifiableMap(backing); } } diff --git a/core/src/main/java/dev/triumphteam/gui/element/RenderedItem.java b/core/src/main/java/dev/triumphteam/gui/element/RenderedItem.java deleted file mode 100644 index b3ef306b..00000000 --- a/core/src/main/java/dev/triumphteam/gui/element/RenderedItem.java +++ /dev/null @@ -1,4 +0,0 @@ -package dev.triumphteam.gui.element; - -public record RenderedItem(I item, ItemClickAction action) { -} diff --git a/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java b/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java similarity index 64% rename from core/src/main/java/dev/triumphteam/gui/element/GuiElement.java rename to core/src/main/java/dev/triumphteam/gui/item/GuiItem.java index b912a7be..44b50f13 100644 --- a/core/src/main/java/dev/triumphteam/gui/element/GuiElement.java +++ b/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java @@ -1,8 +1,8 @@ -package dev.triumphteam.gui.element; +package dev.triumphteam.gui.item; import org.jetbrains.annotations.NotNull; -public interface GuiElement { +public interface GuiItem { @NotNull I render(); diff --git a/core/src/main/java/dev/triumphteam/gui/element/ItemClickAction.java b/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java similarity index 67% rename from core/src/main/java/dev/triumphteam/gui/element/ItemClickAction.java rename to core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java index 82f18bb5..a065903b 100644 --- a/core/src/main/java/dev/triumphteam/gui/element/ItemClickAction.java +++ b/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.element; +package dev.triumphteam.gui.item; @FunctionalInterface public interface ItemClickAction { diff --git a/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java new file mode 100644 index 00000000..ee3afcd4 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java @@ -0,0 +1,6 @@ +package dev.triumphteam.gui.item; + +import org.jetbrains.annotations.NotNull; + +public record RenderedGuiItem(@NotNull I item, @NotNull ItemClickAction action) { +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java b/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java similarity index 51% rename from core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java rename to core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java index 000ae3d9..dafe5d1f 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/BaseMutableState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java @@ -1,25 +1,22 @@ package dev.triumphteam.gui.state; -import dev.triumphteam.gui.GuiView; -import dev.triumphteam.gui.state.builtin.SimpleState; +import dev.triumphteam.gui.state.builtin.SimpleMutableState; import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; /** - * Base implementation for a {@link MutableState}. + * Abstract implementation for a {@link MutableState}. * The mutability of the value {@link T} is dependent on the given {@link StateMutationPolicy}. * * @param The type of the value. - * @see SimpleState + * @see SimpleMutableState */ -public abstract class BaseMutableState implements MutableState { - - private final StateListenerContainer listenerContainer = new StateListenerContainer(); +public abstract class AbstractMutableState extends AbstractState implements MutableState { private final StateMutationPolicy mutationPolicy; private T value; - public BaseMutableState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { + public AbstractMutableState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { this.value = value; this.mutationPolicy = mutationPolicy; } @@ -32,7 +29,7 @@ public T getValue() { @Override public void setValue(final T value) { // Will not mutate value if they are equivalent - if (!mutationPolicy.equivalent(this.value, value)) return; + if (mutationPolicy.equivalent(this.value, value)) return; this.value = value; trigger(); @@ -42,14 +39,4 @@ public void setValue(final T value) { public @NotNull StateMutationPolicy stateMutationPolicy() { return mutationPolicy; } - - @Override - public void trigger() { - listenerContainer.triggerAll(); - } - - @Override - public void addListener(final @NotNull GuiView view, final @NotNull Runnable listener) { - listenerContainer.addListener(view, listener); - } } diff --git a/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java b/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java new file mode 100644 index 00000000..3b13c17e --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java @@ -0,0 +1,20 @@ +package dev.triumphteam.gui.state; + +import dev.triumphteam.gui.GuiView; +import org.jetbrains.annotations.NotNull; + + +public abstract class AbstractState implements State { + + private final StateListenerContainer listenerContainer = new StateListenerContainer(); + + @Override + public void trigger() { + listenerContainer.triggerAll(); + } + + @Override + public void addListener(final @NotNull GuiView view, final @NotNull Runnable listener) { + listenerContainer.addListener(view, listener); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java index 6296da9c..f228c1f7 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java @@ -1,6 +1,6 @@ package dev.triumphteam.gui.state; -import dev.triumphteam.gui.state.builtin.SimpleState; +import dev.triumphteam.gui.state.builtin.SimpleMutableState; import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; @@ -12,8 +12,8 @@ * Same for the nullability of the value. * * @param The type the state accepts. - * @see BaseMutableState - * @see SimpleState + * @see AbstractMutableState + * @see SimpleMutableState */ public interface MutableState extends State { diff --git a/core/src/main/java/dev/triumphteam/gui/state/State.java b/core/src/main/java/dev/triumphteam/gui/state/State.java index 29e6bf18..7c2befcd 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/State.java +++ b/core/src/main/java/dev/triumphteam/gui/state/State.java @@ -1,7 +1,7 @@ package dev.triumphteam.gui.state; import dev.triumphteam.gui.GuiView; -import dev.triumphteam.gui.state.builtin.SimpleState; +import dev.triumphteam.gui.state.builtin.SimpleMutableState; import org.jetbrains.annotations.NotNull; /** @@ -10,8 +10,8 @@ * Its sole purpose is to trigger updates on the GUI. * * @see MutableState - * @see BaseMutableState - * @see SimpleState + * @see AbstractMutableState + * @see SimpleMutableState */ public interface State { diff --git a/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java b/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java new file mode 100644 index 00000000..7254f7d0 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java @@ -0,0 +1,5 @@ +package dev.triumphteam.gui.state.builtin; + +import dev.triumphteam.gui.state.AbstractState; + +public final class EmptyState extends AbstractState {} diff --git a/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleState.java b/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java similarity index 55% rename from core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleState.java rename to core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java index e099656a..f8bb077d 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java @@ -1,6 +1,6 @@ package dev.triumphteam.gui.state.builtin; -import dev.triumphteam.gui.state.BaseMutableState; +import dev.triumphteam.gui.state.AbstractMutableState; import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; @@ -9,11 +9,11 @@ * The simplest implementation of {@link MutableState}. * * @param The type of the value. - * @see BaseMutableState For the implementation. + * @see AbstractMutableState For the implementation. */ -public final class SimpleState extends BaseMutableState { +public final class SimpleMutableState extends AbstractMutableState { - public SimpleState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { + public SimpleMutableState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { super(value, mutationPolicy); } } diff --git a/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java b/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java index 281433dd..1aff88e3 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java +++ b/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java @@ -26,10 +26,6 @@ final class ReferenceEquality implements StateMutationPolicy { public static final StateMutationPolicy INSTANCE = new ReferenceEquality(); - private ReferenceEquality() { - throw new AssertionError("Should not be instantiated"); - } - @Override public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { return a == b; @@ -44,10 +40,6 @@ final class StructuralEquality implements StateMutationPolicy { public static final StateMutationPolicy INSTANCE = new StructuralEquality(); - private StructuralEquality() { - throw new AssertionError("Should not be instantiated"); - } - @Override public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { if (a == null || b == null) return false; @@ -63,10 +55,6 @@ final class NeverEqual implements StateMutationPolicy { public static final StateMutationPolicy INSTANCE = new NeverEqual(); - private NeverEqual() { - throw new AssertionError("Should not be instantiated"); - } - @Override public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { return false; diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a62c715..ed496f50 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ annotations = "23.0.0" caffeine = "3.1.8" # Minecraft -paper = "1.16.5-R0.1-SNAPSHOT" +paper = "1.20.4-R0.1-SNAPSHOT" [libraries] # Core @@ -18,7 +18,7 @@ annotations = { module = "org.jetbrains:annotations", version.ref = "annotations caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" } # Minecraft -paper = { module = "org.spigotmc:spigot-api", version.ref = "paper" } +paper = { module = "io.papermc.paper:paper-api", version.ref = "paper" } # Kotlin coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } From 919db30ae28488079769635a3a4123fbe28dde37 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 3 May 2024 17:41:39 +0100 Subject: [PATCH 08/43] feature: Extendable click system --- .../triumphteam/gui/bukkit/BukkitGuiView.java | 4 +- .../java/dev/triumphteam/gui/bukkit/Gui.java | 3 +- ...{BaseGuiView.java => AbstractGuiView.java} | 26 ++++--- .../gui/{BaseGui.java => Gui.java} | 2 +- .../gui/builder/BaseGuiBuilder.java | 4 +- .../triumphteam/gui/click/ClickContext.java | 4 + .../gui/click/action/EmptyGuiClickAction.java | 4 + .../gui/click/action/GuiClickAction.java | 5 ++ .../click/action/RunnableGuiClickAction.java | 10 +++ .../click/completable/CompletableClick.java | 14 ++++ .../gui/click/completable/DeferredClick.java | 44 +++++++++++ .../gui/click/handler/ClickHandler.java | 16 ++++ .../gui/click/handler/FutureClickHandler.java | 40 ++++++++++ .../gui/click/handler/SimpleClickHandler.java | 25 ++++++ .../gui/click/processor/ClickProcessor.java | 57 ++++++++++++++ .../gui/component/ReactiveGuiComponent.java | 2 +- .../gui/component/RenderedComponent.java | 5 +- .../component/builtin/PaginatedComponent.java | 17 ----- .../components/PaginatedComponent.java | 30 ++++++++ .../AbstractFunctionalStateContainer.java | 62 +++++++++++++++ .../functional/FunctionalGuiComponent.java | 68 +---------------- .../functional/FunctionalStateContainer.java | 76 +++++++++++++++++++ .../functional/GuiComponentProducer.java | 10 +++ .../SimpleFunctionalGuiComponent.java | 49 +----------- .../renderer/DefaultGuiComponentRenderer.java | 4 +- .../renderer/GuiComponentRenderer.java | 4 +- .../gui/container/GuiContainer.java | 8 +- .../gui/container/MapBackedContainer.java | 15 ++-- .../dev/triumphteam/gui/item/GuiItem.java | 5 +- .../triumphteam/gui/item/ItemClickAction.java | 7 -- .../triumphteam/gui/item/RenderedGuiItem.java | 7 +- .../gui/item/items/SimpleGuiItem.java | 26 +++++++ .../java/dev/triumphteam/gui/slot/Slot.java | 4 + 33 files changed, 483 insertions(+), 174 deletions(-) rename core/src/main/java/dev/triumphteam/gui/{BaseGuiView.java => AbstractGuiView.java} (72%) rename core/src/main/java/dev/triumphteam/gui/{BaseGui.java => Gui.java} (93%) create mode 100644 core/src/main/java/dev/triumphteam/gui/click/ClickContext.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/action/EmptyGuiClickAction.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/completable/CompletableClick.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/handler/FutureClickHandler.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java create mode 100644 core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalStateContainer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalStateContainer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentProducer.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java create mode 100644 core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java index 48177ea9..2e664f2a 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java @@ -1,6 +1,6 @@ package dev.triumphteam.gui.bukkit; -import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.AbstractGuiView; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.renderer.DefaultGuiComponentRenderer; import dev.triumphteam.gui.item.RenderedGuiItem; @@ -15,7 +15,7 @@ import java.util.List; import java.util.Map; -public final class BukkitGuiView extends BaseGuiView implements InventoryHolder { +public final class BukkitGuiView extends AbstractGuiView implements InventoryHolder { private final Inventory inventory; diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java index da26aff1..591efdc6 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java @@ -1,6 +1,5 @@ package dev.triumphteam.gui.bukkit; -import dev.triumphteam.gui.BaseGui; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import org.bukkit.entity.Player; @@ -9,7 +8,7 @@ import java.util.List; -public final class Gui implements BaseGui { +public final class Gui implements dev.triumphteam.gui.Gui { private final List> components; diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java similarity index 72% rename from core/src/main/java/dev/triumphteam/gui/BaseGuiView.java rename to core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 852469d4..77fe3e3d 100644 --- a/core/src/main/java/dev/triumphteam/gui/BaseGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -2,8 +2,9 @@ import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.RenderedComponent; +import dev.triumphteam.gui.component.StatefulGuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; -import dev.triumphteam.gui.item.ItemClickAction; +import dev.triumphteam.gui.click.action.GuiClickAction; import dev.triumphteam.gui.item.RenderedGuiItem; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; @@ -13,16 +14,18 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -public abstract class BaseGuiView implements GuiView { +public abstract class AbstractGuiView implements GuiView { private final P viewer; private final List> components; private final GuiComponentRenderer renderer; + // Cache of rendered components private final Map, RenderedComponent> renderedComponents = new ConcurrentHashMap<>(); - private final Map componentClickActions = new ConcurrentHashMap<>(); + // Cache of click actions for the items in the inventory + private final Map> componentClickActions = new ConcurrentHashMap<>(); - public BaseGuiView( + public AbstractGuiView( final @NotNull P viewer, final @NotNull List<@NotNull GuiComponent> components, final @NotNull GuiComponentRenderer renderer @@ -38,10 +41,13 @@ public BaseGuiView( protected void setup() { components.forEach(component -> { - // Add listener to used states - component.states().forEach(state -> { - state.addListener(this, () -> renderer.renderComponent(viewer, component, this)); - }); + + if (component instanceof StatefulGuiComponent) { + // Add listener to used states + ((StatefulGuiComponent) component).states().forEach(state -> { + state.addListener(this, () -> renderer.renderComponent(viewer, component, this)); + }); + } // Then render component renderer.renderComponent(viewer, component, this); @@ -72,9 +78,9 @@ public void completeRendered(final @NotNull RenderedComponent renderedComp protected abstract void clearSlot(final @NotNull Slot slot); - protected abstract void populateInventory(final @NotNull Map> renderedItems); + protected abstract void populateInventory(final @NotNull Map> renderedItems); - public @Nullable ItemClickAction getAction(final int slot) { + public @Nullable GuiClickAction

getAction(final int slot) { return componentClickActions.get(new Slot(slot)); } } diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGui.java b/core/src/main/java/dev/triumphteam/gui/Gui.java similarity index 93% rename from core/src/main/java/dev/triumphteam/gui/BaseGui.java rename to core/src/main/java/dev/triumphteam/gui/Gui.java index 5d4ec18c..40467ebb 100644 --- a/core/src/main/java/dev/triumphteam/gui/BaseGui.java +++ b/core/src/main/java/dev/triumphteam/gui/Gui.java @@ -9,7 +9,7 @@ * * @param

A player. */ -public interface BaseGui

{ +public interface Gui

{ /** * Opens a {@link GuiView} of this GUI for the {@link P} player. diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 798ffaa5..7c910295 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,6 +1,6 @@ package dev.triumphteam.gui.builder; -import dev.triumphteam.gui.BaseGui; +import dev.triumphteam.gui.Gui; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.functional.GuiComponentBuilder; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; @@ -11,7 +11,7 @@ import java.util.List; @SuppressWarnings({"unchecked", "UnusedReturnValue"}) -public abstract class BaseGuiBuilder, P, G extends BaseGui

, I> { +public abstract class BaseGuiBuilder, P, G extends Gui

, I> { protected final List> componentRenderers = new ArrayList<>(); diff --git a/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java b/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java new file mode 100644 index 00000000..1db69d77 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java @@ -0,0 +1,4 @@ +package dev.triumphteam.gui.click; + +public record ClickContext() { +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/action/EmptyGuiClickAction.java b/core/src/main/java/dev/triumphteam/gui/click/action/EmptyGuiClickAction.java new file mode 100644 index 00000000..81238799 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/action/EmptyGuiClickAction.java @@ -0,0 +1,4 @@ +package dev.triumphteam.gui.click.action; + +public final class EmptyGuiClickAction

implements GuiClickAction

{ +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java b/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java new file mode 100644 index 00000000..b6f35c14 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java @@ -0,0 +1,5 @@ +package dev.triumphteam.gui.click.action; + +public interface GuiClickAction

{ + +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java b/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java new file mode 100644 index 00000000..4c409a62 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java @@ -0,0 +1,10 @@ +package dev.triumphteam.gui.click.action; + +import dev.triumphteam.gui.click.ClickContext; +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface RunnableGuiClickAction

extends GuiClickAction

{ + + void run(final @NotNull P player, final @NotNull ClickContext context); +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/completable/CompletableClick.java b/core/src/main/java/dev/triumphteam/gui/click/completable/CompletableClick.java new file mode 100644 index 00000000..77719312 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/completable/CompletableClick.java @@ -0,0 +1,14 @@ +package dev.triumphteam.gui.click.completable; + +import org.jetbrains.annotations.Nullable; + +public interface CompletableClick { + + boolean isDone(); + + void complete(final @Nullable Throwable throwable); + + boolean completingLater(); + + void completingLater(final boolean value); +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java b/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java new file mode 100644 index 00000000..21dc8a29 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java @@ -0,0 +1,44 @@ +package dev.triumphteam.gui.click.completable; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; + +public final class DeferredClick implements CompletableClick { + + private final CompletableFuture deferred = CompletableFuture.completedFuture(null); + private boolean completingLater = false; + + public DeferredClick(final @NotNull BiConsumer onComplete) { + deferred.whenComplete(onComplete); + } + + @Override + public boolean isDone() { + return deferred.isDone() || deferred.isCancelled(); + } + + @Override + public void complete(final @Nullable Throwable throwable) { + if (isDone()) return; + + if (throwable != null) { + deferred.completeExceptionally(throwable); + return; + } + + deferred.complete(true); + } + + @Override + public boolean completingLater() { + return completingLater; + } + + @Override + public void completingLater(final boolean value) { + this.completingLater = value; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java new file mode 100644 index 00000000..4e375b90 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java @@ -0,0 +1,16 @@ +package dev.triumphteam.gui.click.handler; + +import dev.triumphteam.gui.click.ClickContext; +import dev.triumphteam.gui.click.action.GuiClickAction; +import dev.triumphteam.gui.click.completable.CompletableClick; +import org.jetbrains.annotations.NotNull; + +public interface ClickHandler

{ + + void handle( + final @NotNull P player, + final @NotNull ClickContext context, + final @NotNull GuiClickAction

action, + final @NotNull CompletableClick deferred + ); +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/FutureClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/FutureClickHandler.java new file mode 100644 index 00000000..1d103a00 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/FutureClickHandler.java @@ -0,0 +1,40 @@ +package dev.triumphteam.gui.click.handler; + +import dev.triumphteam.gui.click.ClickContext; +import dev.triumphteam.gui.click.action.GuiClickAction; +import dev.triumphteam.gui.click.action.RunnableGuiClickAction; +import dev.triumphteam.gui.click.completable.CompletableClick; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +public final class FutureClickHandler

implements ClickHandler

{ + + private final long timeout; + private final TimeUnit unit; + + public FutureClickHandler(final long timeout, final @NotNull TimeUnit unit) { + this.timeout = timeout; + this.unit = unit; + } + + @Override + public void handle( + final @NotNull P player, + final @NotNull ClickContext context, + final @NotNull GuiClickAction

action, + final @NotNull CompletableClick deferred + ) { + + if (!(action instanceof RunnableGuiClickAction

)) { + return; + } + + deferred.completingLater(true); + + CompletableFuture.runAsync(() -> ((RunnableGuiClickAction

) action).run(player, context)) + .orTimeout(timeout, unit) + .whenComplete((unused, throwable) -> deferred.complete(throwable)); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java new file mode 100644 index 00000000..c113b46c --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java @@ -0,0 +1,25 @@ +package dev.triumphteam.gui.click.handler; + +import dev.triumphteam.gui.click.ClickContext; +import dev.triumphteam.gui.click.action.GuiClickAction; +import dev.triumphteam.gui.click.action.RunnableGuiClickAction; +import dev.triumphteam.gui.click.completable.CompletableClick; +import org.jetbrains.annotations.NotNull; + +public final class SimpleClickHandler

implements ClickHandler

{ + + @Override + public void handle( + final @NotNull P player, + final @NotNull ClickContext context, + final @NotNull GuiClickAction

action, + final @NotNull CompletableClick deferred + ) { + + if (!(action instanceof RunnableGuiClickAction

)) { + return; + } + + ((RunnableGuiClickAction

) action).run(player, context); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java new file mode 100644 index 00000000..26ef67a8 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java @@ -0,0 +1,57 @@ +package dev.triumphteam.gui.click.processor; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import dev.triumphteam.gui.AbstractGuiView; +import dev.triumphteam.gui.click.handler.ClickHandler; +import kotlin.Unit; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Supplier; + +public final class ClickProcessor { + + private final Cache spamPrevention = Caffeine.newBuilder() + .expireAfterWrite(200L, TimeUnit.MILLISECONDS) + .build(); + + private final AtomicBoolean isProcessing = new AtomicBoolean(false); + + public void processClick( + final int slot, + final @NotNull UUID clickerUuid, + final @NotNull AbstractGuiView view + ) { + + if (canClick(clickerUuid)) { + return; + } + + if (!isProcessing.compareAndSet(false, true)) { + return; + } + + // context + + final var action = view.getAction(slot); + final var handler = clickHandlerSupplier.get(); + handler.handle(action); + } + + private boolean canClick(final @NotNull UUID clickerUuid) { + if (isProcessing.get()) { + return false; + } + + final var spamming = spamPrevention.getIfPresent(clickerUuid); + if (spamming != null) { + spamPrevention.put(clickerUuid, spamming); + return true; + } + + return false; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java index 88a7a1b3..4d20b364 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java @@ -5,5 +5,5 @@ public interface ReactiveGuiComponent extends StatefulGuiComponent { - void render(final @NotNull GuiContainer<@NotNull I> container, final @NotNull P player); + void render(final @NotNull GuiContainer<@NotNull P, @NotNull I> container, final @NotNull P player); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java index 08015c16..e61c2f22 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java @@ -1,13 +1,16 @@ package dev.triumphteam.gui.component; +import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.item.RenderedGuiItem; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; import java.util.Map; +import java.util.function.Supplier; public record RenderedComponent( @NotNull GuiComponent component, - Map> renderedItems + @NotNull Supplier> clickHandler, + @NotNull Map> renderedItems ) { } diff --git a/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java deleted file mode 100644 index 84df7458..00000000 --- a/core/src/main/java/dev/triumphteam/gui/component/builtin/PaginatedComponent.java +++ /dev/null @@ -1,17 +0,0 @@ -package dev.triumphteam.gui.component.builtin; - -import dev.triumphteam.gui.component.GuiComponent; -import dev.triumphteam.gui.state.State; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public final class PaginatedComponent implements GuiComponent { - - @Override - public @NotNull List<@NotNull State> states() { - return List.of(); - } - - -} diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java new file mode 100644 index 00000000..cf3f1568 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java @@ -0,0 +1,30 @@ +package dev.triumphteam.gui.component.components; + +import dev.triumphteam.gui.component.ReactiveGuiComponent; +import dev.triumphteam.gui.container.GuiContainer; +import dev.triumphteam.gui.state.State; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public final class PaginatedComponent implements ReactiveGuiComponent { + + private final List items; + + public PaginatedComponent(final @NotNull List items) { + this.items = items; + } + + @Override + public @NotNull List<@NotNull State> states() { + return List.of(); + } + + @Override + public void render(final @NotNull GuiContainer container, final @NotNull P player) { + container.set(22, ); + container.set(23, ); + + + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalStateContainer.java b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalStateContainer.java new file mode 100644 index 00000000..020b0920 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalStateContainer.java @@ -0,0 +1,62 @@ +package dev.triumphteam.gui.component.functional; + +import dev.triumphteam.gui.state.MutableState; +import dev.triumphteam.gui.state.State; +import dev.triumphteam.gui.state.builtin.EmptyState; +import dev.triumphteam.gui.state.builtin.SimpleMutableState; +import dev.triumphteam.gui.state.policy.StateMutationPolicy; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public abstract class AbstractFunctionalStateContainer implements FunctionalStateContainer { + + private final List states = new ArrayList<>(); + + @Override + public @NotNull State state() { + return state(new EmptyState()); + } + + @Override + public @NotNull S state(final @NotNull S state) { + states.add(state); + return state; + } + + @Override + public @NotNull MutableState<@NotNull T> state(@NotNull final T value) { + return state(value, StateMutationPolicy.StructuralEquality.INSTANCE); + } + + @Override + public @NotNull MutableState<@NotNull T> state( + final @NotNull T value, + final @NotNull StateMutationPolicy mutationPolicy + ) { + var state = new SimpleMutableState<>(value, mutationPolicy); + states.add(state); + return state; + } + + @Override + public @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value) { + return nullableState(value, StateMutationPolicy.StructuralEquality.INSTANCE); + } + + @Override + public @NotNull MutableState<@Nullable T> nullableState( + final @Nullable T value, + final @NotNull StateMutationPolicy mutationPolicy + ) { + var state = new SimpleMutableState<>(value, mutationPolicy); + states.add(state); + return state; + } + + protected @NotNull List getStates() { + return states; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java index 0636fa91..df743f73 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java @@ -1,14 +1,10 @@ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.builder.BaseGuiBuilder; -import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; -import dev.triumphteam.gui.state.MutableState; -import dev.triumphteam.gui.state.State; -import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Similar to a {@link GuiComponent} this component will take in states and render a component. @@ -17,67 +13,7 @@ * @param

The player type. * @param The item type. */ -public interface FunctionalGuiComponent { - - @NotNull - State state(); - - /** - * Associate a {@link State} to the component. - * - * @param state A state. - * @return The same state passed. - */ - @NotNull - S state(final @NotNull S state); - - /** - * Create a new state with the given default value. - * - * @param value The default value of the state. - * @param The type of the value. - * @return The newly created {@link MutableState}. - */ - @NotNull MutableState<@NotNull T> state(final @NotNull T value); - - /** - * Create a new state with the given default value. - * Uses the given {@link StateMutationPolicy} for equivalence check. - * - * @param value The default value of the state. - * @param mutationPolicy The mutation policy to use. - * @param The type of the value. - * @return The newly created {@link MutableState}. - */ - @NotNull MutableState<@NotNull T> state( - final @NotNull T value, - final @NotNull StateMutationPolicy mutationPolicy - ); - - /** - * Create a new state with the given default value. - * In this case, the value is nullable. - * - * @param value The default value of the state. - * @param The type of the value. - * @return The newly created {@link MutableState}. - */ - @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value); - - /** - * Create a new state with the given default value. - * In this case, the value is nullable. - * Uses the given {@link StateMutationPolicy} for equivalence check. - * - * @param value The default value of the state. - * @param mutationPolicy The mutation policy to use. - * @param The type of the value. - * @return The newly created {@link MutableState}. - */ - @NotNull MutableState<@Nullable T> nullableState( - final @Nullable T value, - final @NotNull StateMutationPolicy mutationPolicy - ); +public interface FunctionalGuiComponent extends FunctionalStateContainer { /** * A component render function. diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalStateContainer.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalStateContainer.java new file mode 100644 index 00000000..eb0de00b --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalStateContainer.java @@ -0,0 +1,76 @@ +package dev.triumphteam.gui.component.functional; + +import dev.triumphteam.gui.state.MutableState; +import dev.triumphteam.gui.state.State; +import dev.triumphteam.gui.state.builtin.EmptyState; +import dev.triumphteam.gui.state.policy.StateMutationPolicy; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +interface FunctionalStateContainer { + + /** + * Associate am empty {@link State} to the component. + * + * @return A new {@link EmptyState}. + */ + @NotNull + State state(); + + /** + * Associate a {@link S} type {@link State} to the component. + * + * @param state A state. + * @return The same state passed. + */ + @NotNull + S state(final @NotNull S state); + + /** + * Create a new state with the given default value. + * + * @param value The default value of the state. + * @param The type of the value. + * @return The newly created {@link MutableState}. + */ + @NotNull MutableState<@NotNull T> state(final @NotNull T value); + + /** + * Create a new state with the given default value. + * Uses the given {@link StateMutationPolicy} for equivalence check. + * + * @param value The default value of the state. + * @param mutationPolicy The mutation policy to use. + * @param The type of the value. + * @return The newly created {@link MutableState}. + */ + @NotNull MutableState<@NotNull T> state( + final @NotNull T value, + final @NotNull StateMutationPolicy mutationPolicy + ); + + /** + * Create a new state with the given default value. + * In this case, the value is nullable. + * + * @param value The default value of the state. + * @param The type of the value. + * @return The newly created {@link MutableState}. + */ + @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value); + + /** + * Create a new state with the given default value. + * In this case, the value is nullable. + * Uses the given {@link StateMutationPolicy} for equivalence check. + * + * @param value The default value of the state. + * @param mutationPolicy The mutation policy to use. + * @param The type of the value. + * @return The newly created {@link MutableState}. + */ + @NotNull MutableState<@Nullable T> nullableState( + final @Nullable T value, + final @NotNull StateMutationPolicy mutationPolicy + ); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentProducer.java b/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentProducer.java new file mode 100644 index 00000000..9eb55c8b --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentProducer.java @@ -0,0 +1,10 @@ +package dev.triumphteam.gui.component.functional; + +import dev.triumphteam.gui.component.GuiComponent; +import org.jetbrains.annotations.NotNull; + +public interface GuiComponentProducer { + + @NotNull + GuiComponent asGuiComponent(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index efee765c..d8e22426 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -1,65 +1,24 @@ package dev.triumphteam.gui.component.functional; -import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.exception.GuiException; -import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.State; -import dev.triumphteam.gui.state.builtin.SimpleMutableState; -import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; -public final class SimpleFunctionalGuiComponent implements FunctionalGuiComponent { +public final class SimpleFunctionalGuiComponent extends AbstractFunctionalStateContainer implements FunctionalGuiComponent, GuiComponentProducer { - private final List states = new ArrayList<>(); private GuiComponentRender component = null; - @Override - public @NotNull State state(final @NotNull State state) { - states.add(state); - return state; - } - - @Override - public @NotNull MutableState<@NotNull T> state(@NotNull final T value) { - return state(value, StateMutationPolicy.StructuralEquality.INSTANCE); - } - - @Override - public @NotNull MutableState<@NotNull T> state( - final @NotNull T value, - final @NotNull StateMutationPolicy mutationPolicy - ) { - var state = new SimpleMutableState<>(value, mutationPolicy); - states.add(state); - return state; - } - - @Override - public @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value) { - return nullableState(value, StateMutationPolicy.StructuralEquality.INSTANCE); - } - - @Override - public @NotNull MutableState<@Nullable T> nullableState( - final @Nullable T value, - final @NotNull StateMutationPolicy mutationPolicy - ) { - var state = new SimpleMutableState<>(value, mutationPolicy); - states.add(state); - return state; - } - @Override public void render(final @NotNull GuiComponentRender component) { this.component = component; } + @Override public @NotNull GuiComponent asGuiComponent() { if (component == null) { throw new GuiException("TODO"); @@ -73,7 +32,7 @@ public void render(final @NotNull GuiContainer<@NotNull I> container, @NotNull f @Override public @NotNull List states() { - return states; + return getStates(); } }; } diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java index 04184372..0b50430c 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java @@ -1,6 +1,6 @@ package dev.triumphteam.gui.component.renderer; -import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.AbstractGuiView; import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.RenderedComponent; @@ -13,7 +13,7 @@ public final class DefaultGuiComponentRenderer implements GuiComponentRend public void renderComponent( final @NotNull P player, final @NotNull GuiComponent component, - final @NotNull BaseGuiView view + final @NotNull AbstractGuiView view ) { final var container = new MapBackedContainer(); diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java index 258b5c21..dabbe9e8 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java @@ -1,6 +1,6 @@ package dev.triumphteam.gui.component.renderer; -import dev.triumphteam.gui.BaseGuiView; +import dev.triumphteam.gui.AbstractGuiView; import dev.triumphteam.gui.component.GuiComponent; import org.jetbrains.annotations.NotNull; @@ -9,6 +9,6 @@ public interface GuiComponentRenderer { void renderComponent( final @NotNull P player, final @NotNull GuiComponent component, - final @NotNull BaseGuiView view + final @NotNull AbstractGuiView view ); } diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java index cbd54e12..6a908295 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -4,14 +4,14 @@ import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; -public interface GuiContainer { +public interface GuiContainer { @NotNull GuiContainerType containerType(); - void set(final int slot, final @NotNull GuiItem<@NotNull I> guiItem); + void set(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); - void set(final int row, final int column, final @NotNull GuiItem<@NotNull I> guiItem); + void set(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); - void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull I> guiItem); + void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); } diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index 13c95be0..87c9572c 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -9,9 +9,9 @@ import java.util.HashMap; import java.util.Map; -public final class MapBackedContainer implements GuiContainer { +public final class MapBackedContainer implements GuiContainer { - private final Map> backing = new HashMap<>(100); + private final Map> backing = new HashMap<>(100); @Override public @NotNull GuiContainerType containerType() { @@ -19,25 +19,24 @@ public final class MapBackedContainer implements GuiContainer { } @Override - public void set(final int slot, final @NotNull GuiItem<@NotNull I> guiItem) { + public void set(final int slot, final @NotNull GuiItem<@NotNull P,@NotNull I> guiItem) { set(new Slot(slot), guiItem); } @Override - public void set(final int row, final int column, final @NotNull GuiItem<@NotNull I> guiItem) { - // TODO(matt): This - set(new Slot(0), guiItem); + public void set(final int row, final int column, final @NotNull GuiItem<@NotNull P,@NotNull I> guiItem) { + set(Slot.fromRowCol(row, column), guiItem); } @Override - public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull I> guiItem) { + public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { // Render item final var renderedItem = new RenderedGuiItem<>(guiItem.render(), guiItem.getClickAction()); // Add rendered to backing backing.put(slot, renderedItem); } - public @NotNull Map> complete() { + public @NotNull Map> complete() { return Collections.unmodifiableMap(backing); } } diff --git a/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java index 44b50f13..03222498 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java +++ b/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java @@ -1,12 +1,13 @@ package dev.triumphteam.gui.item; +import dev.triumphteam.gui.click.action.GuiClickAction; import org.jetbrains.annotations.NotNull; -public interface GuiItem { +public interface GuiItem { @NotNull I render(); @NotNull - ItemClickAction getClickAction(); + GuiClickAction

getClickAction(); } diff --git a/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java b/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java deleted file mode 100644 index a065903b..00000000 --- a/core/src/main/java/dev/triumphteam/gui/item/ItemClickAction.java +++ /dev/null @@ -1,7 +0,0 @@ -package dev.triumphteam.gui.item; - -@FunctionalInterface -public interface ItemClickAction { - - void click(); -} diff --git a/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java index ee3afcd4..b07b5cc7 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java +++ b/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java @@ -1,6 +1,9 @@ package dev.triumphteam.gui.item; +import dev.triumphteam.gui.click.action.GuiClickAction; import org.jetbrains.annotations.NotNull; -public record RenderedGuiItem(@NotNull I item, @NotNull ItemClickAction action) { -} +public record RenderedGuiItem( + @NotNull I item, + @NotNull GuiClickAction

action +) {} diff --git a/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java new file mode 100644 index 00000000..e2d97f5b --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java @@ -0,0 +1,26 @@ +package dev.triumphteam.gui.item.items; + +import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.click.action.GuiClickAction; +import org.jetbrains.annotations.NotNull; + +public final class SimpleGuiItem implements GuiItem { + + private final I item; + private final GuiClickAction clickAction; + + public SimpleGuiItem(final @NotNull I item, final @NotNull GuiClickAction clickAction) { + this.item = item; + this.clickAction = clickAction; + } + + @Override + public @NotNull I render() { + return item; + } + + @Override + public @NotNull GuiClickAction getClickAction() { + return clickAction; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java index 02e4fa0e..1978f329 100644 --- a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java +++ b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java @@ -1,4 +1,8 @@ package dev.triumphteam.gui.slot; public record Slot(int slot) { + + public static int fromRowCol(final int row, final int column) { + return (column + (row - 1) * 9) - 1; + } } From a6abd38de214b90042173d29887fb474f28599a0 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 4 May 2024 20:53:16 +0100 Subject: [PATCH 09/43] feature: Implementing new click system --- .../triumphteam/gui/bukkit/BukkitGuiView.java | 18 ++++++-- .../gui/bukkit/GuiBukkitListener.java | 5 +- core/build.gradle.kts | 1 + .../dev/triumphteam/gui/AbstractGuiView.java | 43 +++++++++++------ .../gui/click/processor/ClickProcessor.java | 46 ++++++++++++++----- .../gui/component/GuiComponent.java | 11 ++++- .../gui/component/RenderedComponent.java | 3 -- .../components/PaginatedComponent.java | 5 +- .../functional/FunctionalGuiComponent.java | 4 ++ .../functional/GuiComponentRender.java | 2 +- .../SimpleFunctionalGuiComponent.java | 16 ++++++- .../renderer/DefaultGuiComponentRenderer.java | 7 ++- .../gui/container/MapBackedContainer.java | 12 +++-- .../triumphteam/gui/item/RenderedGuiItem.java | 2 + .../gui/item/items/SimpleGuiItem.java | 26 ----------- 15 files changed, 129 insertions(+), 72 deletions(-) delete mode 100644 core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java index 2e664f2a..c4cecb79 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java @@ -1,6 +1,7 @@ package dev.triumphteam.gui.bukkit; import dev.triumphteam.gui.AbstractGuiView; +import dev.triumphteam.gui.click.handler.SimpleClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.renderer.DefaultGuiComponentRenderer; import dev.triumphteam.gui.item.RenderedGuiItem; @@ -14,6 +15,7 @@ import java.util.List; import java.util.Map; +import java.util.UUID; public final class BukkitGuiView extends AbstractGuiView implements InventoryHolder { @@ -24,14 +26,14 @@ public BukkitGuiView( final @NotNull List> components ) { // TODO(matt): Renderer from constructor - super(player, components, new DefaultGuiComponentRenderer<>()); + super(player, components, new DefaultGuiComponentRenderer<>(), new SimpleClickHandler<>()); this.inventory = Bukkit.createInventory(this, 54, "Gui"); } @Override public void open() { - getViewer().openInventory(inventory); + viewer().openInventory(inventory); setup(); } @@ -52,7 +54,17 @@ protected void clearSlot(final @NotNull Slot slot) { } @Override - protected void populateInventory(final @NotNull Map> renderedItems) { + public @NotNull String viewerName() { + return viewer().getName(); + } + + @Override + public @NotNull UUID viewerUuid() { + return viewer().getUniqueId(); + } + + @Override + protected void populateInventory(final @NotNull Map> renderedItems) { renderedItems.forEach((slot, item) -> inventory.setItem(slot.slot(), item.item())); } } diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java index d5a58137..40a2dfd5 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java +++ b/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java @@ -23,8 +23,7 @@ public void onGuiClick(final InventoryClickEvent event) { } event.setCancelled(true); - final var action = view.getAction(event.getSlot()); - if (action == null) return; - action.click(); + + view.getClickProcessor().processClick(event.getSlot(), view); } } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index aac3946e..aaa10337 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -4,4 +4,5 @@ plugins { dependencies { implementation(libs.caffeine) + compileOnly("org.slf4j:slf4j-api:2.0.13") } diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 77fe3e3d..2bed64b9 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -1,10 +1,11 @@ package dev.triumphteam.gui; +import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.click.processor.ClickProcessor; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.RenderedComponent; import dev.triumphteam.gui.component.StatefulGuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; -import dev.triumphteam.gui.click.action.GuiClickAction; import dev.triumphteam.gui.item.RenderedGuiItem; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; @@ -12,6 +13,7 @@ import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; public abstract class AbstractGuiView implements GuiView { @@ -19,26 +21,39 @@ public abstract class AbstractGuiView implements GuiView { private final P viewer; private final List> components; private final GuiComponentRenderer renderer; + private final ClickHandler

defaultClickHandler; + // Click processor + private final ClickProcessor clickProcessor = new ClickProcessor<>(); // Cache of rendered components private final Map, RenderedComponent> renderedComponents = new ConcurrentHashMap<>(); - // Cache of click actions for the items in the inventory - private final Map> componentClickActions = new ConcurrentHashMap<>(); + // All the gui items that have been rendered and are in the inventory + private final Map> allRenderedItems = new ConcurrentHashMap<>(); public AbstractGuiView( final @NotNull P viewer, final @NotNull List<@NotNull GuiComponent> components, - final @NotNull GuiComponentRenderer renderer + final @NotNull GuiComponentRenderer renderer, + final @NotNull ClickHandler

defaultClickHandler ) { this.viewer = viewer; this.components = components; this.renderer = renderer; + this.defaultClickHandler = defaultClickHandler; } - public @NotNull P getViewer() { + public @NotNull P viewer() { return viewer; } + public abstract @NotNull String viewerName(); + + public abstract @NotNull UUID viewerUuid(); + + protected abstract void clearSlot(final @NotNull Slot slot); + + protected abstract void populateInventory(final @NotNull Map<@NotNull Slot, @NotNull RenderedGuiItem> renderedItems); + protected void setup() { components.forEach(component -> { @@ -62,25 +77,27 @@ public void completeRendered(final @NotNull RenderedComponent renderedComp // Clear its uses existing.renderedItems().forEach((slot, ignored) -> { clearSlot(slot); - componentClickActions.remove(slot); + allRenderedItems.remove(slot); }); } renderedComponents.put(ownerComponent, renderedComponent); final var renderedItems = renderedComponent.renderedItems(); - renderedItems.forEach((slot, renderedItem) -> { - componentClickActions.put(slot, renderedItem.action()); - }); + allRenderedItems.putAll(renderedItems); populateInventory(renderedItems); } - protected abstract void clearSlot(final @NotNull Slot slot); + public @NotNull ClickProcessor getClickProcessor() { + return clickProcessor; + } - protected abstract void populateInventory(final @NotNull Map> renderedItems); + public @Nullable RenderedGuiItem getItem(final int slot) { + return allRenderedItems.get(new Slot(slot)); + } - public @Nullable GuiClickAction

getAction(final int slot) { - return componentClickActions.get(new Slot(slot)); + public @NotNull ClickHandler

getDefaultClickHandler() { + return defaultClickHandler; } } diff --git a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java index 26ef67a8..a65a2cbc 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java +++ b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java @@ -3,30 +3,32 @@ import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import dev.triumphteam.gui.AbstractGuiView; -import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.click.ClickContext; +import dev.triumphteam.gui.click.completable.DeferredClick; import kotlin.Unit; import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Supplier; public final class ClickProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(ClickProcessor.class); + private final Cache spamPrevention = Caffeine.newBuilder() .expireAfterWrite(200L, TimeUnit.MILLISECONDS) .build(); private final AtomicBoolean isProcessing = new AtomicBoolean(false); - public void processClick( - final int slot, - final @NotNull UUID clickerUuid, - final @NotNull AbstractGuiView view - ) { + public void processClick(final int slot, final @NotNull AbstractGuiView view) { + + final var viewerUuid = view.viewerUuid(); - if (canClick(clickerUuid)) { + if (canClick(viewerUuid)) { return; } @@ -34,11 +36,31 @@ public void processClick( return; } - // context + final var clickContext = new ClickContext(); + + final var renderedItem = view.getItem(slot); + if (renderedItem == null) return; + + final var handler = renderedItem.clickHandler(); - final var action = view.getAction(slot); - final var handler = clickHandlerSupplier.get(); - handler.handle(action); + final var deferredClick = new DeferredClick((ignored, throwable) -> { + if (throwable != null) { + LOGGER.error( + "An exception occurred while processing click for '{}' on slot '{}'.", + view.viewerName(), + slot, + throwable + ); + } + + this.isProcessing.compareAndSet(true, false); + }); + + handler.handle(view.viewer(), clickContext, renderedItem.action(), deferredClick); + + if (!deferredClick.completingLater()) { + deferredClick.complete(null); + } } private boolean canClick(final @NotNull UUID clickerUuid) { diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java index 42de287c..7c74b8e3 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java @@ -1,3 +1,12 @@ package dev.triumphteam.gui.component; -public interface GuiComponent {} +import dev.triumphteam.gui.click.handler.ClickHandler; +import org.jetbrains.annotations.Nullable; + +public interface GuiComponent { + + @Nullable + default ClickHandler

clickHandler() { + return null; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java index e61c2f22..43fd582c 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java @@ -1,16 +1,13 @@ package dev.triumphteam.gui.component; -import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.item.RenderedGuiItem; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; import java.util.Map; -import java.util.function.Supplier; public record RenderedComponent( @NotNull GuiComponent component, - @NotNull Supplier> clickHandler, @NotNull Map> renderedItems ) { } diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java index cf3f1568..14f1f1bf 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java @@ -21,10 +21,7 @@ public PaginatedComponent(final @NotNull List items) { } @Override - public void render(final @NotNull GuiContainer container, final @NotNull P player) { - container.set(22, ); - container.set(23, ); - + public void render(final @NotNull GuiContainer container, @NotNull final P player) { } } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java index df743f73..1de25c86 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java @@ -1,10 +1,12 @@ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.builder.BaseGuiBuilder; +import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Similar to a {@link GuiComponent} this component will take in states and render a component. @@ -15,6 +17,8 @@ */ public interface FunctionalGuiComponent extends FunctionalStateContainer { + void clickHandler(final @Nullable ClickHandler

clickHandler); + /** * A component render function. * The function inside works the same as a normal {@link ReactiveGuiComponent#render(GuiContainer, Object)} would. diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java b/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java index b46ef56f..ea5bfd07 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java @@ -7,7 +7,7 @@ public interface GuiComponentRender { void render( - final @NotNull GuiContainer container, + final @NotNull GuiContainer<@NotNull P, @NotNull I> container, final @NotNull P player ); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index d8e22426..8ff83ec2 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -1,17 +1,25 @@ package dev.triumphteam.gui.component.functional; +import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.exception.GuiException; import dev.triumphteam.gui.state.State; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; public final class SimpleFunctionalGuiComponent extends AbstractFunctionalStateContainer implements FunctionalGuiComponent, GuiComponentProducer { private GuiComponentRender component = null; + private ClickHandler

clickHandler; + + @Override + public void clickHandler(final @Nullable ClickHandler

clickHandler) { + this.clickHandler = clickHandler; + } @Override public void render(final @NotNull GuiComponentRender component) { @@ -25,8 +33,14 @@ public void render(final @NotNull GuiComponentRender component) { } return new ReactiveGuiComponent<>() { + + @Override + public @Nullable ClickHandler

clickHandler() { + return clickHandler; + } + @Override - public void render(final @NotNull GuiContainer<@NotNull I> container, @NotNull final P player) { + public void render(final @NotNull GuiContainer<@NotNull P, @NotNull I> container, @NotNull final P player) { component.render(container, player); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java index 0b50430c..3bc33b2f 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java @@ -1,8 +1,8 @@ package dev.triumphteam.gui.component.renderer; import dev.triumphteam.gui.AbstractGuiView; -import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.component.RenderedComponent; import dev.triumphteam.gui.container.MapBackedContainer; import org.jetbrains.annotations.NotNull; @@ -16,7 +16,10 @@ public void renderComponent( final @NotNull AbstractGuiView view ) { - final var container = new MapBackedContainer(); + final var componentClickHandler = component.clickHandler(); + final var container = new MapBackedContainer( + componentClickHandler == null ? view.getDefaultClickHandler() : componentClickHandler + ); if (component instanceof ReactiveGuiComponent) { ((ReactiveGuiComponent) component).render(container, player); diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index 87c9572c..cb7e6431 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -1,5 +1,6 @@ package dev.triumphteam.gui.container; +import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.item.GuiItem; import dev.triumphteam.gui.item.RenderedGuiItem; import dev.triumphteam.gui.slot.Slot; @@ -12,6 +13,11 @@ public final class MapBackedContainer implements GuiContainer { private final Map> backing = new HashMap<>(100); + private final ClickHandler

clickHandler; + + public MapBackedContainer(final @NotNull ClickHandler

clickHandler) { + this.clickHandler = clickHandler; + } @Override public @NotNull GuiContainerType containerType() { @@ -19,19 +25,19 @@ public final class MapBackedContainer implements GuiContainer { } @Override - public void set(final int slot, final @NotNull GuiItem<@NotNull P,@NotNull I> guiItem) { + public void set(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { set(new Slot(slot), guiItem); } @Override - public void set(final int row, final int column, final @NotNull GuiItem<@NotNull P,@NotNull I> guiItem) { + public void set(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { set(Slot.fromRowCol(row, column), guiItem); } @Override public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { // Render item - final var renderedItem = new RenderedGuiItem<>(guiItem.render(), guiItem.getClickAction()); + final var renderedItem = new RenderedGuiItem<>(guiItem.render(), clickHandler, guiItem.getClickAction()); // Add rendered to backing backing.put(slot, renderedItem); } diff --git a/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java index b07b5cc7..2f338651 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java +++ b/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java @@ -1,9 +1,11 @@ package dev.triumphteam.gui.item; import dev.triumphteam.gui.click.action.GuiClickAction; +import dev.triumphteam.gui.click.handler.ClickHandler; import org.jetbrains.annotations.NotNull; public record RenderedGuiItem( @NotNull I item, + @NotNull ClickHandler

clickHandler, @NotNull GuiClickAction

action ) {} diff --git a/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java deleted file mode 100644 index e2d97f5b..00000000 --- a/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java +++ /dev/null @@ -1,26 +0,0 @@ -package dev.triumphteam.gui.item.items; - -import dev.triumphteam.gui.item.GuiItem; -import dev.triumphteam.gui.click.action.GuiClickAction; -import org.jetbrains.annotations.NotNull; - -public final class SimpleGuiItem implements GuiItem { - - private final I item; - private final GuiClickAction clickAction; - - public SimpleGuiItem(final @NotNull I item, final @NotNull GuiClickAction clickAction) { - this.item = item; - this.clickAction = clickAction; - } - - @Override - public @NotNull I render() { - return item; - } - - @Override - public @NotNull GuiClickAction getClickAction() { - return clickAction; - } -} From 46b58bc12ee2f873f3514ae61b1e03a4be539897 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 4 May 2024 20:55:20 +0100 Subject: [PATCH 10/43] chore: Bukkit -> Paper --- {bukkit => paper}/build.gradle.kts | 0 .../main/java/dev/triumphteam/gui/paper}/BukkitGuiView.java | 2 +- .../src/main/java/dev/triumphteam/gui/paper}/Gui.java | 2 +- .../java/dev/triumphteam/gui/paper}/GuiBukkitListener.java | 2 +- .../java/dev/triumphteam/gui/paper}/builder/GuiBuilder.java | 4 ++-- settings.gradle.kts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) rename {bukkit => paper}/build.gradle.kts (100%) rename {bukkit/src/main/java/dev/triumphteam/gui/bukkit => paper/src/main/java/dev/triumphteam/gui/paper}/BukkitGuiView.java (98%) rename {bukkit/src/main/java/dev/triumphteam/gui/bukkit => paper/src/main/java/dev/triumphteam/gui/paper}/Gui.java (96%) rename {bukkit/src/main/java/dev/triumphteam/gui/bukkit => paper/src/main/java/dev/triumphteam/gui/paper}/GuiBukkitListener.java (96%) rename {bukkit/src/main/java/dev/triumphteam/gui/bukkit => paper/src/main/java/dev/triumphteam/gui/paper}/builder/GuiBuilder.java (78%) diff --git a/bukkit/build.gradle.kts b/paper/build.gradle.kts similarity index 100% rename from bukkit/build.gradle.kts rename to paper/build.gradle.kts diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java b/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java similarity index 98% rename from bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java rename to paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java index c4cecb79..986bcad8 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/BukkitGuiView.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.bukkit; +package dev.triumphteam.gui.paper; import dev.triumphteam.gui.AbstractGuiView; import dev.triumphteam.gui.click.handler.SimpleClickHandler; diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java similarity index 96% rename from bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java rename to paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index 591efdc6..04821f98 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/Gui.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.bukkit; +package dev.triumphteam.gui.paper; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java similarity index 96% rename from bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java rename to paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java index 40a2dfd5..2fc8de4f 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/GuiBukkitListener.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.bukkit; +package dev.triumphteam.gui.paper; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; diff --git a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/GuiBuilder.java similarity index 78% rename from bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java rename to paper/src/main/java/dev/triumphteam/gui/paper/builder/GuiBuilder.java index ea6b1136..af8666eb 100644 --- a/bukkit/src/main/java/dev/triumphteam/gui/bukkit/builder/GuiBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/GuiBuilder.java @@ -1,7 +1,7 @@ -package dev.triumphteam.gui.bukkit.builder; +package dev.triumphteam.gui.paper.builder; import dev.triumphteam.gui.builder.BaseGuiBuilder; -import dev.triumphteam.gui.bukkit.Gui; +import dev.triumphteam.gui.paper.Gui; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; diff --git a/settings.gradle.kts b/settings.gradle.kts index 60c97c5c..d46d4d1e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -7,7 +7,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") rootProject.name = "triumph-gui" -listOf("core", "bukkit").forEach(::includeProject) +listOf("core", "paper").forEach(::includeProject) fun includeProject(name: String) { include(name) { From 988574d02cf98753b7a5c1b697efc0811ac68e92 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 4 May 2024 20:57:44 +0100 Subject: [PATCH 11/43] chore: Dependencies re-arrange --- core/build.gradle.kts | 2 +- gradle/libs.versions.toml | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index aaa10337..7c52f9d4 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -4,5 +4,5 @@ plugins { dependencies { implementation(libs.caffeine) - compileOnly("org.slf4j:slf4j-api:2.0.13") + compileOnly(libs.logger) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ed496f50..655679fc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,8 +6,9 @@ coroutines = "1.6.4" license = "0.16.1" # Core -annotations = "23.0.0" +annotations = "24.1.0" caffeine = "3.1.8" +logger = "2.0.13" # Minecraft paper = "1.20.4-R0.1-SNAPSHOT" @@ -16,6 +17,7 @@ paper = "1.20.4-R0.1-SNAPSHOT" # Core annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" } caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" } +logger = { module = "org.slf4j:slf4j-api", version.ref = "logger" } # Minecraft paper = { module = "io.papermc.paper:paper-api", version.ref = "paper" } From 7ad5f4d59c642bb1e5a032c899a09d153821d25e Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 6 May 2024 00:17:01 +0100 Subject: [PATCH 12/43] feature: Bringing back the item builder --- .../src/main/kotlin/gui.base.gradle.kts | 2 +- .../gui/builder/BaseGuiBuilder.java | 4 +- .../gui/click/completable/DeferredClick.java | 2 +- ...ava => CompletableFutureClickHandler.java} | 8 +- .../gui/click/processor/ClickProcessor.java | 10 +- .../GuiComponentProducer.java | 3 +- ...va => AbstractFunctionalGuiComponent.java} | 31 ++++- ...r.java => BaseFunctionalGuiComponent.java} | 17 ++- .../functional/FunctionalGuiComponent.java | 8 +- ...ava => FunctionalGuiComponentBuilder.java} | 2 +- ...java => FunctionalGuiComponentRender.java} | 2 +- .../SimpleFunctionalGuiComponent.java | 15 +-- .../gui/item/items/SimpleGuiItem.java | 26 ++++ gradle/libs.versions.toml | 4 +- paper/build.gradle.kts | 6 +- .../java/dev/triumphteam/gui/paper/Gui.java | 8 +- .../paper/builder/{ => gui}/GuiBuilder.java | 2 +- .../builder/item/AbstractItemBuilder.java | 115 ++++++++++++++++++ .../gui/paper/builder/item/ItemBuilder.java | 20 +++ 19 files changed, 239 insertions(+), 46 deletions(-) rename core/src/main/java/dev/triumphteam/gui/click/handler/{FutureClickHandler.java => CompletableFutureClickHandler.java} (81%) rename core/src/main/java/dev/triumphteam/gui/component/{functional => }/GuiComponentProducer.java (59%) rename core/src/main/java/dev/triumphteam/gui/component/functional/{AbstractFunctionalStateContainer.java => AbstractFunctionalGuiComponent.java} (62%) rename core/src/main/java/dev/triumphteam/gui/component/functional/{FunctionalStateContainer.java => BaseFunctionalGuiComponent.java} (84%) rename core/src/main/java/dev/triumphteam/gui/component/functional/{GuiComponentBuilder.java => FunctionalGuiComponentBuilder.java} (79%) rename core/src/main/java/dev/triumphteam/gui/component/functional/{GuiComponentRender.java => FunctionalGuiComponentRender.java} (84%) create mode 100644 core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java rename paper/src/main/java/dev/triumphteam/gui/paper/builder/{ => gui}/GuiBuilder.java (88%) create mode 100644 paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java create mode 100644 paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java diff --git a/build-logic/src/main/kotlin/gui.base.gradle.kts b/build-logic/src/main/kotlin/gui.base.gradle.kts index 049402f0..ea7030f6 100644 --- a/build-logic/src/main/kotlin/gui.base.gradle.kts +++ b/build-logic/src/main/kotlin/gui.base.gradle.kts @@ -19,7 +19,7 @@ dependencies { java { - toolchain.languageVersion.set(JavaLanguageVersion.of(17)) + toolchain.languageVersion.set(JavaLanguageVersion.of(16)) withSourcesJar() withJavadocJar() } diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 7c910295..d6491a43 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -2,7 +2,7 @@ import dev.triumphteam.gui.Gui; import dev.triumphteam.gui.component.GuiComponent; -import dev.triumphteam.gui.component.functional.GuiComponentBuilder; +import dev.triumphteam.gui.component.functional.FunctionalGuiComponentBuilder; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -16,7 +16,7 @@ public abstract class BaseGuiBuilder, P, G protected final List> componentRenderers = new ArrayList<>(); @Contract("_ -> this") - public @NotNull B component(final @NotNull GuiComponentBuilder builder) { + public @NotNull B component(final @NotNull FunctionalGuiComponentBuilder builder) { final var componentRenderer = new SimpleFunctionalGuiComponent(); builder.accept(componentRenderer); componentRenderers.add(componentRenderer); diff --git a/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java b/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java index 21dc8a29..8d1be3d9 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java +++ b/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java @@ -8,7 +8,7 @@ public final class DeferredClick implements CompletableClick { - private final CompletableFuture deferred = CompletableFuture.completedFuture(null); + private final CompletableFuture deferred = new CompletableFuture<>(); private boolean completingLater = false; public DeferredClick(final @NotNull BiConsumer onComplete) { diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/FutureClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java similarity index 81% rename from core/src/main/java/dev/triumphteam/gui/click/handler/FutureClickHandler.java rename to core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java index 1d103a00..7905ff15 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/FutureClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java @@ -9,12 +9,16 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; -public final class FutureClickHandler

implements ClickHandler

{ +public final class CompletableFutureClickHandler

implements ClickHandler

{ private final long timeout; private final TimeUnit unit; - public FutureClickHandler(final long timeout, final @NotNull TimeUnit unit) { + public CompletableFutureClickHandler() { + this(6, TimeUnit.SECONDS); + } + + public CompletableFutureClickHandler(final long timeout, final @NotNull TimeUnit unit) { this.timeout = timeout; this.unit = unit; } diff --git a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java index a65a2cbc..db993fa3 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java +++ b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java @@ -5,11 +5,11 @@ import dev.triumphteam.gui.AbstractGuiView; import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.completable.DeferredClick; -import kotlin.Unit; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.time.LocalTime; import java.util.UUID; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -18,7 +18,7 @@ public final class ClickProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(ClickProcessor.class); - private final Cache spamPrevention = Caffeine.newBuilder() + private final Cache spamPrevention = Caffeine.newBuilder() .expireAfterWrite(200L, TimeUnit.MILLISECONDS) .build(); @@ -28,7 +28,7 @@ public void processClick(final int slot, final @NotNull AbstractGuiView vi final var viewerUuid = view.viewerUuid(); - if (canClick(viewerUuid)) { + if (!canClick(viewerUuid)) { return; } @@ -69,8 +69,8 @@ private boolean canClick(final @NotNull UUID clickerUuid) { } final var spamming = spamPrevention.getIfPresent(clickerUuid); - if (spamming != null) { - spamPrevention.put(clickerUuid, spamming); + if (spamming == null) { + spamPrevention.put(clickerUuid, LocalTime.now()); return true; } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentProducer.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java similarity index 59% rename from core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentProducer.java rename to core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java index 9eb55c8b..9d37d35c 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentProducer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java @@ -1,6 +1,5 @@ -package dev.triumphteam.gui.component.functional; +package dev.triumphteam.gui.component; -import dev.triumphteam.gui.component.GuiComponent; import org.jetbrains.annotations.NotNull; public interface GuiComponentProducer { diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalStateContainer.java b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java similarity index 62% rename from core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalStateContainer.java rename to core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java index 020b0920..89d2360b 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalStateContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java @@ -1,5 +1,8 @@ package dev.triumphteam.gui.component.functional; +import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.click.handler.CompletableFutureClickHandler; +import dev.triumphteam.gui.click.handler.SimpleClickHandler; import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.State; import dev.triumphteam.gui.state.builtin.EmptyState; @@ -10,10 +13,12 @@ import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; -public abstract class AbstractFunctionalStateContainer implements FunctionalStateContainer { +public abstract class AbstractFunctionalGuiComponent

implements BaseFunctionalGuiComponent

{ private final List states = new ArrayList<>(); + private ClickHandler

clickHandler = null; @Override public @NotNull State state() { @@ -56,6 +61,30 @@ public abstract class AbstractFunctionalStateContainer implements FunctionalStat return state; } + @Override + public void withClickHandler(final @Nullable ClickHandler

clickHandler) { + this.clickHandler = clickHandler; + } + + @Override + public void withSimpleClickHandler() { + this.clickHandler = new SimpleClickHandler<>(); + } + + @Override + public void withCompletableFutureClickHandler() { + this.clickHandler = new CompletableFutureClickHandler<>(); + } + + @Override + public void withCompletableFutureClickHandler(final long timeout, final @NotNull TimeUnit unit) { + this.clickHandler = new CompletableFutureClickHandler<>(timeout, unit); + } + + public @Nullable ClickHandler

getClickHandler() { + return clickHandler; + } + protected @NotNull List getStates() { return states; } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalStateContainer.java b/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java similarity index 84% rename from core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalStateContainer.java rename to core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java index eb0de00b..cfd95ae2 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalStateContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java @@ -1,5 +1,6 @@ package dev.triumphteam.gui.component.functional; +import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.State; import dev.triumphteam.gui.state.builtin.EmptyState; @@ -7,7 +8,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -interface FunctionalStateContainer { +import java.util.concurrent.TimeUnit; + +interface BaseFunctionalGuiComponent

{ /** * Associate am empty {@link State} to the component. @@ -73,4 +76,16 @@ interface FunctionalStateContainer { final @Nullable T value, final @NotNull StateMutationPolicy mutationPolicy ); + + /** + * TODO + * @param clickHandler + */ + void withClickHandler(final @Nullable ClickHandler

clickHandler); + + void withSimpleClickHandler(); + + void withCompletableFutureClickHandler(); + + void withCompletableFutureClickHandler(final long timeout, final @NotNull TimeUnit unit); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java index 1de25c86..bb2c3f86 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java @@ -1,12 +1,10 @@ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.builder.BaseGuiBuilder; -import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * Similar to a {@link GuiComponent} this component will take in states and render a component. @@ -15,9 +13,7 @@ * @param

The player type. * @param The item type. */ -public interface FunctionalGuiComponent extends FunctionalStateContainer { - - void clickHandler(final @Nullable ClickHandler

clickHandler); +public interface FunctionalGuiComponent extends BaseFunctionalGuiComponent

{ /** * A component render function. @@ -25,5 +21,5 @@ public interface FunctionalGuiComponent extends FunctionalStateContainer { * * @param render The component render. */ - void render(final @NotNull GuiComponentRender<@NotNull P, @NotNull I> render); + void render(final @NotNull FunctionalGuiComponentRender<@NotNull P, @NotNull I> render); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentBuilder.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java similarity index 79% rename from core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentBuilder.java rename to core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java index d9620118..6f664084 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java @@ -3,7 +3,7 @@ import org.jetbrains.annotations.NotNull; @FunctionalInterface -public interface GuiComponentBuilder { +public interface FunctionalGuiComponentBuilder { void accept(final @NotNull FunctionalGuiComponent<@NotNull P, @NotNull I> component); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java similarity index 84% rename from core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java rename to core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java index ea5bfd07..dad24086 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/GuiComponentRender.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull; @FunctionalInterface -public interface GuiComponentRender { +public interface FunctionalGuiComponentRender { void render( final @NotNull GuiContainer<@NotNull P, @NotNull I> container, diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index 8ff83ec2..5e74f0bf 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -2,6 +2,7 @@ import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.GuiComponentProducer; import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.exception.GuiException; @@ -11,18 +12,12 @@ import java.util.List; -public final class SimpleFunctionalGuiComponent extends AbstractFunctionalStateContainer implements FunctionalGuiComponent, GuiComponentProducer { +public final class SimpleFunctionalGuiComponent extends AbstractFunctionalGuiComponent

implements FunctionalGuiComponent, GuiComponentProducer { - private GuiComponentRender component = null; - private ClickHandler

clickHandler; + private FunctionalGuiComponentRender component = null; @Override - public void clickHandler(final @Nullable ClickHandler

clickHandler) { - this.clickHandler = clickHandler; - } - - @Override - public void render(final @NotNull GuiComponentRender component) { + public void render(final @NotNull FunctionalGuiComponentRender component) { this.component = component; } @@ -36,7 +31,7 @@ public void render(final @NotNull GuiComponentRender component) { @Override public @Nullable ClickHandler

clickHandler() { - return clickHandler; + return getClickHandler(); } @Override diff --git a/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java new file mode 100644 index 00000000..2eb22db7 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java @@ -0,0 +1,26 @@ +package dev.triumphteam.gui.item.items; + +import dev.triumphteam.gui.click.action.GuiClickAction; +import dev.triumphteam.gui.item.GuiItem; +import org.jetbrains.annotations.NotNull; + +public final class SimpleGuiItem implements GuiItem { + + private final I item; + private final GuiClickAction

clickAction; + + public SimpleGuiItem(final @NotNull I item, final @NotNull GuiClickAction

clickAction) { + this.item = item; + this.clickAction = clickAction; + } + + @Override + public @NotNull I render() { + return item; + } + + @Override + public @NotNull GuiClickAction

getClickAction() { + return clickAction; + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 655679fc..1afb7e8f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,7 @@ caffeine = "3.1.8" logger = "2.0.13" # Minecraft -paper = "1.20.4-R0.1-SNAPSHOT" +paper = "1.16.5-R0.1-SNAPSHOT" [libraries] # Core @@ -20,7 +20,7 @@ caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "c logger = { module = "org.slf4j:slf4j-api", version.ref = "logger" } # Minecraft -paper = { module = "io.papermc.paper:paper-api", version.ref = "paper" } +paper = { module = "com.destroystokyo.paper:paper-api", version.ref = "paper" } # Kotlin coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts index f1497eca..db38d083 100644 --- a/paper/build.gradle.kts +++ b/paper/build.gradle.kts @@ -3,14 +3,10 @@ plugins { } repositories { - maven("https://repo.papermc.io/repository/maven-public/") + maven("https://papermc.io/repo/repository/maven-public/") } dependencies { api(projects.triumphGuiCore) compileOnly(libs.paper) } - -java { - toolchain.languageVersion.set(JavaLanguageVersion.of(17)) -} diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index 04821f98..e86415f0 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -10,15 +10,13 @@ public final class Gui implements dev.triumphteam.gui.Gui { - private final List> components; - static { GuiBukkitListener.register(); } - public Gui( - final @NotNull List> componentRenderers - ) { + private final List> components; + + public Gui(final @NotNull List> componentRenderers) { this.components = componentRenderers.stream().map(SimpleFunctionalGuiComponent::asGuiComponent).toList(); } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/GuiBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java similarity index 88% rename from paper/src/main/java/dev/triumphteam/gui/paper/builder/GuiBuilder.java rename to paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java index af8666eb..7b905355 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/builder/GuiBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.paper.builder; +package dev.triumphteam.gui.paper.builder.gui; import dev.triumphteam.gui.builder.BaseGuiBuilder; import dev.triumphteam.gui.paper.Gui; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java new file mode 100644 index 00000000..c4173368 --- /dev/null +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java @@ -0,0 +1,115 @@ +package dev.triumphteam.gui.paper.builder.item; + +import com.google.common.base.Preconditions; +import dev.triumphteam.gui.click.action.GuiClickAction; +import dev.triumphteam.gui.click.action.RunnableGuiClickAction; +import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.item.items.SimpleGuiItem; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; + +@SuppressWarnings("unchecked") +public abstract class AbstractItemBuilder> { + + private static final EnumSet LEATHER_ARMOR = EnumSet.of( + Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS + ); + + private ItemStack itemStack; + private ItemMeta meta; + + protected AbstractItemBuilder(final @NotNull ItemStack itemStack) { + Preconditions.checkNotNull(itemStack, "Item can't be null!"); + + this.itemStack = itemStack; + meta = itemStack.hasItemMeta() ? itemStack.getItemMeta() : Bukkit.getItemFactory().getItemMeta(itemStack.getType()); + } + + /** + * Sets the display name of the item using {@link Component} + * + * @param name The {@link Component} name + * @return {@link B} + * @since 3.0.0 + */ + @NotNull + @Contract("_ -> this") + public B name(final @NotNull Component name) { + if (meta == null) return (B) this; + + meta.displayName(name); + return (B) this; + } + + /** + * Sets the amount of items + * + * @param amount the amount of items + * @return {@link B} + * @since 3.0.0 + */ + @NotNull + @Contract("_ -> this") + public B amount(final int amount) { + itemStack.setAmount(amount); + return (B) this; + } + + /** + * Set the lore lines of an item + * + * @param lore Lore lines as varargs + * @return {@link B} + * @since 3.0.0 + */ + @NotNull + @Contract("_ -> this") + public B lore(final @Nullable Component @NotNull ... lore) { + return lore(Arrays.asList(lore)); + } + + /** + * Set the lore lines of an item + * + * @param lore A {@link List} with the lore lines + * @return {@link B} + * @since 3.0.0 + */ + @NotNull + @Contract("_ -> this") + public B lore(final @NotNull List<@Nullable Component> lore) { + if (meta == null) return (B) this; + meta.lore(lore); + return (B) this; + } + + @NotNull + @Contract(" -> new") + public ItemStack asItemStack() { + itemStack.setItemMeta(meta); + return itemStack; + } + + @NotNull + @Contract("_ -> new") + public GuiItem asGuiItem(final @NotNull RunnableGuiClickAction action) { + return new SimpleGuiItem<>(asItemStack(), action); + } + + @NotNull + @Contract("_ -> new") + public GuiItem asGuiItem(final @NotNull GuiClickAction action) { + return new SimpleGuiItem<>(asItemStack(), action); + } +} diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java new file mode 100644 index 00000000..7739d81c --- /dev/null +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java @@ -0,0 +1,20 @@ +package dev.triumphteam.gui.paper.builder.item; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +public final class ItemBuilder extends AbstractItemBuilder { + + public ItemBuilder(final @NotNull ItemStack itemStack) { + super(itemStack); + } + + public static ItemBuilder from(final @NotNull ItemStack itemStack) { + return new ItemBuilder(itemStack); + } + + public static ItemBuilder from(final @NotNull Material material) { + return new ItemBuilder(new ItemStack(material)); + } +} From 6f1ee7bacbd5ce4d9afc02321bafbfe236a01cfa Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 6 May 2024 17:56:34 +0100 Subject: [PATCH 13/43] chore: Click fixes and some comments --- .../gui/builder/BaseGuiBuilder.java | 6 +- .../gui/click/action/GuiClickAction.java | 18 +++- .../click/action/RunnableGuiClickAction.java | 17 ++++ ...letableClick.java => ClickController.java} | 5 +- ...Click.java => DefaultClickController.java} | 7 +- .../gui/click/handler/ClickHandler.java | 22 ++++- .../CompletableFutureClickHandler.java | 20 ++-- .../gui/click/handler/SimpleClickHandler.java | 18 +++- .../gui/click/processor/ClickProcessor.java | 96 ++++++++++++++----- .../components/PaginatedComponent.java | 54 ++++++++++- .../SimpleFunctionalGuiComponent.java | 4 +- .../gui/exception/GuiException.java | 10 -- .../gui/exception/TriumphGuiException.java | 10 ++ .../triumphteam/gui/layout/BoxGuiLayout.java | 25 +++++ .../dev/triumphteam/gui/layout/GuiLayout.java | 12 +++ .../java/dev/triumphteam/gui/paper/Gui.java | 5 +- .../gui/paper/builder/gui/GuiBuilder.java | 2 +- 17 files changed, 270 insertions(+), 61 deletions(-) rename core/src/main/java/dev/triumphteam/gui/click/completable/{CompletableClick.java => ClickController.java} (83%) rename core/src/main/java/dev/triumphteam/gui/click/completable/{DeferredClick.java => DefaultClickController.java} (83%) delete mode 100644 core/src/main/java/dev/triumphteam/gui/exception/GuiException.java create mode 100644 core/src/main/java/dev/triumphteam/gui/exception/TriumphGuiException.java create mode 100644 core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java create mode 100644 core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index d6491a43..428bf189 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -13,19 +13,19 @@ @SuppressWarnings({"unchecked", "UnusedReturnValue"}) public abstract class BaseGuiBuilder, P, G extends Gui

, I> { - protected final List> componentRenderers = new ArrayList<>(); + protected final List> components = new ArrayList<>(); @Contract("_ -> this") public @NotNull B component(final @NotNull FunctionalGuiComponentBuilder builder) { final var componentRenderer = new SimpleFunctionalGuiComponent(); builder.accept(componentRenderer); - componentRenderers.add(componentRenderer); + components.add(componentRenderer.asGuiComponent()); return (B) this; } @Contract("_ -> this") public @NotNull B component(final @NotNull GuiComponent component) { - // TODO(matt): Yeah + components.add(component); return (B) this; } diff --git a/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java b/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java index b6f35c14..67b092cd 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java +++ b/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java @@ -1,5 +1,19 @@ package dev.triumphteam.gui.click.action; -public interface GuiClickAction

{ +import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.click.handler.CompletableFutureClickHandler; +import dev.triumphteam.gui.click.handler.SimpleClickHandler; -} +/** + * Represents an action for when a player clicks on the GUI. + * This interface is empty to allow users to implement their own. + * The implementation of the click action is entirely dependent on the + * {@link ClickHandler} used. + * + * @param

The player type. + * @see RunnableGuiClickAction + * @see ClickHandler + * @see SimpleClickHandler + * @see CompletableFutureClickHandler + */ +public interface GuiClickAction

{} diff --git a/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java b/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java index 4c409a62..c3ff7f3c 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java +++ b/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java @@ -1,10 +1,27 @@ package dev.triumphteam.gui.click.action; import dev.triumphteam.gui.click.ClickContext; +import dev.triumphteam.gui.click.handler.CompletableFutureClickHandler; +import dev.triumphteam.gui.click.handler.SimpleClickHandler; import org.jetbrains.annotations.NotNull; +/** + * The main/default click action type. + * A simple {@link Runnable} like functional interface. + * This is by default handled by {@link CompletableFutureClickHandler} and {@link SimpleClickHandler}. + * + * @param

The player type. + * @see SimpleClickHandler + * @see CompletableFutureClickHandler + */ @FunctionalInterface public interface RunnableGuiClickAction

extends GuiClickAction

{ + /** + * Run the click action. + * + * @param player The instance of the player clicking on the GUI. + * @param context The click context. + */ void run(final @NotNull P player, final @NotNull ClickContext context); } diff --git a/core/src/main/java/dev/triumphteam/gui/click/completable/CompletableClick.java b/core/src/main/java/dev/triumphteam/gui/click/completable/ClickController.java similarity index 83% rename from core/src/main/java/dev/triumphteam/gui/click/completable/CompletableClick.java rename to core/src/main/java/dev/triumphteam/gui/click/completable/ClickController.java index 77719312..804c2484 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/completable/CompletableClick.java +++ b/core/src/main/java/dev/triumphteam/gui/click/completable/ClickController.java @@ -2,7 +2,10 @@ import org.jetbrains.annotations.Nullable; -public interface CompletableClick { +/** + * TODO + */ +public interface ClickController { boolean isDone(); diff --git a/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java b/core/src/main/java/dev/triumphteam/gui/click/completable/DefaultClickController.java similarity index 83% rename from core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java rename to core/src/main/java/dev/triumphteam/gui/click/completable/DefaultClickController.java index 8d1be3d9..24931237 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/completable/DeferredClick.java +++ b/core/src/main/java/dev/triumphteam/gui/click/completable/DefaultClickController.java @@ -6,12 +6,15 @@ import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; -public final class DeferredClick implements CompletableClick { +/** + * TODO + */ +public final class DefaultClickController implements ClickController { private final CompletableFuture deferred = new CompletableFuture<>(); private boolean completingLater = false; - public DeferredClick(final @NotNull BiConsumer onComplete) { + public DefaultClickController(final @NotNull BiConsumer onComplete) { deferred.whenComplete(onComplete); } diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java index 4e375b90..7844febf 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java @@ -2,15 +2,33 @@ import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.action.GuiClickAction; -import dev.triumphteam.gui.click.completable.CompletableClick; +import dev.triumphteam.gui.click.completable.ClickController; import org.jetbrains.annotations.NotNull; +/** + * The click handler is responsible for handling a {@link GuiClickAction}. + * This can have many different behaviors, like sync clicks, async clicks, Kotlin suspending clicks, etc. + * It is left to the user to implement other behaviors. + * + * @param

The player instance. + * @see CompletableFutureClickHandler + * @see SimpleClickHandler + * @see GuiClickAction + */ public interface ClickHandler

{ + /** + * Handle the click action given the {@link ClickController}. + * + * @param player The player clicking in the GUI. + * @param context The click context, containing information about the click. + * @param action The action to run. + * @param controller The controller which can be used to control how the click is processed. + */ void handle( final @NotNull P player, final @NotNull ClickContext context, final @NotNull GuiClickAction

action, - final @NotNull CompletableClick deferred + final @NotNull ClickController controller ); } diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java index 7905ff15..a9aa3667 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java @@ -3,12 +3,18 @@ import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.action.GuiClickAction; import dev.triumphteam.gui.click.action.RunnableGuiClickAction; -import dev.triumphteam.gui.click.completable.CompletableClick; +import dev.triumphteam.gui.click.completable.ClickController; +import dev.triumphteam.gui.exception.TriumphGuiException; import org.jetbrains.annotations.NotNull; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +/** + * A {@link ClickHandler} implementation that runs the click action async using {@link CompletableFuture}. + * + * @param

The player type. + */ public final class CompletableFutureClickHandler

implements ClickHandler

{ private final long timeout; @@ -28,17 +34,19 @@ public void handle( final @NotNull P player, final @NotNull ClickContext context, final @NotNull GuiClickAction

action, - final @NotNull CompletableClick deferred + final @NotNull ClickController controller ) { - + // Only accept runnable actions if (!(action instanceof RunnableGuiClickAction

)) { - return; + throw new TriumphGuiException("The click action type '" + action.getClass().getName() + "' is supported by the 'CompletableFutureClickHandler'."); } - deferred.completingLater(true); + // Tell the controller that it'll be complete later as to block all new clicks + controller.completingLater(true); + // Run the action async and complete click when finished CompletableFuture.runAsync(() -> ((RunnableGuiClickAction

) action).run(player, context)) .orTimeout(timeout, unit) - .whenComplete((unused, throwable) -> deferred.complete(throwable)); + .whenComplete((unused, throwable) -> controller.complete(throwable)); } } diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java index c113b46c..52389fe6 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java @@ -3,9 +3,18 @@ import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.action.GuiClickAction; import dev.triumphteam.gui.click.action.RunnableGuiClickAction; -import dev.triumphteam.gui.click.completable.CompletableClick; +import dev.triumphteam.gui.click.completable.ClickController; +import dev.triumphteam.gui.exception.TriumphGuiException; import org.jetbrains.annotations.NotNull; +/** + * The simplest click handler, all it does is run the action given. + * + * @param

The player type. + * @see ClickHandler + * @see GuiClickAction + * @see CompletableFutureClickHandler for async handler. + */ public final class SimpleClickHandler

implements ClickHandler

{ @Override @@ -13,13 +22,14 @@ public void handle( final @NotNull P player, final @NotNull ClickContext context, final @NotNull GuiClickAction

action, - final @NotNull CompletableClick deferred + final @NotNull ClickController controller ) { - + // Only accept runnable actions if (!(action instanceof RunnableGuiClickAction

)) { - return; + throw new TriumphGuiException("The click action type '" + action.getClass().getName() + "' is supported by the 'CompletableFutureClickHandler'."); } + // Run the action ((RunnableGuiClickAction

) action).run(player, context); } } diff --git a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java index db993fa3..07784f64 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java +++ b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java @@ -4,7 +4,9 @@ import com.github.benmanes.caffeine.cache.Caffeine; import dev.triumphteam.gui.AbstractGuiView; import dev.triumphteam.gui.click.ClickContext; -import dev.triumphteam.gui.click.completable.DeferredClick; +import dev.triumphteam.gui.click.action.EmptyGuiClickAction; +import dev.triumphteam.gui.click.completable.DefaultClickController; +import dev.triumphteam.gui.click.handler.ClickHandler; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,38 +14,72 @@ import java.time.LocalTime; import java.util.UUID; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; +/** + * The job of the click processor is to handle everything related to a player clicking on a GUI. + * The processor will only allow one click to go through per time, if a click is taking too long it'll block + * all other clicks from happening. + * This is to prevent unwanted interactions. + *

+ * The processor can also handle cases of players spam clicking. + * The prevention duration can be configured. + * + * @param

The player type. + * @param The item type. + */ public final class ClickProcessor { private static final Logger LOGGER = LoggerFactory.getLogger(ClickProcessor.class); - private final Cache spamPrevention = Caffeine.newBuilder() - .expireAfterWrite(200L, TimeUnit.MILLISECONDS) - .build(); + private final long spamPreventionDuration; + private final Cache spamPrevention; - private final AtomicBoolean isProcessing = new AtomicBoolean(false); + private boolean isProcessing = false; + public ClickProcessor(final long spamPreventionDuration) { + // Cache for spam prevention + this.spamPreventionDuration = spamPreventionDuration; + this.spamPrevention = Caffeine.newBuilder() + .expireAfterWrite(spamPreventionDuration, TimeUnit.MILLISECONDS) + .build(); + } + + /** + * Process the current click. + * Will mark the processor as busy once the click starts then may or may not free it once it's done processing. + * A click can be blocked for a much longer time depending on the {@link ClickHandler} being used. + * + * @param slot The slot being clicked. + * @param view The current view. + */ public void processClick(final int slot, final @NotNull AbstractGuiView view) { final var viewerUuid = view.viewerUuid(); + // Check if the player can currently click if (!canClick(viewerUuid)) { return; } - if (!isProcessing.compareAndSet(false, true)) { + final var renderedItem = view.getItem(slot); + if (renderedItem == null) return; + + final var action = renderedItem.action(); + // Early exit if action is empty + if (action instanceof EmptyGuiClickAction

) { return; } - final var clickContext = new ClickContext(); + // Start processing the click - final var renderedItem = view.getItem(slot); - if (renderedItem == null) return; + this.isProcessing = true; + final var clickContext = new ClickContext(); final var handler = renderedItem.clickHandler(); - final var deferredClick = new DeferredClick((ignored, throwable) -> { + // Prepare the controller with the whenComplete handler + final var clickController = new DefaultClickController((ignored, throwable) -> { + // If something went wrong with the click log the error and stop processing if (throwable != null) { LOGGER.error( "An exception occurred while processing click for '{}' on slot '{}'.", @@ -53,27 +89,43 @@ public void processClick(final int slot, final @NotNull AbstractGuiView vi ); } - this.isProcessing.compareAndSet(true, false); + this.isProcessing = false; }); - handler.handle(view.viewer(), clickContext, renderedItem.action(), deferredClick); + // The handler needs to catch so the click can finish + // The exception is passed to the controller and still logged + Exception handledException = null; + try { + handler.handle(view.viewer(), clickContext, renderedItem.action(), clickController); + } catch (final Exception exception) { + handledException = exception; + } - if (!deferredClick.completingLater()) { - deferredClick.complete(null); + // If not completing later makes sure to immediately complete it + if (!clickController.completingLater()) { + clickController.complete(handledException); } } + /** + * Checks if the player can currently click on the GUI. + * + * @param clickerUuid The UUID of the clicker. + * @return True if the processor is not busy and not timed out from spamming. + */ private boolean canClick(final @NotNull UUID clickerUuid) { - if (isProcessing.get()) { - return false; - } - final var spamming = spamPrevention.getIfPresent(clickerUuid); - if (spamming == null) { + // If spam prevention is disabled, ignore it + if (spamPreventionDuration != 0) { + final var spamming = spamPrevention.getIfPresent(clickerUuid); + if (spamming != null) { + return false; + } + spamPrevention.put(clickerUuid, LocalTime.now()); - return true; } - return false; + // Check if the processor is not currently busy + return !isProcessing; } } diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java index 14f1f1bf..ff30bfb3 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java @@ -1,27 +1,75 @@ package dev.triumphteam.gui.component.components; +import dev.triumphteam.gui.click.action.RunnableGuiClickAction; import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; +import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.item.items.SimpleGuiItem; +import dev.triumphteam.gui.layout.GuiLayout; +import dev.triumphteam.gui.slot.Slot; +import dev.triumphteam.gui.state.MutableState; import dev.triumphteam.gui.state.State; +import dev.triumphteam.gui.state.builtin.SimpleMutableState; +import dev.triumphteam.gui.state.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; import java.util.List; public final class PaginatedComponent implements ReactiveGuiComponent { - private final List items; + private final Slot back; + private final I backItem; + private final Slot forward; + private final I forwardItem; + private final List> items; + private final GuiLayout layout; - public PaginatedComponent(final @NotNull List items) { + private final MutableState pageState = new SimpleMutableState<>(0, StateMutationPolicy.StructuralEquality.INSTANCE); + + public PaginatedComponent( + final @NotNull Slot back, + final @NotNull I backItem, + final @NotNull Slot forward, + final @NotNull I forwardItem, + final @NotNull List> items, + final @NotNull GuiLayout layout + ) { + this.back = back; + this.backItem = backItem; + this.forward = forward; + this.forwardItem = forwardItem; this.items = items; + this.layout = layout; } @Override public @NotNull List<@NotNull State> states() { - return List.of(); + return List.of(pageState); } @Override public void render(final @NotNull GuiContainer container, @NotNull final P player) { + final var page = pageState.getValue(); + + container.set(back, new SimpleGuiItem<>(backItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.setValue(page - 1))); + container.set(forward, new SimpleGuiItem<>(forwardItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.setValue(page + 1))); + + final var slots = layout.generatePositions(); + final var size = slots.size(); + + final var offset = page * size; + + for (int i = 0; i < size; i++) { + final var offsetSlot = offset + i; + + /*if (offsetSlot >= items.size() || offsetSlot < 0) { + return; + }*/ + + final var slot = slots.get(i); + final var item = items.get(offsetSlot); + container.set(slot, item); + } } } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index 5e74f0bf..cf4debc1 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -5,7 +5,7 @@ import dev.triumphteam.gui.component.GuiComponentProducer; import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; -import dev.triumphteam.gui.exception.GuiException; +import dev.triumphteam.gui.exception.TriumphGuiException; import dev.triumphteam.gui.state.State; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,7 +24,7 @@ public void render(final @NotNull FunctionalGuiComponentRender component) @Override public @NotNull GuiComponent asGuiComponent() { if (component == null) { - throw new GuiException("TODO"); + throw new TriumphGuiException("TODO"); } return new ReactiveGuiComponent<>() { diff --git a/core/src/main/java/dev/triumphteam/gui/exception/GuiException.java b/core/src/main/java/dev/triumphteam/gui/exception/GuiException.java deleted file mode 100644 index f3bc47fe..00000000 --- a/core/src/main/java/dev/triumphteam/gui/exception/GuiException.java +++ /dev/null @@ -1,10 +0,0 @@ -package dev.triumphteam.gui.exception; - -import org.jetbrains.annotations.NotNull; - -public final class GuiException extends RuntimeException { - - public GuiException(final @NotNull String message) { - super(message); - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/exception/TriumphGuiException.java b/core/src/main/java/dev/triumphteam/gui/exception/TriumphGuiException.java new file mode 100644 index 00000000..a8f3a841 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/exception/TriumphGuiException.java @@ -0,0 +1,10 @@ +package dev.triumphteam.gui.exception; + +import org.jetbrains.annotations.NotNull; + +public final class TriumphGuiException extends RuntimeException { + + public TriumphGuiException(final @NotNull String message) { + super(message); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java new file mode 100644 index 00000000..3e932471 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java @@ -0,0 +1,25 @@ +package dev.triumphteam.gui.layout; + +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public final class BoxGuiLayout implements GuiLayout { + + private final List slots = new ArrayList<>(); + + public BoxGuiLayout(final int minRow, final int minCol, final int maxRow, final int maxCol) { + for (int row = minRow; row <= maxRow; row++) { + for (int col = minCol; col <= maxCol; col++) { + slots.add(new Slot(Slot.fromRowCol(row, col))); + } + } + } + + @Override + public @NotNull List<@NotNull Slot> generatePositions() { + return slots; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java new file mode 100644 index 00000000..0e4f3952 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java @@ -0,0 +1,12 @@ +package dev.triumphteam.gui.layout; + +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface GuiLayout { + + @NotNull + List<@NotNull Slot> generatePositions(); +} diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index e86415f0..fe25957a 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -1,7 +1,6 @@ package dev.triumphteam.gui.paper; import dev.triumphteam.gui.component.GuiComponent; -import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -16,8 +15,8 @@ public final class Gui implements dev.triumphteam.gui.Gui { private final List> components; - public Gui(final @NotNull List> componentRenderers) { - this.components = componentRenderers.stream().map(SimpleFunctionalGuiComponent::asGuiComponent).toList(); + public Gui(final @NotNull List> components) { + this.components = components; } @Override diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java index 7b905355..37f212e0 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java @@ -9,6 +9,6 @@ public final class GuiBuilder extends BaseGuiBuilder Date: Tue, 7 May 2024 19:15:28 +0100 Subject: [PATCH 14/43] feature: Container types --- core/build.gradle.kts | 6 +- .../dev/triumphteam/gui/AbstractGuiView.java | 23 ++- .../gui/builder/BaseGuiBuilder.java | 152 +++++++++++++++++- .../ClickController.java | 2 +- .../DefaultClickController.java | 2 +- .../gui/click/handler/ClickHandler.java | 2 +- .../CompletableFutureClickHandler.java | 2 +- .../gui/click/handler/SimpleClickHandler.java | 2 +- .../gui/click/processor/ClickProcessor.java | 14 +- .../gui/component/RenderedComponent.java | 3 +- .../renderer/DefaultGuiComponentRenderer.java | 3 +- .../gui/container/GuiContainer.java | 1 + .../gui/container/GuiContainerType.java | 10 -- .../gui/container/MapBackedContainer.java | 23 ++- .../gui/container/type/GuiContainerType.java | 11 ++ .../triumphteam/gui/layout/BoxGuiLayout.java | 8 +- .../triumphteam/gui/settings/GuiSettings.java | 46 ++++++ .../java/dev/triumphteam/gui/slot/Slot.java | 6 +- .../gui/state/StateListenerContainer.java | 6 +- gradle/libs.versions.toml | 6 +- .../triumphteam/gui/paper/BukkitGuiView.java | 30 ++-- .../java/dev/triumphteam/gui/paper/Gui.java | 27 ---- .../gui/paper/GuiBukkitListener.java | 7 +- .../dev/triumphteam/gui/paper/PaperGui.java | 58 +++++++ .../gui/paper/PaperGuiSettings.java | 41 +++++ .../gui/paper/builder/gui/GuiBuilder.java | 36 ++++- .../container/type/ChestContainerType.java | 52 ++++++ .../container/type/PaperContainerType.java | 16 ++ 28 files changed, 491 insertions(+), 104 deletions(-) rename core/src/main/java/dev/triumphteam/gui/click/{completable => controller}/ClickController.java (84%) rename core/src/main/java/dev/triumphteam/gui/click/{completable => controller}/DefaultClickController.java (96%) delete mode 100644 core/src/main/java/dev/triumphteam/gui/container/GuiContainerType.java create mode 100644 core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java create mode 100644 core/src/main/java/dev/triumphteam/gui/settings/GuiSettings.java delete mode 100644 paper/src/main/java/dev/triumphteam/gui/paper/Gui.java create mode 100644 paper/src/main/java/dev/triumphteam/gui/paper/PaperGui.java create mode 100644 paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java create mode 100644 paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java create mode 100644 paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 7c52f9d4..9681e165 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -3,6 +3,8 @@ plugins { } dependencies { - implementation(libs.caffeine) - compileOnly(libs.logger) + compileOnlyApi(libs.guava) + compileOnlyApi(libs.adventure.api) + + compileOnlyApi(libs.logger) } diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 2bed64b9..0dac8c4b 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -6,8 +6,8 @@ import dev.triumphteam.gui.component.RenderedComponent; import dev.triumphteam.gui.component.StatefulGuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; +import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.item.RenderedGuiItem; -import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -22,24 +22,29 @@ public abstract class AbstractGuiView implements GuiView { private final List> components; private final GuiComponentRenderer renderer; private final ClickHandler

defaultClickHandler; + private final GuiContainerType containerType; // Click processor - private final ClickProcessor clickProcessor = new ClickProcessor<>(); + private final ClickProcessor clickProcessor; // Cache of rendered components private final Map, RenderedComponent> renderedComponents = new ConcurrentHashMap<>(); // All the gui items that have been rendered and are in the inventory - private final Map> allRenderedItems = new ConcurrentHashMap<>(); + private final Map> allRenderedItems = new ConcurrentHashMap<>(); public AbstractGuiView( final @NotNull P viewer, final @NotNull List<@NotNull GuiComponent> components, + final @NotNull GuiContainerType containerType, final @NotNull GuiComponentRenderer renderer, - final @NotNull ClickHandler

defaultClickHandler + final @NotNull ClickHandler

defaultClickHandler, + final @NotNull ClickProcessor clickProcessor ) { this.viewer = viewer; this.components = components; + this.containerType = containerType; this.renderer = renderer; this.defaultClickHandler = defaultClickHandler; + this.clickProcessor = clickProcessor; } public @NotNull P viewer() { @@ -50,9 +55,9 @@ public AbstractGuiView( public abstract @NotNull UUID viewerUuid(); - protected abstract void clearSlot(final @NotNull Slot slot); + protected abstract void clearSlot(final int slot); - protected abstract void populateInventory(final @NotNull Map<@NotNull Slot, @NotNull RenderedGuiItem> renderedItems); + protected abstract void populateInventory(final @NotNull Map> renderedItems); protected void setup() { components.forEach(component -> { @@ -94,10 +99,14 @@ public void completeRendered(final @NotNull RenderedComponent renderedComp } public @Nullable RenderedGuiItem getItem(final int slot) { - return allRenderedItems.get(new Slot(slot)); + return allRenderedItems.get(slot); } public @NotNull ClickHandler

getDefaultClickHandler() { return defaultClickHandler; } + + public @NotNull GuiContainerType getContainerType() { + return containerType; + } } diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 428bf189..12bab9cd 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,20 +1,117 @@ package dev.triumphteam.gui.builder; import dev.triumphteam.gui.Gui; +import dev.triumphteam.gui.GuiView; +import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.GuiComponentProducer; +import dev.triumphteam.gui.component.functional.FunctionalGuiComponent; import dev.triumphteam.gui.component.functional.FunctionalGuiComponentBuilder; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; +import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; +import dev.triumphteam.gui.container.type.GuiContainerType; +import dev.triumphteam.gui.exception.TriumphGuiException; +import dev.triumphteam.gui.settings.GuiSettings; +import net.kyori.adventure.text.Component; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; +/** + * Main builder for all GUIs. + * Container the main base methods that are shared between all implementations. + * + * @param The implementation of this {@link BaseGuiBuilder}. + * @param

The player type. + * @param The {@link Gui} type. + * @param The item type. + */ @SuppressWarnings({"unchecked", "UnusedReturnValue"}) public abstract class BaseGuiBuilder, P, G extends Gui

, I> { - protected final List> components = new ArrayList<>(); + private final GuiSettings guiSettings; + private final GuiContainerType containerType; + private final List> components = new ArrayList<>(); + private ClickHandler

clickHandler = null; + private GuiComponentRenderer componentRenderer = null; + private Component title = null; + private long spamPreventionDuration = -1; + + public BaseGuiBuilder( + final GuiSettings guiSettings, + final @NotNull GuiContainerType containerType + ) { + this.guiSettings = guiSettings; + this.containerType = containerType; + } + + /** + * Sets the title of the {@link GuiView}. + * + * @param title The title {@link Component}. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ + @Contract("_ -> this") + public @NotNull B title(final @NotNull Component title) { + this.title = title; + return (B) this; + } + + /** + * Sets the {@link ClickHandler} to be used for all {@link GuiComponent} unless they provide their own. + * + * @param clickHandler The default {@link ClickHandler}. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ + @Contract("_ -> this") + public @NotNull B clickHandler(final @NotNull ClickHandler

clickHandler) { + this.clickHandler = clickHandler; + return (B) this; + } + + /** + * Sets the {@link GuiComponentRenderer} to be used by the {@link Gui}. + * + * @param componentRenderer The {@link GuiComponentRenderer} to use. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ + @Contract("_ -> this") + public @NotNull B componentRenderer(final @NotNull GuiComponentRenderer componentRenderer) { + this.componentRenderer = componentRenderer; + return (B) this; + } + + /** + * Sets how long the spam prevention should be, in {@link TimeUnit#MILLISECONDS}. + * Set it to {@code 0} to disable it altogether. + * + * @param spamPreventionDuration How long the spam prevention should last. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ + @Contract("_ -> this") + public @NotNull B spamPreventionDuration(final long spamPreventionDuration) { + if (spamPreventionDuration < 0) { + throw new TriumphGuiException("Spam prevention duration cannot be negative!"); + } + + this.spamPreventionDuration = spamPreventionDuration; + return (B) this; + } + + /** + * Adds a {@link GuiComponent} to the {@link Gui}. + *

+ * The {@link FunctionalGuiComponentBuilder} will create a {@link FunctionalGuiComponent}, + * which by itself is NOT a {@link GuiComponent} but instead a {@link GuiComponentProducer}.

+ * This will in turn build a real {@link GuiComponent} before being added to the {@link Gui}. + * + * @param builder The functional component builder. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ @Contract("_ -> this") public @NotNull B component(final @NotNull FunctionalGuiComponentBuilder builder) { final var componentRenderer = new SimpleFunctionalGuiComponent(); @@ -23,11 +120,64 @@ public abstract class BaseGuiBuilder, P, G return (B) this; } + /** + * Adds a {@link GuiComponent} to the {@link Gui}. + * + * @param component Any type of {@link GuiComponent}. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ @Contract("_ -> this") public @NotNull B component(final @NotNull GuiComponent component) { components.add(component); return (B) this; } + /** + * Finalizes the builder and creates a {@link G} instance of {@link Gui} depending on the platform. + * + * @return {@link G} which is a {@link Gui}. + */ public abstract G build(); + + // ---------------- Internal getters ---------------- // + + protected @NotNull GuiContainerType getContainerType() { + return containerType; + } + + protected @NotNull List> getComponents() { + return components; + } + + protected @NotNull ClickHandler

getClickHandler() { + if (clickHandler == null) { + return guiSettings.getClickHandler(); + } + + return clickHandler; + } + + protected @NotNull GuiComponentRenderer getComponentRenderer() { + if (componentRenderer == null) { + return guiSettings.getComponentRenderer(); + } + + return componentRenderer; + } + + protected @NotNull Component getTitle() { + if (title == null) { + throw new TriumphGuiException("Cannot create GUI with empty title!"); + } + + return title; + } + + protected long getSpamPreventionDuration() { + if (spamPreventionDuration < 0) { + return guiSettings.getSpamPreventionDuration(); + } + + return spamPreventionDuration; + } } diff --git a/core/src/main/java/dev/triumphteam/gui/click/completable/ClickController.java b/core/src/main/java/dev/triumphteam/gui/click/controller/ClickController.java similarity index 84% rename from core/src/main/java/dev/triumphteam/gui/click/completable/ClickController.java rename to core/src/main/java/dev/triumphteam/gui/click/controller/ClickController.java index 804c2484..f5af8586 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/completable/ClickController.java +++ b/core/src/main/java/dev/triumphteam/gui/click/controller/ClickController.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.click.completable; +package dev.triumphteam.gui.click.controller; import org.jetbrains.annotations.Nullable; diff --git a/core/src/main/java/dev/triumphteam/gui/click/completable/DefaultClickController.java b/core/src/main/java/dev/triumphteam/gui/click/controller/DefaultClickController.java similarity index 96% rename from core/src/main/java/dev/triumphteam/gui/click/completable/DefaultClickController.java rename to core/src/main/java/dev/triumphteam/gui/click/controller/DefaultClickController.java index 24931237..ca05729c 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/completable/DefaultClickController.java +++ b/core/src/main/java/dev/triumphteam/gui/click/controller/DefaultClickController.java @@ -1,4 +1,4 @@ -package dev.triumphteam.gui.click.completable; +package dev.triumphteam.gui.click.controller; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java index 7844febf..2afda3a2 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java @@ -2,7 +2,7 @@ import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.action.GuiClickAction; -import dev.triumphteam.gui.click.completable.ClickController; +import dev.triumphteam.gui.click.controller.ClickController; import org.jetbrains.annotations.NotNull; /** diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java index a9aa3667..3b6e53c1 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java @@ -3,7 +3,7 @@ import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.action.GuiClickAction; import dev.triumphteam.gui.click.action.RunnableGuiClickAction; -import dev.triumphteam.gui.click.completable.ClickController; +import dev.triumphteam.gui.click.controller.ClickController; import dev.triumphteam.gui.exception.TriumphGuiException; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java index 52389fe6..b4dbe7f4 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java @@ -3,7 +3,7 @@ import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.action.GuiClickAction; import dev.triumphteam.gui.click.action.RunnableGuiClickAction; -import dev.triumphteam.gui.click.completable.ClickController; +import dev.triumphteam.gui.click.controller.ClickController; import dev.triumphteam.gui.exception.TriumphGuiException; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java index 07784f64..2df1e299 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java +++ b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java @@ -1,11 +1,11 @@ package dev.triumphteam.gui.click.processor; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import dev.triumphteam.gui.AbstractGuiView; import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.action.EmptyGuiClickAction; -import dev.triumphteam.gui.click.completable.DefaultClickController; +import dev.triumphteam.gui.click.controller.DefaultClickController; import dev.triumphteam.gui.click.handler.ClickHandler; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; @@ -17,7 +17,7 @@ /** * The job of the click processor is to handle everything related to a player clicking on a GUI. - * The processor will only allow one click to go through per time, if a click is taking too long it'll block + * The processor will only allow one click to go through per time, if a click is taking too long, it'll block * all other clicks from happening. * This is to prevent unwanted interactions. *

@@ -39,7 +39,7 @@ public final class ClickProcessor { public ClickProcessor(final long spamPreventionDuration) { // Cache for spam prevention this.spamPreventionDuration = spamPreventionDuration; - this.spamPrevention = Caffeine.newBuilder() + this.spamPrevention = CacheBuilder.newBuilder() .expireAfterWrite(spamPreventionDuration, TimeUnit.MILLISECONDS) .build(); } @@ -79,7 +79,7 @@ public void processClick(final int slot, final @NotNull AbstractGuiView vi // Prepare the controller with the whenComplete handler final var clickController = new DefaultClickController((ignored, throwable) -> { - // If something went wrong with the click log the error and stop processing + // If something went wrong with the click log, the error and stop processing if (throwable != null) { LOGGER.error( "An exception occurred while processing click for '{}' on slot '{}'.", @@ -96,7 +96,7 @@ public void processClick(final int slot, final @NotNull AbstractGuiView vi // The exception is passed to the controller and still logged Exception handledException = null; try { - handler.handle(view.viewer(), clickContext, renderedItem.action(), clickController); + handler.handle(view.viewer(), clickContext, action, clickController); } catch (final Exception exception) { handledException = exception; } diff --git a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java index 43fd582c..89eff52d 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java @@ -1,13 +1,12 @@ package dev.triumphteam.gui.component; import dev.triumphteam.gui.item.RenderedGuiItem; -import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; import java.util.Map; public record RenderedComponent( @NotNull GuiComponent component, - @NotNull Map> renderedItems + @NotNull Map> renderedItems ) { } diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java index 3bc33b2f..6d65bd3c 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java @@ -18,7 +18,8 @@ public void renderComponent( final var componentClickHandler = component.clickHandler(); final var container = new MapBackedContainer( - componentClickHandler == null ? view.getDefaultClickHandler() : componentClickHandler + componentClickHandler == null ? view.getDefaultClickHandler() : componentClickHandler, + view.getContainerType() ); if (component instanceof ReactiveGuiComponent) { diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java index 6a908295..78affb0f 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -1,5 +1,6 @@ package dev.triumphteam.gui.container; +import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.item.GuiItem; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainerType.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainerType.java deleted file mode 100644 index 8d55ad2d..00000000 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainerType.java +++ /dev/null @@ -1,10 +0,0 @@ -package dev.triumphteam.gui.container; - -public enum GuiContainerType { - - CHEST, - CHEST_COMBINED, - - ; - -} diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index cb7e6431..e326d037 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -1,6 +1,7 @@ package dev.triumphteam.gui.container; import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.item.GuiItem; import dev.triumphteam.gui.item.RenderedGuiItem; import dev.triumphteam.gui.slot.Slot; @@ -12,11 +13,16 @@ public final class MapBackedContainer implements GuiContainer { - private final Map> backing = new HashMap<>(100); + private final Map> backing = new HashMap<>(100); private final ClickHandler

clickHandler; + private final GuiContainerType containerType; - public MapBackedContainer(final @NotNull ClickHandler

clickHandler) { + public MapBackedContainer( + final @NotNull ClickHandler

clickHandler, + final @NotNull GuiContainerType containerType + ) { this.clickHandler = clickHandler; + this.containerType = containerType; } @Override @@ -25,24 +31,25 @@ public MapBackedContainer(final @NotNull ClickHandler

clickHandler) { } @Override - public void set(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { - set(new Slot(slot), guiItem); + public void set(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { + set(containerType.mapSlot(Slot.of(row, column)), guiItem); } @Override - public void set(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { - set(Slot.fromRowCol(row, column), guiItem); + public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { + set(containerType.mapSlot(slot), guiItem); } @Override - public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { + public void set(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { + // TODO VALIDATE SLOT HERE TOO // Render item final var renderedItem = new RenderedGuiItem<>(guiItem.render(), clickHandler, guiItem.getClickAction()); // Add rendered to backing backing.put(slot, renderedItem); } - public @NotNull Map> complete() { + public @NotNull Map> complete() { return Collections.unmodifiableMap(backing); } } diff --git a/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java b/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java new file mode 100644 index 00000000..5503c843 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java @@ -0,0 +1,11 @@ +package dev.triumphteam.gui.container.type; + +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +public interface GuiContainerType { + + int mapSlot(final @NotNull Slot slot); + + Slot mapSlot(final int slot); +} diff --git a/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java index 3e932471..5abecf99 100644 --- a/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java +++ b/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java @@ -10,10 +10,10 @@ public final class BoxGuiLayout implements GuiLayout { private final List slots = new ArrayList<>(); - public BoxGuiLayout(final int minRow, final int minCol, final int maxRow, final int maxCol) { - for (int row = minRow; row <= maxRow; row++) { - for (int col = minCol; col <= maxCol; col++) { - slots.add(new Slot(Slot.fromRowCol(row, col))); + public BoxGuiLayout(final @NotNull Slot min, final @NotNull Slot max) { + for (int row = min.row(); row <= max.row(); row++) { + for (int col = min.column(); col <= max.column(); col++) { + slots.add(Slot.of(row, col)); } } } diff --git a/core/src/main/java/dev/triumphteam/gui/settings/GuiSettings.java b/core/src/main/java/dev/triumphteam/gui/settings/GuiSettings.java new file mode 100644 index 00000000..bcbe86f5 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/settings/GuiSettings.java @@ -0,0 +1,46 @@ +package dev.triumphteam.gui.settings; + +import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.click.handler.SimpleClickHandler; +import dev.triumphteam.gui.component.renderer.DefaultGuiComponentRenderer; +import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("unchecked") +public abstract class GuiSettings> { + + private ClickHandler

clickHandler = new SimpleClickHandler<>(); + private GuiComponentRenderer componentRenderer = new DefaultGuiComponentRenderer<>(); + private long spamPreventionDuration = 200L; + + public S clickHandler(final @NotNull ClickHandler

clickHandler) { + this.clickHandler = clickHandler; + return (S) this; + } + + public S componentRenderer(final @NotNull GuiComponentRenderer componentRenderer) { + this.componentRenderer = componentRenderer; + return (S) this; + } + + public S spamPreventionDuration(final long spamPreventionDuration) { + if (spamPreventionDuration < 0L) { + throw new IllegalArgumentException("Spam prevention duration cannot be negative!"); + } + + this.spamPreventionDuration = spamPreventionDuration; + return (S) this; + } + + public @NotNull ClickHandler

getClickHandler() { + return clickHandler; + } + + public @NotNull GuiComponentRenderer getComponentRenderer() { + return componentRenderer; + } + + public long getSpamPreventionDuration() { + return spamPreventionDuration; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java index 1978f329..83d7dfea 100644 --- a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java +++ b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java @@ -1,8 +1,8 @@ package dev.triumphteam.gui.slot; -public record Slot(int slot) { +public record Slot(int row, int column) { - public static int fromRowCol(final int row, final int column) { - return (column + (row - 1) * 9) - 1; + public static Slot of(final int row, final int column) { + return new Slot(row, column); } } diff --git a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java index 3438a485..8b770736 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java @@ -1,7 +1,7 @@ package dev.triumphteam.gui.state; -import com.github.benmanes.caffeine.cache.Cache; -import com.github.benmanes.caffeine.cache.Caffeine; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; import dev.triumphteam.gui.GuiView; import org.jetbrains.annotations.NotNull; @@ -29,7 +29,7 @@ public final class StateListenerContainer { * @return A {@link java.util.concurrent.ConcurrentMap} with weak keys. */ private static Map, Queue> createListenerMap() { - final Cache, Queue> cache = Caffeine.newBuilder() + final Cache, Queue> cache = CacheBuilder.newBuilder() .weakKeys() .build(); diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1afb7e8f..71e86f6e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,20 +7,22 @@ license = "0.16.1" # Core annotations = "24.1.0" -caffeine = "3.1.8" +guava = "33.2.0-jre" logger = "2.0.13" # Minecraft +adventure = "4.16.0" paper = "1.16.5-R0.1-SNAPSHOT" [libraries] # Core annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" } -caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" } +guava = { module = "com.google.guava:guava", version.ref = "guava" } logger = { module = "org.slf4j:slf4j-api", version.ref = "logger" } # Minecraft paper = { module = "com.destroystokyo.paper:paper-api", version.ref = "paper" } +adventure-api = { module = "net.kyori:adventure-api", version.ref = "adventure" } # Kotlin coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java b/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java index 986bcad8..791a530d 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java @@ -1,12 +1,13 @@ package dev.triumphteam.gui.paper; import dev.triumphteam.gui.AbstractGuiView; -import dev.triumphteam.gui.click.handler.SimpleClickHandler; +import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.click.processor.ClickProcessor; import dev.triumphteam.gui.component.GuiComponent; -import dev.triumphteam.gui.component.renderer.DefaultGuiComponentRenderer; +import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; import dev.triumphteam.gui.item.RenderedGuiItem; -import dev.triumphteam.gui.slot.Slot; -import org.bukkit.Bukkit; +import dev.triumphteam.gui.paper.container.type.PaperContainerType; +import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; @@ -23,12 +24,15 @@ public final class BukkitGuiView extends AbstractGuiView impl public BukkitGuiView( final @NotNull Player player, - final @NotNull List> components + final @NotNull Component title, + final @NotNull PaperContainerType containerType, + final @NotNull List> components, + final @NotNull GuiComponentRenderer componentRenderer, + final @NotNull ClickHandler clickHandler, + final long spamPreventionDuration ) { - // TODO(matt): Renderer from constructor - super(player, components, new DefaultGuiComponentRenderer<>(), new SimpleClickHandler<>()); - - this.inventory = Bukkit.createInventory(this, 54, "Gui"); + super(player, components, containerType, componentRenderer, clickHandler, new ClickProcessor<>(spamPreventionDuration)); + this.inventory = containerType.createInventory(this, title); } @Override @@ -49,8 +53,8 @@ public Inventory getInventory() { } @Override - protected void clearSlot(final @NotNull Slot slot) { - inventory.clear(slot.slot()); + protected void clearSlot(final int slot) { + inventory.clear(slot); } @Override @@ -64,7 +68,7 @@ protected void clearSlot(final @NotNull Slot slot) { } @Override - protected void populateInventory(final @NotNull Map> renderedItems) { - renderedItems.forEach((slot, item) -> inventory.setItem(slot.slot(), item.item())); + protected void populateInventory(final @NotNull Map> renderedItems) { + renderedItems.forEach((slot, item) -> inventory.setItem(slot, item.item())); } } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java deleted file mode 100644 index fe25957a..00000000 --- a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ /dev/null @@ -1,27 +0,0 @@ -package dev.triumphteam.gui.paper; - -import dev.triumphteam.gui.component.GuiComponent; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public final class Gui implements dev.triumphteam.gui.Gui { - - static { - GuiBukkitListener.register(); - } - - private final List> components; - - public Gui(final @NotNull List> components) { - this.components = components; - } - - @Override - public void open(final @NotNull Player player) { - final var view = new BukkitGuiView(player, components); - view.open(); - } -} diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java index 2fc8de4f..fc92121c 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java @@ -1,18 +1,15 @@ package dev.triumphteam.gui.paper; -import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; public final class GuiBukkitListener implements Listener { - private static final Plugin plugin = JavaPlugin.getProvidingPlugin(GuiBukkitListener.class); - public static void register() { - Bukkit.getServer().getPluginManager().registerEvents(new GuiBukkitListener(), plugin); + // Auto-register listener if none was registered yet + PaperGuiSettings.get().register(JavaPlugin.getProvidingPlugin(GuiBukkitListener.class)); } @EventHandler diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGui.java b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGui.java new file mode 100644 index 00000000..40636bc6 --- /dev/null +++ b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGui.java @@ -0,0 +1,58 @@ +package dev.triumphteam.gui.paper; + +import dev.triumphteam.gui.Gui; +import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.component.GuiComponent; +import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; +import dev.triumphteam.gui.paper.container.type.PaperContainerType; +import net.kyori.adventure.text.Component; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public final class PaperGui implements Gui { + + static { + GuiBukkitListener.register(); + } + + private final Component title; + private final List> components; + private final PaperContainerType containerType; + private final GuiComponentRenderer componentRenderer; + private final ClickHandler clickHandler; + private final long spamPreventionDuration; + + public PaperGui( + final @NotNull Component title, + final @NotNull List> components, + final @NotNull PaperContainerType containerType, + final @NotNull GuiComponentRenderer componentRenderer, + final @NotNull ClickHandler clickHandler, + final long spamPreventionDuration + ) { + this.title = title; + this.components = components; + this.containerType = containerType; + this.componentRenderer = componentRenderer; + this.clickHandler = clickHandler; + this.spamPreventionDuration = spamPreventionDuration; + } + + @Override + public void open(final @NotNull Player player) { + final var view = new BukkitGuiView( + player, + title, + containerType, + components, + componentRenderer, + clickHandler, + spamPreventionDuration + ); + + view.open(); + } +} diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java new file mode 100644 index 00000000..8ede98dd --- /dev/null +++ b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java @@ -0,0 +1,41 @@ +package dev.triumphteam.gui.paper; + +import dev.triumphteam.gui.exception.TriumphGuiException; +import dev.triumphteam.gui.settings.GuiSettings; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +public final class PaperGuiSettings extends GuiSettings { + + private static final PaperGuiSettings INSTANCE = new PaperGuiSettings(); + + private boolean listenerRegistered = false; + private Plugin plugin = null; + + private PaperGuiSettings() {} + + public static PaperGuiSettings get() { + return INSTANCE; + } + + public PaperGuiSettings register(final @NotNull Plugin plugin) { + // Only register listener once + if (this.listenerRegistered) return this; + + this.plugin = plugin; + Bukkit.getServer().getPluginManager().registerEvents(new GuiBukkitListener(), plugin); + this.listenerRegistered = true; + return this; + } + + public @NotNull Plugin getPlugin() { + if (plugin == null) { + throw new TriumphGuiException("An error occurred while attempting to get the plugin instance."); + } + + return plugin; + } +} diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java index 37f212e0..f569ba2b 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java @@ -1,14 +1,42 @@ package dev.triumphteam.gui.paper.builder.gui; import dev.triumphteam.gui.builder.BaseGuiBuilder; -import dev.triumphteam.gui.paper.Gui; +import dev.triumphteam.gui.container.type.GuiContainerType; +import dev.triumphteam.gui.paper.PaperGui; +import dev.triumphteam.gui.paper.PaperGuiSettings; +import dev.triumphteam.gui.paper.container.type.ChestContainerType; +import dev.triumphteam.gui.paper.container.type.PaperContainerType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; -public final class GuiBuilder extends BaseGuiBuilder { +public final class GuiBuilder extends BaseGuiBuilder { + + public GuiBuilder(final @NotNull GuiContainerType containerType) { + super(PaperGuiSettings.get(), containerType); + } + + public static @NotNull GuiBuilder gui(final @NotNull GuiContainerType type) { + return new GuiBuilder(type); + } + + public static @NotNull GuiBuilder gui(final int rows) { + return gui(ChestContainerType.of(rows)); + } @Override - public Gui build() { - return new Gui(components); + public PaperGui build() { + if (!(getContainerType() instanceof final PaperContainerType paperContainerType)) { + throw new IllegalArgumentException("Container type provided is not supported on Paper platform!"); + } + + return new PaperGui( + getTitle(), + getComponents(), + paperContainerType, + getComponentRenderer(), + getClickHandler(), + getSpamPreventionDuration() + ); } } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java new file mode 100644 index 00000000..01ee456e --- /dev/null +++ b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java @@ -0,0 +1,52 @@ +package dev.triumphteam.gui.paper.container.type; + +import dev.triumphteam.gui.container.type.GuiContainerType; +import dev.triumphteam.gui.exception.TriumphGuiException; +import dev.triumphteam.gui.slot.Slot; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.NotNull; + +public final class ChestContainerType implements PaperContainerType { + + private static final int LOWER_LIMIT = 0; + private final int rows; + private final int upperLimit; + + public ChestContainerType(final int rows) { + this.rows = rows; + this.upperLimit = rows * 9; + } + + public static @NotNull GuiContainerType of(final int rows) { + return new ChestContainerType(rows); + } + + @Override + public int mapSlot(final @NotNull Slot slot) { + final var realSlot = (slot.column() + (slot.row() - 1) * 9) - 1; + + if (realSlot < LOWER_LIMIT || realSlot > upperLimit) { + throw new TriumphGuiException( + "Invalid slot (" + slot.row() + ", " + slot.column() + "). Valid range is (1, 1) to (" + rows + ", 9)." + ); + } + + return realSlot; + } + + @Override + public Slot mapSlot(final int slot) { + return Slot.of(slot / 9 + 1, slot % 9 + 1); + } + + @Override + public @NotNull Inventory createInventory( + final @NotNull InventoryHolder holder, + final @NotNull Component title + ) { + return Bukkit.createInventory(holder, upperLimit, title); + } +} diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java new file mode 100644 index 00000000..d1e064c5 --- /dev/null +++ b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java @@ -0,0 +1,16 @@ +package dev.triumphteam.gui.paper.container.type; + +import dev.triumphteam.gui.container.type.GuiContainerType; +import net.kyori.adventure.text.Component; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.NotNull; + +public interface PaperContainerType extends GuiContainerType { + + @NotNull + Inventory createInventory( + final @NotNull InventoryHolder holder, + final @NotNull Component title + ); +} From 0986dfe6e0a12682fbaf4731ca44583f86a10607 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 13 May 2024 16:47:39 +0100 Subject: [PATCH 15/43] chore: Rework builder factory and gitignore --- .gitignore | 121 ++++++++++++++++-- build-logic/build.gradle.kts | 5 + build-logic/settings.gradle.kts | 20 ++- .../src/main/kotlin/gui.base.gradle.kts | 1 + .../src/main/kotlin/gui.library.gradle.kts | 30 +++++ core/build.gradle.kts | 1 + .../gui/{Gui.java => BaseGui.java} | 2 +- .../gui/builder/BaseGuiBuilder.java | 18 +-- gradle.properties | 3 + paper/build.gradle.kts | 1 + .../gui/paper/{PaperGui.java => Gui.java} | 36 +++++- .../gui/paper/builder/gui/GuiBuilder.java | 17 +-- settings.gradle.kts | 24 ++-- 13 files changed, 229 insertions(+), 50 deletions(-) create mode 100644 build-logic/src/main/kotlin/gui.library.gradle.kts rename core/src/main/java/dev/triumphteam/gui/{Gui.java => BaseGui.java} (93%) create mode 100644 gradle.properties rename paper/src/main/java/dev/triumphteam/gui/paper/{PaperGui.java => Gui.java} (61%) diff --git a/.gitignore b/.gitignore index 57be55c5..bdb4e296 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,123 @@ +test-plugin/ -gui/build/ +# Created by https://www.toptal.com/developers/gitignore/api/gradle,intellij+all +# Edit at https://www.toptal.com/developers/gitignore?templates=gradle,intellij+all -test-plugin/build/ +### Intellij+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 -.idea/ +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf -.gradle/ +# AWS User-specific +.idea/**/aws.xml -temp.java +# Generated files +.idea/**/contentModel.xml -temp.java.asc +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml -gradle.properties +# Gradle +.idea/**/gradle.xml +.idea/**/libraries -test-plugin/ +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr -build/ +# CMake +cmake-build-*/ +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +# Sonarlint plugin +.idea/sonarlint + +### Gradle ### +.gradle +build/ run/ -fabric-test/ +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +### Gradle Patch ### +**/build/ + +# Eclipse Gradle plugin generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath + +# End of https://www.toptal.com/developers/gitignore/api/gradle,intellij+all diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index 8999fb75..5c623fd8 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -1,5 +1,8 @@ +import dev.triumphteam.root.root + plugins { `kotlin-dsl` + id("dev.triumphteam.root.logic") version "0.0.4" } dependencies { @@ -8,4 +11,6 @@ dependencies { // Bundled plugins implementation(libs.bundles.build) + + root("0.0.6") } diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts index d6c5922e..c0a3eef6 100644 --- a/build-logic/settings.gradle.kts +++ b/build-logic/settings.gradle.kts @@ -1,3 +1,6 @@ +import dev.triumphteam.root.localLibs +import dev.triumphteam.root.releasesRepo + rootProject.name = "build-logic" dependencyResolutionManagement { @@ -5,11 +8,24 @@ dependencyResolutionManagement { repositories { gradlePluginPortal() mavenCentral() + releasesRepo() } versionCatalogs { + register("libs") { - from(files("../gradle/libs.versions.toml")) // include from parent project + from(files(localLibs)) } } -} \ No newline at end of file +} + +pluginManagement { + repositories { + gradlePluginPortal() + maven("https://repo.triumphteam.dev/releases") + } +} + +plugins { + id("dev.triumphteam.root.settings") version "0.0.6" +} diff --git a/build-logic/src/main/kotlin/gui.base.gradle.kts b/build-logic/src/main/kotlin/gui.base.gradle.kts index ea7030f6..d29ab102 100644 --- a/build-logic/src/main/kotlin/gui.base.gradle.kts +++ b/build-logic/src/main/kotlin/gui.base.gradle.kts @@ -6,6 +6,7 @@ val libs = the() plugins { `java-library` kotlin("jvm") + id("dev.triumphteam.root") id("com.github.hierynomus.license") } diff --git a/build-logic/src/main/kotlin/gui.library.gradle.kts b/build-logic/src/main/kotlin/gui.library.gradle.kts new file mode 100644 index 00000000..a9775407 --- /dev/null +++ b/build-logic/src/main/kotlin/gui.library.gradle.kts @@ -0,0 +1,30 @@ +import dev.triumphteam.root.PublishConfigure + +plugins { + `maven-publish` + signing + id("dev.triumphteam.root") +} + +root { + configurePublishing { + configure { + + from(components["java"]) + + snapshotsRepo(PublishConfigure.TRIUMPH_SNAPSHOTS) { + username = property("triumph.repo.user") + password = property("triumph.repo.token") + } + + releasesRepo(PublishConfigure.CENTRAL) { + username = property("central.repo.user") + password = property("central.repo.password") + } + + signing { + sign(publishing.publications["maven"]) + } + } + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 9681e165..2e081302 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("gui.base") + id("gui.library") } dependencies { diff --git a/core/src/main/java/dev/triumphteam/gui/Gui.java b/core/src/main/java/dev/triumphteam/gui/BaseGui.java similarity index 93% rename from core/src/main/java/dev/triumphteam/gui/Gui.java rename to core/src/main/java/dev/triumphteam/gui/BaseGui.java index 40467ebb..5d4ec18c 100644 --- a/core/src/main/java/dev/triumphteam/gui/Gui.java +++ b/core/src/main/java/dev/triumphteam/gui/BaseGui.java @@ -9,7 +9,7 @@ * * @param

A player. */ -public interface Gui

{ +public interface BaseGui

{ /** * Opens a {@link GuiView} of this GUI for the {@link P} player. diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 12bab9cd..395f7393 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,6 +1,6 @@ package dev.triumphteam.gui.builder; -import dev.triumphteam.gui.Gui; +import dev.triumphteam.gui.BaseGui; import dev.triumphteam.gui.GuiView; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; @@ -26,11 +26,11 @@ * * @param The implementation of this {@link BaseGuiBuilder}. * @param

The player type. - * @param The {@link Gui} type. + * @param The {@link BaseGui} type. * @param The item type. */ @SuppressWarnings({"unchecked", "UnusedReturnValue"}) -public abstract class BaseGuiBuilder, P, G extends Gui

, I> { +public abstract class BaseGuiBuilder, P, G extends BaseGui

, I> { private final GuiSettings guiSettings; private final GuiContainerType containerType; @@ -74,7 +74,7 @@ public BaseGuiBuilder( } /** - * Sets the {@link GuiComponentRenderer} to be used by the {@link Gui}. + * Sets the {@link GuiComponentRenderer} to be used by the {@link BaseGui}. * * @param componentRenderer The {@link GuiComponentRenderer} to use. * @return The {@link B} instance of the {@link BaseGuiBuilder}. @@ -103,11 +103,11 @@ public BaseGuiBuilder( } /** - * Adds a {@link GuiComponent} to the {@link Gui}. + * Adds a {@link GuiComponent} to the {@link BaseGui}. *

* The {@link FunctionalGuiComponentBuilder} will create a {@link FunctionalGuiComponent}, * which by itself is NOT a {@link GuiComponent} but instead a {@link GuiComponentProducer}.

- * This will in turn build a real {@link GuiComponent} before being added to the {@link Gui}. + * This will in turn build a real {@link GuiComponent} before being added to the {@link BaseGui}. * * @param builder The functional component builder. * @return The {@link B} instance of the {@link BaseGuiBuilder}. @@ -121,7 +121,7 @@ public BaseGuiBuilder( } /** - * Adds a {@link GuiComponent} to the {@link Gui}. + * Adds a {@link GuiComponent} to the {@link BaseGui}. * * @param component Any type of {@link GuiComponent}. * @return The {@link B} instance of the {@link BaseGuiBuilder}. @@ -133,9 +133,9 @@ public BaseGuiBuilder( } /** - * Finalizes the builder and creates a {@link G} instance of {@link Gui} depending on the platform. + * Finalizes the builder and creates a {@link G} instance of {@link BaseGui} depending on the platform. * - * @return {@link G} which is a {@link Gui}. + * @return {@link G} which is a {@link BaseGui}. */ public abstract G build(); diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..107d1282 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,3 @@ +kotlin.stdlib.default.dependency=false +version=4.0.0-SNAPSHOT +group=dev.triumphteam diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts index db38d083..2353516e 100644 --- a/paper/build.gradle.kts +++ b/paper/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("gui.base") + id("gui.library") } repositories { diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGui.java b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java similarity index 61% rename from paper/src/main/java/dev/triumphteam/gui/paper/PaperGui.java rename to paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index 40636bc6..80a537a1 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGui.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -1,18 +1,25 @@ package dev.triumphteam.gui.paper; -import dev.triumphteam.gui.Gui; +import dev.triumphteam.gui.BaseGui; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; +import dev.triumphteam.gui.container.type.GuiContainerType; +import dev.triumphteam.gui.paper.builder.gui.GuiBuilder; +import dev.triumphteam.gui.paper.container.type.ChestContainerType; import dev.triumphteam.gui.paper.container.type.PaperContainerType; import net.kyori.adventure.text.Component; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.List; -public final class PaperGui implements Gui { +/** + * The GUI implementation for Paper servers. + */ +public final class Gui implements BaseGui { static { GuiBukkitListener.register(); @@ -25,7 +32,7 @@ public final class PaperGui implements Gui { private final ClickHandler clickHandler; private final long spamPreventionDuration; - public PaperGui( + public Gui( final @NotNull Component title, final @NotNull List> components, final @NotNull PaperContainerType containerType, @@ -41,6 +48,29 @@ public PaperGui( this.spamPreventionDuration = spamPreventionDuration; } + /** + * Create a new {@link GuiBuilder} to create a new {@link Gui}. + * + * @param type The {@link GuiContainerType} to be used. + * @return A new {@link GuiBuilder}. + */ + @Contract("_ -> new") + public static GuiBuilder of(final @NotNull GuiContainerType type) { + return new GuiBuilder(type); + } + + /** + * Create a new {@link GuiBuilder} to create a new {@link Gui}. + * This factory will default to using a {@link ChestContainerType}. + * + * @param rows The rows of the {@link ChestContainerType}. + * @return A new {@link GuiBuilder}. + */ + @Contract("_ -> new") + public static GuiBuilder of(final int rows) { + return new GuiBuilder(new ChestContainerType(rows)); + } + @Override public void open(final @NotNull Player player) { final var view = new BukkitGuiView( diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java index f569ba2b..509633d9 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java @@ -2,35 +2,26 @@ import dev.triumphteam.gui.builder.BaseGuiBuilder; import dev.triumphteam.gui.container.type.GuiContainerType; -import dev.triumphteam.gui.paper.PaperGui; +import dev.triumphteam.gui.paper.Gui; import dev.triumphteam.gui.paper.PaperGuiSettings; -import dev.triumphteam.gui.paper.container.type.ChestContainerType; import dev.triumphteam.gui.paper.container.type.PaperContainerType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -public final class GuiBuilder extends BaseGuiBuilder { +public final class GuiBuilder extends BaseGuiBuilder { public GuiBuilder(final @NotNull GuiContainerType containerType) { super(PaperGuiSettings.get(), containerType); } - public static @NotNull GuiBuilder gui(final @NotNull GuiContainerType type) { - return new GuiBuilder(type); - } - - public static @NotNull GuiBuilder gui(final int rows) { - return gui(ChestContainerType.of(rows)); - } - @Override - public PaperGui build() { + public Gui build() { if (!(getContainerType() instanceof final PaperContainerType paperContainerType)) { throw new IllegalArgumentException("Container type provided is not supported on Paper platform!"); } - return new PaperGui( + return new Gui( getTitle(), getComponents(), paperContainerType, diff --git a/settings.gradle.kts b/settings.gradle.kts index d46d4d1e..ac6a5862 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,24 +1,24 @@ +import dev.triumphteam.root.includeProject + dependencyResolutionManagement { includeBuild("build-logic") repositories.gradlePluginPortal() } -enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") +pluginManagement { + repositories { + gradlePluginPortal() + maven("https://repo.triumphteam.dev/releases") + } +} rootProject.name = "triumph-gui" -listOf("core", "paper").forEach(::includeProject) - -fun includeProject(name: String) { - include(name) { - this.name = "${rootProject.name}-$name" - } -} +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -fun include(name: String, block: ProjectDescriptor.() -> Unit) { - include(name) - project(":$name").apply(block) +plugins { + id("dev.triumphteam.root.settings") version "0.0.6" } -//include("fabric-test") +listOf("core", "paper").forEach(::includeProject) include("test-plugin") From 118cf2fa347eab4e16de054bd7edd131829ca6a3 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 13 May 2024 16:48:25 +0100 Subject: [PATCH 16/43] chore: License --- LICENSE | 2 +- .../dev/triumphteam/gui/AbstractGuiView.java | 23 +++++++++++++++++++ .../java/dev/triumphteam/gui/BaseGui.java | 23 +++++++++++++++++++ .../java/dev/triumphteam/gui/GuiView.java | 23 +++++++++++++++++++ .../gui/builder/BaseGuiBuilder.java | 23 +++++++++++++++++++ .../triumphteam/gui/click/ClickContext.java | 23 +++++++++++++++++++ .../gui/click/action/EmptyGuiClickAction.java | 23 +++++++++++++++++++ .../gui/click/action/GuiClickAction.java | 23 +++++++++++++++++++ .../click/action/RunnableGuiClickAction.java | 23 +++++++++++++++++++ .../gui/click/controller/ClickController.java | 23 +++++++++++++++++++ .../controller/DefaultClickController.java | 23 +++++++++++++++++++ .../gui/click/handler/ClickHandler.java | 23 +++++++++++++++++++ .../CompletableFutureClickHandler.java | 23 +++++++++++++++++++ .../gui/click/handler/SimpleClickHandler.java | 23 +++++++++++++++++++ .../gui/click/processor/ClickProcessor.java | 23 +++++++++++++++++++ .../gui/component/GuiComponent.java | 23 +++++++++++++++++++ .../gui/component/GuiComponentProducer.java | 23 +++++++++++++++++++ .../gui/component/ReactiveGuiComponent.java | 23 +++++++++++++++++++ .../gui/component/RenderedComponent.java | 23 +++++++++++++++++++ .../gui/component/StatefulGuiComponent.java | 23 +++++++++++++++++++ .../components/PaginatedComponent.java | 23 +++++++++++++++++++ .../AbstractFunctionalGuiComponent.java | 23 +++++++++++++++++++ .../BaseFunctionalGuiComponent.java | 23 +++++++++++++++++++ .../functional/FunctionalGuiComponent.java | 23 +++++++++++++++++++ .../FunctionalGuiComponentBuilder.java | 23 +++++++++++++++++++ .../FunctionalGuiComponentRender.java | 23 +++++++++++++++++++ .../SimpleFunctionalGuiComponent.java | 23 +++++++++++++++++++ .../renderer/DefaultGuiComponentRenderer.java | 23 +++++++++++++++++++ .../renderer/GuiComponentRenderer.java | 23 +++++++++++++++++++ .../gui/container/GuiContainer.java | 23 +++++++++++++++++++ .../gui/container/MapBackedContainer.java | 23 +++++++++++++++++++ .../gui/container/type/GuiContainerType.java | 23 +++++++++++++++++++ .../gui/exception/TriumphGuiException.java | 23 +++++++++++++++++++ .../dev/triumphteam/gui/item/GuiItem.java | 23 +++++++++++++++++++ .../triumphteam/gui/item/RenderedGuiItem.java | 23 +++++++++++++++++++ .../gui/item/items/SimpleGuiItem.java | 23 +++++++++++++++++++ .../triumphteam/gui/layout/BoxGuiLayout.java | 23 +++++++++++++++++++ .../dev/triumphteam/gui/layout/GuiLayout.java | 23 +++++++++++++++++++ .../triumphteam/gui/settings/GuiSettings.java | 23 +++++++++++++++++++ .../java/dev/triumphteam/gui/slot/Slot.java | 23 +++++++++++++++++++ .../gui/state/AbstractMutableState.java | 23 +++++++++++++++++++ .../triumphteam/gui/state/AbstractState.java | 23 +++++++++++++++++++ .../triumphteam/gui/state/MutableState.java | 23 +++++++++++++++++++ .../java/dev/triumphteam/gui/state/State.java | 23 +++++++++++++++++++ .../gui/state/StateListenerContainer.java | 23 +++++++++++++++++++ .../gui/state/builtin/EmptyState.java | 23 +++++++++++++++++++ .../gui/state/builtin/SimpleMutableState.java | 23 +++++++++++++++++++ .../gui/state/policy/StateMutationPolicy.java | 23 +++++++++++++++++++ .../triumphteam/gui/paper/BukkitGuiView.java | 23 +++++++++++++++++++ .../java/dev/triumphteam/gui/paper/Gui.java | 23 +++++++++++++++++++ .../gui/paper/GuiBukkitListener.java | 23 +++++++++++++++++++ .../gui/paper/PaperGuiSettings.java | 23 +++++++++++++++++++ .../gui/paper/builder/gui/GuiBuilder.java | 23 +++++++++++++++++++ .../builder/item/AbstractItemBuilder.java | 23 +++++++++++++++++++ .../gui/paper/builder/item/ItemBuilder.java | 23 +++++++++++++++++++ .../container/type/ChestContainerType.java | 23 +++++++++++++++++++ .../container/type/PaperContainerType.java | 23 +++++++++++++++++++ 57 files changed, 1289 insertions(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index b4bac0e2..9a0bff4d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 TriumphTeam +Copyright (c) 2024 TriumphTeam Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 0dac8c4b..19bdb467 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui; import dev.triumphteam.gui.click.handler.ClickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/BaseGui.java b/core/src/main/java/dev/triumphteam/gui/BaseGui.java index 5d4ec18c..d7fe1326 100644 --- a/core/src/main/java/dev/triumphteam/gui/BaseGui.java +++ b/core/src/main/java/dev/triumphteam/gui/BaseGui.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/GuiView.java b/core/src/main/java/dev/triumphteam/gui/GuiView.java index 9f17fbee..353f0b87 100644 --- a/core/src/main/java/dev/triumphteam/gui/GuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/GuiView.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui; public interface GuiView { diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 395f7393..13b00ce4 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.builder; import dev.triumphteam.gui.BaseGui; diff --git a/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java b/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java index 1db69d77..50f368b3 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java +++ b/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click; public record ClickContext() { diff --git a/core/src/main/java/dev/triumphteam/gui/click/action/EmptyGuiClickAction.java b/core/src/main/java/dev/triumphteam/gui/click/action/EmptyGuiClickAction.java index 81238799..04b211ed 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/action/EmptyGuiClickAction.java +++ b/core/src/main/java/dev/triumphteam/gui/click/action/EmptyGuiClickAction.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.action; public final class EmptyGuiClickAction

implements GuiClickAction

{ diff --git a/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java b/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java index 67b092cd..d071428a 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java +++ b/core/src/main/java/dev/triumphteam/gui/click/action/GuiClickAction.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.action; import dev.triumphteam.gui.click.handler.ClickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java b/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java index c3ff7f3c..4a2fb14f 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java +++ b/core/src/main/java/dev/triumphteam/gui/click/action/RunnableGuiClickAction.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.action; import dev.triumphteam.gui.click.ClickContext; diff --git a/core/src/main/java/dev/triumphteam/gui/click/controller/ClickController.java b/core/src/main/java/dev/triumphteam/gui/click/controller/ClickController.java index f5af8586..34468bf2 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/controller/ClickController.java +++ b/core/src/main/java/dev/triumphteam/gui/click/controller/ClickController.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.controller; import org.jetbrains.annotations.Nullable; diff --git a/core/src/main/java/dev/triumphteam/gui/click/controller/DefaultClickController.java b/core/src/main/java/dev/triumphteam/gui/click/controller/DefaultClickController.java index ca05729c..6b790eae 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/controller/DefaultClickController.java +++ b/core/src/main/java/dev/triumphteam/gui/click/controller/DefaultClickController.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.controller; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java index 2afda3a2..fe166527 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/ClickHandler.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.handler; import dev.triumphteam.gui.click.ClickContext; diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java index 3b6e53c1..643b39d3 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.handler; import dev.triumphteam.gui.click.ClickContext; diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java index b4dbe7f4..a127aa88 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.handler; import dev.triumphteam.gui.click.ClickContext; diff --git a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java index 2df1e299..4e594983 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java +++ b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click.processor; import com.google.common.cache.Cache; diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java index 7c74b8e3..fdbf53eb 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component; import dev.triumphteam.gui.click.handler.ClickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java index 9d37d35c..4bd9ace7 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java index 4d20b364..6e9af0ad 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component; import dev.triumphteam.gui.container.GuiContainer; diff --git a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java index 89eff52d..2c4c231d 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/RenderedComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component; import dev.triumphteam.gui.item.RenderedGuiItem; diff --git a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java index 4e40a1cc..d977d9f7 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component; import dev.triumphteam.gui.state.State; diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java index ff30bfb3..446c3a85 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.components; import dev.triumphteam.gui.click.action.RunnableGuiClickAction; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java index 89d2360b..61340f49 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.click.handler.ClickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java index cfd95ae2..13180162 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.click.handler.ClickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java index bb2c3f86..ceb6f20f 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.builder.BaseGuiBuilder; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java index 6f664084..3fd9f9a2 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.functional; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java index dad24086..c933bd02 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.container.GuiContainer; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index cf4debc1..3dd0e5f8 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.click.handler.ClickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java index 6d65bd3c..91907157 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.renderer; import dev.triumphteam.gui.AbstractGuiView; diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java index dabbe9e8..013f4841 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/GuiComponentRenderer.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component.renderer; import dev.triumphteam.gui.AbstractGuiView; diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java index 78affb0f..73a53b4e 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.container; import dev.triumphteam.gui.container.type.GuiContainerType; diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index e326d037..0c68d5b5 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.container; import dev.triumphteam.gui.click.handler.ClickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java b/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java index 5503c843..3ced9ec1 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java +++ b/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.container.type; import dev.triumphteam.gui.slot.Slot; diff --git a/core/src/main/java/dev/triumphteam/gui/exception/TriumphGuiException.java b/core/src/main/java/dev/triumphteam/gui/exception/TriumphGuiException.java index a8f3a841..f1343817 100644 --- a/core/src/main/java/dev/triumphteam/gui/exception/TriumphGuiException.java +++ b/core/src/main/java/dev/triumphteam/gui/exception/TriumphGuiException.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.exception; import org.jetbrains.annotations.NotNull; diff --git a/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java index 03222498..b7dd6cb9 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java +++ b/core/src/main/java/dev/triumphteam/gui/item/GuiItem.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.item; import dev.triumphteam.gui.click.action.GuiClickAction; diff --git a/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java index 2f338651..0f8735db 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java +++ b/core/src/main/java/dev/triumphteam/gui/item/RenderedGuiItem.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.item; import dev.triumphteam.gui.click.action.GuiClickAction; diff --git a/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java b/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java index 2eb22db7..f9c9d0eb 100644 --- a/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java +++ b/core/src/main/java/dev/triumphteam/gui/item/items/SimpleGuiItem.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.item.items; import dev.triumphteam.gui.click.action.GuiClickAction; diff --git a/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java index 5abecf99..8f5c4402 100644 --- a/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java +++ b/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.layout; import dev.triumphteam.gui.slot.Slot; diff --git a/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java index 0e4f3952..2dc34073 100644 --- a/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java +++ b/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.layout; import dev.triumphteam.gui.slot.Slot; diff --git a/core/src/main/java/dev/triumphteam/gui/settings/GuiSettings.java b/core/src/main/java/dev/triumphteam/gui/settings/GuiSettings.java index bcbe86f5..d736bf9a 100644 --- a/core/src/main/java/dev/triumphteam/gui/settings/GuiSettings.java +++ b/core/src/main/java/dev/triumphteam/gui/settings/GuiSettings.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.settings; import dev.triumphteam.gui.click.handler.ClickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java index 83d7dfea..c9541859 100644 --- a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java +++ b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.slot; public record Slot(int row, int column) { diff --git a/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java b/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java index dafe5d1f..698437d4 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.state; import dev.triumphteam.gui.state.builtin.SimpleMutableState; diff --git a/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java b/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java index 3b13c17e..09b5fe87 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.state; import dev.triumphteam.gui.GuiView; diff --git a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java index f228c1f7..f7803736 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.state; import dev.triumphteam.gui.state.builtin.SimpleMutableState; diff --git a/core/src/main/java/dev/triumphteam/gui/state/State.java b/core/src/main/java/dev/triumphteam/gui/state/State.java index 7c2befcd..e7cd72d7 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/State.java +++ b/core/src/main/java/dev/triumphteam/gui/state/State.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.state; import dev.triumphteam.gui.GuiView; diff --git a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java index 8b770736..d9ced79e 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.state; import com.google.common.cache.Cache; diff --git a/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java b/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java index 7254f7d0..166e47b4 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.state.builtin; import dev.triumphteam.gui.state.AbstractState; diff --git a/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java b/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java index f8bb077d..177ef223 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java +++ b/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.state.builtin; import dev.triumphteam.gui.state.AbstractMutableState; diff --git a/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java b/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java index 1aff88e3..8e040d21 100644 --- a/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java +++ b/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.state.policy; import dev.triumphteam.gui.state.MutableState; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java b/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java index 791a530d..4b62920c 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper; import dev.triumphteam.gui.AbstractGuiView; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index 80a537a1..e324636d 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper; import dev.triumphteam.gui.BaseGui; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java index fc92121c..769ea06e 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper; import org.bukkit.event.EventHandler; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java index 8ede98dd..86291f33 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper; import dev.triumphteam.gui.exception.TriumphGuiException; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java index 509633d9..04993fbb 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper.builder.gui; import dev.triumphteam.gui.builder.BaseGuiBuilder; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java index c4173368..de3e24f2 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper.builder.item; import com.google.common.base.Preconditions; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java index 7739d81c..004c37d8 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper.builder.item; import org.bukkit.Material; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java index 01ee456e..fdf35032 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper.container.type; import dev.triumphteam.gui.container.type.GuiContainerType; diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java index d1e064c5..d62f67b6 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper.container.type; import dev.triumphteam.gui.container.type.GuiContainerType; From e57ac8b7c9953c72d820c1fca6aaddffec55fc21 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 14 May 2024 14:19:52 +0100 Subject: [PATCH 17/43] chore: Moving to Nova over built in states --- .../src/main/kotlin/gui.base.gradle.kts | 1 + core/build.gradle.kts | 2 + .../BaseFunctionalGuiComponent.java | 72 +------------------ gradle/libs.versions.toml | 3 + 4 files changed, 8 insertions(+), 70 deletions(-) diff --git a/build-logic/src/main/kotlin/gui.base.gradle.kts b/build-logic/src/main/kotlin/gui.base.gradle.kts index d29ab102..b18192d1 100644 --- a/build-logic/src/main/kotlin/gui.base.gradle.kts +++ b/build-logic/src/main/kotlin/gui.base.gradle.kts @@ -12,6 +12,7 @@ plugins { repositories { mavenCentral() + maven("https://triumphteam.dev/snapshots/") } dependencies { diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 2e081302..53932a6a 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -4,6 +4,8 @@ plugins { } dependencies { + api(libs.nova) + compileOnlyApi(libs.guava) compileOnlyApi(libs.adventure.api) diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java index 13180162..511abbca 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java @@ -24,81 +24,13 @@ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.click.handler.ClickHandler; -import dev.triumphteam.gui.state.MutableState; -import dev.triumphteam.gui.state.State; -import dev.triumphteam.gui.state.builtin.EmptyState; -import dev.triumphteam.gui.state.policy.StateMutationPolicy; +import dev.triumphteam.nova.holder.StateHolder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.concurrent.TimeUnit; -interface BaseFunctionalGuiComponent

{ - - /** - * Associate am empty {@link State} to the component. - * - * @return A new {@link EmptyState}. - */ - @NotNull - State state(); - - /** - * Associate a {@link S} type {@link State} to the component. - * - * @param state A state. - * @return The same state passed. - */ - @NotNull - S state(final @NotNull S state); - - /** - * Create a new state with the given default value. - * - * @param value The default value of the state. - * @param The type of the value. - * @return The newly created {@link MutableState}. - */ - @NotNull MutableState<@NotNull T> state(final @NotNull T value); - - /** - * Create a new state with the given default value. - * Uses the given {@link StateMutationPolicy} for equivalence check. - * - * @param value The default value of the state. - * @param mutationPolicy The mutation policy to use. - * @param The type of the value. - * @return The newly created {@link MutableState}. - */ - @NotNull MutableState<@NotNull T> state( - final @NotNull T value, - final @NotNull StateMutationPolicy mutationPolicy - ); - - /** - * Create a new state with the given default value. - * In this case, the value is nullable. - * - * @param value The default value of the state. - * @param The type of the value. - * @return The newly created {@link MutableState}. - */ - @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value); - - /** - * Create a new state with the given default value. - * In this case, the value is nullable. - * Uses the given {@link StateMutationPolicy} for equivalence check. - * - * @param value The default value of the state. - * @param mutationPolicy The mutation policy to use. - * @param The type of the value. - * @return The newly created {@link MutableState}. - */ - @NotNull MutableState<@Nullable T> nullableState( - final @Nullable T value, - final @NotNull StateMutationPolicy mutationPolicy - ); +interface BaseFunctionalGuiComponent

extends StateHolder { /** * TODO diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 71e86f6e..517e4749 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,6 +9,7 @@ license = "0.16.1" annotations = "24.1.0" guava = "33.2.0-jre" logger = "2.0.13" +nova = "1.0.0-SNAPSHOT" # Minecraft adventure = "4.16.0" @@ -19,6 +20,8 @@ paper = "1.16.5-R0.1-SNAPSHOT" annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" } guava = { module = "com.google.guava:guava", version.ref = "guava" } logger = { module = "org.slf4j:slf4j-api", version.ref = "logger" } +nova = { module = "dev.triumphteam:nova", version.ref = "nova" } +nova-kotlin = { module = "dev.triumphteam:nova-kotlin", version.ref = "nova" } # Minecraft paper = { module = "com.destroystokyo.paper:paper-api", version.ref = "paper" } From 791f5a7c045762b0b65758c020a2f2e78ac15302 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 21 May 2024 19:12:40 +0100 Subject: [PATCH 18/43] chore: Move state usage to Nova instead of built-in --- .../dev/triumphteam/gui/AbstractGuiView.java | 3 +- .../gui/component/StatefulGuiComponent.java | 2 +- .../components/PaginatedComponent.java | 8 +- .../AbstractFunctionalGuiComponent.java | 10 +-- .../SimpleFunctionalGuiComponent.java | 2 +- .../gui/state/AbstractMutableState.java | 65 -------------- .../triumphteam/gui/state/AbstractState.java | 43 ---------- .../triumphteam/gui/state/MutableState.java | 68 --------------- .../java/dev/triumphteam/gui/state/State.java | 58 ------------- .../gui/state/StateListenerContainer.java | 78 ----------------- .../gui/state/builtin/EmptyState.java | 28 ------ .../gui/state/builtin/SimpleMutableState.java | 42 --------- .../gui/state/policy/StateMutationPolicy.java | 86 ------------------- 13 files changed, 13 insertions(+), 480 deletions(-) delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/AbstractState.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/MutableState.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/State.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 19bdb467..6cfc7788 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -31,6 +31,7 @@ import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.item.RenderedGuiItem; +import dev.triumphteam.nova.Stateful; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -39,7 +40,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -public abstract class AbstractGuiView implements GuiView { +public abstract class AbstractGuiView implements GuiView, Stateful { private final P viewer; private final List> components; diff --git a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java index d977d9f7..7e338df2 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java @@ -23,7 +23,7 @@ */ package dev.triumphteam.gui.component; -import dev.triumphteam.gui.state.State; +import dev.triumphteam.nova.State; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java index 446c3a85..5165748d 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java @@ -30,10 +30,10 @@ import dev.triumphteam.gui.item.items.SimpleGuiItem; import dev.triumphteam.gui.layout.GuiLayout; import dev.triumphteam.gui.slot.Slot; -import dev.triumphteam.gui.state.MutableState; -import dev.triumphteam.gui.state.State; -import dev.triumphteam.gui.state.builtin.SimpleMutableState; -import dev.triumphteam.gui.state.policy.StateMutationPolicy; +import dev.triumphteam.nova.MutableState; +import dev.triumphteam.nova.State; +import dev.triumphteam.nova.builtin.SimpleMutableState; +import dev.triumphteam.nova.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; import java.util.List; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java index 61340f49..c7406d4c 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java @@ -26,11 +26,11 @@ import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.click.handler.CompletableFutureClickHandler; import dev.triumphteam.gui.click.handler.SimpleClickHandler; -import dev.triumphteam.gui.state.MutableState; -import dev.triumphteam.gui.state.State; -import dev.triumphteam.gui.state.builtin.EmptyState; -import dev.triumphteam.gui.state.builtin.SimpleMutableState; -import dev.triumphteam.gui.state.policy.StateMutationPolicy; +import dev.triumphteam.nova.MutableState; +import dev.triumphteam.nova.State; +import dev.triumphteam.nova.builtin.EmptyState; +import dev.triumphteam.nova.builtin.SimpleMutableState; +import dev.triumphteam.nova.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index 3dd0e5f8..609c8a48 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -29,7 +29,7 @@ import dev.triumphteam.gui.component.ReactiveGuiComponent; import dev.triumphteam.gui.container.GuiContainer; import dev.triumphteam.gui.exception.TriumphGuiException; -import dev.triumphteam.gui.state.State; +import dev.triumphteam.nova.State; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java b/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java deleted file mode 100644 index 698437d4..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/AbstractMutableState.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.state; - -import dev.triumphteam.gui.state.builtin.SimpleMutableState; -import dev.triumphteam.gui.state.policy.StateMutationPolicy; -import org.jetbrains.annotations.NotNull; - -/** - * Abstract implementation for a {@link MutableState}. - * The mutability of the value {@link T} is dependent on the given {@link StateMutationPolicy}. - * - * @param The type of the value. - * @see SimpleMutableState - */ -public abstract class AbstractMutableState extends AbstractState implements MutableState { - - private final StateMutationPolicy mutationPolicy; - private T value; - - public AbstractMutableState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { - this.value = value; - this.mutationPolicy = mutationPolicy; - } - - @Override - public T getValue() { - return value; - } - - @Override - public void setValue(final T value) { - // Will not mutate value if they are equivalent - if (mutationPolicy.equivalent(this.value, value)) return; - - this.value = value; - trigger(); - } - - @Override - public @NotNull StateMutationPolicy stateMutationPolicy() { - return mutationPolicy; - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java b/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java deleted file mode 100644 index 09b5fe87..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/AbstractState.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.state; - -import dev.triumphteam.gui.GuiView; -import org.jetbrains.annotations.NotNull; - - -public abstract class AbstractState implements State { - - private final StateListenerContainer listenerContainer = new StateListenerContainer(); - - @Override - public void trigger() { - listenerContainer.triggerAll(); - } - - @Override - public void addListener(final @NotNull GuiView view, final @NotNull Runnable listener) { - listenerContainer.addListener(view, listener); - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java b/core/src/main/java/dev/triumphteam/gui/state/MutableState.java deleted file mode 100644 index f7803736..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/MutableState.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.state; - -import dev.triumphteam.gui.state.builtin.SimpleMutableState; -import dev.triumphteam.gui.state.policy.StateMutationPolicy; -import org.jetbrains.annotations.NotNull; - -/** - * A representation of a {@link State} that is mutable. - * Modifying value of type {@link T} will trigger the component associated with this state to re-render. - * Setting the value to an equal value as the current, may or may not trigger an update, - * all depending on the implementation of the used {@link MutableState}. - * Same for the nullability of the value. - * - * @param The type the state accepts. - * @see AbstractMutableState - * @see SimpleMutableState - */ -public interface MutableState extends State { - - /** - * Gets the current value of the state. - * The nullability of this value depends on the value passed. - * - * @return The value of the state. - */ - T getValue(); - - /** - * Set a new value to the state. - * This may or may not trigger a component to re-draw. - * - * @param value The new value of the state. - */ - void setValue(final T value); - - /** - * Which mutation policy is used by this state. - * The mutation policy is not used outside the state itself, - * so it can be ignored if not actively used but custom implementations of {@link MutableState}. - * - * @return The used mutation policy. - */ - @NotNull - StateMutationPolicy stateMutationPolicy(); -} diff --git a/core/src/main/java/dev/triumphteam/gui/state/State.java b/core/src/main/java/dev/triumphteam/gui/state/State.java deleted file mode 100644 index e7cd72d7..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/State.java +++ /dev/null @@ -1,58 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.state; - -import dev.triumphteam.gui.GuiView; -import dev.triumphteam.gui.state.builtin.SimpleMutableState; -import org.jetbrains.annotations.NotNull; - -/** - * A representation of a "state" in the GUI. - * A state doesn't necessarily need to hold any value. - * Its sole purpose is to trigger updates on the GUI. - * - * @see MutableState - * @see AbstractMutableState - * @see SimpleMutableState - */ -public interface State { - - /** - * Trigger a component to re-render. - */ - void trigger(); - - /** - * Adds a new listener to the state. - * Avoid calling this method manually if you don't know what you are doing, - * this is mostly done internally by the {@link GuiView}. - *

- * The listener is tied to the lifecycle of the {@link GuiView}, - * so avoid holding the view if it is no longer needed. - * - * @param view The {@link GuiView} which will be handling this state. - * @param listener The listener to be called when a state is triggered. - */ - void addListener(final @NotNull GuiView view, final @NotNull Runnable listener); -} diff --git a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java b/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java deleted file mode 100644 index d9ced79e..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/StateListenerContainer.java +++ /dev/null @@ -1,78 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.state; - -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import dev.triumphteam.gui.GuiView; -import org.jetbrains.annotations.NotNull; - -import java.util.Map; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; - -/** - * A map backed container for state listeners. - * This container uses a map with weak keys, so instances of the {@link GuiView} can prevent - * values from being garbage collected correctly. - */ -public final class StateListenerContainer { - - /** - * Listeners cache. - * The keys of the map are weak. - * The value of the map is a {@link ConcurrentLinkedQueue}. - */ - private final Map, Queue> listeners = createListenerMap(); - - /** - * Creates a map to be used for the listeners. - * - * @return A {@link java.util.concurrent.ConcurrentMap} with weak keys. - */ - private static Map, Queue> createListenerMap() { - final Cache, Queue> cache = CacheBuilder.newBuilder() - .weakKeys() - .build(); - - return cache.asMap(); - } - - /** - * Adds listener tied to the {@link GuiView} lifecycle. - * - * @param view The view to be used as the reference. - * @param listener The listener to run when a state is triggered. - */ - public void addListener(final @NotNull GuiView view, final @NotNull Runnable listener) { - listeners.computeIfAbsent(view, ignored -> new ConcurrentLinkedQueue<>()).add(listener); - } - - /** - * Triggers all listeners that this state uses. - */ - public void triggerAll() { - listeners.values().forEach(listeners -> listeners.forEach(Runnable::run)); - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java b/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java deleted file mode 100644 index 166e47b4..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/builtin/EmptyState.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.state.builtin; - -import dev.triumphteam.gui.state.AbstractState; - -public final class EmptyState extends AbstractState {} diff --git a/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java b/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java deleted file mode 100644 index 177ef223..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/builtin/SimpleMutableState.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.state.builtin; - -import dev.triumphteam.gui.state.AbstractMutableState; -import dev.triumphteam.gui.state.MutableState; -import dev.triumphteam.gui.state.policy.StateMutationPolicy; -import org.jetbrains.annotations.NotNull; - -/** - * The simplest implementation of {@link MutableState}. - * - * @param The type of the value. - * @see AbstractMutableState For the implementation. - */ -public final class SimpleMutableState extends AbstractMutableState { - - public SimpleMutableState(final T value, final @NotNull StateMutationPolicy mutationPolicy) { - super(value, mutationPolicy); - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java b/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java deleted file mode 100644 index 8e040d21..00000000 --- a/core/src/main/java/dev/triumphteam/gui/state/policy/StateMutationPolicy.java +++ /dev/null @@ -1,86 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.state.policy; - -import dev.triumphteam.gui.state.MutableState; -import org.jetbrains.annotations.Nullable; - -/** - * States how a {@link MutableState} handles equality. - * By default, {@link StructuralEquality} is used. - */ -public interface StateMutationPolicy { - - /** - * Checks if the two values are equivalent. - * - * @param a The first value. - * @param b The second value. - * @return Whether or not they are equivalent. - */ - boolean equivalent(final @Nullable Object a, final @Nullable Object b); - - /** - * A {@link StateMutationPolicy} that checks for reference equality. - * This class is a singleton and {@link ReferenceEquality#INSTANCE} should always be the used instance. - */ - final class ReferenceEquality implements StateMutationPolicy { - - public static final StateMutationPolicy INSTANCE = new ReferenceEquality(); - - @Override - public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { - return a == b; - } - } - - /** - * A {@link StateMutationPolicy} that checks for structural equality. - * This class is a singleton and {@link StructuralEquality#INSTANCE} should always be the used instance. - */ - final class StructuralEquality implements StateMutationPolicy { - - public static final StateMutationPolicy INSTANCE = new StructuralEquality(); - - @Override - public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { - if (a == null || b == null) return false; - return a.equals(b); - } - } - - /** - * A {@link StateMutationPolicy} that makes values never be equivalent. - * This class is a singleton and {@link NeverEqual#INSTANCE} should always be the used instance. - */ - final class NeverEqual implements StateMutationPolicy { - - public static final StateMutationPolicy INSTANCE = new NeverEqual(); - - @Override - public boolean equivalent(final @Nullable Object a, final @Nullable Object b) { - return false; - } - } -} From 2e1db8d727fb3c4fe3aeeb1df8fb31cf9dfff056 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 16 Oct 2024 23:23:37 +0100 Subject: [PATCH 19/43] feature: Filler, Kotlin extensions, and shortcut for stateless component --- .../dev/triumphteam/gui/AbstractGuiView.java | 3 +- .../gui/builder/BaseGuiBuilder.java | 23 +++++-- .../gui/component/ReactiveGuiComponent.java | 2 +- .../gui/component/SimpleGuiComponent.java | 29 ++++++++ .../AbstractFunctionalGuiComponent.java | 64 ++---------------- .../functional/FunctionalGuiComponent.java | 2 +- .../FunctionalGuiComponentRender.java | 5 +- .../SimpleFunctionalGuiComponent.java | 34 ++-------- .../gui/container/GuiContainer.java | 11 ++-- .../gui/container/MapBackedContainer.java | 6 ++ .../gui/layout/BorderGuiLayout.java | 66 +++++++++++++++++++ .../java/dev/triumphteam/gui/slot/Slot.java | 12 ++-- gradle/libs.versions.toml | 2 +- kotlin/build.gradle.kts | 10 +++ kotlin/src/main/kotlin/GuiBuilderExt.kt | 13 ++++ kotlin/src/main/kotlin/SlotExt.kt | 13 ++++ kotlin/src/main/kotlin/package-info.kt | 1 + .../builder/item/AbstractItemBuilder.java | 7 ++ settings.gradle.kts | 2 +- 19 files changed, 197 insertions(+), 108 deletions(-) create mode 100644 core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java create mode 100644 kotlin/build.gradle.kts create mode 100644 kotlin/src/main/kotlin/GuiBuilderExt.kt create mode 100644 kotlin/src/main/kotlin/SlotExt.kt create mode 100644 kotlin/src/main/kotlin/package-info.kt diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 6cfc7788..19bdb467 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -31,7 +31,6 @@ import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.item.RenderedGuiItem; -import dev.triumphteam.nova.Stateful; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,7 +39,7 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -public abstract class AbstractGuiView implements GuiView, Stateful { +public abstract class AbstractGuiView implements GuiView { private final P viewer; private final List> components; diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 13b00ce4..fa1671c0 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,8 +28,10 @@ import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.GuiComponentProducer; +import dev.triumphteam.gui.component.SimpleGuiComponent; import dev.triumphteam.gui.component.functional.FunctionalGuiComponent; import dev.triumphteam.gui.component.functional.FunctionalGuiComponentBuilder; +import dev.triumphteam.gui.component.functional.FunctionalGuiComponentRender; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; import dev.triumphteam.gui.container.type.GuiContainerType; @@ -40,6 +42,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; @@ -143,6 +146,18 @@ public BaseGuiBuilder( return (B) this; } + /** + * For faster creation of components that don't require states. + * Use this for components you don't need to update, aka static items. + * + * @param render The component render. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ + @Contract("_ -> this") + public @NotNull B statelessComponent(final @NotNull FunctionalGuiComponentRender render) { + return component(new SimpleGuiComponent<>(render, Collections.emptyList())); + } + /** * Adds a {@link GuiComponent} to the {@link BaseGui}. * diff --git a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java index 6e9af0ad..ff30fb68 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/ReactiveGuiComponent.java @@ -28,5 +28,5 @@ public interface ReactiveGuiComponent extends StatefulGuiComponent { - void render(final @NotNull GuiContainer<@NotNull P, @NotNull I> container, final @NotNull P player); + void render(final @NotNull GuiContainer<@NotNull P, @NotNull I> container); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponent.java new file mode 100644 index 00000000..c062f805 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponent.java @@ -0,0 +1,29 @@ +package dev.triumphteam.gui.component; + +import dev.triumphteam.gui.component.functional.FunctionalGuiComponentRender; +import dev.triumphteam.gui.container.GuiContainer; +import dev.triumphteam.nova.State; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public final class SimpleGuiComponent implements ReactiveGuiComponent { + + private final FunctionalGuiComponentRender component; + private final List states; + + public SimpleGuiComponent(final @NotNull FunctionalGuiComponentRender component, final @NotNull List states) { + this.component = component; + this.states = states; + } + + @Override + public void render(final @NotNull GuiContainer<@NotNull P, @NotNull I> container) { + component.render(container); + } + + @Override + public @NotNull List states() { + return states; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java index c7406d4c..f998bb41 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,64 +26,16 @@ import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.click.handler.CompletableFutureClickHandler; import dev.triumphteam.gui.click.handler.SimpleClickHandler; -import dev.triumphteam.nova.MutableState; -import dev.triumphteam.nova.State; -import dev.triumphteam.nova.builtin.EmptyState; -import dev.triumphteam.nova.builtin.SimpleMutableState; -import dev.triumphteam.nova.policy.StateMutationPolicy; +import dev.triumphteam.nova.holder.AbstractStateHolder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; import java.util.concurrent.TimeUnit; -public abstract class AbstractFunctionalGuiComponent

implements BaseFunctionalGuiComponent

{ +public abstract class AbstractFunctionalGuiComponent

extends AbstractStateHolder implements BaseFunctionalGuiComponent

{ - private final List states = new ArrayList<>(); private ClickHandler

clickHandler = null; - @Override - public @NotNull State state() { - return state(new EmptyState()); - } - - @Override - public @NotNull S state(final @NotNull S state) { - states.add(state); - return state; - } - - @Override - public @NotNull MutableState<@NotNull T> state(@NotNull final T value) { - return state(value, StateMutationPolicy.StructuralEquality.INSTANCE); - } - - @Override - public @NotNull MutableState<@NotNull T> state( - final @NotNull T value, - final @NotNull StateMutationPolicy mutationPolicy - ) { - var state = new SimpleMutableState<>(value, mutationPolicy); - states.add(state); - return state; - } - - @Override - public @NotNull MutableState<@Nullable T> nullableState(final @Nullable T value) { - return nullableState(value, StateMutationPolicy.StructuralEquality.INSTANCE); - } - - @Override - public @NotNull MutableState<@Nullable T> nullableState( - final @Nullable T value, - final @NotNull StateMutationPolicy mutationPolicy - ) { - var state = new SimpleMutableState<>(value, mutationPolicy); - states.add(state); - return state; - } - @Override public void withClickHandler(final @Nullable ClickHandler

clickHandler) { this.clickHandler = clickHandler; @@ -107,8 +59,4 @@ public void withCompletableFutureClickHandler(final long timeout, final @NotNull public @Nullable ClickHandler

getClickHandler() { return clickHandler; } - - protected @NotNull List getStates() { - return states; - } } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java index ceb6f20f..01d2207e 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponent.java @@ -40,7 +40,7 @@ public interface FunctionalGuiComponent extends BaseFunctionalGuiComponent /** * A component render function. - * The function inside works the same as a normal {@link ReactiveGuiComponent#render(GuiContainer, Object)} would. + * The function inside works the same as a normal {@link ReactiveGuiComponent#render(GuiContainer)} would. * * @param render The component render. */ diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java index c933bd02..ce68f392 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentRender.java @@ -29,8 +29,5 @@ @FunctionalInterface public interface FunctionalGuiComponentRender { - void render( - final @NotNull GuiContainer<@NotNull P, @NotNull I> container, - final @NotNull P player - ); + void render(final @NotNull GuiContainer<@NotNull P, @NotNull I> container); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index 609c8a48..aef25a97 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,17 +23,11 @@ */ package dev.triumphteam.gui.component.functional; -import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.GuiComponentProducer; -import dev.triumphteam.gui.component.ReactiveGuiComponent; -import dev.triumphteam.gui.container.GuiContainer; +import dev.triumphteam.gui.component.SimpleGuiComponent; import dev.triumphteam.gui.exception.TriumphGuiException; -import dev.triumphteam.nova.State; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; public final class SimpleFunctionalGuiComponent extends AbstractFunctionalGuiComponent

implements FunctionalGuiComponent, GuiComponentProducer { @@ -50,22 +44,6 @@ public void render(final @NotNull FunctionalGuiComponentRender component) throw new TriumphGuiException("TODO"); } - return new ReactiveGuiComponent<>() { - - @Override - public @Nullable ClickHandler

clickHandler() { - return getClickHandler(); - } - - @Override - public void render(final @NotNull GuiContainer<@NotNull P, @NotNull I> container, @NotNull final P player) { - component.render(container, player); - } - - @Override - public @NotNull List states() { - return getStates(); - } - }; + return new SimpleGuiComponent<>(component, getStates()); } } diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java index 73a53b4e..959a5132 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,6 +25,7 @@ import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.item.GuiItem; +import dev.triumphteam.gui.layout.GuiLayout; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; @@ -38,4 +39,6 @@ public interface GuiContainer { void set(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); + + void fill(final @NotNull GuiLayout layout, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); } diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index 0c68d5b5..6e0818f9 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -27,6 +27,7 @@ import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.item.GuiItem; import dev.triumphteam.gui.item.RenderedGuiItem; +import dev.triumphteam.gui.layout.GuiLayout; import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; @@ -72,6 +73,11 @@ public void set(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> g backing.put(slot, renderedItem); } + @Override + public void fill(final @NotNull GuiLayout layout, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { + layout.generatePositions().forEach(position -> set(position, guiItem)); + } + public @NotNull Map> complete() { return Collections.unmodifiableMap(backing); } diff --git a/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java new file mode 100644 index 00000000..68910518 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java @@ -0,0 +1,66 @@ +/** + * MIT License + *

+ * Copyright (c) 2024 TriumphTeam + *

+ * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + *

+ * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + *

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package dev.triumphteam.gui.layout; + +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +public final class BorderGuiLayout implements GuiLayout { + + private final List slots = new ArrayList<>(); + + public BorderGuiLayout(final int rows) { + this(Slot.origin(), Slot.max(rows)); + } + + public BorderGuiLayout(final @NotNull Slot min, final @NotNull Slot max) { + // Top border + for (int col = min.column(); col <= max.column(); col++) { + slots.add(new Slot(min.row(), col)); + } + + // Bottom border + for (int col = min.column(); col <= max.column(); col++) { + slots.add(new Slot(max.row(), col)); + } + + // Left border + for (int row = min.row() + 1; row < max.row(); row++) { + slots.add(new Slot(row, min.column())); + } + + // Right border + for (int row = min.row() + 1; row < max.row(); row++) { + slots.add(new Slot(row, max.column())); + } + } + + @Override + public @NotNull List<@NotNull Slot> generatePositions() { + return slots; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java index c9541859..036e4e30 100644 --- a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java +++ b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,4 +28,8 @@ public record Slot(int row, int column) { public static Slot of(final int row, final int column) { return new Slot(row, column); } + + public static Slot origin() {return new Slot(1, 1);} + + public static Slot max(final int rows) {return new Slot(rows, 9);} } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 517e4749..9140f6a9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] # kotlin -kotlin = "1.8.10" +kotlin = "2.0.21" coroutines = "1.6.4" license = "0.16.1" diff --git a/kotlin/build.gradle.kts b/kotlin/build.gradle.kts new file mode 100644 index 00000000..7480f9b1 --- /dev/null +++ b/kotlin/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("gui.base") + id("gui.library") +} + +dependencies { + api(libs.nova.kotlin) + implementation(kotlin("stdlib")) + implementation(projects.triumphGuiCore) +} diff --git a/kotlin/src/main/kotlin/GuiBuilderExt.kt b/kotlin/src/main/kotlin/GuiBuilderExt.kt new file mode 100644 index 00000000..73bb4eb3 --- /dev/null +++ b/kotlin/src/main/kotlin/GuiBuilderExt.kt @@ -0,0 +1,13 @@ +package dev.triumphteam.gui.kotlin + +import dev.triumphteam.gui.BaseGui +import dev.triumphteam.gui.builder.BaseGuiBuilder +import dev.triumphteam.gui.component.functional.FunctionalGuiComponent +import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent + +// TODO(matt): Actually make this suspending +public fun , P, G : BaseGui

, I> BaseGuiBuilder.suspendingComponent( + block: FunctionalGuiComponent.() -> Unit, +): B { + return component(SimpleFunctionalGuiComponent().apply(block).asGuiComponent()) +} diff --git a/kotlin/src/main/kotlin/SlotExt.kt b/kotlin/src/main/kotlin/SlotExt.kt new file mode 100644 index 00000000..eecaa122 --- /dev/null +++ b/kotlin/src/main/kotlin/SlotExt.kt @@ -0,0 +1,13 @@ +package dev.triumphteam.gui.kotlin + +import dev.triumphteam.gui.slot.Slot + +public operator fun Slot.component1(): Int = row +public operator fun Slot.component2(): Int = column + +public fun slot(row: Int, column: Int): Slot = Slot(row, column) + +public fun main() { + + val (row, column) = Slot.of(1, 2) +} diff --git a/kotlin/src/main/kotlin/package-info.kt b/kotlin/src/main/kotlin/package-info.kt new file mode 100644 index 00000000..f094e893 --- /dev/null +++ b/kotlin/src/main/kotlin/package-info.kt @@ -0,0 +1 @@ +package dev.triumphteam.gui.kotlin diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java index de3e24f2..dfd5d076 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java @@ -24,6 +24,7 @@ package dev.triumphteam.gui.paper.builder.item; import com.google.common.base.Preconditions; +import dev.triumphteam.gui.click.action.EmptyGuiClickAction; import dev.triumphteam.gui.click.action.GuiClickAction; import dev.triumphteam.gui.click.action.RunnableGuiClickAction; import dev.triumphteam.gui.item.GuiItem; @@ -135,4 +136,10 @@ public GuiItem asGuiItem(final @NotNull RunnableGuiClickActio public GuiItem asGuiItem(final @NotNull GuiClickAction action) { return new SimpleGuiItem<>(asItemStack(), action); } + + @NotNull + @Contract(" -> new") + public GuiItem asGuiItem() { + return new SimpleGuiItem<>(asItemStack(), new EmptyGuiClickAction<>()); + } } diff --git a/settings.gradle.kts b/settings.gradle.kts index ac6a5862..d9866538 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -20,5 +20,5 @@ plugins { id("dev.triumphteam.root.settings") version "0.0.6" } -listOf("core", "paper").forEach(::includeProject) +listOf("core", "paper", "kotlin").forEach(::includeProject) include("test-plugin") From e4ab63a8c8b6861460f75353b32fd8bc8885aa4a Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 16 Oct 2024 23:31:57 +0100 Subject: [PATCH 20/43] fix: Some compile errors --- .../gui/component/components/PaginatedComponent.java | 2 +- .../gui/component/renderer/DefaultGuiComponentRenderer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java index 5165748d..68a9d614 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java @@ -71,7 +71,7 @@ public PaginatedComponent( } @Override - public void render(final @NotNull GuiContainer container, @NotNull final P player) { + public void render(final @NotNull GuiContainer container) { final var page = pageState.getValue(); container.set(back, new SimpleGuiItem<>(backItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.setValue(page - 1))); diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java index 91907157..4b7066ad 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java @@ -46,7 +46,7 @@ public void renderComponent( ); if (component instanceof ReactiveGuiComponent) { - ((ReactiveGuiComponent) component).render(container, player); + ((ReactiveGuiComponent) component).render(container); } final var renderedItems = container.complete(); From d2911e587a439e26f2fa4301af4f57700aac6ba6 Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 17 Oct 2024 23:05:31 +0100 Subject: [PATCH 21/43] feature: Reactive GUI title --- .gitignore | 2 + .../src/main/kotlin/gui.base.gradle.kts | 2 +- .../dev/triumphteam/gui/AbstractGuiView.java | 56 +++++++++++++++++-- .../gui/builder/BaseGuiBuilder.java | 34 +++++++---- .../gui/component/GuiComponentProducer.java | 32 ----------- .../gui/component/StatefulGuiComponent.java | 11 ++-- .../FunctionalGuiComponentBuilder.java | 32 ----------- .../SimpleFunctionalGuiComponent.java | 4 +- .../gui/container/type/GuiContainerType.java | 2 +- .../dev/triumphteam/gui/title/GuiTitle.java | 3 + .../gui/title/ReactiveGuiTitle.java | 9 +++ .../triumphteam/gui/title/SimpleGuiTitle.java | 29 ++++++++++ .../gui/title/StatefulGuiTitle.java | 11 ++++ .../title/functional/FunctionalGuiTitle.java | 9 +++ .../functional/FunctionalGuiTitleRender.java | 10 ++++ .../functional/SimpleFunctionalGuiTitle.java | 24 ++++++++ .../renderer/DefaultGuiTitleRenderer.java | 27 +++++++++ .../gui/title/renderer/GuiTitleRenderer.java | 15 +++++ gradle/libs.versions.toml | 4 +- paper/build.gradle.kts | 2 +- .../triumphteam/gui/paper/BukkitGuiView.java | 38 ++++++++----- .../java/dev/triumphteam/gui/paper/Gui.java | 14 ++--- .../gui/paper/GuiBukkitListener.java | 26 +++++++-- 23 files changed, 276 insertions(+), 120 deletions(-) delete mode 100644 core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java delete mode 100644 core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/GuiTitle.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/ReactiveGuiTitle.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/SimpleGuiTitle.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/StatefulGuiTitle.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitle.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitleRender.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/functional/SimpleFunctionalGuiTitle.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java create mode 100644 core/src/main/java/dev/triumphteam/gui/title/renderer/GuiTitleRenderer.java diff --git a/.gitignore b/.gitignore index bdb4e296..b2d4192d 100644 --- a/.gitignore +++ b/.gitignore @@ -121,3 +121,5 @@ gradle-app.setting .classpath # End of https://www.toptal.com/developers/gitignore/api/gradle,intellij+all + +*.salive diff --git a/build-logic/src/main/kotlin/gui.base.gradle.kts b/build-logic/src/main/kotlin/gui.base.gradle.kts index b18192d1..7183102b 100644 --- a/build-logic/src/main/kotlin/gui.base.gradle.kts +++ b/build-logic/src/main/kotlin/gui.base.gradle.kts @@ -21,7 +21,7 @@ dependencies { java { - toolchain.languageVersion.set(JavaLanguageVersion.of(16)) + toolchain.languageVersion.set(JavaLanguageVersion.of(21)) withSourcesJar() withJavadocJar() } diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 19bdb467..e0cf1b73 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -30,7 +30,13 @@ import dev.triumphteam.gui.component.StatefulGuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; import dev.triumphteam.gui.container.type.GuiContainerType; +import dev.triumphteam.gui.exception.TriumphGuiException; import dev.triumphteam.gui.item.RenderedGuiItem; +import dev.triumphteam.gui.title.GuiTitle; +import dev.triumphteam.gui.title.StatefulGuiTitle; +import dev.triumphteam.gui.title.renderer.DefaultGuiTitleRenderer; +import dev.triumphteam.gui.title.renderer.GuiTitleRenderer; +import net.kyori.adventure.text.Component; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,30 +44,37 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; public abstract class AbstractGuiView implements GuiView { private final P viewer; + private final GuiTitle title; private final List> components; private final GuiComponentRenderer renderer; private final ClickHandler

defaultClickHandler; private final GuiContainerType containerType; + private final GuiTitleRenderer titleRenderer = new DefaultGuiTitleRenderer(); + private final AtomicBoolean firstOpen = new AtomicBoolean(true); // Click processor private final ClickProcessor clickProcessor; // Cache of rendered components private final Map, RenderedComponent> renderedComponents = new ConcurrentHashMap<>(); // All the gui items that have been rendered and are in the inventory private final Map> allRenderedItems = new ConcurrentHashMap<>(); + private Component renderedTitle = null; public AbstractGuiView( final @NotNull P viewer, + final @NotNull GuiTitle title, final @NotNull List<@NotNull GuiComponent> components, final @NotNull GuiContainerType containerType, final @NotNull GuiComponentRenderer renderer, final @NotNull ClickHandler

defaultClickHandler, final @NotNull ClickProcessor clickProcessor ) { + this.title = title; this.viewer = viewer; this.components = components; this.containerType = containerType; @@ -82,6 +95,30 @@ public AbstractGuiView( protected abstract void populateInventory(final @NotNull Map> renderedItems); + protected abstract void openInventory(); + + @Override + public void open() { + if (title instanceof StatefulGuiTitle statefulGuiTitle) { + // Add listener to used states + statefulGuiTitle.states().forEach(state -> { + state.addListener(this, () -> { + firstOpen.compareAndSet(true, false); + titleRenderer.renderTitle(title, (rendered) -> { + this.renderedTitle = rendered; + openInventory(); + }); + }); + }); + } + + titleRenderer.renderTitle(title, (rendered) -> { + this.renderedTitle = rendered; + openInventory(); + setup(); + }); + } + protected void setup() { components.forEach(component -> { @@ -132,4 +169,15 @@ public void completeRendered(final @NotNull RenderedComponent renderedComp public @NotNull GuiContainerType getContainerType() { return containerType; } + + public Component getTitle() { + if (renderedTitle == null) { + throw new TriumphGuiException("Tried to get title before it was available."); + } + return renderedTitle; + } + + public boolean isFirstOpen() { + return firstOpen.get(); + } } diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index fa1671c0..63a3b794 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -27,16 +27,18 @@ import dev.triumphteam.gui.GuiView; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; -import dev.triumphteam.gui.component.GuiComponentProducer; import dev.triumphteam.gui.component.SimpleGuiComponent; import dev.triumphteam.gui.component.functional.FunctionalGuiComponent; -import dev.triumphteam.gui.component.functional.FunctionalGuiComponentBuilder; import dev.triumphteam.gui.component.functional.FunctionalGuiComponentRender; import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.exception.TriumphGuiException; import dev.triumphteam.gui.settings.GuiSettings; +import dev.triumphteam.gui.title.functional.FunctionalGuiTitle; +import dev.triumphteam.gui.title.GuiTitle; +import dev.triumphteam.gui.title.functional.SimpleFunctionalGuiTitle; +import dev.triumphteam.gui.title.SimpleGuiTitle; import net.kyori.adventure.text.Component; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -45,6 +47,7 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; /** * Main builder for all GUIs. @@ -64,7 +67,7 @@ public abstract class BaseGuiBuilder, P, G private ClickHandler

clickHandler = null; private GuiComponentRenderer componentRenderer = null; - private Component title = null; + private GuiTitle title = null; private long spamPreventionDuration = -1; public BaseGuiBuilder( @@ -83,7 +86,14 @@ public BaseGuiBuilder( */ @Contract("_ -> this") public @NotNull B title(final @NotNull Component title) { - this.title = title; + this.title = new SimpleGuiTitle(() -> title, Collections.emptyList()); + return (B) this; + } + + public @NotNull B title(final @NotNull Consumer<@NotNull FunctionalGuiTitle> title) { + final var simpleTitle = new SimpleFunctionalGuiTitle(); + title.accept(simpleTitle); + this.title = simpleTitle.asGuiTitle(); return (B) this; } @@ -131,18 +141,18 @@ public BaseGuiBuilder( /** * Adds a {@link GuiComponent} to the {@link BaseGui}. *

- * The {@link FunctionalGuiComponentBuilder} will create a {@link FunctionalGuiComponent}, - * which by itself is NOT a {@link GuiComponent} but instead a {@link GuiComponentProducer}.

+ * The {@link Consumer} will create a {@link FunctionalGuiComponent}, + * which by itself is NOT a {@link GuiComponent}.

* This will in turn build a real {@link GuiComponent} before being added to the {@link BaseGui}. * - * @param builder The functional component builder. + * @param component The functional component builder. * @return The {@link B} instance of the {@link BaseGuiBuilder}. */ @Contract("_ -> this") - public @NotNull B component(final @NotNull FunctionalGuiComponentBuilder builder) { - final var componentRenderer = new SimpleFunctionalGuiComponent(); - builder.accept(componentRenderer); - components.add(componentRenderer.asGuiComponent()); + public @NotNull B component(final @NotNull Consumer<@NotNull FunctionalGuiComponent> component) { + final var simpleComponent = new SimpleFunctionalGuiComponent(); + component.accept(simpleComponent); + components.add(simpleComponent.asGuiComponent()); return (B) this; } @@ -203,7 +213,7 @@ public BaseGuiBuilder( return componentRenderer; } - protected @NotNull Component getTitle() { + protected @NotNull GuiTitle getTitle() { if (title == null) { throw new TriumphGuiException("Cannot create GUI with empty title!"); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java b/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java deleted file mode 100644 index 4bd9ace7..00000000 --- a/core/src/main/java/dev/triumphteam/gui/component/GuiComponentProducer.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.component; - -import org.jetbrains.annotations.NotNull; - -public interface GuiComponentProducer { - - @NotNull - GuiComponent asGuiComponent(); -} diff --git a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java index 7e338df2..07c28a4c 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -30,6 +30,5 @@ public interface StatefulGuiComponent extends GuiComponent { - @NotNull - List states(); + @NotNull List states(); } diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java b/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java deleted file mode 100644 index 3fd9f9a2..00000000 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/FunctionalGuiComponentBuilder.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.component.functional; - -import org.jetbrains.annotations.NotNull; - -@FunctionalInterface -public interface FunctionalGuiComponentBuilder { - - void accept(final @NotNull FunctionalGuiComponent<@NotNull P, @NotNull I> component); -} diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index aef25a97..f8b4ce72 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -24,12 +24,11 @@ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.component.GuiComponent; -import dev.triumphteam.gui.component.GuiComponentProducer; import dev.triumphteam.gui.component.SimpleGuiComponent; import dev.triumphteam.gui.exception.TriumphGuiException; import org.jetbrains.annotations.NotNull; -public final class SimpleFunctionalGuiComponent extends AbstractFunctionalGuiComponent

implements FunctionalGuiComponent, GuiComponentProducer { +public final class SimpleFunctionalGuiComponent extends AbstractFunctionalGuiComponent

implements FunctionalGuiComponent { private FunctionalGuiComponentRender component = null; @@ -38,7 +37,6 @@ public void render(final @NotNull FunctionalGuiComponentRender component) this.component = component; } - @Override public @NotNull GuiComponent asGuiComponent() { if (component == null) { throw new TriumphGuiException("TODO"); diff --git a/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java b/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java index 3ced9ec1..3ccd39a6 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java +++ b/core/src/main/java/dev/triumphteam/gui/container/type/GuiContainerType.java @@ -30,5 +30,5 @@ public interface GuiContainerType { int mapSlot(final @NotNull Slot slot); - Slot mapSlot(final int slot); + @NotNull Slot mapSlot(final int slot); } diff --git a/core/src/main/java/dev/triumphteam/gui/title/GuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/GuiTitle.java new file mode 100644 index 00000000..12c21748 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/GuiTitle.java @@ -0,0 +1,3 @@ +package dev.triumphteam.gui.title; + +public interface GuiTitle {} diff --git a/core/src/main/java/dev/triumphteam/gui/title/ReactiveGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/ReactiveGuiTitle.java new file mode 100644 index 00000000..2290c6b5 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/ReactiveGuiTitle.java @@ -0,0 +1,9 @@ +package dev.triumphteam.gui.title; + +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +public interface ReactiveGuiTitle extends StatefulGuiTitle { + + @NotNull Component render(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/title/SimpleGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/SimpleGuiTitle.java new file mode 100644 index 00000000..cd3036d4 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/SimpleGuiTitle.java @@ -0,0 +1,29 @@ +package dev.triumphteam.gui.title; + +import dev.triumphteam.gui.title.functional.FunctionalGuiTitleRender; +import dev.triumphteam.nova.State; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public final class SimpleGuiTitle implements ReactiveGuiTitle { + + private final List states; + private final FunctionalGuiTitleRender render; + + public SimpleGuiTitle(final @NotNull FunctionalGuiTitleRender render, final @NotNull List states) { + this.render = render; + this.states = states; + } + + @Override + public @NotNull Component render() { + return render.render(); + } + + @Override + public @NotNull List states() { + return states; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/title/StatefulGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/StatefulGuiTitle.java new file mode 100644 index 00000000..9f4b32fc --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/StatefulGuiTitle.java @@ -0,0 +1,11 @@ +package dev.triumphteam.gui.title; + +import dev.triumphteam.nova.State; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface StatefulGuiTitle extends GuiTitle { + + @NotNull List states(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitle.java new file mode 100644 index 00000000..6aca8022 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitle.java @@ -0,0 +1,9 @@ +package dev.triumphteam.gui.title.functional; + +import dev.triumphteam.nova.holder.StateHolder; +import org.jetbrains.annotations.NotNull; + +public interface FunctionalGuiTitle extends StateHolder { + + void render(final @NotNull FunctionalGuiTitleRender render); +} diff --git a/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitleRender.java b/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitleRender.java new file mode 100644 index 00000000..928b9bb9 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitleRender.java @@ -0,0 +1,10 @@ +package dev.triumphteam.gui.title.functional; + +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +@FunctionalInterface +public interface FunctionalGuiTitleRender { + + @NotNull Component render(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/title/functional/SimpleFunctionalGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/functional/SimpleFunctionalGuiTitle.java new file mode 100644 index 00000000..60d13b24 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/functional/SimpleFunctionalGuiTitle.java @@ -0,0 +1,24 @@ +package dev.triumphteam.gui.title.functional; + +import dev.triumphteam.gui.exception.TriumphGuiException; +import dev.triumphteam.gui.title.GuiTitle; +import dev.triumphteam.gui.title.SimpleGuiTitle; +import dev.triumphteam.nova.holder.AbstractStateHolder; +import org.jetbrains.annotations.NotNull; + +public final class SimpleFunctionalGuiTitle extends AbstractStateHolder implements FunctionalGuiTitle { + + private FunctionalGuiTitleRender guiTitleRender = null; + + @Override + public void render(final @NotNull FunctionalGuiTitleRender render) { + this.guiTitleRender = render; + } + + public @NotNull GuiTitle asGuiTitle() { + if (guiTitleRender == null) { + throw new TriumphGuiException("TODO TITLE"); + } + return new SimpleGuiTitle(guiTitleRender, getStates()); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java b/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java new file mode 100644 index 00000000..7620a366 --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java @@ -0,0 +1,27 @@ +package dev.triumphteam.gui.title.renderer; + +import dev.triumphteam.gui.exception.TriumphGuiException; +import dev.triumphteam.gui.title.GuiTitle; +import dev.triumphteam.gui.title.ReactiveGuiTitle; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public final class DefaultGuiTitleRenderer implements GuiTitleRenderer { + + @Override + public void renderTitle( + final @NotNull GuiTitle title, + final @NotNull Consumer thenRun + ) { + + if ((title instanceof ReactiveGuiTitle reactiveGuiTitle)) { + final var component = reactiveGuiTitle.render(); + thenRun.accept(component); + return; + } + + throw new TriumphGuiException("Could not render title as it is not supported by the current renderer."); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/title/renderer/GuiTitleRenderer.java b/core/src/main/java/dev/triumphteam/gui/title/renderer/GuiTitleRenderer.java new file mode 100644 index 00000000..7f642b4b --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/title/renderer/GuiTitleRenderer.java @@ -0,0 +1,15 @@ +package dev.triumphteam.gui.title.renderer; + +import dev.triumphteam.gui.title.GuiTitle; +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.NotNull; + +import java.util.function.Consumer; + +public interface GuiTitleRenderer { + + void renderTitle( + final @NotNull GuiTitle title, + final @NotNull Consumer thenRun + ); +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9140f6a9..ba29e53a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ nova = "1.0.0-SNAPSHOT" # Minecraft adventure = "4.16.0" -paper = "1.16.5-R0.1-SNAPSHOT" +paper = "1.21.1-R0.1-SNAPSHOT" [libraries] # Core @@ -24,7 +24,7 @@ nova = { module = "dev.triumphteam:nova", version.ref = "nova" } nova-kotlin = { module = "dev.triumphteam:nova-kotlin", version.ref = "nova" } # Minecraft -paper = { module = "com.destroystokyo.paper:paper-api", version.ref = "paper" } +paper = { module = "io.papermc.paper:paper-api", version.ref = "paper" } adventure-api = { module = "net.kyori:adventure-api", version.ref = "adventure" } # Kotlin diff --git a/paper/build.gradle.kts b/paper/build.gradle.kts index 2353516e..500e2cac 100644 --- a/paper/build.gradle.kts +++ b/paper/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } repositories { - maven("https://papermc.io/repo/repository/maven-public/") + maven("https://repo.papermc.io/repository/maven-public/") } dependencies { diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java b/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java index 4b62920c..da2c02d8 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -28,9 +28,10 @@ import dev.triumphteam.gui.click.processor.ClickProcessor; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; +import dev.triumphteam.gui.exception.TriumphGuiException; import dev.triumphteam.gui.item.RenderedGuiItem; import dev.triumphteam.gui.paper.container.type.PaperContainerType; -import net.kyori.adventure.text.Component; +import dev.triumphteam.gui.title.GuiTitle; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; @@ -43,25 +44,29 @@ public final class BukkitGuiView extends AbstractGuiView implements InventoryHolder { - private final Inventory inventory; + private final PaperContainerType containerType; + private Inventory inventory = null; public BukkitGuiView( final @NotNull Player player, - final @NotNull Component title, + final @NotNull GuiTitle title, final @NotNull PaperContainerType containerType, final @NotNull List> components, final @NotNull GuiComponentRenderer componentRenderer, final @NotNull ClickHandler clickHandler, final long spamPreventionDuration ) { - super(player, components, containerType, componentRenderer, clickHandler, new ClickProcessor<>(spamPreventionDuration)); - this.inventory = containerType.createInventory(this, title); + super(player, title, components, containerType, componentRenderer, clickHandler, new ClickProcessor<>(spamPreventionDuration)); + this.containerType = containerType; } @Override - public void open() { + public void openInventory() { + if (inventory == null) { + this.inventory = containerType.createInventory(this, getTitle()); + } + viewer().openInventory(inventory); - setup(); } @Override @@ -69,14 +74,15 @@ public void close() { } - @NotNull @Override - public Inventory getInventory() { + public @NotNull Inventory getInventory() { + checkInventory(); return inventory; } @Override protected void clearSlot(final int slot) { + checkInventory(); inventory.clear(slot); } @@ -94,4 +100,10 @@ protected void clearSlot(final int slot) { protected void populateInventory(final @NotNull Map> renderedItems) { renderedItems.forEach((slot, item) -> inventory.setItem(slot, item.item())); } + + private void checkInventory() throws TriumphGuiException { + if (inventory == null) { + throw new TriumphGuiException("Tried to get inventory before it was available."); + } + } } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index e324636d..b861ace0 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -31,7 +31,7 @@ import dev.triumphteam.gui.paper.builder.gui.GuiBuilder; import dev.triumphteam.gui.paper.container.type.ChestContainerType; import dev.triumphteam.gui.paper.container.type.PaperContainerType; -import net.kyori.adventure.text.Component; +import dev.triumphteam.gui.title.GuiTitle; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Contract; @@ -48,7 +48,7 @@ public final class Gui implements BaseGui { GuiBukkitListener.register(); } - private final Component title; + private final GuiTitle title; private final List> components; private final PaperContainerType containerType; private final GuiComponentRenderer componentRenderer; @@ -56,7 +56,7 @@ public final class Gui implements BaseGui { private final long spamPreventionDuration; public Gui( - final @NotNull Component title, + final @NotNull GuiTitle title, final @NotNull List> components, final @NotNull PaperContainerType containerType, final @NotNull GuiComponentRenderer componentRenderer, diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java index 769ea06e..9e93bde9 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,7 +26,9 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; public final class GuiBukkitListener implements Listener { @@ -36,14 +38,26 @@ public static void register() { } @EventHandler - public void onGuiClick(final InventoryClickEvent event) { + public void onGuiClick(final @NotNull InventoryClickEvent event) { final var holder = event.getInventory().getHolder(); if (!(holder instanceof final BukkitGuiView view)) { return; } event.setCancelled(true); - view.getClickProcessor().processClick(event.getSlot(), view); } + + @EventHandler + public void onInventoryOpen(final @NotNull InventoryOpenEvent event) { + final var holder = event.getInventory().getHolder(); + if (!(holder instanceof final BukkitGuiView view)) { + return; + } + + if (!view.isFirstOpen()) { + System.out.println("Not first open"); + event.titleOverride(view.getTitle()); + } + } } From 04281c9eb335e18b0f81208968196ea5307ac766 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 18 Oct 2024 00:29:07 +0100 Subject: [PATCH 22/43] chore: Code cleanup --- .../java/dev/triumphteam/gui/AbstractGuiView.java | 4 ++-- .../click/handler/CompletableFutureClickHandler.java | 4 ++-- .../gui/click/handler/SimpleClickHandler.java | 4 ++-- .../renderer/DefaultGuiComponentRenderer.java | 12 ++++++------ .../gui/title/renderer/DefaultGuiTitleRenderer.java | 9 ++++----- .../dev/triumphteam/gui/paper/GuiBukkitListener.java | 1 - 6 files changed, 16 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index e0cf1b73..bfc6aac2 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -122,9 +122,9 @@ public void open() { protected void setup() { components.forEach(component -> { - if (component instanceof StatefulGuiComponent) { + if (component instanceof StatefulGuiComponent statefulComponent) { // Add listener to used states - ((StatefulGuiComponent) component).states().forEach(state -> { + statefulComponent.states().forEach(state -> { state.addListener(this, () -> renderer.renderComponent(viewer, component, this)); }); } diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java index 643b39d3..da227c96 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/CompletableFutureClickHandler.java @@ -60,7 +60,7 @@ public void handle( final @NotNull ClickController controller ) { // Only accept runnable actions - if (!(action instanceof RunnableGuiClickAction

)) { + if (!(action instanceof RunnableGuiClickAction

runnableAction)) { throw new TriumphGuiException("The click action type '" + action.getClass().getName() + "' is supported by the 'CompletableFutureClickHandler'."); } @@ -68,7 +68,7 @@ public void handle( controller.completingLater(true); // Run the action async and complete click when finished - CompletableFuture.runAsync(() -> ((RunnableGuiClickAction

) action).run(player, context)) + CompletableFuture.runAsync(() -> runnableAction.run(player, context)) .orTimeout(timeout, unit) .whenComplete((unused, throwable) -> controller.complete(throwable)); } diff --git a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java index a127aa88..e37c959b 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java +++ b/core/src/main/java/dev/triumphteam/gui/click/handler/SimpleClickHandler.java @@ -48,11 +48,11 @@ public void handle( final @NotNull ClickController controller ) { // Only accept runnable actions - if (!(action instanceof RunnableGuiClickAction

)) { + if (!(action instanceof RunnableGuiClickAction

runnableAction)) { throw new TriumphGuiException("The click action type '" + action.getClass().getName() + "' is supported by the 'CompletableFutureClickHandler'."); } // Run the action - ((RunnableGuiClickAction

) action).run(player, context); + runnableAction.run(player, context); } } diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java index 4b7066ad..cff9d27d 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -45,8 +45,8 @@ public void renderComponent( view.getContainerType() ); - if (component instanceof ReactiveGuiComponent) { - ((ReactiveGuiComponent) component).render(container); + if (component instanceof ReactiveGuiComponent reactiveComponent) { + reactiveComponent.render(container); } final var renderedItems = container.complete(); diff --git a/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java b/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java index 7620a366..13756896 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java @@ -16,12 +16,11 @@ public void renderTitle( final @NotNull Consumer thenRun ) { - if ((title instanceof ReactiveGuiTitle reactiveGuiTitle)) { - final var component = reactiveGuiTitle.render(); - thenRun.accept(component); - return; + if (!(title instanceof ReactiveGuiTitle reactiveGuiTitle)) { + throw new TriumphGuiException("Could not render title as it is not supported by the current renderer."); } - throw new TriumphGuiException("Could not render title as it is not supported by the current renderer."); + final var component = reactiveGuiTitle.render(); + thenRun.accept(component); } } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java index 9e93bde9..ef2982d8 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java @@ -56,7 +56,6 @@ public void onInventoryOpen(final @NotNull InventoryOpenEvent event) { } if (!view.isFirstOpen()) { - System.out.println("Not first open"); event.titleOverride(view.getTitle()); } } From ade42a4f9b8a62743b64e6007695c221f772e2fe Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 18 Oct 2024 20:28:41 +0100 Subject: [PATCH 23/43] chore: Rename some files and update Nova to use "remember" over "state" --- .../components/PaginatedComponent.java | 4 +-- .../java/dev/triumphteam/gui/paper/Gui.java | 4 +-- ...kitListener.java => PaperGuiListener.java} | 35 +++++++++++++------ .../gui/paper/PaperGuiSettings.java | 2 +- .../{BukkitGuiView.java => PaperGuiView.java} | 4 +-- .../container/type/ChestContainerType.java | 2 +- 6 files changed, 31 insertions(+), 20 deletions(-) rename paper/src/main/java/dev/triumphteam/gui/paper/{GuiBukkitListener.java => PaperGuiListener.java} (66%) rename paper/src/main/java/dev/triumphteam/gui/paper/{BukkitGuiView.java => PaperGuiView.java} (96%) diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java index 68a9d614..f23c72b9 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java @@ -32,8 +32,6 @@ import dev.triumphteam.gui.slot.Slot; import dev.triumphteam.nova.MutableState; import dev.triumphteam.nova.State; -import dev.triumphteam.nova.builtin.SimpleMutableState; -import dev.triumphteam.nova.policy.StateMutationPolicy; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -47,7 +45,7 @@ public final class PaginatedComponent implements ReactiveGuiComponent> items; private final GuiLayout layout; - private final MutableState pageState = new SimpleMutableState<>(0, StateMutationPolicy.StructuralEquality.INSTANCE); + private final MutableState pageState = MutableState.of(1); public PaginatedComponent( final @NotNull Slot back, diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index b861ace0..cb3a6b3c 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -45,7 +45,7 @@ public final class Gui implements BaseGui { static { - GuiBukkitListener.register(); + PaperGuiListener.register(); } private final GuiTitle title; @@ -96,7 +96,7 @@ public static GuiBuilder of(final int rows) { @Override public void open(final @NotNull Player player) { - final var view = new BukkitGuiView( + final var view = new PaperGuiView( player, title, containerType, diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java similarity index 66% rename from paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java rename to paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java index ef2982d8..3b334372 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/GuiBukkitListener.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java @@ -26,37 +26,50 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryOpenEvent; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public final class GuiBukkitListener implements Listener { +public final class PaperGuiListener implements Listener { public static void register() { // Auto-register listener if none was registered yet - PaperGuiSettings.get().register(JavaPlugin.getProvidingPlugin(GuiBukkitListener.class)); + PaperGuiSettings.get().register(JavaPlugin.getProvidingPlugin(PaperGuiListener.class)); } @EventHandler public void onGuiClick(final @NotNull InventoryClickEvent event) { - final var holder = event.getInventory().getHolder(); - if (!(holder instanceof final BukkitGuiView view)) { - return; - } + final var view = convertHolder(event.getInventory().getHolder()); + if (view == null) return; event.setCancelled(true); view.getClickProcessor().processClick(event.getSlot(), view); } @EventHandler - public void onInventoryOpen(final @NotNull InventoryOpenEvent event) { - final var holder = event.getInventory().getHolder(); - if (!(holder instanceof final BukkitGuiView view)) { - return; - } + public void onGuiDrag(final @NotNull InventoryDragEvent event) { + final var view = convertHolder(event.getInventory().getHolder()); + if (view == null) return; + + event.setCancelled(true); + } + + @EventHandler + public void onGuiOpen(final @NotNull InventoryOpenEvent event) { + final var view = convertHolder(event.getInventory().getHolder()); + if (view == null) return; if (!view.isFirstOpen()) { event.titleOverride(view.getTitle()); } } + + private @Nullable PaperGuiView convertHolder(final @Nullable InventoryHolder holder) { + if (holder == null) return null; + if (holder instanceof PaperGuiView paperGuiView) return paperGuiView; + return null; + } } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java index 86291f33..29472cb1 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java @@ -49,7 +49,7 @@ public PaperGuiSettings register(final @NotNull Plugin plugin) { if (this.listenerRegistered) return this; this.plugin = plugin; - Bukkit.getServer().getPluginManager().registerEvents(new GuiBukkitListener(), plugin); + Bukkit.getServer().getPluginManager().registerEvents(new PaperGuiListener(), plugin); this.listenerRegistered = true; return this; } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java similarity index 96% rename from paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java rename to paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java index da2c02d8..f88d466b 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/BukkitGuiView.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java @@ -42,12 +42,12 @@ import java.util.Map; import java.util.UUID; -public final class BukkitGuiView extends AbstractGuiView implements InventoryHolder { +public final class PaperGuiView extends AbstractGuiView implements InventoryHolder { private final PaperContainerType containerType; private Inventory inventory = null; - public BukkitGuiView( + public PaperGuiView( final @NotNull Player player, final @NotNull GuiTitle title, final @NotNull PaperContainerType containerType, diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java index fdf35032..1217ca6d 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java @@ -61,7 +61,7 @@ public int mapSlot(final @NotNull Slot slot) { } @Override - public Slot mapSlot(final int slot) { + public @NotNull Slot mapSlot(final int slot) { return Slot.of(slot / 9 + 1, slot % 9 + 1); } From 3ee3ead31565ff829e01d65ec9824dd7aaca2299 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 18 Oct 2024 22:47:24 +0100 Subject: [PATCH 24/43] chore: Kotlin Container extensions --- .../components/PaginatedComponent.java | 8 ++++---- .../gui/container/GuiContainer.java | 6 +++--- .../gui/container/MapBackedContainer.java | 12 ++++++------ kotlin/src/main/kotlin/ContainerExt.kt | 18 ++++++++++++++++++ kotlin/src/main/kotlin/SlotExt.kt | 5 ----- 5 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 kotlin/src/main/kotlin/ContainerExt.kt diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java index f23c72b9..1ecfc0b4 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java @@ -70,10 +70,10 @@ public PaginatedComponent( @Override public void render(final @NotNull GuiContainer container) { - final var page = pageState.getValue(); + final var page = pageState.get(); - container.set(back, new SimpleGuiItem<>(backItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.setValue(page - 1))); - container.set(forward, new SimpleGuiItem<>(forwardItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.setValue(page + 1))); + container.setItem(back, new SimpleGuiItem<>(backItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.set(page - 1))); + container.setItem(forward, new SimpleGuiItem<>(forwardItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.set(page + 1))); final var slots = layout.generatePositions(); final var size = slots.size(); @@ -90,7 +90,7 @@ public void render(final @NotNull GuiContainer container) { final var slot = slots.get(i); final var item = items.get(offsetSlot); - container.set(slot, item); + container.setItem(slot, item); } } } diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java index 959a5132..addec797 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -34,11 +34,11 @@ public interface GuiContainer { @NotNull GuiContainerType containerType(); - void set(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); + void setItem(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); - void set(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); + void setItem(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); - void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); + void setItem(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); void fill(final @NotNull GuiLayout layout, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem); } diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index 6e0818f9..d6f3cfbb 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -55,17 +55,17 @@ public MapBackedContainer( } @Override - public void set(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { - set(containerType.mapSlot(Slot.of(row, column)), guiItem); + public void setItem(final int row, final int column, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { + setItem(containerType.mapSlot(Slot.of(row, column)), guiItem); } @Override - public void set(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { - set(containerType.mapSlot(slot), guiItem); + public void setItem(final @NotNull Slot slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { + setItem(containerType.mapSlot(slot), guiItem); } @Override - public void set(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { + public void setItem(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { // TODO VALIDATE SLOT HERE TOO // Render item final var renderedItem = new RenderedGuiItem<>(guiItem.render(), clickHandler, guiItem.getClickAction()); @@ -75,7 +75,7 @@ public void set(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull I> g @Override public void fill(final @NotNull GuiLayout layout, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { - layout.generatePositions().forEach(position -> set(position, guiItem)); + layout.generatePositions().forEach(position -> setItem(position, guiItem)); } public @NotNull Map> complete() { diff --git a/kotlin/src/main/kotlin/ContainerExt.kt b/kotlin/src/main/kotlin/ContainerExt.kt new file mode 100644 index 00000000..68ba7a72 --- /dev/null +++ b/kotlin/src/main/kotlin/ContainerExt.kt @@ -0,0 +1,18 @@ +package dev.triumphteam.gui.kotlin + +import dev.triumphteam.gui.container.GuiContainer +import dev.triumphteam.gui.item.GuiItem +import dev.triumphteam.gui.layout.GuiLayout +import dev.triumphteam.gui.slot.Slot + +public operator fun

GuiContainer.set(row: Int, column: Int, item: GuiItem): Unit = + setItem(row, column, item) + +public operator fun

GuiContainer.set(slot: Slot, item: GuiItem): Unit = + setItem(slot, item) + +public operator fun

GuiContainer.set(slot: Int, item: GuiItem): Unit = + setItem(slot, item) + +public operator fun

GuiContainer.set(layout: GuiLayout, item: GuiItem): Unit = + fill(layout, item) diff --git a/kotlin/src/main/kotlin/SlotExt.kt b/kotlin/src/main/kotlin/SlotExt.kt index eecaa122..ff76a68a 100644 --- a/kotlin/src/main/kotlin/SlotExt.kt +++ b/kotlin/src/main/kotlin/SlotExt.kt @@ -6,8 +6,3 @@ public operator fun Slot.component1(): Int = row public operator fun Slot.component2(): Int = column public fun slot(row: Int, column: Int): Slot = Slot(row, column) - -public fun main() { - - val (row, column) = Slot.of(1, 2) -} From a817b8d1f0a7e0179e46723911572651cf74a534 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 19 Oct 2024 00:51:01 +0100 Subject: [PATCH 25/43] feature: Basic click context with some information about the click --- .../dev/triumphteam/gui/AbstractGuiView.java | 5 ++-- .../gui/builder/BaseGuiBuilder.java | 14 +++++++---- .../triumphteam/gui/click/ClickContext.java | 12 ++++++---- .../dev/triumphteam/gui/click/GuiClick.java | 19 +++++++++++++++ .../gui/click/processor/ClickProcessor.java | 20 +++++++--------- .../gui/paper/PaperGuiListener.java | 24 ++++++++++++++++++- 6 files changed, 71 insertions(+), 23 deletions(-) create mode 100644 core/src/main/java/dev/triumphteam/gui/click/GuiClick.java diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index bfc6aac2..4e07a6da 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -23,6 +23,7 @@ */ package dev.triumphteam.gui; +import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.click.processor.ClickProcessor; import dev.triumphteam.gui.component.GuiComponent; @@ -154,8 +155,8 @@ public void completeRendered(final @NotNull RenderedComponent renderedComp populateInventory(renderedItems); } - public @NotNull ClickProcessor getClickProcessor() { - return clickProcessor; + public void processClick(final @NotNull ClickContext context) { + clickProcessor.processClick(context, this); } public @Nullable RenderedGuiItem getItem(final int slot) { diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 63a3b794..1ef41694 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -24,7 +24,6 @@ package dev.triumphteam.gui.builder; import dev.triumphteam.gui.BaseGui; -import dev.triumphteam.gui.GuiView; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.SimpleGuiComponent; @@ -35,10 +34,10 @@ import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.exception.TriumphGuiException; import dev.triumphteam.gui.settings.GuiSettings; -import dev.triumphteam.gui.title.functional.FunctionalGuiTitle; import dev.triumphteam.gui.title.GuiTitle; -import dev.triumphteam.gui.title.functional.SimpleFunctionalGuiTitle; import dev.triumphteam.gui.title.SimpleGuiTitle; +import dev.triumphteam.gui.title.functional.FunctionalGuiTitle; +import dev.triumphteam.gui.title.functional.SimpleFunctionalGuiTitle; import net.kyori.adventure.text.Component; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -79,7 +78,7 @@ public BaseGuiBuilder( } /** - * Sets the title of the {@link GuiView}. + * Sets the title of the {@link BaseGui}. * * @param title The title {@link Component}. * @return The {@link B} instance of the {@link BaseGuiBuilder}. @@ -90,6 +89,13 @@ public BaseGuiBuilder( return (B) this; } + /** + * Sets the title of the {@link BaseGui}. + * This version is reactive and will update when the provided state changes. + * + * @param title The title builder function. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ public @NotNull B title(final @NotNull Consumer<@NotNull FunctionalGuiTitle> title) { final var simpleTitle = new SimpleFunctionalGuiTitle(); title.accept(simpleTitle); diff --git a/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java b/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java index 50f368b3..e2372743 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java +++ b/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,5 +23,7 @@ */ package dev.triumphteam.gui.click; -public record ClickContext() { +import org.jetbrains.annotations.NotNull; + +public record ClickContext(@NotNull GuiClick guiClick, int slot) { } diff --git a/core/src/main/java/dev/triumphteam/gui/click/GuiClick.java b/core/src/main/java/dev/triumphteam/gui/click/GuiClick.java new file mode 100644 index 00000000..27d0fdbb --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/click/GuiClick.java @@ -0,0 +1,19 @@ +package dev.triumphteam.gui.click; + +public enum GuiClick { + + LEFT, + SHIFT_LEFT, + RIGHT, + SHIFT_RIGHT, + WINDOW_BORDER_LEFT, + WINDOW_BORDER_RIGHT, + MIDDLE, + NUMBER_KEY, + DOUBLE_CLICK, + DROP, + CONTROL_DROP, + CREATIVE, + SWAP_OFFHAND, + UNKNOWN, +} diff --git a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java index 4e594983..4d56381a 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java +++ b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -72,10 +72,10 @@ public ClickProcessor(final long spamPreventionDuration) { * Will mark the processor as busy once the click starts then may or may not free it once it's done processing. * A click can be blocked for a much longer time depending on the {@link ClickHandler} being used. * - * @param slot The slot being clicked. + * @param context The context of the click. * @param view The current view. */ - public void processClick(final int slot, final @NotNull AbstractGuiView view) { + public void processClick(final @NotNull ClickContext context, final @NotNull AbstractGuiView view) { final var viewerUuid = view.viewerUuid(); @@ -84,7 +84,7 @@ public void processClick(final int slot, final @NotNull AbstractGuiView vi return; } - final var renderedItem = view.getItem(slot); + final var renderedItem = view.getItem(context.slot()); if (renderedItem == null) return; final var action = renderedItem.action(); @@ -97,9 +97,7 @@ public void processClick(final int slot, final @NotNull AbstractGuiView vi this.isProcessing = true; - final var clickContext = new ClickContext(); final var handler = renderedItem.clickHandler(); - // Prepare the controller with the whenComplete handler final var clickController = new DefaultClickController((ignored, throwable) -> { // If something went wrong with the click log, the error and stop processing @@ -107,7 +105,7 @@ public void processClick(final int slot, final @NotNull AbstractGuiView vi LOGGER.error( "An exception occurred while processing click for '{}' on slot '{}'.", view.viewerName(), - slot, + context.slot(), throwable ); } @@ -119,7 +117,7 @@ public void processClick(final int slot, final @NotNull AbstractGuiView vi // The exception is passed to the controller and still logged Exception handledException = null; try { - handler.handle(view.viewer(), clickContext, action, clickController); + handler.handle(view.viewer(), context, action, clickController); } catch (final Exception exception) { handledException = exception; } diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java index 3b334372..e2d5d7e6 100644 --- a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java +++ b/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java @@ -23,8 +23,11 @@ */ package dev.triumphteam.gui.paper; +import dev.triumphteam.gui.click.ClickContext; +import dev.triumphteam.gui.click.GuiClick; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryOpenEvent; @@ -46,7 +49,7 @@ public void onGuiClick(final @NotNull InventoryClickEvent event) { if (view == null) return; event.setCancelled(true); - view.getClickProcessor().processClick(event.getSlot(), view); + view.processClick(new ClickContext(mapClick(event.getClick()), event.getSlot())); } @EventHandler @@ -72,4 +75,23 @@ public void onGuiOpen(final @NotNull InventoryOpenEvent event) { if (holder instanceof PaperGuiView paperGuiView) return paperGuiView; return null; } + + private @NotNull GuiClick mapClick(final @NotNull ClickType clickType) { + return switch (clickType) { + case ClickType.LEFT -> GuiClick.LEFT; + case ClickType.SHIFT_LEFT -> GuiClick.SHIFT_LEFT; + case ClickType.RIGHT -> GuiClick.RIGHT; + case ClickType.SHIFT_RIGHT -> GuiClick.SHIFT_RIGHT; + case ClickType.WINDOW_BORDER_LEFT -> GuiClick.WINDOW_BORDER_LEFT; + case ClickType.WINDOW_BORDER_RIGHT -> GuiClick.WINDOW_BORDER_RIGHT; + case ClickType.MIDDLE -> GuiClick.MIDDLE; + case ClickType.NUMBER_KEY -> GuiClick.NUMBER_KEY; + case ClickType.DOUBLE_CLICK -> GuiClick.DOUBLE_CLICK; + case ClickType.DROP -> GuiClick.DROP; + case ClickType.CONTROL_DROP -> GuiClick.CONTROL_DROP; + case ClickType.CREATIVE -> GuiClick.CREATIVE; + case ClickType.SWAP_OFFHAND -> GuiClick.SWAP_OFFHAND; + case ClickType.UNKNOWN -> GuiClick.UNKNOWN; + }; + } } From dc706f0677f51b4c2512011775138340c2743202 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 19 Oct 2024 00:54:13 +0100 Subject: [PATCH 26/43] chore: Change visibility of some dependencies --- build-logic/src/main/kotlin/gui.base.gradle.kts | 2 +- core/build.gradle.kts | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/build-logic/src/main/kotlin/gui.base.gradle.kts b/build-logic/src/main/kotlin/gui.base.gradle.kts index 7183102b..8fca780b 100644 --- a/build-logic/src/main/kotlin/gui.base.gradle.kts +++ b/build-logic/src/main/kotlin/gui.base.gradle.kts @@ -16,7 +16,7 @@ repositories { } dependencies { - compileOnlyApi(libs.annotations) + compileOnly(libs.annotations) } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 53932a6a..9f549850 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -6,8 +6,7 @@ plugins { dependencies { api(libs.nova) - compileOnlyApi(libs.guava) - compileOnlyApi(libs.adventure.api) - - compileOnlyApi(libs.logger) + compileOnly(libs.guava) + compileOnly(libs.adventure.api) + compileOnly(libs.logger) } From 6b2c10b1c0a5daa0c09a20c43282f8176dfcc687 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 19 Oct 2024 01:36:09 +0100 Subject: [PATCH 27/43] chore: Re-organized files and started adding examples --- build-logic/build.gradle.kts | 7 +++-- build-logic/settings.gradle.kts | 2 +- .../src/main/kotlin/gui.library.gradle.kts | 2 +- .../main/kotlin/gui.paper-example.gradle.kts | 23 +++++++++++++++ examples/paper/java/build.gradle.kts | 29 +++++++++++++++++++ .../triumphteam/gui/example/GuiPlugin.java | 11 +++++++ gradle/libs.versions.toml | 15 +++++++++- paper/{ => paper}/build.gradle.kts | 0 .../java/dev/triumphteam/gui/paper/Gui.java | 0 .../gui/paper/PaperGuiListener.java | 0 .../gui/paper/PaperGuiSettings.java | 0 .../triumphteam/gui/paper/PaperGuiView.java | 0 .../gui/paper/builder/gui/GuiBuilder.java | 0 .../builder/item/AbstractItemBuilder.java | 0 .../gui/paper/builder/item/ItemBuilder.java | 0 .../container/type/ChestContainerType.java | 0 .../container/type/PaperContainerType.java | 0 settings.gradle.kts | 14 +++++++-- 18 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 build-logic/src/main/kotlin/gui.paper-example.gradle.kts create mode 100644 examples/paper/java/build.gradle.kts create mode 100644 examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java rename paper/{ => paper}/build.gradle.kts (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/Gui.java (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java (100%) rename paper/{ => paper}/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java (100%) diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index 5c623fd8..51fb213e 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -2,7 +2,7 @@ import dev.triumphteam.root.root plugins { `kotlin-dsl` - id("dev.triumphteam.root.logic") version "0.0.4" + id("dev.triumphteam.root.logic") version "0.0.14" } dependencies { @@ -12,5 +12,8 @@ dependencies { // Bundled plugins implementation(libs.bundles.build) - root("0.0.6") + // Bundled example plugins + implementation(libs.bundles.paper.examples) + + root("0.0.14") } diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts index c0a3eef6..61d53387 100644 --- a/build-logic/settings.gradle.kts +++ b/build-logic/settings.gradle.kts @@ -27,5 +27,5 @@ pluginManagement { } plugins { - id("dev.triumphteam.root.settings") version "0.0.6" + id("dev.triumphteam.root.settings") version "0.0.14" } diff --git a/build-logic/src/main/kotlin/gui.library.gradle.kts b/build-logic/src/main/kotlin/gui.library.gradle.kts index a9775407..c992f65c 100644 --- a/build-logic/src/main/kotlin/gui.library.gradle.kts +++ b/build-logic/src/main/kotlin/gui.library.gradle.kts @@ -1,4 +1,4 @@ -import dev.triumphteam.root.PublishConfigure +import dev.triumphteam.root.configure.PublishConfigure plugins { `maven-publish` diff --git a/build-logic/src/main/kotlin/gui.paper-example.gradle.kts b/build-logic/src/main/kotlin/gui.paper-example.gradle.kts new file mode 100644 index 00000000..bedc541a --- /dev/null +++ b/build-logic/src/main/kotlin/gui.paper-example.gradle.kts @@ -0,0 +1,23 @@ +import org.gradle.accessors.dm.LibrariesForLibs + +// Hack which exposes `libs` to this convention plugin +val libs = the() + +plugins { + `java-library` + id("xyz.jpenilla.run-paper") + id("xyz.jpenilla.resource-factory-bukkit-convention") + id("com.gradleup.shadow") +} + +repositories { + mavenCentral() +} + +dependencies { + compileOnly(libs.paper) +} + +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(21)) +} diff --git a/examples/paper/java/build.gradle.kts b/examples/paper/java/build.gradle.kts new file mode 100644 index 00000000..e096f540 --- /dev/null +++ b/examples/paper/java/build.gradle.kts @@ -0,0 +1,29 @@ +import xyz.jpenilla.resourcefactory.bukkit.BukkitPluginYaml + +plugins { + id("gui.base") + id("gui.paper-example") +} + +repositories { + maven("https://repo.papermc.io/repository/maven-public/") +} + +dependencies { + implementation(projects.triumphGuiPaper) +} + +tasks { + runServer { + minecraftVersion("1.21.1") + } + + bukkitPluginYaml { + main.set("dev.triumphteam.gui.example.GuiPlugin") + load = BukkitPluginYaml.PluginLoadOrder.STARTUP + authors.add("Matt") + apiVersion = "1.21" + commands.add(commands.create("example")) + foliaSupported.set(true) + } +} diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java new file mode 100644 index 00000000..423b70f4 --- /dev/null +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java @@ -0,0 +1,11 @@ +package dev.triumphteam.gui.example; + +import org.bukkit.plugin.java.JavaPlugin; + +public final class GuiPlugin extends JavaPlugin { + + @Override + public void onEnable() { + getCommand("example").setExecutor(this); + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ba29e53a..23bf02bd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,6 +15,11 @@ nova = "1.0.0-SNAPSHOT" adventure = "4.16.0" paper = "1.21.1-R0.1-SNAPSHOT" +# Build +run-paper = "2.3.1" +resource-factory = "1.2.0" +shadow = "8.3.3" + [libraries] # Core annotations = { module = "org.jetbrains:annotations", version.ref = "annotations" } @@ -30,12 +35,20 @@ adventure-api = { module = "net.kyori:adventure-api", version.ref = "adventure" # Kotlin coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } -# build +# Build build-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } build-license = { module = "gradle.plugin.com.hierynomus.gradle.plugins:license-gradle-plugin", version.ref = "license" } +build-run-paper = { module = "xyz.jpenilla:run-task", version.ref = "run-paper" } +build-resource-factory = { module = "xyz.jpenilla:resource-factory", version.ref = "resource-factory" } +build-shadow = { module = "com.gradleup.shadow:shadow-gradle-plugin", version.ref = "shadow" } [bundles] build = [ "build-kotlin", "build-license", ] +paper-examples = [ + "build-run-paper", + "build-resource-factory", + "build-shadow", +] diff --git a/paper/build.gradle.kts b/paper/paper/build.gradle.kts similarity index 100% rename from paper/build.gradle.kts rename to paper/paper/build.gradle.kts diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/Gui.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiSettings.java diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/container/type/ChestContainerType.java diff --git a/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java similarity index 100% rename from paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/container/type/PaperContainerType.java diff --git a/settings.gradle.kts b/settings.gradle.kts index d9866538..ceb734e2 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,8 +17,18 @@ rootProject.name = "triumph-gui" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") plugins { - id("dev.triumphteam.root.settings") version "0.0.6" + id("dev.triumphteam.root.settings") version "0.0.14" } -listOf("core", "paper", "kotlin").forEach(::includeProject) +listOf( + "core" to "core", + "kotlin" to "kotlin", + + "paper/paper" to "paper", + "paper/kotlin" to "paper-kotlin", + + "examples/paper/java" to "example-paper-java", + "examples/paper/kotlin" to "example-paper-kotlin", +).forEach(::includeProject) + include("test-plugin") From 442cebaaa07b650881a3f1700e0c6e60323ee47a Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 19 Oct 2024 21:35:50 +0100 Subject: [PATCH 28/43] feature: Better Kotlin builder and some Kotlin examples --- .../gui/builder/BaseGuiBuilder.java | 39 +++++++++--- examples/paper/kotlin/build.gradle.kts | 30 +++++++++ .../paper/kotlin/src/main/kotlin/GuiPlugin.kt | 10 +++ .../src/main/kotlin/examples/CookieClicker.kt | 45 ++++++++++++++ .../src/main/kotlin/examples/StaticGui.kt | 37 +++++++++++ .../kotlin/src/main/kotlin/package-info.kt | 1 + kotlin/build.gradle.kts | 6 +- .../builder/AbstractKotlinGuiBuilder.kt | 61 +++++++++++++++++++ paper/kotlin/build.gradle.kts | 16 +++++ .../src/main/kotlin/builder/Container.kt | 12 ++++ .../kotlin/builder/PaperKotlinGuiBuilder.kt | 22 +++++++ paper/kotlin/src/main/kotlin/package-info.kt | 1 + .../java/dev/triumphteam/gui/paper/Gui.java | 21 +++---- .../triumphteam/gui/paper/PaperGuiView.java | 6 +- .../{GuiBuilder.java => PaperGuiBuilder.java} | 19 +++--- 15 files changed, 290 insertions(+), 36 deletions(-) create mode 100644 examples/paper/kotlin/build.gradle.kts create mode 100644 examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt create mode 100644 examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt create mode 100644 examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt create mode 100644 examples/paper/kotlin/src/main/kotlin/package-info.kt create mode 100644 kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt create mode 100644 paper/kotlin/build.gradle.kts create mode 100644 paper/kotlin/src/main/kotlin/builder/Container.kt create mode 100644 paper/kotlin/src/main/kotlin/builder/PaperKotlinGuiBuilder.kt create mode 100644 paper/kotlin/src/main/kotlin/package-info.kt rename paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/{GuiBuilder.java => PaperGuiBuilder.java} (78%) diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 1ef41694..91205b79 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -58,12 +58,11 @@ * @param The item type. */ @SuppressWarnings({"unchecked", "UnusedReturnValue"}) -public abstract class BaseGuiBuilder, P, G extends BaseGui

, I> { +public abstract class BaseGuiBuilder, P, G extends BaseGui

, I, C extends GuiContainerType> { private final GuiSettings guiSettings; - private final GuiContainerType containerType; private final List> components = new ArrayList<>(); - + private C containerType; private ClickHandler

clickHandler = null; private GuiComponentRenderer componentRenderer = null; private GuiTitle title = null; @@ -71,10 +70,22 @@ public abstract class BaseGuiBuilder, P, G public BaseGuiBuilder( final GuiSettings guiSettings, - final @NotNull GuiContainerType containerType + final @NotNull C defaultContainerType ) { this.guiSettings = guiSettings; - this.containerType = containerType; + this.containerType = defaultContainerType; + } + + /** + * Sets the title of the {@link BaseGui}. + * + * @param title The title {@link GuiTitle}. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ + @Contract("_ -> this") + public @NotNull B title(final @NotNull GuiTitle title) { + this.title = title; + return (B) this; } /** @@ -85,8 +96,7 @@ public BaseGuiBuilder( */ @Contract("_ -> this") public @NotNull B title(final @NotNull Component title) { - this.title = new SimpleGuiTitle(() -> title, Collections.emptyList()); - return (B) this; + return title(new SimpleGuiTitle(() -> title, Collections.emptyList())); } /** @@ -99,7 +109,18 @@ public BaseGuiBuilder( public @NotNull B title(final @NotNull Consumer<@NotNull FunctionalGuiTitle> title) { final var simpleTitle = new SimpleFunctionalGuiTitle(); title.accept(simpleTitle); - this.title = simpleTitle.asGuiTitle(); + return title(simpleTitle.asGuiTitle()); + } + + /** + * Sets the container type of the GUI. + * + * @param containerType The {@link GuiContainerType} to be used. + * @return The {@link B} instance of the {@link BaseGuiBuilder}. + */ + @Contract("_ -> this") + public @NotNull B containerType(final @NotNull C containerType) { + this.containerType = containerType; return (B) this; } @@ -195,7 +216,7 @@ public BaseGuiBuilder( // ---------------- Internal getters ---------------- // - protected @NotNull GuiContainerType getContainerType() { + protected @NotNull C getContainerType() { return containerType; } diff --git a/examples/paper/kotlin/build.gradle.kts b/examples/paper/kotlin/build.gradle.kts new file mode 100644 index 00000000..20822781 --- /dev/null +++ b/examples/paper/kotlin/build.gradle.kts @@ -0,0 +1,30 @@ +import xyz.jpenilla.resourcefactory.bukkit.BukkitPluginYaml + +plugins { + id("gui.base") + id("gui.paper-example") +} + +repositories { + maven("https://repo.papermc.io/repository/maven-public/") +} + +dependencies { + implementation(kotlin("stdlid")) + implementation(projects.triumphGuiPaperKotlin) +} + +tasks { + runServer { + minecraftVersion("1.21.1") + } + + bukkitPluginYaml { + main.set("dev.triumphteam.gui.example.GuiPlugin") + load = BukkitPluginYaml.PluginLoadOrder.STARTUP + authors.add("Matt") + apiVersion = "1.21" + commands.add(commands.create("example")) + foliaSupported.set(true) + } +} diff --git a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt new file mode 100644 index 00000000..0688545f --- /dev/null +++ b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt @@ -0,0 +1,10 @@ +package dev.triumphteam.gui.example + +import org.bukkit.plugin.java.JavaPlugin + +public class GuiPlugin : JavaPlugin() { + + override fun onEnable() { + getCommand("example")?.setExecutor(this) + } +} diff --git a/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt b/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt new file mode 100644 index 00000000..823304a1 --- /dev/null +++ b/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt @@ -0,0 +1,45 @@ +package dev.triumphteam.gui.example.examples + +import dev.triumphteam.gui.kotlin.set +import dev.triumphteam.gui.paper.builder.item.ItemBuilder +import dev.triumphteam.gui.paper.kotlin.builder.buildGui +import dev.triumphteam.gui.paper.kotlin.builder.chestContainer +import dev.triumphteam.nova.getValue +import dev.triumphteam.nova.setValue +import net.kyori.adventure.text.Component +import org.bukkit.Material +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + +public class CookieClicker : CommandExecutor { + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + if (sender !is Player) return false + + val gui = buildGui { + + containerType = chestContainer { + rows = 1 + } + + component { + + // Remember how many times the item was clicked + var clicks by remember(0) + + render { container -> + container[1, 1] = ItemBuilder.from(Material.COOKIE) + .name(Component.text("Clicked $clicks times!")) + .asGuiItem { _, _ -> + clicks++ + } + } + } + } + + gui.open(sender) + return true + } +} diff --git a/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt b/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt new file mode 100644 index 00000000..98cb3d73 --- /dev/null +++ b/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt @@ -0,0 +1,37 @@ +package dev.triumphteam.gui.example.examples + +import dev.triumphteam.gui.kotlin.set +import dev.triumphteam.gui.paper.builder.item.ItemBuilder +import dev.triumphteam.gui.paper.kotlin.builder.buildGui +import dev.triumphteam.gui.paper.kotlin.builder.chestContainer +import net.kyori.adventure.text.Component +import org.bukkit.Material +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + +public class StaticGui : CommandExecutor { + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { + if (sender !is Player) return false + + val gui = buildGui { + // If not set, defaults to chest - 1 row + containerType = chestContainer { + rows = 6 + } + + statelessComponent { container -> + container[1, 1] = ItemBuilder.from(Material.PAPER) + .name(Component.text("My Paper")) + .asGuiItem { player, _ -> + player.sendMessage("You have clicked on the paper item!") + } + } + } + + gui.open(sender) + return true + } +} diff --git a/examples/paper/kotlin/src/main/kotlin/package-info.kt b/examples/paper/kotlin/src/main/kotlin/package-info.kt new file mode 100644 index 00000000..ceb94ad4 --- /dev/null +++ b/examples/paper/kotlin/src/main/kotlin/package-info.kt @@ -0,0 +1 @@ +package dev.triumphteam.gui.example diff --git a/kotlin/build.gradle.kts b/kotlin/build.gradle.kts index 7480f9b1..7419696e 100644 --- a/kotlin/build.gradle.kts +++ b/kotlin/build.gradle.kts @@ -5,6 +5,8 @@ plugins { dependencies { api(libs.nova.kotlin) - implementation(kotlin("stdlib")) - implementation(projects.triumphGuiCore) + api(projects.triumphGuiCore) + + compileOnly(kotlin("stdlib")) + compileOnly(libs.adventure.api) } diff --git a/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt b/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt new file mode 100644 index 00000000..7118113c --- /dev/null +++ b/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt @@ -0,0 +1,61 @@ +package dev.triumphteam.gui.kotlin.builder + +import dev.triumphteam.gui.BaseGui +import dev.triumphteam.gui.builder.BaseGuiBuilder +import dev.triumphteam.gui.click.handler.ClickHandler +import dev.triumphteam.gui.component.functional.FunctionalGuiComponent +import dev.triumphteam.gui.component.functional.FunctionalGuiComponentRender +import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent +import dev.triumphteam.gui.component.renderer.GuiComponentRenderer +import dev.triumphteam.gui.container.type.GuiContainerType +import dev.triumphteam.gui.title.functional.FunctionalGuiTitle +import dev.triumphteam.gui.title.functional.SimpleFunctionalGuiTitle +import net.kyori.adventure.text.Component +import kotlin.time.Duration + +public abstract class AbstractKotlinGuiBuilder, P, G : BaseGui

, I, C : GuiContainerType>( + @PublishedApi internal val backing: B, +) { + + public var containerType: C? = null + set(value) { + field = value + value?.let(backing::containerType) + } + + public var spamPreventionDuration: Duration? = null + set(value) { + field = value + backing.spamPreventionDuration(value?.inWholeMilliseconds ?: -1) + } + + public var clickHandler: ClickHandler

? = null + set(value) { + field = value + value?.let(backing::clickHandler) + } + + public var componentRenderer: GuiComponentRenderer? = null + set(value) { + field = value + value?.let(backing::componentRenderer) + } + + public fun title(title: Component) { + backing.title(title) + } + + public inline fun title(block: FunctionalGuiTitle.() -> Unit) { + backing.title(SimpleFunctionalGuiTitle().apply(block).asGuiTitle()) + } + + public fun statelessComponent(render: FunctionalGuiComponentRender) { + backing.statelessComponent(render) + } + + public inline fun component(block: FunctionalGuiComponent.() -> Unit) { + backing.component(SimpleFunctionalGuiComponent().apply(block).asGuiComponent()) + } + + protected fun backing(): B = backing +} diff --git a/paper/kotlin/build.gradle.kts b/paper/kotlin/build.gradle.kts new file mode 100644 index 00000000..b90d73ef --- /dev/null +++ b/paper/kotlin/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id("gui.base") + id("gui.library") +} + +repositories { + maven("https://repo.papermc.io/repository/maven-public/") +} + +dependencies { + compileOnly(libs.paper) + compileOnly(kotlin("stdlib")) + + api(projects.triumphGuiPaper) + api(projects.triumphGuiKotlin) +} diff --git a/paper/kotlin/src/main/kotlin/builder/Container.kt b/paper/kotlin/src/main/kotlin/builder/Container.kt new file mode 100644 index 00000000..97bcd640 --- /dev/null +++ b/paper/kotlin/src/main/kotlin/builder/Container.kt @@ -0,0 +1,12 @@ +package dev.triumphteam.gui.paper.kotlin.builder + +import dev.triumphteam.gui.paper.container.type.ChestContainerType +import dev.triumphteam.gui.paper.container.type.PaperContainerType + +public class ContainerBuilder @PublishedApi internal constructor() { + public var rows: Int = 1 +} + +public inline fun chestContainer(block: ContainerBuilder.() -> Unit): PaperContainerType { + return ChestContainerType(ContainerBuilder().apply(block).rows) +} diff --git a/paper/kotlin/src/main/kotlin/builder/PaperKotlinGuiBuilder.kt b/paper/kotlin/src/main/kotlin/builder/PaperKotlinGuiBuilder.kt new file mode 100644 index 00000000..82f0b68d --- /dev/null +++ b/paper/kotlin/src/main/kotlin/builder/PaperKotlinGuiBuilder.kt @@ -0,0 +1,22 @@ +package dev.triumphteam.gui.paper.kotlin.builder + +import dev.triumphteam.gui.kotlin.builder.AbstractKotlinGuiBuilder +import dev.triumphteam.gui.paper.Gui +import dev.triumphteam.gui.paper.builder.gui.PaperGuiBuilder +import dev.triumphteam.gui.paper.container.type.ChestContainerType +import dev.triumphteam.gui.paper.container.type.PaperContainerType +import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack + +public class PaperKotlinGuiBuilder @PublishedApi internal constructor() : + AbstractKotlinGuiBuilder( + PaperGuiBuilder(ChestContainerType(1)) + ) { + + @PublishedApi + internal fun build(): Gui = backing().build() +} + +public inline fun buildGui(builder: PaperKotlinGuiBuilder.() -> Unit): Gui { + return PaperKotlinGuiBuilder().apply(builder).build() +} diff --git a/paper/kotlin/src/main/kotlin/package-info.kt b/paper/kotlin/src/main/kotlin/package-info.kt new file mode 100644 index 00000000..31671162 --- /dev/null +++ b/paper/kotlin/src/main/kotlin/package-info.kt @@ -0,0 +1 @@ +package dev.triumphteam.gui.paper.kotlin diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index cb3a6b3c..aa6831d4 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -27,8 +27,7 @@ import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; -import dev.triumphteam.gui.container.type.GuiContainerType; -import dev.triumphteam.gui.paper.builder.gui.GuiBuilder; +import dev.triumphteam.gui.paper.builder.gui.PaperGuiBuilder; import dev.triumphteam.gui.paper.container.type.ChestContainerType; import dev.triumphteam.gui.paper.container.type.PaperContainerType; import dev.triumphteam.gui.title.GuiTitle; @@ -72,26 +71,26 @@ public Gui( } /** - * Create a new {@link GuiBuilder} to create a new {@link Gui}. + * Create a new {@link PaperGuiBuilder} to create a new {@link Gui}. * - * @param type The {@link GuiContainerType} to be used. - * @return A new {@link GuiBuilder}. + * @param type The {@link PaperContainerType} to be used. + * @return A new {@link PaperGuiBuilder}. */ @Contract("_ -> new") - public static GuiBuilder of(final @NotNull GuiContainerType type) { - return new GuiBuilder(type); + public static PaperGuiBuilder of(final @NotNull PaperContainerType type) { + return new PaperGuiBuilder(type); } /** - * Create a new {@link GuiBuilder} to create a new {@link Gui}. + * Create a new {@link PaperGuiBuilder} to create a new {@link Gui}. * This factory will default to using a {@link ChestContainerType}. * * @param rows The rows of the {@link ChestContainerType}. - * @return A new {@link GuiBuilder}. + * @return A new {@link PaperGuiBuilder}. */ @Contract("_ -> new") - public static GuiBuilder of(final int rows) { - return new GuiBuilder(new ChestContainerType(rows)); + public static PaperGuiBuilder of(final int rows) { + return new PaperGuiBuilder(new ChestContainerType(rows)); } @Override diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java index f88d466b..ac836261 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java @@ -66,12 +66,14 @@ public void openInventory() { this.inventory = containerType.createInventory(this, getTitle()); } - viewer().openInventory(inventory); + final var viewer = viewer(); + viewer.getScheduler().run(PaperGuiSettings.get().getPlugin(), (task) -> viewer.openInventory(inventory), null); } @Override public void close() { - + final var viewer = viewer(); + viewer.getScheduler().runDelayed(PaperGuiSettings.get().getPlugin(), (task) -> viewer.closeInventory(), null, 2L); } @Override diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java similarity index 78% rename from paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java rename to paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java index 04993fbb..eceb8031 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/GuiBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,7 +24,6 @@ package dev.triumphteam.gui.paper.builder.gui; import dev.triumphteam.gui.builder.BaseGuiBuilder; -import dev.triumphteam.gui.container.type.GuiContainerType; import dev.triumphteam.gui.paper.Gui; import dev.triumphteam.gui.paper.PaperGuiSettings; import dev.triumphteam.gui.paper.container.type.PaperContainerType; @@ -32,22 +31,18 @@ import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; -public final class GuiBuilder extends BaseGuiBuilder { +public final class PaperGuiBuilder extends BaseGuiBuilder { - public GuiBuilder(final @NotNull GuiContainerType containerType) { + public PaperGuiBuilder(final @NotNull PaperContainerType containerType) { super(PaperGuiSettings.get(), containerType); } @Override public Gui build() { - if (!(getContainerType() instanceof final PaperContainerType paperContainerType)) { - throw new IllegalArgumentException("Container type provided is not supported on Paper platform!"); - } - return new Gui( getTitle(), getComponents(), - paperContainerType, + getContainerType(), getComponentRenderer(), getClickHandler(), getSpamPreventionDuration() From f7754f535ba4d7e9bb77884d25dcf38220d5d3e3 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 19 Oct 2024 21:37:11 +0100 Subject: [PATCH 29/43] chore: Actually use command with examples --- examples/paper/kotlin/build.gradle.kts | 3 ++- examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/paper/kotlin/build.gradle.kts b/examples/paper/kotlin/build.gradle.kts index 20822781..b53bbf00 100644 --- a/examples/paper/kotlin/build.gradle.kts +++ b/examples/paper/kotlin/build.gradle.kts @@ -24,7 +24,8 @@ tasks { load = BukkitPluginYaml.PluginLoadOrder.STARTUP authors.add("Matt") apiVersion = "1.21" - commands.add(commands.create("example")) + commands.add(commands.create("gui-static")) + commands.add(commands.create("gui-clicker")) foliaSupported.set(true) } } diff --git a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt index 0688545f..1855daac 100644 --- a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt +++ b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt @@ -1,10 +1,13 @@ package dev.triumphteam.gui.example +import dev.triumphteam.gui.example.examples.CookieClicker +import dev.triumphteam.gui.example.examples.StaticGui import org.bukkit.plugin.java.JavaPlugin public class GuiPlugin : JavaPlugin() { override fun onEnable() { - getCommand("example")?.setExecutor(this) + getCommand("gui-static")?.setExecutor(StaticGui()) + getCommand("gui-clicker")?.setExecutor(CookieClicker()) } } From b7c82b4c009029f6f7abbb2554c625c9b887dff9 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 19 Oct 2024 21:41:01 +0100 Subject: [PATCH 30/43] chore: Remove unused function and fix typo --- examples/paper/kotlin/build.gradle.kts | 2 +- kotlin/src/main/kotlin/GuiBuilderExt.kt | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 kotlin/src/main/kotlin/GuiBuilderExt.kt diff --git a/examples/paper/kotlin/build.gradle.kts b/examples/paper/kotlin/build.gradle.kts index b53bbf00..016f884e 100644 --- a/examples/paper/kotlin/build.gradle.kts +++ b/examples/paper/kotlin/build.gradle.kts @@ -10,7 +10,7 @@ repositories { } dependencies { - implementation(kotlin("stdlid")) + implementation(kotlin("stdlib")) implementation(projects.triumphGuiPaperKotlin) } diff --git a/kotlin/src/main/kotlin/GuiBuilderExt.kt b/kotlin/src/main/kotlin/GuiBuilderExt.kt deleted file mode 100644 index 73bb4eb3..00000000 --- a/kotlin/src/main/kotlin/GuiBuilderExt.kt +++ /dev/null @@ -1,13 +0,0 @@ -package dev.triumphteam.gui.kotlin - -import dev.triumphteam.gui.BaseGui -import dev.triumphteam.gui.builder.BaseGuiBuilder -import dev.triumphteam.gui.component.functional.FunctionalGuiComponent -import dev.triumphteam.gui.component.functional.SimpleFunctionalGuiComponent - -// TODO(matt): Actually make this suspending -public fun , P, G : BaseGui

, I> BaseGuiBuilder.suspendingComponent( - block: FunctionalGuiComponent.() -> Unit, -): B { - return component(SimpleFunctionalGuiComponent().apply(block).asGuiComponent()) -} From 50831f0ccad1976296648b4dd00f252f256ce970 Mon Sep 17 00:00:00 2001 From: Matt Date: Sat, 19 Oct 2024 21:47:49 +0100 Subject: [PATCH 31/43] chore: Make examples a bit more documented --- .../kotlin/src/main/kotlin/examples/CookieClicker.kt | 11 +++++++++++ .../kotlin/src/main/kotlin/examples/StaticGui.kt | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt b/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt index 823304a1..435de6ab 100644 --- a/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt +++ b/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt @@ -12,6 +12,7 @@ import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.entity.Player +import kotlin.time.Duration.Companion.milliseconds public class CookieClicker : CommandExecutor { @@ -20,19 +21,29 @@ public class CookieClicker : CommandExecutor { val gui = buildGui { + // Not needed in this case since it's just using the default value of chest - 1 row containerType = chestContainer { rows = 1 } + // We want fast clicks so let's not have any spam prevention + spamPreventionDuration = 0.milliseconds + + // Simple title for the GUI + title(Component.text("Cookie Clicker Gui")) + + // A reactive component component { // Remember how many times the item was clicked var clicks by remember(0) + // Rendering the component render { container -> container[1, 1] = ItemBuilder.from(Material.COOKIE) .name(Component.text("Clicked $clicks times!")) .asGuiItem { _, _ -> + // Increase clicks which, in turn, updates the state of the component clicks++ } } diff --git a/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt b/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt index 98cb3d73..5aa90c1f 100644 --- a/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt +++ b/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt @@ -22,6 +22,10 @@ public class StaticGui : CommandExecutor { rows = 6 } + // Simple title for the gui + title(Component.text("Static Gui")) + + // A stateless component, we don't care about the item updating, just want the click action statelessComponent { container -> container[1, 1] = ItemBuilder.from(Material.PAPER) .name(Component.text("My Paper")) From 3552abbe4984c4707a1e9a3138119e37e6a3df5d Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 20 Oct 2024 00:52:51 +0100 Subject: [PATCH 32/43] feature: Java examples and updating title example --- examples/paper/java/build.gradle.kts | 4 +- .../triumphteam/gui/example/GuiPlugin.java | 7 ++- .../gui/example/examples/CookieClicker.java | 44 +++++++++++++ .../gui/example/examples/Static.java | 35 +++++++++++ .../gui/example/examples/UpdatingTitle.java | 58 +++++++++++++++++ examples/paper/kotlin/build.gradle.kts | 1 + .../paper/kotlin/src/main/kotlin/GuiPlugin.kt | 6 +- .../examples/{StaticGui.kt => Static.kt} | 2 +- .../src/main/kotlin/examples/UpdatingTitle.kt | 62 +++++++++++++++++++ 9 files changed, 214 insertions(+), 5 deletions(-) create mode 100644 examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/CookieClicker.java create mode 100644 examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java create mode 100644 examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/UpdatingTitle.java rename examples/paper/kotlin/src/main/kotlin/examples/{StaticGui.kt => Static.kt} (97%) create mode 100644 examples/paper/kotlin/src/main/kotlin/examples/UpdatingTitle.kt diff --git a/examples/paper/java/build.gradle.kts b/examples/paper/java/build.gradle.kts index e096f540..777bad78 100644 --- a/examples/paper/java/build.gradle.kts +++ b/examples/paper/java/build.gradle.kts @@ -23,7 +23,9 @@ tasks { load = BukkitPluginYaml.PluginLoadOrder.STARTUP authors.add("Matt") apiVersion = "1.21" - commands.add(commands.create("example")) + commands.add(commands.create("gui-static")) + commands.add(commands.create("gui-clicker")) + commands.add(commands.create("gui-title")) foliaSupported.set(true) } } diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java index 423b70f4..1f1c1f0b 100644 --- a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java @@ -1,11 +1,16 @@ package dev.triumphteam.gui.example; +import dev.triumphteam.gui.example.examples.CookieClicker; +import dev.triumphteam.gui.example.examples.Static; +import dev.triumphteam.gui.example.examples.UpdatingTitle; import org.bukkit.plugin.java.JavaPlugin; public final class GuiPlugin extends JavaPlugin { @Override public void onEnable() { - getCommand("example").setExecutor(this); + getCommand("gui-static").setExecutor(new Static()); + getCommand("gui-clicker").setExecutor(new CookieClicker()); + getCommand("gui-title").setExecutor(new UpdatingTitle()); } } diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/CookieClicker.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/CookieClicker.java new file mode 100644 index 00000000..6506d0f5 --- /dev/null +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/CookieClicker.java @@ -0,0 +1,44 @@ +package dev.triumphteam.gui.example.examples; + +import dev.triumphteam.gui.paper.Gui; +import dev.triumphteam.gui.paper.builder.item.ItemBuilder; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public final class CookieClicker implements CommandExecutor { + + @Override + public boolean onCommand(@NotNull final CommandSender sender, @NotNull final Command command, @NotNull final String label, final @NotNull String[] args) { + if (!(sender instanceof Player senderPlayer)) return false; + + final var gui = Gui + .of(1) + .spamPreventionDuration(0) // We want fast clicks so let's not have any spam prevention + .title(Component.text("Cookie Clicker Gui")) // Simple title for the GUI + .component(component -> { // A reactive component + + // Remember how many times the item was clicked + final var clicks = component.remember(0); + + // Rendering the component + component.render(container -> { + container.setItem(1, 1, ItemBuilder.from(Material.COOKIE) + .name(Component.text("Clicked " + clicks.get() + " times!")) + .asGuiItem((player, context) -> { + // Increase clicks which, in turn, updates the state of the component + clicks.update((value) -> value + 1); + }) + ); + }); + }) + .build(); + + gui.open(senderPlayer); + return true; + } +} diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java new file mode 100644 index 00000000..e6526d15 --- /dev/null +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java @@ -0,0 +1,35 @@ +package dev.triumphteam.gui.example.examples; + +import dev.triumphteam.gui.paper.Gui; +import dev.triumphteam.gui.paper.builder.item.ItemBuilder; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public final class Static implements CommandExecutor { + + @Override + public boolean onCommand(@NotNull final CommandSender sender, @NotNull final Command command, @NotNull final String label, final @NotNull String[] args) { + if (!(sender instanceof Player senderPlayer)) return false; + + final var gui = Gui + .of(6) + .title(Component.text("Static Gui")) // Simple title for the GUI + .statelessComponent(container -> { // A stateless component, we don't care about the item updating, just want the click action + container.setItem(1, 1, ItemBuilder.from(Material.COOKIE) + .name(Component.text("Clicked $clicks times!")) + .asGuiItem((player, context) -> { + player.sendMessage("You have clicked on the paper item!"); + }) + ); + }) + .build(); + + gui.open(senderPlayer); + return true; + } +} diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/UpdatingTitle.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/UpdatingTitle.java new file mode 100644 index 00000000..2adaba80 --- /dev/null +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/UpdatingTitle.java @@ -0,0 +1,58 @@ +package dev.triumphteam.gui.example.examples; + +import dev.triumphteam.gui.paper.Gui; +import dev.triumphteam.gui.paper.builder.item.ItemBuilder; +import dev.triumphteam.nova.MutableState; +import net.kyori.adventure.text.Component; +import org.bukkit.Material; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +public class UpdatingTitle implements CommandExecutor { + + @Override + public boolean onCommand(@NotNull final CommandSender sender, @NotNull final Command command, @NotNull final String label, final @NotNull String[] args) { + if (!(sender instanceof Player senderPlayer)) return false; + + // Firstly, we create a state that'll be used by the title + // It's created here and not directly in the "remember" because it needs to be accessible in the component too + final var titleState = MutableState.of(Component.text("Original title")); + + final var gui = Gui + .of(1) + .title((title) -> { + // Tell the title to remember the state + title.remember(titleState); + // Render the title's value + title.render(titleState::get); + }) + .statelessComponent(container -> { // Since we don't care about updating the items, we can just use a stateless component + + // First item to change the title to PAPER + container.setItem(1, 1, ItemBuilder.from(Material.PAPER) + .name(Component.text("Change title to 'PAPER TITLE'!")) + .asGuiItem((player, context) -> { + titleState.set(Component.text("PAPER TITLE")); // Triggers an update + }) + ); + + // Second item to change title to COOKIE + container.setItem(1, 2, ItemBuilder.from(Material.COOKIE) + .name(Component.text("Change title to 'COOKIE TITLE'!")) + .asGuiItem((player, context) -> { + titleState.set(Component.text("COOKIE TITLE")); // Triggers an update + }) + ); + + // Important to remember; due to by default states using "StateMutabilityPolicy.StructuralEquality" + // it means that if the title is the same as the new value it'll **NOT** trigger an update + }) + .build(); + + gui.open(senderPlayer); + return true; + } +} diff --git a/examples/paper/kotlin/build.gradle.kts b/examples/paper/kotlin/build.gradle.kts index 016f884e..3c8c619d 100644 --- a/examples/paper/kotlin/build.gradle.kts +++ b/examples/paper/kotlin/build.gradle.kts @@ -26,6 +26,7 @@ tasks { apiVersion = "1.21" commands.add(commands.create("gui-static")) commands.add(commands.create("gui-clicker")) + commands.add(commands.create("gui-title")) foliaSupported.set(true) } } diff --git a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt index 1855daac..e54eeb24 100644 --- a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt +++ b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt @@ -1,13 +1,15 @@ package dev.triumphteam.gui.example import dev.triumphteam.gui.example.examples.CookieClicker -import dev.triumphteam.gui.example.examples.StaticGui +import dev.triumphteam.gui.example.examples.Static +import dev.triumphteam.gui.example.examples.UpdatingTitle import org.bukkit.plugin.java.JavaPlugin public class GuiPlugin : JavaPlugin() { override fun onEnable() { - getCommand("gui-static")?.setExecutor(StaticGui()) + getCommand("gui-static")?.setExecutor(Static()) getCommand("gui-clicker")?.setExecutor(CookieClicker()) + getCommand("gui-title")?.setExecutor(UpdatingTitle()) } } diff --git a/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt b/examples/paper/kotlin/src/main/kotlin/examples/Static.kt similarity index 97% rename from examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt rename to examples/paper/kotlin/src/main/kotlin/examples/Static.kt index 5aa90c1f..dbbfd299 100644 --- a/examples/paper/kotlin/src/main/kotlin/examples/StaticGui.kt +++ b/examples/paper/kotlin/src/main/kotlin/examples/Static.kt @@ -11,7 +11,7 @@ import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.entity.Player -public class StaticGui : CommandExecutor { +public class Static : CommandExecutor { override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { if (sender !is Player) return false diff --git a/examples/paper/kotlin/src/main/kotlin/examples/UpdatingTitle.kt b/examples/paper/kotlin/src/main/kotlin/examples/UpdatingTitle.kt new file mode 100644 index 00000000..f749b1f5 --- /dev/null +++ b/examples/paper/kotlin/src/main/kotlin/examples/UpdatingTitle.kt @@ -0,0 +1,62 @@ +package dev.triumphteam.gui.example.examples + +import dev.triumphteam.gui.kotlin.set +import dev.triumphteam.gui.paper.builder.item.ItemBuilder +import dev.triumphteam.gui.paper.kotlin.builder.buildGui +import dev.triumphteam.nova.getValue +import dev.triumphteam.nova.mutableStateOf +import dev.triumphteam.nova.setValue +import net.kyori.adventure.text.Component +import org.bukkit.Material +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + +public class UpdatingTitle : CommandExecutor { + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + if (sender !is Player) return false + + val gui = buildGui { + + // Firstly, we create a state that'll be used by the title + // It's created here and not directly in the "remember" because it needs to be accessible in the component too + val titleState = mutableStateOf(Component.text("Original title")) + + // Delegate the value, so it's nicer to use it + // This isn't really necessary + var title by titleState + + title { + // Tell the title to remember the state + remember(titleState) + // Render the title's value + render { title } + } + + // Since we don't care about updating the items, we can just use a stateless component + statelessComponent { container -> + // First item to change the title to PAPER + container[1, 1] = ItemBuilder.from(Material.PAPER) + .name(Component.text("Change title to 'PAPER TITLE'!")) + .asGuiItem { _, _ -> + title = Component.text("PAPER TITLE") // Triggers an update + } + + // Second item to change title to COOKIE + container[1, 2] = ItemBuilder.from(Material.COOKIE) + .name(Component.text("Change title to 'COOKIE TITLE'!")) + .asGuiItem { _, _ -> + title = Component.text("COOKIE TITLE") // Triggers an update + } + } + + // Important to remember; due to by default states using "StateMutabilityPolicy.StructuralEquality" + // it means that if the title is the same as the new value it'll **NOT** trigger an update + } + + gui.open(sender) + return true + } +} From 41efb428e32adf5b6a5025af3731149bcc66617b Mon Sep 17 00:00:00 2001 From: Matt Date: Sun, 20 Oct 2024 01:00:54 +0100 Subject: [PATCH 33/43] chore: Update license --- .../dev/triumphteam/gui/AbstractGuiView.java | 8 +++---- .../gui/builder/BaseGuiBuilder.java | 8 +++---- .../triumphteam/gui/click/ClickContext.java | 8 +++---- .../dev/triumphteam/gui/click/GuiClick.java | 23 +++++++++++++++++++ .../gui/click/processor/ClickProcessor.java | 8 +++---- .../gui/component/SimpleGuiComponent.java | 23 +++++++++++++++++++ .../gui/component/StatefulGuiComponent.java | 8 +++---- .../AbstractFunctionalGuiComponent.java | 8 +++---- .../SimpleFunctionalGuiComponent.java | 8 +++---- .../renderer/DefaultGuiComponentRenderer.java | 8 +++---- .../gui/container/GuiContainer.java | 8 +++---- .../gui/layout/BorderGuiLayout.java | 16 ++++++------- .../java/dev/triumphteam/gui/slot/Slot.java | 8 +++---- .../dev/triumphteam/gui/title/GuiTitle.java | 23 +++++++++++++++++++ .../gui/title/ReactiveGuiTitle.java | 23 +++++++++++++++++++ .../triumphteam/gui/title/SimpleGuiTitle.java | 23 +++++++++++++++++++ .../gui/title/StatefulGuiTitle.java | 23 +++++++++++++++++++ .../title/functional/FunctionalGuiTitle.java | 23 +++++++++++++++++++ .../functional/FunctionalGuiTitleRender.java | 23 +++++++++++++++++++ .../functional/SimpleFunctionalGuiTitle.java | 23 +++++++++++++++++++ .../renderer/DefaultGuiTitleRenderer.java | 23 +++++++++++++++++++ .../gui/title/renderer/GuiTitleRenderer.java | 23 +++++++++++++++++++ .../triumphteam/gui/example/GuiPlugin.java | 23 +++++++++++++++++++ .../gui/example/examples/CookieClicker.java | 23 +++++++++++++++++++ .../gui/example/examples/Static.java | 23 +++++++++++++++++++ .../gui/example/examples/UpdatingTitle.java | 23 +++++++++++++++++++ .../paper/kotlin/src/main/kotlin/GuiPlugin.kt | 23 +++++++++++++++++++ .../src/main/kotlin/examples/CookieClicker.kt | 23 +++++++++++++++++++ .../kotlin/src/main/kotlin/examples/Static.kt | 23 +++++++++++++++++++ .../src/main/kotlin/examples/UpdatingTitle.kt | 23 +++++++++++++++++++ .../kotlin/src/main/kotlin/package-info.kt | 23 +++++++++++++++++++ kotlin/src/main/kotlin/ContainerExt.kt | 23 +++++++++++++++++++ kotlin/src/main/kotlin/SlotExt.kt | 23 +++++++++++++++++++ .../builder/AbstractKotlinGuiBuilder.kt | 23 +++++++++++++++++++ kotlin/src/main/kotlin/package-info.kt | 23 +++++++++++++++++++ .../src/main/kotlin/builder/Container.kt | 23 +++++++++++++++++++ .../kotlin/builder/PaperKotlinGuiBuilder.kt | 23 +++++++++++++++++++ paper/kotlin/src/main/kotlin/package-info.kt | 23 +++++++++++++++++++ .../java/dev/triumphteam/gui/paper/Gui.java | 8 +++---- .../gui/paper/PaperGuiListener.java | 8 +++---- .../triumphteam/gui/paper/PaperGuiView.java | 8 +++---- .../paper/builder/gui/PaperGuiBuilder.java | 8 +++---- settings.gradle.kts | 4 ++-- 43 files changed, 687 insertions(+), 66 deletions(-) diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 4e07a6da..3ed3f4d8 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index 91205b79..f1edbba4 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java b/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java index e2372743..d0504d60 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java +++ b/core/src/main/java/dev/triumphteam/gui/click/ClickContext.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/click/GuiClick.java b/core/src/main/java/dev/triumphteam/gui/click/GuiClick.java index 27d0fdbb..66db9fbc 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/GuiClick.java +++ b/core/src/main/java/dev/triumphteam/gui/click/GuiClick.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.click; public enum GuiClick { diff --git a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java index 4d56381a..dcd0620d 100644 --- a/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java +++ b/core/src/main/java/dev/triumphteam/gui/click/processor/ClickProcessor.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponent.java index c062f805..ad4956a3 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/SimpleGuiComponent.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.component; import dev.triumphteam.gui.component.functional.FunctionalGuiComponentRender; diff --git a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java index 07c28a4c..84b9957d 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/StatefulGuiComponent.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java index f998bb41..fda79748 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java index f8b4ce72..84b3e907 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/SimpleFunctionalGuiComponent.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java index cff9d27d..a55f0e2b 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/component/renderer/DefaultGuiComponentRenderer.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java index addec797..1368d6fe 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/GuiContainer.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java index 68910518..9af272bb 100644 --- a/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java +++ b/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -40,22 +40,22 @@ public BorderGuiLayout(final int rows) { public BorderGuiLayout(final @NotNull Slot min, final @NotNull Slot max) { // Top border for (int col = min.column(); col <= max.column(); col++) { - slots.add(new Slot(min.row(), col)); + slots.add(Slot.of(min.row(), col)); } // Bottom border for (int col = min.column(); col <= max.column(); col++) { - slots.add(new Slot(max.row(), col)); + slots.add(Slot.of(max.row(), col)); } // Left border for (int row = min.row() + 1; row < max.row(); row++) { - slots.add(new Slot(row, min.column())); + slots.add(Slot.of(row, min.column())); } // Right border for (int row = min.row() + 1; row < max.row(); row++) { - slots.add(new Slot(row, max.column())); + slots.add(Slot.of(row, max.column())); } } diff --git a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java index 036e4e30..7aa0f6a1 100644 --- a/core/src/main/java/dev/triumphteam/gui/slot/Slot.java +++ b/core/src/main/java/dev/triumphteam/gui/slot/Slot.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/core/src/main/java/dev/triumphteam/gui/title/GuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/GuiTitle.java index 12c21748..718db21a 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/GuiTitle.java +++ b/core/src/main/java/dev/triumphteam/gui/title/GuiTitle.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title; public interface GuiTitle {} diff --git a/core/src/main/java/dev/triumphteam/gui/title/ReactiveGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/ReactiveGuiTitle.java index 2290c6b5..b8aa93ca 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/ReactiveGuiTitle.java +++ b/core/src/main/java/dev/triumphteam/gui/title/ReactiveGuiTitle.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title; import net.kyori.adventure.text.Component; diff --git a/core/src/main/java/dev/triumphteam/gui/title/SimpleGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/SimpleGuiTitle.java index cd3036d4..95e0cc87 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/SimpleGuiTitle.java +++ b/core/src/main/java/dev/triumphteam/gui/title/SimpleGuiTitle.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title; import dev.triumphteam.gui.title.functional.FunctionalGuiTitleRender; diff --git a/core/src/main/java/dev/triumphteam/gui/title/StatefulGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/StatefulGuiTitle.java index 9f4b32fc..a7545572 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/StatefulGuiTitle.java +++ b/core/src/main/java/dev/triumphteam/gui/title/StatefulGuiTitle.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title; import dev.triumphteam.nova.State; diff --git a/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitle.java index 6aca8022..8aabdc8e 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitle.java +++ b/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitle.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title.functional; import dev.triumphteam.nova.holder.StateHolder; diff --git a/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitleRender.java b/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitleRender.java index 928b9bb9..437146cd 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitleRender.java +++ b/core/src/main/java/dev/triumphteam/gui/title/functional/FunctionalGuiTitleRender.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title.functional; import net.kyori.adventure.text.Component; diff --git a/core/src/main/java/dev/triumphteam/gui/title/functional/SimpleFunctionalGuiTitle.java b/core/src/main/java/dev/triumphteam/gui/title/functional/SimpleFunctionalGuiTitle.java index 60d13b24..24ced769 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/functional/SimpleFunctionalGuiTitle.java +++ b/core/src/main/java/dev/triumphteam/gui/title/functional/SimpleFunctionalGuiTitle.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title.functional; import dev.triumphteam.gui.exception.TriumphGuiException; diff --git a/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java b/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java index 13756896..38d824df 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/title/renderer/DefaultGuiTitleRenderer.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title.renderer; import dev.triumphteam.gui.exception.TriumphGuiException; diff --git a/core/src/main/java/dev/triumphteam/gui/title/renderer/GuiTitleRenderer.java b/core/src/main/java/dev/triumphteam/gui/title/renderer/GuiTitleRenderer.java index 7f642b4b..9e6e9db7 100644 --- a/core/src/main/java/dev/triumphteam/gui/title/renderer/GuiTitleRenderer.java +++ b/core/src/main/java/dev/triumphteam/gui/title/renderer/GuiTitleRenderer.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.title.renderer; import dev.triumphteam.gui.title.GuiTitle; diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java index 1f1c1f0b..acc80e9e 100644 --- a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/GuiPlugin.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example; import dev.triumphteam.gui.example.examples.CookieClicker; diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/CookieClicker.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/CookieClicker.java index 6506d0f5..a1f01454 100644 --- a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/CookieClicker.java +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/CookieClicker.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example.examples; import dev.triumphteam.gui.paper.Gui; diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java index e6526d15..876783c4 100644 --- a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example.examples; import dev.triumphteam.gui.paper.Gui; diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/UpdatingTitle.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/UpdatingTitle.java index 2adaba80..ca160f92 100644 --- a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/UpdatingTitle.java +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/UpdatingTitle.java @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example.examples; import dev.triumphteam.gui.paper.Gui; diff --git a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt index e54eeb24..ac2261fc 100644 --- a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt +++ b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example import dev.triumphteam.gui.example.examples.CookieClicker diff --git a/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt b/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt index 435de6ab..ebe1393a 100644 --- a/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt +++ b/examples/paper/kotlin/src/main/kotlin/examples/CookieClicker.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example.examples import dev.triumphteam.gui.kotlin.set diff --git a/examples/paper/kotlin/src/main/kotlin/examples/Static.kt b/examples/paper/kotlin/src/main/kotlin/examples/Static.kt index dbbfd299..5a129bf0 100644 --- a/examples/paper/kotlin/src/main/kotlin/examples/Static.kt +++ b/examples/paper/kotlin/src/main/kotlin/examples/Static.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example.examples import dev.triumphteam.gui.kotlin.set diff --git a/examples/paper/kotlin/src/main/kotlin/examples/UpdatingTitle.kt b/examples/paper/kotlin/src/main/kotlin/examples/UpdatingTitle.kt index f749b1f5..e49c2c50 100644 --- a/examples/paper/kotlin/src/main/kotlin/examples/UpdatingTitle.kt +++ b/examples/paper/kotlin/src/main/kotlin/examples/UpdatingTitle.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example.examples import dev.triumphteam.gui.kotlin.set diff --git a/examples/paper/kotlin/src/main/kotlin/package-info.kt b/examples/paper/kotlin/src/main/kotlin/package-info.kt index ceb94ad4..114b949f 100644 --- a/examples/paper/kotlin/src/main/kotlin/package-info.kt +++ b/examples/paper/kotlin/src/main/kotlin/package-info.kt @@ -1 +1,24 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.example diff --git a/kotlin/src/main/kotlin/ContainerExt.kt b/kotlin/src/main/kotlin/ContainerExt.kt index 68ba7a72..776e54c6 100644 --- a/kotlin/src/main/kotlin/ContainerExt.kt +++ b/kotlin/src/main/kotlin/ContainerExt.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.kotlin import dev.triumphteam.gui.container.GuiContainer diff --git a/kotlin/src/main/kotlin/SlotExt.kt b/kotlin/src/main/kotlin/SlotExt.kt index ff76a68a..3a8aa187 100644 --- a/kotlin/src/main/kotlin/SlotExt.kt +++ b/kotlin/src/main/kotlin/SlotExt.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.kotlin import dev.triumphteam.gui.slot.Slot diff --git a/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt b/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt index 7118113c..60b3281b 100644 --- a/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt +++ b/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.kotlin.builder import dev.triumphteam.gui.BaseGui diff --git a/kotlin/src/main/kotlin/package-info.kt b/kotlin/src/main/kotlin/package-info.kt index f094e893..dcf00b02 100644 --- a/kotlin/src/main/kotlin/package-info.kt +++ b/kotlin/src/main/kotlin/package-info.kt @@ -1 +1,24 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.kotlin diff --git a/paper/kotlin/src/main/kotlin/builder/Container.kt b/paper/kotlin/src/main/kotlin/builder/Container.kt index 97bcd640..cdd1c377 100644 --- a/paper/kotlin/src/main/kotlin/builder/Container.kt +++ b/paper/kotlin/src/main/kotlin/builder/Container.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper.kotlin.builder import dev.triumphteam.gui.paper.container.type.ChestContainerType diff --git a/paper/kotlin/src/main/kotlin/builder/PaperKotlinGuiBuilder.kt b/paper/kotlin/src/main/kotlin/builder/PaperKotlinGuiBuilder.kt index 82f0b68d..b1d4d626 100644 --- a/paper/kotlin/src/main/kotlin/builder/PaperKotlinGuiBuilder.kt +++ b/paper/kotlin/src/main/kotlin/builder/PaperKotlinGuiBuilder.kt @@ -1,3 +1,26 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper.kotlin.builder import dev.triumphteam.gui.kotlin.builder.AbstractKotlinGuiBuilder diff --git a/paper/kotlin/src/main/kotlin/package-info.kt b/paper/kotlin/src/main/kotlin/package-info.kt index 31671162..01b121ae 100644 --- a/paper/kotlin/src/main/kotlin/package-info.kt +++ b/paper/kotlin/src/main/kotlin/package-info.kt @@ -1 +1,24 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package dev.triumphteam.gui.paper.kotlin diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index aa6831d4..19ea737f 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java index e2d5d7e6..71d33b3f 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java index ac836261..a67dc3b1 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java index eceb8031..d75373ea 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java @@ -1,18 +1,18 @@ /** * MIT License - *

+ * * Copyright (c) 2024 TriumphTeam - *

+ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - *

+ * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - *

+ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/settings.gradle.kts b/settings.gradle.kts index ceb734e2..db4ed912 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,11 +24,11 @@ listOf( "core" to "core", "kotlin" to "kotlin", + // Platforms and their Kotlin versions "paper/paper" to "paper", "paper/kotlin" to "paper-kotlin", + // Example projects "examples/paper/java" to "example-paper-java", "examples/paper/kotlin" to "example-paper-kotlin", ).forEach(::includeProject) - -include("test-plugin") From 3f9e5c79c4bdc5d9615bd36b9f93b9b6f1d77e61 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 23 Oct 2024 00:16:04 +0100 Subject: [PATCH 34/43] fix: Static example wrong copy-paste --- .../java/dev/triumphteam/gui/example/examples/Static.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java index 876783c4..c2ae519d 100644 --- a/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java +++ b/examples/paper/java/src/main/java/dev/triumphteam/gui/example/examples/Static.java @@ -43,8 +43,8 @@ public boolean onCommand(@NotNull final CommandSender sender, @NotNull final Com .of(6) .title(Component.text("Static Gui")) // Simple title for the GUI .statelessComponent(container -> { // A stateless component, we don't care about the item updating, just want the click action - container.setItem(1, 1, ItemBuilder.from(Material.COOKIE) - .name(Component.text("Clicked $clicks times!")) + container.setItem(1, 1, ItemBuilder.from(Material.PAPER) + .name(Component.text("My Paper")) .asGuiItem((player, context) -> { player.sendMessage("You have clicked on the paper item!"); }) From e02f3b0a647eabce9ce5c739949230c9edc2ee33 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 29 Oct 2024 16:17:35 +0000 Subject: [PATCH 35/43] chore: Make publishing properties only error when publishing --- build-logic/src/main/kotlin/gui.library.gradle.kts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build-logic/src/main/kotlin/gui.library.gradle.kts b/build-logic/src/main/kotlin/gui.library.gradle.kts index c992f65c..0a0f0ecb 100644 --- a/build-logic/src/main/kotlin/gui.library.gradle.kts +++ b/build-logic/src/main/kotlin/gui.library.gradle.kts @@ -13,13 +13,13 @@ root { from(components["java"]) snapshotsRepo(PublishConfigure.TRIUMPH_SNAPSHOTS) { - username = property("triumph.repo.user") - password = property("triumph.repo.token") + username = providers.gradleProperty("triumph.repo.user").orNull ?: "" + password = providers.gradleProperty("triumph.repo.token").orNull ?: "" } releasesRepo(PublishConfigure.CENTRAL) { - username = property("central.repo.user") - password = property("central.repo.password") + username = providers.gradleProperty("central.repo.user").orNull ?: "" + password = providers.gradleProperty("central.repo.password").orNull ?: "" } signing { From 8b247dba6e12abf6df4ba526954b2177ea8a4862 Mon Sep 17 00:00:00 2001 From: "Mr. Afonso" Date: Tue, 29 Oct 2024 18:59:30 +0100 Subject: [PATCH 36/43] feature: Add more utility methods to item builder - Custom Model Data (`#model()`) - Glow (`#glow()`) - Enchantments (`#enchant()` & `#disenchant()`) - Item Flags (`#flags()`) - Unbreakable (`#unbreakable()`) - Persistent Data Container (`#pdc()`) --- .../builder/item/AbstractItemBuilder.java | 193 +++++++++++++++++- 1 file changed, 185 insertions(+), 8 deletions(-) diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java index dfd5d076..df69f2f6 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java @@ -32,9 +32,13 @@ import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.gradle.internal.impldep.io.usethesource.capsule.Map; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -42,14 +46,11 @@ import java.util.Arrays; import java.util.EnumSet; import java.util.List; +import java.util.function.Consumer; @SuppressWarnings("unchecked") public abstract class AbstractItemBuilder> { - private static final EnumSet LEATHER_ARMOR = EnumSet.of( - Material.LEATHER_HELMET, Material.LEATHER_CHESTPLATE, Material.LEATHER_LEGGINGS, Material.LEATHER_BOOTS - ); - private ItemStack itemStack; private ItemMeta meta; @@ -65,7 +66,6 @@ protected AbstractItemBuilder(final @NotNull ItemStack itemStack) { * * @param name The {@link Component} name * @return {@link B} - * @since 3.0.0 */ @NotNull @Contract("_ -> this") @@ -81,7 +81,6 @@ public B name(final @NotNull Component name) { * * @param amount the amount of items * @return {@link B} - * @since 3.0.0 */ @NotNull @Contract("_ -> this") @@ -95,7 +94,6 @@ public B amount(final int amount) { * * @param lore Lore lines as varargs * @return {@link B} - * @since 3.0.0 */ @NotNull @Contract("_ -> this") @@ -108,7 +106,6 @@ public B lore(final @Nullable Component @NotNull ... lore) { * * @param lore A {@link List} with the lore lines * @return {@link B} - * @since 3.0.0 */ @NotNull @Contract("_ -> this") @@ -118,6 +115,186 @@ public B lore(final @NotNull List<@Nullable Component> lore) { return (B) this; } + /** + * Set the custom data model of an item + * + * @param modelData the data of the model to be set + * @return {@link B} + */ + @NotNull + @Contract("_ -> this") + public B model(final int modelData) { + if (meta == null) return (B) this; + meta.setCustomModelData(modelData); + return (B) this; + } + + /** + * Makes the {@link ItemStack} glow + * + * @return {@link B} + */ + @NotNull + @Contract(" -> this") + public B glow() { + return glow(true); + } + + /** + * Adds or removes the {@link ItemStack} glow + * + * @param glow Should the item glow + * @return {@link B} + */ + @NotNull + @Contract("_ -> this") + public B glow(boolean glow) { + if (glow) { + meta.addEnchant(Enchantment.LURE, 1, false); + meta.addItemFlags(ItemFlag.HIDE_ENCHANTS); + return (B) this; + } + + for (final Enchantment enchantment : meta.getEnchants().keySet()) { + meta.removeEnchant(enchantment); + } + + return (B) this; + } + + /** + * Consumer for applying {@link PersistentDataContainer} to the item + * + * @param consumer The {@link Consumer} with the PDC + * @return {@link B} + */ + @NotNull + @Contract("_ -> this") + public B pdc(@NotNull final Consumer consumer) { + consumer.accept(meta.getPersistentDataContainer()); + return (B) this; + } + + /** + * Enchants the {@link ItemStack} with the specified {@link Enchantment} and level + * + * @param enchantment The {@link Enchantment} to add + * @param level The level of the {@link Enchantment} + * @param ignoreLevelRestriction If should or not ignore it + * @return {@link B} + */ + @NotNull + @Contract("_, _, _ -> this") + public B enchant(@NotNull final Enchantment enchantment, final int level, final boolean ignoreLevelRestriction) { + meta.addEnchant(enchantment, level, ignoreLevelRestriction); + return (B) this; + } + + /** + * Enchants the {@link ItemStack} with the specified {@link Enchantment} and level + * + * @param enchantment The {@link Enchantment} to add + * @param level The level of the {@link Enchantment} + * @return {@link B} + */ + @NotNull + @Contract("_, _ -> this") + public B enchant(@NotNull final Enchantment enchantment, final int level) { + return enchant(enchantment, level, true); + } + + /** + * Enchants the {@link ItemStack} with the specified {@link Enchantment} + * + * @param enchantment The {@link Enchantment} to add + * @return {@link B} + */ + @NotNull + @Contract("_ -> this") + public B enchant(@NotNull final Enchantment enchantment) { + return enchant(enchantment, 1, true); + } + + /** + * Enchants the {@link ItemStack} with the specified map where the value + * is the level of the key's enchantment + * + * @param enchantments Enchantments to add + * @param ignoreLevelRestriction If level restriction should be ignored + * @return {@link B} + * @since 3.1.2 + */ + @NotNull + @Contract("_, _ -> this") + public B enchant(@NotNull final Map enchantments, final boolean ignoreLevelRestriction) { + enchantments.forEach((enchantment, level) -> this.enchant(enchantment, level, ignoreLevelRestriction)); + return (B) this; + } + + /** + * Enchants the {@link ItemStack} with the specified map where the value + * is the level of the key's enchantment + * + * @param enchantments Enchantments to add + * @return {@link B} + * @since 3.1.2 + */ + @NotNull + @Contract("_ -> this") + public B enchant(@NotNull final Map enchantments) { + return enchant(enchantments, true); + } + + /** + * Disenchants a certain {@link Enchantment} from the {@link ItemStack} + * + * @param enchantment The {@link Enchantment} to remove + * @return {@link B} + */ + @NotNull + @Contract("_ -> this") + public B disenchant(@NotNull final Enchantment enchantment) { + itemStack.removeEnchantment(enchantment); + return (B) this; + } + + /** + * Add an {@link ItemFlag} to the item + * + * @param flags The {@link ItemFlag} to add + * @return {@link B} + */ + @NotNull + @Contract("_ -> this") + public B flags(@NotNull final ItemFlag... flags) { + meta.addItemFlags(flags); + return (B) this; + } + + /** + * Makes the {@link ItemStack} unbreakable + * + * @return {@link ItemBuilder} + */ + @NotNull + @Contract(" -> this") + public B unbreakable() { + return unbreakable(true); + } + + /** + * Sets the item as unbreakable + * + * @param unbreakable If should or not be unbreakable + * @return {@link ItemBuilder} + */ + @NotNull + @Contract("_ -> this") + public B unbreakable(boolean unbreakable) { + meta.setUnbreakable(unbreakable); + return (B) this; + } + @NotNull @Contract(" -> new") public ItemStack asItemStack() { From 0a10212e1c306a77a1983371e8bd335fe8f75000 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 29 Oct 2024 20:40:10 +0100 Subject: [PATCH 37/43] fix: Compile errors from previous PR --- build-logic/src/main/kotlin/gui.library.gradle.kts | 4 ++-- .../gui/paper/builder/item/AbstractItemBuilder.java | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build-logic/src/main/kotlin/gui.library.gradle.kts b/build-logic/src/main/kotlin/gui.library.gradle.kts index 0a0f0ecb..ae20ea75 100644 --- a/build-logic/src/main/kotlin/gui.library.gradle.kts +++ b/build-logic/src/main/kotlin/gui.library.gradle.kts @@ -22,9 +22,9 @@ root { password = providers.gradleProperty("central.repo.password").orNull ?: "" } - signing { + /*signing { sign(publishing.publications["maven"]) - } + }*/ } } } diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java index df69f2f6..da765931 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java @@ -31,21 +31,19 @@ import dev.triumphteam.gui.item.items.SimpleGuiItem; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; -import org.gradle.internal.impldep.io.usethesource.capsule.Map; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; -import java.util.EnumSet; import java.util.List; +import java.util.Map; import java.util.function.Consumer; @SuppressWarnings("unchecked") From f1e2e950847dc482ab1f84934ad4c32d09d45f95 Mon Sep 17 00:00:00 2001 From: Matt Date: Wed, 30 Oct 2024 15:50:10 -0500 Subject: [PATCH 38/43] feature: Pagination and Scrolling --- .../components/PaginatedComponent.java | 96 ------------------- .../AbstractFunctionalGuiComponent.java | 34 ++++++- .../BaseFunctionalGuiComponent.java | 29 +++++- .../gui/container/MapBackedContainer.java | 2 +- .../gui/layout/BorderGuiLayout.java | 18 ++-- .../triumphteam/gui/layout/BoxGuiLayout.java | 44 +++++++-- .../dev/triumphteam/gui/layout/GuiLayout.java | 30 ++++-- .../pagination/AbstractScrollerState.java | 93 ++++++++++++++++++ .../gui/state/pagination/PageEntry.java | 23 +++++ .../gui/state/pagination/PagerState.java | 28 ++++++ .../gui/state/pagination/ScrollerState.java | 22 +++++ .../state/pagination/SimplePagerState.java | 27 ++++++ .../state/pagination/SimpleScrollerState.java | 17 ++++ kotlin/src/main/kotlin/ScrollerStateExt.kt | 21 ++++ 14 files changed, 356 insertions(+), 128 deletions(-) delete mode 100644 core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/pagination/AbstractScrollerState.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/pagination/PageEntry.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/pagination/PagerState.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/pagination/ScrollerState.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/pagination/SimplePagerState.java create mode 100644 core/src/main/java/dev/triumphteam/gui/state/pagination/SimpleScrollerState.java create mode 100644 kotlin/src/main/kotlin/ScrollerStateExt.kt diff --git a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java b/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java deleted file mode 100644 index 1ecfc0b4..00000000 --- a/core/src/main/java/dev/triumphteam/gui/component/components/PaginatedComponent.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * MIT License - * - * Copyright (c) 2024 TriumphTeam - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package dev.triumphteam.gui.component.components; - -import dev.triumphteam.gui.click.action.RunnableGuiClickAction; -import dev.triumphteam.gui.component.ReactiveGuiComponent; -import dev.triumphteam.gui.container.GuiContainer; -import dev.triumphteam.gui.item.GuiItem; -import dev.triumphteam.gui.item.items.SimpleGuiItem; -import dev.triumphteam.gui.layout.GuiLayout; -import dev.triumphteam.gui.slot.Slot; -import dev.triumphteam.nova.MutableState; -import dev.triumphteam.nova.State; -import org.jetbrains.annotations.NotNull; - -import java.util.List; - -public final class PaginatedComponent implements ReactiveGuiComponent { - - private final Slot back; - private final I backItem; - private final Slot forward; - private final I forwardItem; - private final List> items; - private final GuiLayout layout; - - private final MutableState pageState = MutableState.of(1); - - public PaginatedComponent( - final @NotNull Slot back, - final @NotNull I backItem, - final @NotNull Slot forward, - final @NotNull I forwardItem, - final @NotNull List> items, - final @NotNull GuiLayout layout - ) { - this.back = back; - this.backItem = backItem; - this.forward = forward; - this.forwardItem = forwardItem; - this.items = items; - this.layout = layout; - } - - @Override - public @NotNull List<@NotNull State> states() { - return List.of(pageState); - } - - @Override - public void render(final @NotNull GuiContainer container) { - final var page = pageState.get(); - - container.setItem(back, new SimpleGuiItem<>(backItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.set(page - 1))); - container.setItem(forward, new SimpleGuiItem<>(forwardItem, (RunnableGuiClickAction

) (ignored, context) -> pageState.set(page + 1))); - - final var slots = layout.generatePositions(); - final var size = slots.size(); - - final var offset = page * size; - - for (int i = 0; i < size; i++) { - final var offsetSlot = offset + i; - - /*if (offsetSlot >= items.size() || offsetSlot < 0) { - return; - }*/ - - final var slot = slots.get(i); - final var item = items.get(offsetSlot); - - container.setItem(slot, item); - } - } -} diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java index fda79748..d1d5eb54 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/AbstractFunctionalGuiComponent.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,16 +26,42 @@ import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.click.handler.CompletableFutureClickHandler; import dev.triumphteam.gui.click.handler.SimpleClickHandler; +import dev.triumphteam.gui.layout.GuiLayout; +import dev.triumphteam.gui.state.pagination.PagerState; +import dev.triumphteam.gui.state.pagination.ScrollerState; import dev.triumphteam.nova.holder.AbstractStateHolder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.concurrent.TimeUnit; public abstract class AbstractFunctionalGuiComponent

extends AbstractStateHolder implements BaseFunctionalGuiComponent

{ private ClickHandler

clickHandler = null; + @Override + public @NotNull PagerState rememberPager( + final int startPage, + final @NotNull List elements, + final @NotNull GuiLayout layout) { + return remember(PagerState.of(startPage, elements, layout)); + } + + @Override + public @NotNull PagerState rememberPager(final @NotNull List elements, final @NotNull GuiLayout layout) { + return remember(PagerState.of(elements, layout)); + } + + @Override + public @NotNull ScrollerState rememberScroller( + final int steps, + final @NotNull List elements, + final @NotNull GuiLayout layout + ) { + return remember(ScrollerState.of(steps, elements, layout)); + } + @Override public void withClickHandler(final @Nullable ClickHandler

clickHandler) { this.clickHandler = clickHandler; diff --git a/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java b/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java index 511abbca..61051f9a 100644 --- a/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java +++ b/core/src/main/java/dev/triumphteam/gui/component/functional/BaseFunctionalGuiComponent.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,14 +24,35 @@ package dev.triumphteam.gui.component.functional; import dev.triumphteam.gui.click.handler.ClickHandler; +import dev.triumphteam.gui.layout.GuiLayout; +import dev.triumphteam.gui.state.pagination.PagerState; +import dev.triumphteam.gui.state.pagination.ScrollerState; import dev.triumphteam.nova.holder.StateHolder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.List; import java.util.concurrent.TimeUnit; interface BaseFunctionalGuiComponent

extends StateHolder { + @NotNull PagerState rememberPager( + final int startPage, + final @NotNull List elements, + final @NotNull GuiLayout layout + ); + + @NotNull PagerState rememberPager( + final @NotNull List elements, + final @NotNull GuiLayout layout + ); + + @NotNull ScrollerState rememberScroller( + final int steps, + final @NotNull List elements, + final @NotNull GuiLayout layout + ); + /** * TODO * @param clickHandler diff --git a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java index d6f3cfbb..34867882 100644 --- a/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java +++ b/core/src/main/java/dev/triumphteam/gui/container/MapBackedContainer.java @@ -75,7 +75,7 @@ public void setItem(final int slot, final @NotNull GuiItem<@NotNull P, @NotNull @Override public void fill(final @NotNull GuiLayout layout, final @NotNull GuiItem<@NotNull P, @NotNull I> guiItem) { - layout.generatePositions().forEach(position -> setItem(position, guiItem)); + layout.forEach(position -> setItem(position, guiItem)); } public @NotNull Map> complete() { diff --git a/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java index 9af272bb..5794bb91 100644 --- a/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java +++ b/core/src/main/java/dev/triumphteam/gui/layout/BorderGuiLayout.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public final class BorderGuiLayout implements GuiLayout { @@ -60,7 +61,12 @@ public BorderGuiLayout(final @NotNull Slot min, final @NotNull Slot max) { } @Override - public @NotNull List<@NotNull Slot> generatePositions() { - return slots; + public @NotNull Iterator iterator() { + return slots.iterator(); + } + + @Override + public int size() { + return slots.size(); } } diff --git a/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java index 8f5c4402..e8709d20 100644 --- a/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java +++ b/core/src/main/java/dev/triumphteam/gui/layout/BoxGuiLayout.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,9 +24,11 @@ package dev.triumphteam.gui.layout; import dev.triumphteam.gui.slot.Slot; +import org.checkerframework.checker.units.qual.min; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public final class BoxGuiLayout implements GuiLayout { @@ -34,15 +36,39 @@ public final class BoxGuiLayout implements GuiLayout { private final List slots = new ArrayList<>(); public BoxGuiLayout(final @NotNull Slot min, final @NotNull Slot max) { - for (int row = min.row(); row <= max.row(); row++) { - for (int col = min.column(); col <= max.column(); col++) { - slots.add(Slot.of(row, col)); + this(min, max, Direction.VERTICAL); + } + + public BoxGuiLayout(final @NotNull Slot min, final @NotNull Slot max, final @NotNull Direction direction) { + switch (direction) { + case HORIZONTAL -> { + for (int col = min.column(); col <= max.column(); col++) { + for (int row = min.row(); row <= max.row(); row++) { + slots.add(Slot.of(row, col)); + } + } + } + case VERTICAL -> { + for (int row = min.row(); row <= max.row(); row++) { + for (int col = min.column(); col <= max.column(); col++) { + slots.add(Slot.of(row, col)); + } + } } } } @Override - public @NotNull List<@NotNull Slot> generatePositions() { - return slots; + public @NotNull Iterator iterator() { + return slots.iterator(); + } + + @Override + public int size() { + return slots.size(); + } + + public enum Direction { + HORIZONTAL, VERTICAL } } diff --git a/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java b/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java index 2dc34073..c73e3e42 100644 --- a/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java +++ b/core/src/main/java/dev/triumphteam/gui/layout/GuiLayout.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -26,10 +26,24 @@ import dev.triumphteam.gui.slot.Slot; import org.jetbrains.annotations.NotNull; -import java.util.List; +import javax.swing.*; -public interface GuiLayout { +public interface GuiLayout extends Iterable { - @NotNull - List<@NotNull Slot> generatePositions(); + static @NotNull GuiLayout box( + final @NotNull Slot min, + final @NotNull Slot max, + final @NotNull BoxGuiLayout.Direction direction + ) { + return new BoxGuiLayout(min, max, direction); + } + + static @NotNull GuiLayout box( + final @NotNull Slot min, + final @NotNull Slot max + ) { + return new BoxGuiLayout(min, max); + } + + int size(); } diff --git a/core/src/main/java/dev/triumphteam/gui/state/pagination/AbstractScrollerState.java b/core/src/main/java/dev/triumphteam/gui/state/pagination/AbstractScrollerState.java new file mode 100644 index 00000000..d9ee1bda --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/pagination/AbstractScrollerState.java @@ -0,0 +1,93 @@ +package dev.triumphteam.gui.state.pagination; + +import dev.triumphteam.gui.layout.GuiLayout; +import dev.triumphteam.nova.AbstractState; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static java.lang.Math.ceil; +import static java.lang.Math.min; + +public abstract class AbstractScrollerState extends AbstractState implements ScrollerState { + + private final int steps; + private final int elementsPerView; + private final List elements; + private final GuiLayout layout; + private final int limit; + + private int current; + + public AbstractScrollerState( + final int steps, + final int startPosition, + final @NotNull List elements, + final @NotNull GuiLayout layout + ) { + this.elementsPerView = layout.size(); + + // If no steps we use all elements per view + if (steps < 1) this.steps = this.elementsPerView; + else this.steps = steps; + + this.current = startPosition; + this.elements = elements; + this.layout = layout; + this.limit = (int) ceil((double) elements.size() / steps); + } + + @Override + public void next() { + if (current >= limit) return; + current += steps; + trigger(); + } + + @Override + public void prev() { + if (current <= 1) return; + current -= steps; + trigger(); + } + + @Override + public @NotNull Iterator> iterator() { + // TODO: this should probably be on page change not on iterator call to avoid calculation when multiple calls are made + final var from = current - 1; + final var to = min(from + elementsPerView, elements.size()); + final var subList = new ArrayList>(); + final var layoutIterator = layout.iterator(); + + for (int i = from; i < to; i++) { + if (!layoutIterator.hasNext()) break; + final var slot = layoutIterator.next(); + + subList.add(new PageEntry<>(slot, elements.get(i))); + } + + return subList.iterator(); + } + + protected int getSteps() { + return steps; + } + + protected int getElementsPerView() { + return elementsPerView; + } + + protected List getElements() { + return elements; + } + + protected int getLimit() { + return limit; + } + + protected int getCurrent() { + return current; + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/pagination/PageEntry.java b/core/src/main/java/dev/triumphteam/gui/state/pagination/PageEntry.java new file mode 100644 index 00000000..13f3a2fd --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/pagination/PageEntry.java @@ -0,0 +1,23 @@ +package dev.triumphteam.gui.state.pagination; + +import dev.triumphteam.gui.slot.Slot; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +public record PageEntry(@NotNull Slot slot, @NotNull T element) implements Map.Entry { + @Override + public Slot getKey() { + return slot; + } + + @Override + public T getValue() { + return element; + } + + @Override + public T setValue(T value) { + throw new UnsupportedOperationException("PageEntry is immutable."); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/pagination/PagerState.java b/core/src/main/java/dev/triumphteam/gui/state/pagination/PagerState.java new file mode 100644 index 00000000..1dab0e2c --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/pagination/PagerState.java @@ -0,0 +1,28 @@ +package dev.triumphteam.gui.state.pagination; + +import dev.triumphteam.gui.layout.GuiLayout; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface PagerState extends ScrollerState { + + static @NotNull PagerState of( + final int startPage, + final @NotNull List elements, + final @NotNull GuiLayout layout + ) { + return new SimplePagerState<>(startPage, elements, layout); + } + + static @NotNull PagerState of( + final @NotNull List elements, + final @NotNull GuiLayout layout + ) { + return of(1, elements, layout); + } + + int getCurrentPage(); + + int getPageCount(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/pagination/ScrollerState.java b/core/src/main/java/dev/triumphteam/gui/state/pagination/ScrollerState.java new file mode 100644 index 00000000..de69e77d --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/pagination/ScrollerState.java @@ -0,0 +1,22 @@ +package dev.triumphteam.gui.state.pagination; + +import dev.triumphteam.gui.layout.GuiLayout; +import dev.triumphteam.nova.State; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public interface ScrollerState extends State, Iterable> { + + static @NotNull ScrollerState of( + final int steps, + final @NotNull List elements, + final @NotNull GuiLayout layout + ) { + return new SimpleScrollerState<>(steps, elements, layout); + } + + void prev(); + + void next(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/pagination/SimplePagerState.java b/core/src/main/java/dev/triumphteam/gui/state/pagination/SimplePagerState.java new file mode 100644 index 00000000..5f93581a --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/pagination/SimplePagerState.java @@ -0,0 +1,27 @@ +package dev.triumphteam.gui.state.pagination; + +import dev.triumphteam.gui.layout.GuiLayout; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public final class SimplePagerState extends AbstractScrollerState implements PagerState { + + public SimplePagerState( + final int startPage, + final @NotNull List elements, + final @NotNull GuiLayout layout + ) { + super(0, startPage, elements, layout); + } + + @Override + public int getCurrentPage() { + return getCurrent(); + } + + @Override + public int getPageCount() { + return getLimit(); + } +} diff --git a/core/src/main/java/dev/triumphteam/gui/state/pagination/SimpleScrollerState.java b/core/src/main/java/dev/triumphteam/gui/state/pagination/SimpleScrollerState.java new file mode 100644 index 00000000..4eed1ebe --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/state/pagination/SimpleScrollerState.java @@ -0,0 +1,17 @@ +package dev.triumphteam.gui.state.pagination; + +import dev.triumphteam.gui.layout.GuiLayout; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class SimpleScrollerState extends AbstractScrollerState { + + public SimpleScrollerState( + final int steps, + final @NotNull List elements, + final @NotNull GuiLayout layout + ) { + super(steps, 1, elements, layout); + } +} diff --git a/kotlin/src/main/kotlin/ScrollerStateExt.kt b/kotlin/src/main/kotlin/ScrollerStateExt.kt new file mode 100644 index 00000000..e10e4dd0 --- /dev/null +++ b/kotlin/src/main/kotlin/ScrollerStateExt.kt @@ -0,0 +1,21 @@ +package dev.triumphteam.gui.kotlin + +import dev.triumphteam.gui.layout.GuiLayout +import dev.triumphteam.gui.state.pagination.PagerState +import dev.triumphteam.gui.state.pagination.ScrollerState +import dev.triumphteam.gui.state.pagination.SimplePagerState +import dev.triumphteam.gui.state.pagination.SimpleScrollerState + +public fun pagerState( + startPage: Int = 1, + elements: List, + layout: GuiLayout, +): PagerState = + SimplePagerState(startPage, elements, layout) + +public fun scrollerState( + steps: Int, + elements: List, + layout: GuiLayout, +): ScrollerState = + SimpleScrollerState(steps, elements, layout) From 19df9eedcd37d93993072246b7e659e0d651e7d8 Mon Sep 17 00:00:00 2001 From: Matt Date: Mon, 4 Nov 2024 22:15:00 +0000 Subject: [PATCH 39/43] chore: Add pagination and scrolling examples --- examples/paper/kotlin/build.gradle.kts | 2 + .../paper/kotlin/src/main/kotlin/GuiPlugin.kt | 4 + .../src/main/kotlin/examples/Paginated.kt | 96 ++++++++++++++++ .../src/main/kotlin/examples/Scrolling.kt | 104 ++++++++++++++++++ 4 files changed, 206 insertions(+) create mode 100644 examples/paper/kotlin/src/main/kotlin/examples/Paginated.kt create mode 100644 examples/paper/kotlin/src/main/kotlin/examples/Scrolling.kt diff --git a/examples/paper/kotlin/build.gradle.kts b/examples/paper/kotlin/build.gradle.kts index 3c8c619d..a6b2a405 100644 --- a/examples/paper/kotlin/build.gradle.kts +++ b/examples/paper/kotlin/build.gradle.kts @@ -27,6 +27,8 @@ tasks { commands.add(commands.create("gui-static")) commands.add(commands.create("gui-clicker")) commands.add(commands.create("gui-title")) + commands.add(commands.create("gui-page")) + commands.add(commands.create("gui-scroll")) foliaSupported.set(true) } } diff --git a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt index ac2261fc..0b16581e 100644 --- a/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt +++ b/examples/paper/kotlin/src/main/kotlin/GuiPlugin.kt @@ -24,6 +24,8 @@ package dev.triumphteam.gui.example import dev.triumphteam.gui.example.examples.CookieClicker +import dev.triumphteam.gui.example.examples.Paginated +import dev.triumphteam.gui.example.examples.Scrolling import dev.triumphteam.gui.example.examples.Static import dev.triumphteam.gui.example.examples.UpdatingTitle import org.bukkit.plugin.java.JavaPlugin @@ -34,5 +36,7 @@ public class GuiPlugin : JavaPlugin() { getCommand("gui-static")?.setExecutor(Static()) getCommand("gui-clicker")?.setExecutor(CookieClicker()) getCommand("gui-title")?.setExecutor(UpdatingTitle()) + getCommand("gui-page")?.setExecutor(Paginated()) + getCommand("gui-scroll")?.setExecutor(Scrolling()) } } diff --git a/examples/paper/kotlin/src/main/kotlin/examples/Paginated.kt b/examples/paper/kotlin/src/main/kotlin/examples/Paginated.kt new file mode 100644 index 00000000..063a4b92 --- /dev/null +++ b/examples/paper/kotlin/src/main/kotlin/examples/Paginated.kt @@ -0,0 +1,96 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package dev.triumphteam.gui.example.examples + +import dev.triumphteam.gui.kotlin.set +import dev.triumphteam.gui.kotlin.slot +import dev.triumphteam.gui.layout.GuiLayout +import dev.triumphteam.gui.paper.builder.item.ItemBuilder +import dev.triumphteam.gui.paper.kotlin.builder.buildGui +import dev.triumphteam.gui.paper.kotlin.builder.chestContainer +import net.kyori.adventure.text.Component +import org.bukkit.Material +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + +public class Paginated : CommandExecutor { + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { + if (sender !is Player) return false + + // Simple example to fill in the pages + val materials = Material.entries.filter { it.isItem && !it.isAir }.shuffled() + + val gui = buildGui { + // If not set, defaults to chest - 1 row + containerType = chestContainer { + rows = 6 + } + + // Simple title for the gui + title(Component.text("Paginated Gui")) + + component { + + // Tell the component to remember the pager state with the given elements + // Elements can be anything, in this case it's the material of the page items + // If the element is already a fully built ItemStack it'll always be static as it is rendered outside the component + val pagerState = rememberPager( + materials, + // The layout is very important as it dictates how the items will be distributed in a page and also + // how many items there will be per page + GuiLayout.box(slot(2, 3), slot(4, 7)) + ) + + render { container -> + + // Loop through the page and set items to the container + pagerState.forEach { (slot, element) -> + // Create a new item stack with the material provided by the pager + container[slot] = ItemBuilder.from(element).asGuiItem() + } + + // The previous page button + container[6, 2] = ItemBuilder.from(Material.PAPER) + .name(Component.text("Previous page")) + .asGuiItem { _, _ -> + pagerState.prev() + } + + // The next page button + container[6, 8] = ItemBuilder.from(Material.PAPER) + .name(Component.text("Next page")) + .asGuiItem { _, _ -> + pagerState.next() + } + } + } + } + + gui.open(sender) + return true + } +} diff --git a/examples/paper/kotlin/src/main/kotlin/examples/Scrolling.kt b/examples/paper/kotlin/src/main/kotlin/examples/Scrolling.kt new file mode 100644 index 00000000..67aa3e1b --- /dev/null +++ b/examples/paper/kotlin/src/main/kotlin/examples/Scrolling.kt @@ -0,0 +1,104 @@ +/** + * MIT License + * + * Copyright (c) 2024 TriumphTeam + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package dev.triumphteam.gui.example.examples + +import dev.triumphteam.gui.kotlin.set +import dev.triumphteam.gui.kotlin.slot +import dev.triumphteam.gui.layout.BoxGuiLayout +import dev.triumphteam.gui.layout.GuiLayout +import dev.triumphteam.gui.paper.builder.item.ItemBuilder +import dev.triumphteam.gui.paper.kotlin.builder.buildGui +import dev.triumphteam.gui.paper.kotlin.builder.chestContainer +import net.kyori.adventure.text.Component +import org.bukkit.Material +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender +import org.bukkit.entity.Player + +public class Scrolling : CommandExecutor { + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { + if (sender !is Player) return false + + // Simple example to fill in the pages + val materials = Material.entries.filter { it.isItem && !it.isAir }.shuffled() + + val gui = buildGui { + // If not set, defaults to chest - 1 row + containerType = chestContainer { + rows = 6 + } + + // Simple title for the gui + title(Component.text("Scrolling Gui")) + + // The system is very similar to how you would do a paginated gui + component { + + // Tell the component to remember the scroller state with the given elements + // Elements can be anything, in this case it's the material of the scrolling items + // If the element is already a fully built ItemStack it'll always be static as it is rendered outside the component + val pagerState = rememberPager( + materials, + // The layout is very important as it dictates how the items will be distributed in a "page" and also + // how many items there will be per "page" + // The direction is part of the layout and will control how the scrolling will happen + // This also means that other layouts will behave very differently + GuiLayout.box( + slot(2, 3), + slot(4, 7), + BoxGuiLayout.Direction.VERTICAL, + ) + ) + + render { container -> + + // Loop through the page and set items to the container + pagerState.forEach { (slot, element) -> + // Create a new item stack with the material provided by the pager + container[slot] = ItemBuilder.from(element).asGuiItem() + } + + // The previous page button + container[6, 2] = ItemBuilder.from(Material.PAPER) + .name(Component.text("Previous page")) + .asGuiItem { _, _ -> + pagerState.prev() + } + + // The next page button + container[6, 8] = ItemBuilder.from(Material.PAPER) + .name(Component.text("Next page")) + .asGuiItem { _, _ -> + pagerState.next() + } + } + } + } + + gui.open(sender) + return true + } +} From 9a8c9b978a394d2d3c00f8dae0a20a1c592eaadf Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 29 Nov 2024 10:01:43 +0000 Subject: [PATCH 40/43] hmm --- .../dev/triumphteam/gui/AbstractGuiView.java | 42 ++++++++++++------- .../gui/actions/GuiCloseAction.java | 7 ++++ .../gui/builder/BaseGuiBuilder.java | 20 +++++++-- examples/paper/kotlin/build.gradle.kts | 2 + .../builder/AbstractKotlinGuiBuilder.kt | 5 +++ .../java/dev/triumphteam/gui/paper/Gui.java | 5 +++ .../gui/paper/PaperGuiListener.java | 24 +++++++---- .../triumphteam/gui/paper/PaperGuiView.java | 20 +++++---- .../paper/builder/gui/PaperGuiBuilder.java | 1 + 9 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 core/src/main/java/dev/triumphteam/gui/actions/GuiCloseAction.java diff --git a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java index 3ed3f4d8..6184d69f 100644 --- a/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java +++ b/core/src/main/java/dev/triumphteam/gui/AbstractGuiView.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,6 +23,7 @@ */ package dev.triumphteam.gui; +import dev.triumphteam.gui.actions.GuiCloseAction; import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.click.processor.ClickProcessor; @@ -45,31 +46,32 @@ import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicBoolean; public abstract class AbstractGuiView implements GuiView { private final P viewer; private final GuiTitle title; private final List> components; + private final List closeActions; private final GuiComponentRenderer renderer; private final ClickHandler

defaultClickHandler; private final GuiContainerType containerType; private final GuiTitleRenderer titleRenderer = new DefaultGuiTitleRenderer(); - - private final AtomicBoolean firstOpen = new AtomicBoolean(true); - // Click processor + // Click processor. private final ClickProcessor clickProcessor; - // Cache of rendered components + // Cache of rendered components. private final Map, RenderedComponent> renderedComponents = new ConcurrentHashMap<>(); - // All the gui items that have been rendered and are in the inventory + // All the gui items that have been rendered and are in the inventory. private final Map> allRenderedItems = new ConcurrentHashMap<>(); + // Helper boolean for updating title. + private boolean updating = true; private Component renderedTitle = null; public AbstractGuiView( final @NotNull P viewer, final @NotNull GuiTitle title, final @NotNull List<@NotNull GuiComponent> components, + final @NotNull List closeActions, final @NotNull GuiContainerType containerType, final @NotNull GuiComponentRenderer renderer, final @NotNull ClickHandler

defaultClickHandler, @@ -78,6 +80,7 @@ public AbstractGuiView( this.title = title; this.viewer = viewer; this.components = components; + this.closeActions = closeActions; this.containerType = containerType; this.renderer = renderer; this.defaultClickHandler = defaultClickHandler; @@ -96,7 +99,7 @@ public AbstractGuiView( protected abstract void populateInventory(final @NotNull Map> renderedItems); - protected abstract void openInventory(); + protected abstract void openInventory(final boolean updating); @Override public void open() { @@ -104,10 +107,9 @@ public void open() { // Add listener to used states statefulGuiTitle.states().forEach(state -> { state.addListener(this, () -> { - firstOpen.compareAndSet(true, false); titleRenderer.renderTitle(title, (rendered) -> { this.renderedTitle = rendered; - openInventory(); + openInventory(true); }); }); }); @@ -115,7 +117,7 @@ public void open() { titleRenderer.renderTitle(title, (rendered) -> { this.renderedTitle = rendered; - openInventory(); + openInventory(false); setup(); }); } @@ -171,6 +173,10 @@ public void processClick(final @NotNull ClickContext context) { return containerType; } + public @NotNull List getCloseActions() { + return closeActions; + } + public Component getTitle() { if (renderedTitle == null) { throw new TriumphGuiException("Tried to get title before it was available."); @@ -178,7 +184,11 @@ public Component getTitle() { return renderedTitle; } - public boolean isFirstOpen() { - return firstOpen.get(); + public boolean isUpdating() { + return updating; + } + + protected void setUpdating(final boolean newValue) { + this.updating = newValue; } } diff --git a/core/src/main/java/dev/triumphteam/gui/actions/GuiCloseAction.java b/core/src/main/java/dev/triumphteam/gui/actions/GuiCloseAction.java new file mode 100644 index 00000000..4d2ff46e --- /dev/null +++ b/core/src/main/java/dev/triumphteam/gui/actions/GuiCloseAction.java @@ -0,0 +1,7 @@ +package dev.triumphteam.gui.actions; + +@FunctionalInterface +public interface GuiCloseAction { + + void onClose(); +} diff --git a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java index f1edbba4..fdb04b97 100644 --- a/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java +++ b/core/src/main/java/dev/triumphteam/gui/builder/BaseGuiBuilder.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,6 +24,7 @@ package dev.triumphteam.gui.builder; import dev.triumphteam.gui.BaseGui; +import dev.triumphteam.gui.actions.GuiCloseAction; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.SimpleGuiComponent; @@ -62,6 +63,7 @@ public abstract class BaseGuiBuilder, P, private final GuiSettings guiSettings; private final List> components = new ArrayList<>(); + private final List closeActions = new ArrayList<>(); private C containerType; private ClickHandler

clickHandler = null; private GuiComponentRenderer componentRenderer = null; @@ -207,6 +209,12 @@ public BaseGuiBuilder( return (B) this; } + @Contract("_ -> this") + public @NotNull B onClose(final @NotNull GuiCloseAction closeAction) { + closeActions.add(closeAction); + return (B) this; + } + /** * Finalizes the builder and creates a {@link G} instance of {@link BaseGui} depending on the platform. * @@ -224,6 +232,10 @@ public BaseGuiBuilder( return components; } + protected @NotNull List getCloseActions() { + return closeActions; + } + protected @NotNull ClickHandler

getClickHandler() { if (clickHandler == null) { return guiSettings.getClickHandler(); diff --git a/examples/paper/kotlin/build.gradle.kts b/examples/paper/kotlin/build.gradle.kts index a6b2a405..abc55ecd 100644 --- a/examples/paper/kotlin/build.gradle.kts +++ b/examples/paper/kotlin/build.gradle.kts @@ -30,5 +30,7 @@ tasks { commands.add(commands.create("gui-page")) commands.add(commands.create("gui-scroll")) foliaSupported.set(true) + + // really neat idea, world found a cave that takes you to a place kinda like annihilation movie } } diff --git a/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt b/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt index 60b3281b..a175b6b4 100644 --- a/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt +++ b/kotlin/src/main/kotlin/builder/AbstractKotlinGuiBuilder.kt @@ -24,6 +24,7 @@ package dev.triumphteam.gui.kotlin.builder import dev.triumphteam.gui.BaseGui +import dev.triumphteam.gui.actions.GuiCloseAction import dev.triumphteam.gui.builder.BaseGuiBuilder import dev.triumphteam.gui.click.handler.ClickHandler import dev.triumphteam.gui.component.functional.FunctionalGuiComponent @@ -80,5 +81,9 @@ public abstract class AbstractKotlinGuiBuilder backing.component(SimpleFunctionalGuiComponent().apply(block).asGuiComponent()) } + public fun onClose(block: GuiCloseAction) { + backing.onClose(block) + } + protected fun backing(): B = backing } diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index 19ea737f..7c6f3cba 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -24,6 +24,7 @@ package dev.triumphteam.gui.paper; import dev.triumphteam.gui.BaseGui; +import dev.triumphteam.gui.actions.GuiCloseAction; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.component.GuiComponent; import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; @@ -49,6 +50,7 @@ public final class Gui implements BaseGui { private final GuiTitle title; private final List> components; + private final List closeActions; private final PaperContainerType containerType; private final GuiComponentRenderer componentRenderer; private final ClickHandler clickHandler; @@ -57,6 +59,7 @@ public final class Gui implements BaseGui { public Gui( final @NotNull GuiTitle title, final @NotNull List> components, + final @NotNull List closeActions, final @NotNull PaperContainerType containerType, final @NotNull GuiComponentRenderer componentRenderer, final @NotNull ClickHandler clickHandler, @@ -64,6 +67,7 @@ public Gui( ) { this.title = title; this.components = components; + this.closeActions = closeActions; this.containerType = containerType; this.componentRenderer = componentRenderer; this.clickHandler = clickHandler; @@ -100,6 +104,7 @@ public void open(final @NotNull Player player) { title, containerType, components, + closeActions, componentRenderer, clickHandler, spamPreventionDuration diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java index 71d33b3f..4b5a8f17 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiListener.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -23,12 +23,14 @@ */ package dev.triumphteam.gui.paper; +import dev.triumphteam.gui.actions.GuiCloseAction; import dev.triumphteam.gui.click.ClickContext; import dev.triumphteam.gui.click.GuiClick; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryDragEvent; import org.bukkit.event.inventory.InventoryOpenEvent; import org.bukkit.inventory.InventoryHolder; @@ -65,9 +67,17 @@ public void onGuiOpen(final @NotNull InventoryOpenEvent event) { final var view = convertHolder(event.getInventory().getHolder()); if (view == null) return; - if (!view.isFirstOpen()) { - event.titleOverride(view.getTitle()); - } + if (!view.isUpdating()) return; + event.titleOverride(view.getTitle()); + } + + @EventHandler + public void onGuiClose(final @NotNull InventoryCloseEvent event) { + final var view = convertHolder(event.getInventory().getHolder()); + if (view == null) return; + + if (view.isUpdating()) return; + view.getCloseActions().forEach(GuiCloseAction::onClose); } private @Nullable PaperGuiView convertHolder(final @Nullable InventoryHolder holder) { diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java index a67dc3b1..29e54461 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/PaperGuiView.java @@ -1,18 +1,18 @@ /** * MIT License - * + *

* Copyright (c) 2024 TriumphTeam - * + *

* Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + *

* The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + *

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,6 +24,7 @@ package dev.triumphteam.gui.paper; import dev.triumphteam.gui.AbstractGuiView; +import dev.triumphteam.gui.actions.GuiCloseAction; import dev.triumphteam.gui.click.handler.ClickHandler; import dev.triumphteam.gui.click.processor.ClickProcessor; import dev.triumphteam.gui.component.GuiComponent; @@ -52,22 +53,27 @@ public PaperGuiView( final @NotNull GuiTitle title, final @NotNull PaperContainerType containerType, final @NotNull List> components, + final @NotNull List closeActions, final @NotNull GuiComponentRenderer componentRenderer, final @NotNull ClickHandler clickHandler, final long spamPreventionDuration ) { - super(player, title, components, containerType, componentRenderer, clickHandler, new ClickProcessor<>(spamPreventionDuration)); + super(player, title, components, closeActions, containerType, componentRenderer, clickHandler, new ClickProcessor<>(spamPreventionDuration)); this.containerType = containerType; } @Override - public void openInventory() { + public void openInventory(final boolean updating) { if (inventory == null) { this.inventory = containerType.createInventory(this, getTitle()); } final var viewer = viewer(); - viewer.getScheduler().run(PaperGuiSettings.get().getPlugin(), (task) -> viewer.openInventory(inventory), null); + viewer.getScheduler().run(PaperGuiSettings.get().getPlugin(), (task) -> { + setUpdating(true); + viewer.openInventory(inventory); + setUpdating(false); + }, null); } @Override diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java index d75373ea..c81a63f7 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/gui/PaperGuiBuilder.java @@ -42,6 +42,7 @@ public Gui build() { return new Gui( getTitle(), getComponents(), + getCloseActions(), getContainerType(), getComponentRenderer(), getClickHandler(), From f6c1ed46d06a23f3822cda5f099491d9ef78b39f Mon Sep 17 00:00:00 2001 From: "Mr. Afonso" Date: Thu, 12 Dec 2024 21:53:18 +0100 Subject: [PATCH 41/43] feature: Port skull builder from v3 * Ported the following from v3: - SkullBuilder - SkullUtil - Mojang AuthLib - Added `meta()` getter/setter - Added `skull()` method * Moved AuthLib to the version catalog and pumped the version number. --- gradle/libs.versions.toml | 2 + paper/paper/build.gradle.kts | 1 + .../builder/item/AbstractItemBuilder.java | 46 ++++++ .../gui/paper/builder/item/SkullBuilder.java | 137 ++++++++++++++++++ .../triumphteam/gui/paper/util/SkullUtil.java | 81 +++++++++++ 5 files changed, 267 insertions(+) create mode 100644 paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/SkullBuilder.java create mode 100644 paper/paper/src/main/java/dev/triumphteam/gui/paper/util/SkullUtil.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 23bf02bd..2fff4920 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -14,6 +14,7 @@ nova = "1.0.0-SNAPSHOT" # Minecraft adventure = "4.16.0" paper = "1.21.1-R0.1-SNAPSHOT" +mojang-auth = "6.0.57" # Build run-paper = "2.3.1" @@ -31,6 +32,7 @@ nova-kotlin = { module = "dev.triumphteam:nova-kotlin", version.ref = "nova" } # Minecraft paper = { module = "io.papermc.paper:paper-api", version.ref = "paper" } adventure-api = { module = "net.kyori:adventure-api", version.ref = "adventure" } +mojang-auth = { module = "com.mojang:authlib", version.ref = "mojang-auth" } # Kotlin coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" } diff --git a/paper/paper/build.gradle.kts b/paper/paper/build.gradle.kts index 500e2cac..3d9f853e 100644 --- a/paper/paper/build.gradle.kts +++ b/paper/paper/build.gradle.kts @@ -10,4 +10,5 @@ repositories { dependencies { api(projects.triumphGuiCore) compileOnly(libs.paper) + compileOnly(libs.mojang.auth) } diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java index da765931..5941fd90 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java @@ -293,6 +293,35 @@ public B unbreakable(boolean unbreakable) { return (B) this; } + /** + * Sets the item meta of the item + * + * @param meta The {@link ItemMeta} to set + * @return {@link B} + */ + @NotNull + @Contract("_ -> this") + public B meta(ItemMeta meta) { + this.meta = meta; + return (B) this; + } + + /** + * Returns the {@link ItemMeta} of the item + * + * @return The {@link ItemMeta} of the item + */ + @NotNull + @Contract(" -> new") + public ItemMeta meta() { + return meta; + } + + /** + * Returns the {@link ItemStack} of the item + * + * @return The {@link ItemStack} of the item + */ @NotNull @Contract(" -> new") public ItemStack asItemStack() { @@ -300,18 +329,35 @@ public ItemStack asItemStack() { return itemStack; } + /** + * Returns the {@link GuiItem} of the item + * + * @param action The {@link GuiClickAction} to set + * @return The {@link GuiItem} of the item + */ @NotNull @Contract("_ -> new") public GuiItem asGuiItem(final @NotNull RunnableGuiClickAction action) { return new SimpleGuiItem<>(asItemStack(), action); } + /** + * Returns the {@link GuiItem} of the item + * + * @param action The {@link GuiClickAction} to set + * @return The {@link GuiItem} of the item + */ @NotNull @Contract("_ -> new") public GuiItem asGuiItem(final @NotNull GuiClickAction action) { return new SimpleGuiItem<>(asItemStack(), action); } + /** + * Returns the {@link GuiItem} of the item + * + * @return The {@link GuiItem} of the item + */ @NotNull @Contract(" -> new") public GuiItem asGuiItem() { diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/SkullBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/SkullBuilder.java new file mode 100644 index 00000000..9d111475 --- /dev/null +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/SkullBuilder.java @@ -0,0 +1,137 @@ +package dev.triumphteam.gui.paper.builder.item; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.properties.Property; +import dev.triumphteam.gui.exception.TriumphGuiException; +import dev.triumphteam.gui.paper.util.SkullUtil; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; +import org.bukkit.profile.PlayerProfile; +import org.bukkit.profile.PlayerTextures; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.UUID; + +public final class SkullBuilder extends AbstractItemBuilder { + + private static final Field PROFILE_FIELD; + + static { + Field field; + + try { + final SkullMeta skullMeta = (SkullMeta) SkullUtil.skull().getItemMeta(); + field = skullMeta.getClass().getDeclaredField("profile"); + field.setAccessible(true); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + field = null; + } + + PROFILE_FIELD = field; + } + + SkullBuilder() { + super(SkullUtil.skull()); + } + + SkullBuilder(final @NotNull ItemStack itemStack) { + super(itemStack); + if (!SkullUtil.isPlayerSkull(itemStack)) { + throw new TriumphGuiException("SkullBuilder requires the material to be a PLAYER_HEAD/SKULL_ITEM!"); + } + } + + /** + * Sets the skull texture using a BASE64 string + * + * @param texture The base64 texture + * @param profileId The unique id of the profile + * @return {@link SkullBuilder} + */ + @NotNull + @Contract("_, _ -> this") + public SkullBuilder texture(@NotNull final String texture, @NotNull final UUID profileId) { + if (!SkullUtil.isPlayerSkull(asItemStack())) return this; + + int version = Integer.parseInt(Bukkit.getServer().getMinecraftVersion().replace(".", "")); + if (version >= 1201) { + final String textureUrl = SkullUtil.getSkinUrl(texture); + + if (textureUrl == null) { + return this; + } + + final SkullMeta skullMeta = (SkullMeta) asItemStack().getItemMeta(); + final PlayerProfile profile = Bukkit.createPlayerProfile(profileId, ""); + final PlayerTextures textures = profile.getTextures(); + + try { + textures.setSkin(new URL(textureUrl)); + } catch (MalformedURLException e) { + e.printStackTrace(); + return this; + } + + profile.setTextures(textures); + skullMeta.setOwnerProfile(profile); + meta(skullMeta); + return this; + } + + if (PROFILE_FIELD == null) { + return this; + } + + final SkullMeta skullMeta = (SkullMeta) meta(); + final GameProfile profile = new GameProfile(profileId, ""); + profile.getProperties().put("textures", new Property("textures", texture)); + + try { + PROFILE_FIELD.set(skullMeta, profile); + } catch (IllegalArgumentException | IllegalAccessException ex) { + ex.printStackTrace(); + } + + meta(skullMeta); + return this; + } + + /** + * Sets the skull texture using a BASE64 string + * + * @param texture The base64 texture + * @return {@link SkullBuilder} + */ + @NotNull + @Contract("_ -> this") + public SkullBuilder texture(@NotNull final String texture) { + return texture(texture, UUID.randomUUID()); + } + + /** + * Sets skull owner via bukkit methods + * + * @param player {@link OfflinePlayer} to set skull of + * @return {@link SkullBuilder} + */ + @NotNull + @Contract("_ -> this") + public SkullBuilder owner(@NotNull final OfflinePlayer player) { + if (!SkullUtil.isPlayerSkull(asItemStack())) return this; + + final SkullMeta skullMeta = (SkullMeta) meta(); + + skullMeta.setOwningPlayer(player); + + meta(skullMeta); + return this; + } + +} diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/util/SkullUtil.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/util/SkullUtil.java new file mode 100644 index 00000000..3628393e --- /dev/null +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/util/SkullUtil.java @@ -0,0 +1,81 @@ +package dev.triumphteam.gui.paper.util; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.Base64; + +public final class SkullUtil { + + /** + * The main SKULL material for the version + */ + private static final Material SKULL = getSkullMaterial(); + private static final Gson GSON = new Gson(); + + /** + * Gets the correct {@link Material} for the version + * + * @return The correct SKULL {@link Material} + */ + private static Material getSkullMaterial() { + return Material.PLAYER_HEAD; + } + + /** + * Create a player skull + * + * @return player skull + */ + @SuppressWarnings("deprecation") + public static ItemStack skull() { + return new ItemStack(SKULL); + } + + /** + * Checks if an {@link ItemStack} is a player skull + * + * @param item item to check + * @return whether the item is a player skull + */ + @SuppressWarnings("deprecation") + public static boolean isPlayerSkull(@NotNull final ItemStack item) { + return item.getType() == SKULL; + } + + /** + * Decode a base64 string and extract the url of the skin. Example: + *
+ * - Base64: {@code eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZGNlYjE3MDhkNTQwNGVmMzI2MTAzZTdiNjA1NTljOTE3OGYzZGNlNzI5MDA3YWM5YTBiNDk4YmRlYmU0NjEwNyJ9fX0=} + *
+ * - JSON: {@code {"textures":{"SKIN":{"url":"http://textures.minecraft.net/texture/dceb1708d5404ef326103e7b60559c9178f3dce729007ac9a0b498bdebe46107"}}}} + *
+ * - Result: {@code http://textures.minecraft.net/texture/dceb1708d5404ef326103e7b60559c9178f3dce729007ac9a0b498bdebe46107} + * @param base64Texture the texture + * @return the url of the texture if found, otherwise {@code null} + */ + public static String getSkinUrl(String base64Texture) { + final String decoded = new String(Base64.getDecoder().decode(base64Texture)); + final JsonObject object = GSON.fromJson(decoded, JsonObject.class); + + final JsonElement textures = object.get("textures"); + + if (textures == null) { + return null; + } + + final JsonElement skin = textures.getAsJsonObject().get("SKIN"); + + if (skin == null) { + return null; + } + + final JsonElement url = skin.getAsJsonObject().get("url"); + return url == null ? null : url.getAsString(); + } + +} \ No newline at end of file From f20e43e0ebe4fe50c49873274a186fb3e8c61a5b Mon Sep 17 00:00:00 2001 From: srnyx <25808801+srnyx@users.noreply.github.com> Date: Sun, 19 Jan 2025 17:40:08 -0500 Subject: [PATCH 42/43] feature(paper): Hopper container type --- .../java/dev/triumphteam/gui/paper/Gui.java | 11 +++++ .../container/type/HopperContainerType.java | 47 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 paper/paper/src/main/java/dev/triumphteam/gui/paper/container/type/HopperContainerType.java diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java index 7c6f3cba..a663703e 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/Gui.java @@ -30,6 +30,7 @@ import dev.triumphteam.gui.component.renderer.GuiComponentRenderer; import dev.triumphteam.gui.paper.builder.gui.PaperGuiBuilder; import dev.triumphteam.gui.paper.container.type.ChestContainerType; +import dev.triumphteam.gui.paper.container.type.HopperContainerType; import dev.triumphteam.gui.paper.container.type.PaperContainerType; import dev.triumphteam.gui.title.GuiTitle; import org.bukkit.entity.Player; @@ -97,6 +98,16 @@ public static PaperGuiBuilder of(final int rows) { return new PaperGuiBuilder(new ChestContainerType(rows)); } + /** + * Create a new {@link PaperGuiBuilder} to create a new {@link Gui} using a {@link HopperContainerType}. + * + * @return A new {@link PaperGuiBuilder}. + */ + @Contract(" -> new") + public static PaperGuiBuilder hopper() { + return new PaperGuiBuilder(new HopperContainerType()); + } + @Override public void open(final @NotNull Player player) { final var view = new PaperGuiView( diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/container/type/HopperContainerType.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/container/type/HopperContainerType.java new file mode 100644 index 00000000..fd42771d --- /dev/null +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/container/type/HopperContainerType.java @@ -0,0 +1,47 @@ +package dev.triumphteam.gui.paper.container.type; + +import dev.triumphteam.gui.container.type.GuiContainerType; +import dev.triumphteam.gui.exception.TriumphGuiException; +import dev.triumphteam.gui.slot.Slot; +import net.kyori.adventure.text.Component; +import org.bukkit.Bukkit; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.jetbrains.annotations.NotNull; + +public class HopperContainerType implements PaperContainerType { + + private static final int LOWER_LIMIT = 0; + private static final int UPPER_LIMIT = 5; + + public static @NotNull GuiContainerType of() { + return new HopperContainerType(); + } + + @Override + public int mapSlot(final @NotNull Slot slot) { + final var realSlot = (slot.column() * slot.row()) - 1; + + if (realSlot < LOWER_LIMIT || realSlot > UPPER_LIMIT) { + throw new TriumphGuiException( + "Invalid slot (" + slot.row() + ", " + slot.column() + "). Valid range is (1, 1) to (1, 5)." + ); + } + + return realSlot; + } + + @Override + public @NotNull Slot mapSlot(final int slot) { + return Slot.of(1, slot + 1); + } + + @Override + public @NotNull Inventory createInventory( + final @NotNull InventoryHolder holder, + final @NotNull Component title + ) { + return Bukkit.createInventory(holder, InventoryType.HOPPER, title); + } +} From b5d5afbac5d2df23f441f34adb35790a2054c333 Mon Sep 17 00:00:00 2001 From: Matt Date: Fri, 10 Jan 2025 14:56:42 -0600 Subject: [PATCH 43/43] chore: Small change to builder --- gradle/wrapper/gradle-wrapper.properties | 2 +- .../gui/paper/builder/item/AbstractItemBuilder.java | 2 +- .../dev/triumphteam/gui/paper/builder/item/ItemBuilder.java | 4 ++++ .../dev/triumphteam/gui/paper/builder/item/SkullBuilder.java | 1 - 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 48c0a02c..81aa1c04 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-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java index 5941fd90..b98ab3fc 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/AbstractItemBuilder.java @@ -49,7 +49,7 @@ @SuppressWarnings("unchecked") public abstract class AbstractItemBuilder> { - private ItemStack itemStack; + private final ItemStack itemStack; private ItemMeta meta; protected AbstractItemBuilder(final @NotNull ItemStack itemStack) { diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java index 004c37d8..c2cee84d 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/ItemBuilder.java @@ -40,4 +40,8 @@ public static ItemBuilder from(final @NotNull ItemStack itemStack) { public static ItemBuilder from(final @NotNull Material material) { return new ItemBuilder(new ItemStack(material)); } + + public static SkullBuilder skull() { + return new SkullBuilder(); + } } diff --git a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/SkullBuilder.java b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/SkullBuilder.java index 9d111475..059e6d31 100644 --- a/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/SkullBuilder.java +++ b/paper/paper/src/main/java/dev/triumphteam/gui/paper/builder/item/SkullBuilder.java @@ -30,7 +30,6 @@ public final class SkullBuilder extends AbstractItemBuilder { field = skullMeta.getClass().getDeclaredField("profile"); field.setAccessible(true); } catch (NoSuchFieldException e) { - e.printStackTrace(); field = null; }