├── .editorconfig ├── .github └── workflows │ └── build.yml ├── .gitignore ├── buildSrc ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ ├── gui.common-conventions.gradle.kts │ └── gui.publishing-conventions.gradle.kts ├── docs ├── getting-started.md ├── item │ └── installation.md └── menu │ └── installation.md ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── item ├── api │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── team │ │ └── unnamed │ │ └── gui │ │ └── item │ │ ├── DefaultItemBuilder.java │ │ ├── ItemBuilder.java │ │ ├── ItemBuilderLayout.java │ │ ├── ItemFlag.java │ │ ├── LeatherArmorBuilder.java │ │ ├── LeatherArmorColor.java │ │ └── util │ │ ├── DecorateItemUtils.java │ │ └── DyeItemUtils.java └── skull-api │ ├── build.gradle.kts │ └── src │ └── main │ └── java │ └── team │ └── unnamed │ └── gui │ └── item │ ├── SkullItemBuilder.java │ └── skull │ ├── AshconSkinProvider.java │ ├── MineskinSkinProvider.java │ ├── SkinManager.java │ ├── SkinProvider.java │ └── SkullSkin.java ├── license.txt ├── menu ├── adapt │ ├── v1_16_R3 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── team │ │ │ └── unnamed │ │ │ └── gui │ │ │ └── menu │ │ │ └── v1_16_R3 │ │ │ └── MenuInventoryWrapperImpl.java │ ├── v1_17_R1 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── team │ │ │ └── unnamed │ │ │ └── gui │ │ │ └── menu │ │ │ └── v1_17_R1 │ │ │ └── MenuInventoryWrapperImpl.java │ ├── v1_18_R2 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── team │ │ │ └── unnamed │ │ │ └── gui │ │ │ └── menu │ │ │ └── v1_18_R2 │ │ │ └── MenuInventoryWrapperImpl.java │ ├── v1_19_R1 │ │ ├── build.gradle.kts │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── team │ │ │ └── unnamed │ │ │ └── gui │ │ │ └── menu │ │ │ └── v1_19_R1 │ │ │ └── MenuInventoryWrapperImpl.java │ └── v1_8_R3 │ │ ├── build.gradle.kts │ │ └── src │ │ └── main │ │ └── java │ │ └── team │ │ └── unnamed │ │ └── gui │ │ └── menu │ │ └── v1_8_R3 │ │ └── MenuInventoryWrapperImpl.java ├── api │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── team │ │ └── unnamed │ │ └── gui │ │ └── menu │ │ ├── adapt │ │ └── MenuInventoryWrapper.java │ │ ├── item │ │ ├── ItemClickable.java │ │ ├── ItemClickableBuilder.java │ │ └── action │ │ │ ├── ItemClickableAction.java │ │ │ ├── ItemClickableActionBuilder.java │ │ │ ├── MultipleItemClickableAction.java │ │ │ └── SingleClickableAction.java │ │ ├── listener │ │ ├── InventoryClickListener.java │ │ ├── InventoryCloseListener.java │ │ └── InventoryOpenListener.java │ │ ├── type │ │ ├── DefaultMenuInventory.java │ │ ├── DefaultMenuInventoryBuilder.java │ │ ├── MenuInventory.java │ │ ├── MenuInventoryBuilder.java │ │ ├── MenuInventoryBuilderLayout.java │ │ ├── PaginatedMenuInventory.java │ │ ├── PaginatedMenuInventoryBuilder.java │ │ └── StringLayoutMenuInventoryBuilder.java │ │ └── util │ │ ├── MenuUtil.java │ │ ├── PaginatedMenuUtil.java │ │ └── Slots.java └── plugin │ ├── build.gradle.kts │ └── src │ └── main │ ├── java │ └── team │ │ └── unnamed │ │ └── gui │ │ └── menu │ │ └── plugin │ │ └── MenuPlugin.java │ └── resources │ └── plugin.yml ├── readme.md └── settings.gradle.kts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = false 7 | indent_size = 4 8 | indent_style = space 9 | 10 | # intellij idea 11 | ij_continuation_indent_size = 8 12 | ij_java_do_not_wrap_after_single_annotation = true 13 | ij_java_class_count_to_use_import_on_demand = 10 -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: 'build' 2 | 3 | on: [ 'push', 'pull_request' ] 4 | 5 | jobs: 6 | build: 7 | if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} 8 | runs-on: 'ubuntu-latest' 9 | steps: 10 | - name: 'checkout repo' 11 | uses: 'actions/checkout@v2' 12 | - name: 'setup JDK' 13 | uses: 'actions/setup-java@v1' 14 | with: 15 | java-version: 17 16 | - name: 'gradle build' 17 | run: './gradlew build' 18 | - name: 'gradle publish' 19 | if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} 20 | run: './gradlew publish' 21 | env: 22 | REPO_USER: '${{ secrets.REPO_USER }}' 23 | REPO_PASSWORD: '${{ secrets.REPO_PASSWORD }}' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .gradle 3 | build 4 | *.iml -------------------------------------------------------------------------------- /buildSrc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | `kotlin-dsl` 3 | } 4 | 5 | repositories { 6 | gradlePluginPortal() 7 | } 8 | 9 | tasks { 10 | compileKotlin { 11 | kotlinOptions { 12 | jvmTarget = "8" 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /buildSrc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "buildSrc" -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/gui.common-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.api.plugins.JavaPluginExtension 2 | import org.gradle.jvm.toolchain.JavaLanguageVersion 3 | 4 | plugins { 5 | `java-library` 6 | } 7 | 8 | repositories { 9 | mavenLocal() 10 | maven("https://repo.unnamed.team/repository/unnamed-public/") 11 | maven("https://repo.codemc.io/repository/nms/") 12 | maven("https://oss.sonatype.org/content/repositories/snapshots") 13 | mavenCentral() 14 | } 15 | 16 | configure { 17 | toolchain { 18 | languageVersion.set(JavaLanguageVersion.of(8)) 19 | } 20 | } 21 | 22 | tasks { 23 | compileJava { 24 | options.compilerArgs.add("-parameters") 25 | } 26 | } -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/gui.publishing-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | import org.gradle.api.publish.PublishingExtension 2 | import org.gradle.api.publish.maven.MavenPublication 3 | import org.gradle.kotlin.dsl.configure 4 | import org.gradle.kotlin.dsl.create 5 | import org.gradle.kotlin.dsl.get 6 | 7 | plugins { 8 | id("gui.common-conventions") 9 | `maven-publish` 10 | } 11 | 12 | val snapshotRepository: String by project 13 | val releaseRepository: String by project 14 | 15 | configure { 16 | repositories { 17 | maven { 18 | url = if (project.version.toString().endsWith("-SNAPSHOT")) { 19 | uri(snapshotRepository) 20 | } else { 21 | uri(releaseRepository) 22 | } 23 | 24 | credentials { 25 | val userKey = "REPO_USER" 26 | val pwdKey = "REPO_PASSWORD" 27 | username = project.properties[userKey] as String? 28 | ?: System.getenv(userKey) 29 | password = project.properties[pwdKey] as String? 30 | ?: System.getenv(pwdKey) 31 | } 32 | } 33 | } 34 | 35 | publications { 36 | create("maven") { 37 | from(components["java"]) 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /docs/getting-started.md: -------------------------------------------------------------------------------- 1 | ## Getting Started 2 | 3 | Welcome to the `gui` documentation 4 | 5 | `gui` is a library for creating Minecraft menus. 6 | 7 | ### Features 8 | - Creating menus using string templates to set menu items 9 | - Creating multipage menus using string templates to set menu items 10 | - Creating items using builders to make it easier 11 | - Support for skull items using textures from images and without rate-limiting 12 | - Create leather colored items using builders to make it easier 13 | - Create colored items like panes, glasses, dyes. 14 | 15 | ### More 16 | See more: 17 | 18 | - [Menu Installation](menu/installation.md): -------------------------------------------------------------------------------- /docs/item/installation.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | You can add `gui-api` to your project using [Gradle](https://gradle.org/) 4 | *(recommended)*, [Maven](https://maven.apache.org/) or manually downloading the 5 | JAR files. 6 | 7 | If you want to use skull api you should add `gui-skull-api` subproject to your project. 8 | 9 | ### **Maven Dependency** 10 | Add the repositories into your `` tag (`pom.xml`) 11 | ```xml 12 | 13 | unnamed-public 14 | https://repo.unnamed.team/repository/unnamed-public/ 15 | 16 | ``` 17 | Add the dependency into your `` tag (`pom.xml`) 18 | ```xml 19 | 20 | team.unnamed 21 | gui-item-api 22 | VERSION 23 | 24 | ``` 25 | 26 | ### **Gradle Groovy DSL Dependency** 27 | Add the repositories into your `repositories` section (`build.gradle`) 28 | ```kotlin 29 | maven { 30 | name = 'unnamed-public' 31 | url = 'https://repo.unnamed.team/repository/unnamed-public/' 32 | } 33 | ``` 34 | Add the dependency into your `dependencies` section (`build.gradle`) 35 | ```kotlin 36 | implementation 'team.unnamed:gui-item-api:VERSION' 37 | ``` 38 | 39 | ### **Gradle Kotlin DSL Dependency** 40 | Add the repositories into your `repositories` section (`build.gradle.kts`) 41 | ```kotlin 42 | maven("https://repo.unnamed.team/repository/unnamed-public/") 43 | ``` 44 | Add the dependency into your `dependencies` section (`build.gradle.kts`) 45 | ```kotlin 46 | implementation("team.unnamed:gui-item-api:VERSION") 47 | ``` 48 | -------------------------------------------------------------------------------- /docs/menu/installation.md: -------------------------------------------------------------------------------- 1 | ## Installation 2 | 3 | You can add `gui-menu` to your project using [Gradle](https://gradle.org/) 4 | *(recommended)*, [Maven](https://maven.apache.org/) or manually downloading the 5 | JAR files. 6 | 7 | To use general API you should add just `gui-menu-api` subproject to your project. 8 | Since `gui-menu` uses [adapters](https://github.com/unnamed/gui/tree/main/menu/adapt) for each Minecraft version you should include corresponding 9 | adapters in your project as well. 10 | 11 | Using versions above 1.17 you should use Java 17 or above. 12 | 13 | ### **Maven Dependency** 14 | Add the repositories into your `` tag (`pom.xml`) 15 | ```xml 16 | 17 | unnamed-public 18 | https://repo.unnamed.team/repository/unnamed-public/ 19 | 20 | ``` 21 | Add the dependency into your `` tag (`pom.xml`) 22 | ```xml 23 | 24 | team.unnamed 25 | gui-menu-api 26 | VERSION 27 | 28 | ``` 29 | 30 | ### **Gradle Groovy DSL Dependency** 31 | Add the repositories into your `repositories` section (`build.gradle`) 32 | ```kotlin 33 | maven { 34 | name = 'unnamed-public' 35 | url = 'https://repo.unnamed.team/repository/unnamed-public/' 36 | } 37 | ``` 38 | Add the dependency into your `dependencies` section (`build.gradle`) 39 | ```kotlin 40 | implementation 'team.unnamed:gui-menu-api:VERSION' 41 | ``` 42 | 43 | ### **Gradle Kotlin DSL Dependency** 44 | Add the repositories into your `repositories` section (`build.gradle.kts`) 45 | ```kotlin 46 | maven("https://repo.unnamed.team/repository/unnamed-public/") 47 | ``` 48 | Add the dependency into your `dependencies` section (`build.gradle.kts`) 49 | ```kotlin 50 | implementation("team.unnamed:gui-menu-api:VERSION") 51 | ``` 52 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.parallel=true 2 | org.gradle.cache=true 3 | org.gradle.daemon=true 4 | 5 | group=team.unnamed 6 | version=3.4.0-SNAPSHOT 7 | 8 | snapshotRepository=https://repo.unnamed.team/repository/unnamed-snapshots/ 9 | releaseRepository=https://repo.unnamed.team/repository/unnamed-releases/ -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | annotations = "23.0.0" 3 | 4 | [libraries] 5 | annotations = { group = "org.jetbrains", name = "annotations", version.ref = "annotations"} -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pixeldev/gui/7b2b1d88d7309987b0d9bf0110797c5d4ba1ab0a/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /item/api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gui.publishing-conventions") 3 | } 4 | 5 | dependencies { 6 | api(libs.annotations) 7 | arrayOf("validation", "bukkit").forEach { 8 | api("team.unnamed:commons-$it:3.1.0") 9 | } 10 | 11 | compileOnly("org.spigotmc:spigot:1.11.2-R0.1-SNAPSHOT") 12 | } -------------------------------------------------------------------------------- /item/api/src/main/java/team/unnamed/gui/item/DefaultItemBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item; 2 | 3 | import org.bukkit.Material; 4 | 5 | public class DefaultItemBuilder 6 | extends ItemBuilderLayout { 7 | 8 | protected DefaultItemBuilder( 9 | Material material, int amount, 10 | byte data 11 | ) { 12 | super(material, amount, data); 13 | } 14 | 15 | @Override 16 | protected DefaultItemBuilder back() { 17 | return this; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /item/api/src/main/java/team/unnamed/gui/item/ItemBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item; 2 | 3 | import org.bukkit.DyeColor; 4 | import org.bukkit.Material; 5 | import org.bukkit.enchantments.Enchantment; 6 | import org.bukkit.inventory.ItemStack; 7 | import team.unnamed.gui.item.util.DyeItemUtils; 8 | 9 | import java.util.List; 10 | import java.util.Map; 11 | 12 | public interface ItemBuilder { 13 | 14 | ItemBuilder name(String name); 15 | 16 | ItemBuilder lore(List lore); 17 | 18 | ItemBuilder lore(String... lines); 19 | 20 | ItemBuilder enchantments(Map enchantments); 21 | 22 | ItemBuilder enchant(Enchantment enchantment, int level); 23 | 24 | ItemBuilder flags(List flags); 25 | 26 | ItemBuilder flag(ItemFlag... flags); 27 | 28 | ItemBuilder grow(); 29 | 30 | ItemBuilder unbreakable(boolean unbreakable); 31 | 32 | ItemStack build(); 33 | 34 | static ItemBuilder builder(Material material) { 35 | return builder(material, 1); 36 | } 37 | 38 | static ItemBuilder builder(Material material, int amount) { 39 | return builder(material, amount, (byte) 0); 40 | } 41 | 42 | static ItemBuilder builder(Material material, int amount, byte data) { 43 | return new DefaultItemBuilder(material, amount, data); 44 | } 45 | 46 | static ItemBuilder dyeBuilder(String materialKey, DyeColor dyeColor) { 47 | return dyeBuilder(materialKey, dyeColor, 1); 48 | } 49 | 50 | static ItemBuilder dyeBuilder(String materialKey, DyeColor dyeColor, int amount) { 51 | return DyeItemUtils.createBuilder(materialKey, dyeColor, amount); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /item/api/src/main/java/team/unnamed/gui/item/ItemBuilderLayout.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.enchantments.Enchantment; 5 | import org.bukkit.inventory.ItemStack; 6 | import org.bukkit.inventory.meta.ItemMeta; 7 | import team.unnamed.bukkit.ServerVersion; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Arrays; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | import static team.unnamed.validate.Validate.isNotNull; 16 | 17 | abstract class ItemBuilderLayout 18 | implements ItemBuilder { 19 | 20 | protected final Material material; 21 | private final int amount; 22 | private final byte data; 23 | 24 | private String name; 25 | private List lore; 26 | private Map enchantments; 27 | private List flags; 28 | private boolean unbreakable; 29 | 30 | protected ItemBuilderLayout(Material material, int amount, byte data) { 31 | this.material = material; 32 | this.amount = amount; 33 | this.data = data; 34 | this.lore = new ArrayList<>(); 35 | this.enchantments = new HashMap<>(); 36 | this.flags = new ArrayList<>(); 37 | } 38 | 39 | @Override 40 | public ItemBuilder name(String name) { 41 | this.name = isNotNull(name, "Item name cannot be null."); 42 | return back(); 43 | } 44 | 45 | @Override 46 | public ItemBuilder lore(List lore) { 47 | this.lore = isNotNull(lore, "Item lore cannot be null."); 48 | return back(); 49 | } 50 | 51 | @Override 52 | public ItemBuilder lore(String... lines) { 53 | this.lore = Arrays.asList(isNotNull(lines, "Item lore cannot be null.")); 54 | return back(); 55 | } 56 | 57 | @Override 58 | public ItemBuilder enchantments(Map enchantments) { 59 | this.enchantments = isNotNull(enchantments, "Item enchantments cannot be null."); 60 | return back(); 61 | } 62 | 63 | @Override 64 | public ItemBuilder enchant(Enchantment enchantment, int level) { 65 | this.enchantments.put(isNotNull(enchantment, "Item enchantment cannot be null."), level); 66 | return back(); 67 | } 68 | 69 | @Override 70 | public ItemBuilder flags(List flags) { 71 | this.flags = isNotNull(flags, "Item flags cannot be null."); 72 | return back(); 73 | } 74 | 75 | @Override 76 | public ItemBuilder flag(ItemFlag... flags) { 77 | this.flags.addAll(Arrays.asList(flags)); 78 | return back(); 79 | } 80 | 81 | @Override 82 | public ItemBuilder grow() { 83 | this.enchantments.put(Enchantment.DURABILITY, 3); 84 | this.flags.add(ItemFlag.HIDE_ENCHANTS); 85 | return back(); 86 | } 87 | 88 | @Override 89 | public ItemBuilder unbreakable(boolean unbreakable) { 90 | this.unbreakable = unbreakable; 91 | return back(); 92 | } 93 | 94 | @Override 95 | public ItemStack build() { 96 | ItemStack itemStack = new ItemStack(material, amount, data); 97 | ItemMeta meta = itemStack.getItemMeta(); 98 | 99 | enchantments.forEach((enchantment, level) -> meta.addEnchant(enchantment, level, true)); 100 | 101 | meta.setDisplayName(name); 102 | meta.setLore(lore); 103 | 104 | int currentVersion = ServerVersion.CURRENT.getMinor(); 105 | 106 | if (currentVersion != 7) { 107 | List itemFlags = new ArrayList<>(); 108 | 109 | if (currentVersion <= 13) { 110 | flags.remove(ItemFlag.HIDE_DYE); 111 | } 112 | 113 | for (ItemFlag itemFlag : flags) { 114 | itemFlags.add(org.bukkit.inventory.ItemFlag.valueOf(itemFlag.name())); 115 | } 116 | 117 | itemFlags.forEach(meta::addItemFlags); 118 | } 119 | 120 | if (currentVersion >= 11) { 121 | meta.setUnbreakable(unbreakable); 122 | } else { 123 | meta.spigot().setUnbreakable(unbreakable); 124 | } 125 | 126 | itemStack.setItemMeta(meta); 127 | 128 | return itemStack; 129 | } 130 | 131 | protected abstract T back(); 132 | 133 | } 134 | -------------------------------------------------------------------------------- /item/api/src/main/java/team/unnamed/gui/item/ItemFlag.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item; 2 | 3 | public enum ItemFlag { 4 | HIDE_ENCHANTS, 5 | HIDE_ATTRIBUTES, 6 | HIDE_UNBREAKABLE, 7 | HIDE_DESTROYS, 8 | HIDE_PLACED_ON, 9 | HIDE_POTION_EFFECTS, 10 | HIDE_DYE 11 | } 12 | -------------------------------------------------------------------------------- /item/api/src/main/java/team/unnamed/gui/item/LeatherArmorBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item; 2 | 3 | import org.bukkit.Color; 4 | import org.bukkit.Material; 5 | import org.bukkit.inventory.ItemStack; 6 | import org.bukkit.inventory.meta.LeatherArmorMeta; 7 | 8 | import static team.unnamed.validate.Validate.isState; 9 | 10 | public class LeatherArmorBuilder 11 | extends ItemBuilderLayout { 12 | 13 | private int red; 14 | private int green; 15 | private int blue; 16 | 17 | protected LeatherArmorBuilder(Material material, int amount) { 18 | super(material, amount, (byte) 0); 19 | } 20 | 21 | public LeatherArmorBuilder fromLeatherColor(LeatherArmorColor armorColor) { 22 | return fromRgb(armorColor.getRed(), armorColor.getGreen(), armorColor.getBlue()); 23 | } 24 | 25 | public LeatherArmorBuilder fromRgb(int red, int green, int blue) { 26 | this.red = red; 27 | this.green = green; 28 | this.blue = blue; 29 | return this; 30 | } 31 | 32 | @Override 33 | public ItemStack build() { 34 | isState(material.name().startsWith("LEATHER_"), 35 | "Material must be leather armor."); 36 | 37 | ItemStack itemStack = super.build(); 38 | LeatherArmorMeta armorMeta = (LeatherArmorMeta) itemStack.getItemMeta(); 39 | armorMeta.setColor(Color.fromRGB(this.red, this.green, this.blue)); 40 | itemStack.setItemMeta(armorMeta); 41 | 42 | return itemStack; 43 | } 44 | 45 | @Override 46 | protected LeatherArmorBuilder back() { 47 | return this; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /item/api/src/main/java/team/unnamed/gui/item/LeatherArmorColor.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item; 2 | 3 | public enum LeatherArmorColor { 4 | 5 | DARK_BLUE(0, 0, 255), 6 | LIGHT_BLUE(51, 153, 255), 7 | LIGHT_RED(255, 0, 0), 8 | DARK_RED(152, 0, 0), 9 | CYAN(102, 255, 255), 10 | YELLOW(255, 255, 0), 11 | ORANGE(255, 128, 0), 12 | LIME(0, 255, 0), 13 | GREEN(0, 204, 0), 14 | PURPLE(76, 0, 153), 15 | PINK(255, 153, 255), 16 | BLACK(0, 0, 0), 17 | WHITE(255, 255, 255), 18 | DARK_GRAY(128, 128, 128), 19 | LIGHT_GRAY(192, 192, 192); 20 | 21 | private final int red; 22 | private final int green; 23 | private final int blue; 24 | 25 | LeatherArmorColor(int red, int green, int blue) { 26 | this.red = red; 27 | this.green = green; 28 | this.blue = blue; 29 | } 30 | 31 | public int getRed() { 32 | return red; 33 | } 34 | 35 | public int getGreen() { 36 | return green; 37 | } 38 | 39 | public int getBlue() { 40 | return blue; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /item/api/src/main/java/team/unnamed/gui/item/util/DecorateItemUtils.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item.util; 2 | 3 | import org.bukkit.DyeColor; 4 | import org.bukkit.inventory.ItemStack; 5 | import team.unnamed.gui.item.ItemBuilder; 6 | 7 | public final class DecorateItemUtils { 8 | 9 | private DecorateItemUtils() { 10 | throw new UnsupportedOperationException(); 11 | } 12 | 13 | public static ItemBuilder stainedPaneBuilder(DyeColor dyeColor) { 14 | return ItemBuilder.dyeBuilder("STAINED_GLASS_PANE", dyeColor) 15 | .name(" "); 16 | } 17 | 18 | public static ItemStack stainedPane(DyeColor dyeColor) { 19 | return stainedPaneBuilder(dyeColor).build(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /item/api/src/main/java/team/unnamed/gui/item/util/DyeItemUtils.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item.util; 2 | 3 | import org.bukkit.DyeColor; 4 | import org.bukkit.Material; 5 | import team.unnamed.bukkit.ServerVersion; 6 | import team.unnamed.gui.item.ItemBuilder; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | public class DyeItemUtils { 12 | 13 | 14 | private static final Map COLORS_BY_DYE; 15 | 16 | static { 17 | COLORS_BY_DYE = new HashMap<>(); 18 | 19 | for (DyeColor dyeColor : DyeColor.values()) { 20 | switch (dyeColor) { 21 | case GRAY: { 22 | COLORS_BY_DYE.put(dyeColor, "LIGHT_GRAY"); 23 | break; 24 | } 25 | case SILVER: { 26 | COLORS_BY_DYE.put(dyeColor, "GRAY"); 27 | break; 28 | } 29 | default: { 30 | COLORS_BY_DYE.put(dyeColor, dyeColor.name()); 31 | break; 32 | } 33 | } 34 | } 35 | } 36 | 37 | private DyeItemUtils() { 38 | throw new UnsupportedOperationException(); 39 | } 40 | 41 | @SuppressWarnings("deprecation") 42 | public static ItemBuilder createBuilder(String materialKey, DyeColor dyeColor, int amount) { 43 | Material material; 44 | byte data; 45 | 46 | if (ServerVersion.CURRENT.getMinor() < 13) { 47 | material = Material.valueOf(materialKey); 48 | data = materialKey.equals("DYE") ? dyeColor.getDyeData() : dyeColor.getWoolData(); 49 | } else { 50 | if (materialKey.equals("STAINED_CLAY")) { 51 | materialKey = "TERRACOTTA"; 52 | } 53 | 54 | material = Material.valueOf( 55 | COLORS_BY_DYE.get(dyeColor) + "_" + materialKey 56 | ); 57 | data = 0; 58 | } 59 | 60 | return ItemBuilder.builder(material, amount, data); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /item/skull-api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gui.publishing-conventions") 3 | } 4 | 5 | dependencies { 6 | api(project(":gui-item-api")) 7 | compileOnly("org.spigotmc:spigot:1.8.8-R0.1-SNAPSHOT") 8 | } -------------------------------------------------------------------------------- /item/skull-api/src/main/java/team/unnamed/gui/item/SkullItemBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item; 2 | 3 | import com.mojang.authlib.GameProfile; 4 | import com.mojang.authlib.properties.Property; 5 | import org.bukkit.Material; 6 | import org.bukkit.inventory.ItemStack; 7 | import org.bukkit.inventory.meta.SkullMeta; 8 | import team.unnamed.bukkit.ServerVersion; 9 | import team.unnamed.gui.item.skull.SkullSkin; 10 | 11 | import java.lang.reflect.Field; 12 | import java.util.UUID; 13 | 14 | public class SkullItemBuilder 15 | extends ItemBuilderLayout { 16 | 17 | private static final Field PROFILE_FIELD; 18 | private static final Material SKULL_MATERIAL; 19 | private static final byte DATA; 20 | 21 | static { 22 | try { 23 | Class metaClass = Class.forName( 24 | "org.bukkit.craftbukkit." 25 | + ServerVersion.CURRENT + 26 | ".inventory.CraftMetaSkull" 27 | ); 28 | 29 | PROFILE_FIELD = metaClass.getDeclaredField("profile"); 30 | 31 | if (ServerVersion.CURRENT.getMinor() < 13) { 32 | SKULL_MATERIAL = Material.SKULL_ITEM; 33 | DATA = 3; 34 | } else { 35 | SKULL_MATERIAL = Material.getMaterial("PLAYER_HEAD"); 36 | DATA = 0; 37 | } 38 | } catch (ClassNotFoundException | NoSuchFieldException e) { 39 | throw new IllegalStateException("Cannot get the SkullMeta profile field!", e); 40 | } 41 | } 42 | 43 | private final SkullSkin skin; 44 | 45 | private SkullItemBuilder(int amount, SkullSkin skin) { 46 | super(SKULL_MATERIAL, amount, DATA); 47 | this.skin = skin; 48 | } 49 | 50 | public static SkullItemBuilder create(SkullSkin skin) { 51 | return new SkullItemBuilder(1, skin); 52 | } 53 | 54 | public static SkullItemBuilder create(int amount, SkullSkin skin) { 55 | return new SkullItemBuilder(amount, skin); 56 | } 57 | 58 | @Override 59 | public ItemStack build() { 60 | ItemStack itemStack = super.build(); 61 | SkullMeta skullMeta = (SkullMeta) itemStack.getItemMeta(); 62 | 63 | GameProfile gameProfile = new GameProfile(UUID.randomUUID(), null); 64 | 65 | gameProfile.getProperties().put("textures", new Property( 66 | "textures", 67 | skin.getValue(), 68 | skin.getSignature() 69 | )); 70 | 71 | boolean accessible = PROFILE_FIELD.isAccessible(); 72 | PROFILE_FIELD.setAccessible(true); 73 | 74 | try { 75 | PROFILE_FIELD.set(skullMeta, gameProfile); 76 | } catch (IllegalAccessException e) { 77 | e.printStackTrace(); 78 | } finally { 79 | PROFILE_FIELD.setAccessible(accessible); 80 | } 81 | 82 | itemStack.setItemMeta(skullMeta); 83 | 84 | return itemStack; 85 | } 86 | 87 | @Override 88 | protected SkullItemBuilder back() { 89 | return this; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /item/skull-api/src/main/java/team/unnamed/gui/item/skull/AshconSkinProvider.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item.skull; 2 | 3 | import com.google.gson.JsonObject; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.io.Reader; 9 | import java.net.HttpURLConnection; 10 | import java.net.URL; 11 | 12 | public class AshconSkinProvider implements SkinProvider { 13 | 14 | private static final String BASE_URL = "https://api.ashcon.app/mojang/v2/user/"; 15 | 16 | protected AshconSkinProvider() { 17 | } 18 | 19 | @Override 20 | public @Nullable SkullSkin fetchSkin(Type type, String key) throws Exception { 21 | if (type == Type.URL) { 22 | return null; 23 | } 24 | 25 | URL url = new URL(BASE_URL + key); 26 | HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 27 | 28 | connection.setRequestProperty("Accept", "application/json"); 29 | connection.setRequestProperty("User-Agent", "unnamed-gui"); 30 | connection.setRequestMethod("GET"); 31 | 32 | try (Reader reader = new BufferedReader(new InputStreamReader( 33 | connection.getInputStream() 34 | ))) { 35 | JsonObject json = PARSER.parse(reader).getAsJsonObject(); 36 | JsonObject texturesJson = json.getAsJsonObject("textures"); 37 | 38 | if (texturesJson == null) { 39 | return null; 40 | } 41 | 42 | JsonObject rawJson = texturesJson.getAsJsonObject("raw"); 43 | 44 | String signature = rawJson.get("signature").getAsString(); 45 | String value = rawJson.get("value").getAsString(); 46 | 47 | return new SkullSkin(signature, value); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /item/skull-api/src/main/java/team/unnamed/gui/item/skull/MineskinSkinProvider.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item.skull; 2 | 3 | import com.google.gson.JsonObject; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.InputStreamReader; 8 | import java.io.OutputStream; 9 | import java.io.Reader; 10 | import java.net.HttpURLConnection; 11 | import java.net.MalformedURLException; 12 | import java.net.URL; 13 | import java.nio.charset.StandardCharsets; 14 | 15 | public class MineskinSkinProvider implements SkinProvider { 16 | 17 | private static final URL URL_GENERATE_URL; 18 | 19 | static { 20 | try { 21 | URL_GENERATE_URL = new URL("https://api.mineskin.org/generate/url"); 22 | } catch (MalformedURLException e) { 23 | throw new RuntimeException(e); 24 | } 25 | } 26 | 27 | protected MineskinSkinProvider() { 28 | } 29 | 30 | @Override 31 | public @Nullable SkullSkin fetchSkin(Type type, String key) throws Exception { 32 | HttpURLConnection connection = (HttpURLConnection) URL_GENERATE_URL.openConnection(); 33 | 34 | connection.setRequestProperty("Accept", "application/json"); 35 | connection.setRequestProperty("User-Agent", "unnamed-gui"); 36 | connection.setRequestProperty("Content-Type", "application/json"); 37 | connection.setRequestMethod("POST"); 38 | 39 | connection.setDoOutput(true); 40 | 41 | try (OutputStream out = connection.getOutputStream()) { 42 | byte[] data = ("{ \"url\": \"" + key + "\" }").getBytes(StandardCharsets.UTF_8); 43 | out.write(data); 44 | } 45 | 46 | JsonObject jsonResponse; 47 | 48 | // execute request and read response 49 | try (Reader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { 50 | jsonResponse = PARSER.parse(reader).getAsJsonObject(); 51 | } 52 | 53 | JsonObject data = jsonResponse.getAsJsonObject("data"); 54 | 55 | JsonObject texture = data.getAsJsonObject("texture"); 56 | String signature = texture.get("signature").getAsString(); 57 | String value = texture.get("value").getAsString(); 58 | return new SkullSkin(signature, value); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /item/skull-api/src/main/java/team/unnamed/gui/item/skull/SkinManager.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item.skull; 2 | 3 | import org.jetbrains.annotations.NotNull; 4 | 5 | import javax.annotation.Nullable; 6 | import java.util.Map; 7 | import java.util.concurrent.CompletableFuture; 8 | import java.util.concurrent.CompletionException; 9 | import java.util.concurrent.ConcurrentHashMap; 10 | import java.util.concurrent.Executor; 11 | 12 | public class SkinManager { 13 | 14 | private final Map skins; 15 | private final Executor executor; 16 | 17 | public SkinManager(Executor executor) { 18 | this.executor = executor; 19 | this.skins = new ConcurrentHashMap<>(); 20 | } 21 | 22 | public @Nullable SkullSkin getSkin(String key) { 23 | return skins.get(key); 24 | } 25 | 26 | public CompletableFuture fetchSkin( 27 | @NotNull SkinProvider skinProvider, 28 | @NotNull SkinProvider.Type type, 29 | @NotNull String key 30 | ) { 31 | return CompletableFuture.supplyAsync(() -> { 32 | try { 33 | SkullSkin skin = skins.get(key); 34 | 35 | if (skin == null) { 36 | skin = skinProvider.fetchSkin(type, key); 37 | } 38 | 39 | if (skin == null) { 40 | return null; 41 | } 42 | 43 | if (!skins.containsKey(key)) { 44 | skins.put(key, skin); 45 | } 46 | 47 | return skin; 48 | } catch (Exception e) { 49 | throw new CompletionException(e); 50 | } 51 | }, executor); 52 | } 53 | 54 | public void setSkin(String key, SkullSkin skin) { 55 | skins.put(key, skin); 56 | } 57 | 58 | public @Nullable SkullSkin removeSkin(String key) { 59 | return skins.remove(key); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /item/skull-api/src/main/java/team/unnamed/gui/item/skull/SkinProvider.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item.skull; 2 | 3 | import com.google.gson.JsonParser; 4 | import org.jetbrains.annotations.Nullable; 5 | 6 | public interface SkinProvider { 7 | 8 | JsonParser PARSER = new JsonParser(); 9 | 10 | SkinProvider MINESKIN = new MineskinSkinProvider(); 11 | SkinProvider ASHCON = new AshconSkinProvider(); 12 | 13 | @Nullable SkullSkin fetchSkin(Type type, String key) throws Exception; 14 | 15 | enum Type { 16 | UUID, 17 | URL 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /item/skull-api/src/main/java/team/unnamed/gui/item/skull/SkullSkin.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.item.skull; 2 | 3 | public class SkullSkin { 4 | 5 | private final String signature; 6 | private final String value; 7 | 8 | public SkullSkin(String signature, String value) { 9 | this.signature = signature; 10 | this.value = value; 11 | } 12 | 13 | public String getSignature() { 14 | return signature; 15 | } 16 | 17 | public String getValue() { 18 | return value; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "SkullSkin{" + 24 | "signature='" + signature + '\'' + 25 | ", value='" + value + '\'' + 26 | '}'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2022 Unnamed Team 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /menu/adapt/v1_16_R3/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gui.publishing-conventions") 3 | } 4 | 5 | dependencies { 6 | api(project(":gui-menu-api")) 7 | compileOnly("org.spigotmc:spigot:1.16.5-R0.1-SNAPSHOT") 8 | } -------------------------------------------------------------------------------- /menu/adapt/v1_16_R3/src/main/java/team/unnamed/gui/menu/v1_16_R3/MenuInventoryWrapperImpl.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.v1_16_R3; 2 | 3 | import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftInventoryCustom; 4 | import org.bukkit.inventory.Inventory; 5 | import org.bukkit.inventory.InventoryHolder; 6 | import org.jetbrains.annotations.NotNull; 7 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 8 | import team.unnamed.gui.menu.type.MenuInventory; 9 | 10 | public class MenuInventoryWrapperImpl 11 | extends CraftInventoryCustom 12 | implements MenuInventoryWrapper { 13 | 14 | private final MenuInventory menuInventory; 15 | 16 | public MenuInventoryWrapperImpl( 17 | InventoryHolder owner, 18 | MenuInventory menuInventory 19 | ) { 20 | super( 21 | owner, 22 | menuInventory.getSlots(), 23 | menuInventory.getTitle() 24 | ); 25 | 26 | this.menuInventory = menuInventory; 27 | } 28 | 29 | @Override 30 | public @NotNull Inventory getRawInventory() { 31 | return this; 32 | } 33 | 34 | @Override 35 | public @NotNull MenuInventory getMenuInventory() { 36 | return menuInventory; 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /menu/adapt/v1_17_R1/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gui.publishing-conventions") 3 | } 4 | 5 | configure { 6 | toolchain { 7 | languageVersion.set(JavaLanguageVersion.of(17)) 8 | } 9 | } 10 | 11 | dependencies { 12 | api(project(":gui-menu-api")) 13 | compileOnly("org.spigotmc:spigot:1.17.1-R0.1-SNAPSHOT") 14 | } -------------------------------------------------------------------------------- /menu/adapt/v1_17_R1/src/main/java/team/unnamed/gui/menu/v1_17_R1/MenuInventoryWrapperImpl.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.v1_17_R1; 2 | 3 | import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftInventoryCustom; 4 | import org.bukkit.inventory.Inventory; 5 | import org.bukkit.inventory.InventoryHolder; 6 | import org.jetbrains.annotations.NotNull; 7 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 8 | import team.unnamed.gui.menu.type.MenuInventory; 9 | 10 | public class MenuInventoryWrapperImpl 11 | extends CraftInventoryCustom 12 | implements MenuInventoryWrapper { 13 | 14 | private final MenuInventory menuInventory; 15 | 16 | public MenuInventoryWrapperImpl( 17 | InventoryHolder owner, 18 | MenuInventory menuInventory 19 | ) { 20 | super( 21 | owner, 22 | menuInventory.getSlots(), 23 | menuInventory.getTitle() 24 | ); 25 | 26 | this.menuInventory = menuInventory; 27 | } 28 | 29 | @Override 30 | public @NotNull Inventory getRawInventory() { 31 | return this; 32 | } 33 | 34 | @Override 35 | public @NotNull MenuInventory getMenuInventory() { 36 | return menuInventory; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /menu/adapt/v1_18_R2/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gui.publishing-conventions") 3 | id("io.papermc.paperweight.userdev") version "1.3.5" 4 | } 5 | 6 | java { 7 | toolchain { 8 | languageVersion.set(JavaLanguageVersion.of(17)) 9 | } 10 | } 11 | 12 | tasks { 13 | assemble { 14 | dependsOn(reobfJar) 15 | } 16 | } 17 | 18 | dependencies { 19 | api(project(":gui-menu-api")) 20 | paperDevBundle("1.18.2-R0.1-SNAPSHOT") 21 | } -------------------------------------------------------------------------------- /menu/adapt/v1_18_R2/src/main/java/team/unnamed/gui/menu/v1_18_R2/MenuInventoryWrapperImpl.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.v1_18_R2; 2 | 3 | import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftInventoryCustom; 4 | import org.bukkit.inventory.Inventory; 5 | import org.bukkit.inventory.InventoryHolder; 6 | import org.jetbrains.annotations.NotNull; 7 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 8 | import team.unnamed.gui.menu.type.MenuInventory; 9 | 10 | public class MenuInventoryWrapperImpl extends CraftInventoryCustom 11 | implements MenuInventoryWrapper { 12 | 13 | private final MenuInventory menuInventory; 14 | 15 | public MenuInventoryWrapperImpl( 16 | InventoryHolder owner, 17 | MenuInventory menuInventory 18 | ) { 19 | super( 20 | owner, 21 | menuInventory.getSlots(), 22 | menuInventory.getTitle() 23 | ); 24 | 25 | this.menuInventory = menuInventory; 26 | } 27 | 28 | @Override 29 | public @NotNull Inventory getRawInventory() { 30 | return this; 31 | } 32 | 33 | @Override 34 | public @NotNull MenuInventory getMenuInventory() { 35 | return menuInventory; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /menu/adapt/v1_19_R1/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gui.publishing-conventions") 3 | id("io.papermc.paperweight.userdev") version "1.3.5" 4 | } 5 | 6 | java { 7 | toolchain { 8 | languageVersion.set(JavaLanguageVersion.of(17)) 9 | } 10 | } 11 | 12 | tasks { 13 | assemble { 14 | dependsOn(reobfJar) 15 | } 16 | } 17 | 18 | dependencies { 19 | api(project(":gui-menu-api")) 20 | paperDevBundle("1.19.2-R0.1-SNAPSHOT") 21 | } -------------------------------------------------------------------------------- /menu/adapt/v1_19_R1/src/main/java/team/unnamed/gui/menu/v1_19_R1/MenuInventoryWrapperImpl.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.v1_19_R1; 2 | 3 | import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftInventoryCustom; 4 | import org.bukkit.inventory.Inventory; 5 | import org.bukkit.inventory.InventoryHolder; 6 | import org.jetbrains.annotations.NotNull; 7 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 8 | import team.unnamed.gui.menu.type.MenuInventory; 9 | 10 | public class MenuInventoryWrapperImpl extends CraftInventoryCustom 11 | implements MenuInventoryWrapper { 12 | 13 | private final MenuInventory menuInventory; 14 | 15 | public MenuInventoryWrapperImpl( 16 | InventoryHolder owner, 17 | MenuInventory menuInventory 18 | ) { 19 | super( 20 | owner, 21 | menuInventory.getSlots(), 22 | menuInventory.getTitle() 23 | ); 24 | 25 | this.menuInventory = menuInventory; 26 | } 27 | 28 | @Override 29 | public @NotNull Inventory getRawInventory() { 30 | return this; 31 | } 32 | 33 | @Override 34 | public @NotNull MenuInventory getMenuInventory() { 35 | return menuInventory; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /menu/adapt/v1_8_R3/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gui.publishing-conventions") 3 | } 4 | 5 | dependencies { 6 | api(project(":gui-menu-api")) 7 | compileOnly("org.spigotmc:spigot:1.8.8-R0.1-SNAPSHOT") 8 | } -------------------------------------------------------------------------------- /menu/adapt/v1_8_R3/src/main/java/team/unnamed/gui/menu/v1_8_R3/MenuInventoryWrapperImpl.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.v1_8_R3; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.Material; 5 | import org.bukkit.entity.HumanEntity; 6 | import org.bukkit.event.inventory.InventoryType; 7 | import org.bukkit.inventory.Inventory; 8 | import org.bukkit.inventory.InventoryHolder; 9 | import org.bukkit.inventory.ItemStack; 10 | import org.jetbrains.annotations.NotNull; 11 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 12 | import team.unnamed.gui.menu.type.MenuInventory; 13 | 14 | import java.util.HashMap; 15 | import java.util.List; 16 | import java.util.ListIterator; 17 | 18 | public class MenuInventoryWrapperImpl 19 | implements MenuInventoryWrapper, 20 | InventoryHolder, Inventory { 21 | 22 | private final Inventory raw; 23 | private final MenuInventory menuInventory; 24 | 25 | public MenuInventoryWrapperImpl( 26 | InventoryHolder owner, 27 | MenuInventory menuInventory 28 | ) { 29 | this.menuInventory = menuInventory; 30 | 31 | raw = Bukkit.createInventory( 32 | owner, 33 | menuInventory.getSlots(), 34 | menuInventory.getTitle() 35 | ); 36 | } 37 | 38 | @Override 39 | public int getSize() { 40 | return raw.getSize(); 41 | } 42 | 43 | @Override 44 | public int getMaxStackSize() { 45 | return raw.getMaxStackSize(); 46 | } 47 | 48 | @Override 49 | public void setMaxStackSize(int i) { 50 | raw.setMaxStackSize(i); 51 | } 52 | 53 | @Override 54 | public String getName() { 55 | return raw.getName(); 56 | } 57 | 58 | @Override 59 | public ItemStack getItem(int i) { 60 | return raw.getItem(i); 61 | } 62 | 63 | @Override 64 | public void setItem(int i, ItemStack itemStack) { 65 | raw.setItem(i, itemStack); 66 | } 67 | 68 | @Override 69 | public HashMap addItem(ItemStack... itemStacks) throws IllegalArgumentException { 70 | return raw.addItem(itemStacks); 71 | } 72 | 73 | @Override 74 | public HashMap removeItem(ItemStack... itemStacks) throws IllegalArgumentException { 75 | return raw.removeItem(itemStacks); 76 | } 77 | 78 | @Override 79 | public ItemStack[] getContents() { 80 | return raw.getContents(); 81 | } 82 | 83 | @Override 84 | public void setContents(ItemStack[] itemStacks) throws IllegalArgumentException { 85 | raw.setContents(itemStacks); 86 | } 87 | 88 | @Override 89 | public boolean contains(int i) { 90 | return raw.contains(i); 91 | } 92 | 93 | @Override 94 | public boolean contains(Material material) throws IllegalArgumentException { 95 | return raw.contains(material); 96 | } 97 | 98 | @Override 99 | public boolean contains(ItemStack itemStack) { 100 | return raw.contains(itemStack); 101 | } 102 | 103 | @Override 104 | public boolean contains(int i, int i1) { 105 | return raw.contains(i, i1); 106 | } 107 | 108 | @Override 109 | public boolean contains(Material material, int i) throws IllegalArgumentException { 110 | return raw.contains(material, i); 111 | } 112 | 113 | @Override 114 | public boolean contains(ItemStack itemStack, int i) { 115 | return raw.contains(itemStack, i); 116 | } 117 | 118 | @Override 119 | public boolean containsAtLeast(ItemStack itemStack, int i) { 120 | return raw.containsAtLeast(itemStack, i); 121 | } 122 | 123 | @Override 124 | public HashMap all(int i) { 125 | return raw.all(i); 126 | } 127 | 128 | @Override 129 | public HashMap all(Material material) throws IllegalArgumentException { 130 | return raw.all(material); 131 | } 132 | 133 | @Override 134 | public HashMap all(ItemStack itemStack) { 135 | return raw.all(itemStack); 136 | } 137 | 138 | @Override 139 | public int first(int i) { 140 | return raw.first(i); 141 | } 142 | 143 | @Override 144 | public int first(Material material) throws IllegalArgumentException { 145 | return raw.first(material); 146 | } 147 | 148 | @Override 149 | public int first(ItemStack itemStack) { 150 | return raw.first(itemStack); 151 | } 152 | 153 | @Override 154 | public int firstEmpty() { 155 | return raw.firstEmpty(); 156 | } 157 | 158 | @Override 159 | public void remove(int i) { 160 | raw.remove(i); 161 | } 162 | 163 | @Override 164 | public void remove(Material material) throws IllegalArgumentException { 165 | raw.remove(material); 166 | } 167 | 168 | @Override 169 | public void remove(ItemStack itemStack) { 170 | raw.remove(itemStack); 171 | } 172 | 173 | @Override 174 | public void clear(int i) { 175 | raw.clear(i); 176 | } 177 | 178 | @Override 179 | public void clear() { 180 | raw.clear(); 181 | } 182 | 183 | @Override 184 | public List getViewers() { 185 | return raw.getViewers(); 186 | } 187 | 188 | @Override 189 | public String getTitle() { 190 | return raw.getTitle(); 191 | } 192 | 193 | @Override 194 | public InventoryType getType() { 195 | return raw.getType(); 196 | } 197 | 198 | @Override 199 | public InventoryHolder getHolder() { 200 | return this; 201 | } 202 | 203 | @Override 204 | public ListIterator iterator() { 205 | return raw.iterator(); 206 | } 207 | 208 | @Override 209 | public ListIterator iterator(int i) { 210 | return raw.iterator(i); 211 | } 212 | 213 | @Override 214 | public Inventory getInventory() { 215 | return this; 216 | } 217 | 218 | @Override 219 | @NotNull 220 | public Inventory getRawInventory() { 221 | return this; 222 | } 223 | 224 | @Override 225 | @NotNull 226 | public MenuInventory getMenuInventory() { 227 | return menuInventory; 228 | } 229 | 230 | } 231 | -------------------------------------------------------------------------------- /menu/api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("gui.publishing-conventions") 3 | } 4 | 5 | dependencies { 6 | api(libs.annotations) 7 | 8 | arrayOf("validation", "bukkit").forEach { 9 | api("team.unnamed:commons-$it:3.1.0") 10 | } 11 | 12 | compileOnly("org.spigotmc:spigot-api:1.8.8-R0.1-SNAPSHOT") 13 | } -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/adapt/MenuInventoryWrapper.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.adapt; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import org.jetbrains.annotations.NotNull; 5 | import team.unnamed.gui.menu.type.MenuInventory; 6 | 7 | public interface MenuInventoryWrapper { 8 | 9 | @NotNull MenuInventory getMenuInventory(); 10 | 11 | @NotNull Inventory getRawInventory(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/item/ItemClickable.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.item; 2 | 3 | import org.bukkit.inventory.ItemStack; 4 | import team.unnamed.gui.menu.item.action.ItemClickableAction; 5 | 6 | public class ItemClickable { 7 | 8 | private final int slot; 9 | private final ItemStack itemStack; 10 | private final ItemClickableAction action; 11 | 12 | private ItemClickable( 13 | int slot, ItemStack itemStack, 14 | ItemClickableAction action 15 | ) { 16 | this.slot = slot; 17 | this.itemStack = itemStack; 18 | this.action = action; 19 | } 20 | 21 | public static ItemClickable onlyItem(ItemStack itemStack) { 22 | return onlyItem(itemStack, ItemClickableAction.CANCEL_CLICK); 23 | } 24 | 25 | public static ItemClickable onlyItem(ItemStack itemStack, ItemClickableAction action) { 26 | return of(-1, itemStack, action); 27 | } 28 | 29 | public static ItemClickable of(int slot, ItemStack itemStack) { 30 | return of(slot, itemStack, ItemClickableAction.CANCEL_CLICK); 31 | } 32 | 33 | public static ItemClickable of(int slot, ItemStack itemStack, 34 | ItemClickableAction action) { 35 | return new ItemClickable(slot, itemStack, action); 36 | } 37 | 38 | public static ItemClickableBuilder builder(int slot) { 39 | return new ItemClickableBuilder(slot); 40 | } 41 | 42 | public static ItemClickableBuilder builder() { 43 | return new ItemClickableBuilder(-1); 44 | } 45 | 46 | public int getSlot() { 47 | return slot; 48 | } 49 | 50 | public ItemStack getItemStack() { 51 | return itemStack; 52 | } 53 | 54 | public ItemClickableAction getAction() { 55 | return action; 56 | } 57 | 58 | public ItemClickable clone(int slot) { 59 | return new ItemClickable(slot, this.itemStack, this.action); 60 | } 61 | 62 | public ItemClickable clone(ItemClickableAction action) { 63 | return new ItemClickable(this.slot, this.itemStack, action); 64 | } 65 | 66 | public ItemClickable clone(ItemStack itemStack) { 67 | return new ItemClickable(this.slot, itemStack, this.action); 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return "ItemClickable{" + 73 | "slot=" + slot + 74 | ", itemStack=" + itemStack + 75 | '}'; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/item/ItemClickableBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.item; 2 | 3 | import org.bukkit.event.inventory.InventoryClickEvent; 4 | import org.bukkit.inventory.ItemStack; 5 | import team.unnamed.gui.menu.item.action.ItemClickableAction; 6 | import team.unnamed.gui.menu.item.action.ItemClickableActionBuilder; 7 | 8 | import java.util.function.Consumer; 9 | import java.util.function.Predicate; 10 | 11 | import static team.unnamed.validate.Validate.isNotNull; 12 | 13 | public class ItemClickableBuilder { 14 | 15 | private final int slot; 16 | private ItemStack item; 17 | private ItemClickableAction action; 18 | 19 | protected ItemClickableBuilder(int slot) { 20 | this.slot = slot; 21 | } 22 | 23 | public ItemClickableBuilder item(ItemStack item) { 24 | this.item = isNotNull(item, "Item cannot be null."); 25 | return this; 26 | } 27 | 28 | public ItemClickableBuilder multipleAction(Consumer action) { 29 | ItemClickableActionBuilder.Multiple actionBuilder = ItemClickableAction.builder() 30 | .multipleAction(); 31 | action.accept(actionBuilder); 32 | this.action = actionBuilder.build(); 33 | return this; 34 | } 35 | 36 | public ItemClickableBuilder action(Predicate action) { 37 | isNotNull(action, "Action cannot be null."); 38 | this.action = ItemClickableAction.single(action); 39 | return this; 40 | } 41 | 42 | public ItemClickable build() { 43 | return ItemClickable.of(this.slot, this.item, this.action); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/item/action/ItemClickableAction.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.item.action; 2 | 3 | import org.bukkit.event.inventory.ClickType; 4 | import org.bukkit.event.inventory.InventoryClickEvent; 5 | import org.jetbrains.annotations.Nullable; 6 | 7 | import java.util.function.Predicate; 8 | 9 | public interface ItemClickableAction { 10 | 11 | ItemClickableAction CANCEL_CLICK = new SingleClickableAction(inventory -> true); 12 | 13 | @Nullable Predicate getAction(ClickType clickType); 14 | 15 | static ItemClickableActionBuilder builder() { 16 | return new ItemClickableActionBuilder(); 17 | } 18 | 19 | static ItemClickableAction single(Predicate action) { 20 | return new SingleClickableAction(action); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/item/action/ItemClickableActionBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.item.action; 2 | 3 | import org.bukkit.event.inventory.ClickType; 4 | import org.bukkit.event.inventory.InventoryClickEvent; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | import java.util.function.Predicate; 9 | 10 | import static team.unnamed.validate.Validate.isNotNull; 11 | 12 | public class ItemClickableActionBuilder { 13 | 14 | protected ItemClickableActionBuilder() { 15 | } 16 | 17 | public Multiple multipleAction() { 18 | return new Multiple(); 19 | } 20 | 21 | public ItemClickableAction globalAction(Predicate action) { 22 | return new SingleClickableAction(isNotNull( 23 | action, 24 | "Action cannot be null." 25 | )); 26 | } 27 | 28 | public static class Multiple { 29 | 30 | private final Map> actions; 31 | 32 | public Multiple() { 33 | this.actions = new HashMap<>(); 34 | } 35 | 36 | public Multiple link(ClickType clickType, Predicate action) { 37 | actions.put( 38 | isNotNull(clickType, "Click type cannot be null."), 39 | isNotNull(action, "Action cannot be null.") 40 | ); 41 | return this; 42 | } 43 | 44 | public ItemClickableAction build() { 45 | return new MultipleItemClickableAction(actions); 46 | } 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/item/action/MultipleItemClickableAction.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.item.action; 2 | 3 | import org.bukkit.event.inventory.ClickType; 4 | import org.bukkit.event.inventory.InventoryClickEvent; 5 | 6 | import java.util.Map; 7 | import java.util.function.Predicate; 8 | 9 | public class MultipleItemClickableAction 10 | implements ItemClickableAction { 11 | 12 | private final Map> actions; 13 | 14 | public MultipleItemClickableAction(Map> actions) { 15 | this.actions = actions; 16 | } 17 | 18 | @Override 19 | public Predicate getAction(ClickType clickType) { 20 | return actions.get(clickType); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/item/action/SingleClickableAction.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.item.action; 2 | 3 | import org.bukkit.event.inventory.ClickType; 4 | import org.bukkit.event.inventory.InventoryClickEvent; 5 | 6 | import java.util.function.Predicate; 7 | 8 | public class SingleClickableAction 9 | implements ItemClickableAction { 10 | 11 | private final Predicate action; 12 | 13 | protected SingleClickableAction(Predicate action) { 14 | this.action = action; 15 | } 16 | 17 | @Override 18 | public Predicate getAction(ClickType clickType) { 19 | return action; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/listener/InventoryClickListener.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.listener; 2 | 3 | import org.bukkit.event.EventHandler; 4 | import org.bukkit.event.Listener; 5 | import org.bukkit.event.inventory.InventoryClickEvent; 6 | import org.bukkit.inventory.Inventory; 7 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 8 | import team.unnamed.gui.menu.item.ItemClickable; 9 | import team.unnamed.gui.menu.item.action.ItemClickableAction; 10 | import team.unnamed.gui.menu.type.MenuInventory; 11 | import team.unnamed.gui.menu.util.MenuUtil; 12 | 13 | import java.util.function.Predicate; 14 | 15 | public class InventoryClickListener 16 | implements Listener { 17 | 18 | @EventHandler 19 | public void onClick(InventoryClickEvent event) { 20 | Inventory inventory = event.getClickedInventory(); 21 | 22 | if (MenuUtil.isCustomMenu(inventory)) { 23 | int clickedSlot = event.getSlot(); 24 | 25 | if (clickedSlot < 0) { 26 | return; 27 | } 28 | 29 | MenuInventoryWrapper wrapper = MenuUtil.getAsWrapper(inventory); 30 | MenuInventory menuInventory = wrapper.getMenuInventory(); 31 | ItemClickable itemClickable = menuInventory.getItem(clickedSlot); 32 | 33 | if (itemClickable == null) { 34 | event.setCancelled(!menuInventory.canIntroduceItems()); 35 | return; 36 | } 37 | 38 | if (event.getRawSlot() != clickedSlot && !menuInventory.canIntroduceItems()) { 39 | event.setCancelled(true); 40 | return; 41 | } 42 | 43 | ItemClickableAction action = itemClickable.getAction(); 44 | Predicate clickAction = action.getAction(event.getClick()); 45 | 46 | if (clickAction == null) { 47 | event.setCancelled(!menuInventory.canIntroduceItems()); 48 | } else { 49 | event.setCancelled(clickAction.test(event)); 50 | } 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/listener/InventoryCloseListener.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.listener; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.event.EventHandler; 5 | import org.bukkit.event.Listener; 6 | import org.bukkit.event.inventory.InventoryCloseEvent; 7 | import org.bukkit.inventory.Inventory; 8 | import org.bukkit.plugin.Plugin; 9 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 10 | import team.unnamed.gui.menu.type.MenuInventory; 11 | import team.unnamed.gui.menu.util.MenuUtil; 12 | 13 | import java.util.function.Predicate; 14 | 15 | public class InventoryCloseListener 16 | implements Listener { 17 | 18 | private final Plugin plugin; 19 | 20 | public InventoryCloseListener(Plugin plugin) { 21 | this.plugin = plugin; 22 | } 23 | 24 | @EventHandler 25 | public void onClose(InventoryCloseEvent event) { 26 | Inventory inventory = event.getInventory(); 27 | 28 | if (MenuUtil.isCustomMenu(inventory)) { 29 | MenuInventoryWrapper wrapper = MenuUtil.getAsWrapper(inventory); 30 | MenuInventory menuInventory = wrapper.getMenuInventory(); 31 | Predicate action = menuInventory.getCloseAction(); 32 | 33 | if (action != null) { 34 | if (action.test(inventory)) { 35 | Bukkit.getScheduler().runTaskLater( 36 | plugin, () -> event.getPlayer().openInventory(inventory), 1); 37 | } 38 | } 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/listener/InventoryOpenListener.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.listener; 2 | 3 | import org.bukkit.event.EventHandler; 4 | import org.bukkit.event.Listener; 5 | import org.bukkit.event.inventory.InventoryOpenEvent; 6 | import org.bukkit.inventory.Inventory; 7 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 8 | import team.unnamed.gui.menu.type.MenuInventory; 9 | import team.unnamed.gui.menu.util.MenuUtil; 10 | 11 | import java.util.function.Predicate; 12 | 13 | public class InventoryOpenListener 14 | implements Listener { 15 | 16 | @EventHandler 17 | public void onOpen(InventoryOpenEvent event) { 18 | Inventory inventory = event.getInventory(); 19 | 20 | if (MenuUtil.isCustomMenu(inventory)) { 21 | MenuInventoryWrapper wrapper = MenuUtil.getAsWrapper(inventory); 22 | MenuInventory menuInventory = wrapper.getMenuInventory(); 23 | Predicate action = menuInventory.getOpenAction(); 24 | 25 | if (action != null) { 26 | if (action.test(inventory)) { 27 | event.setCancelled(true); 28 | } 29 | } 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/type/DefaultMenuInventory.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.type; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | import team.unnamed.gui.menu.item.ItemClickable; 7 | import team.unnamed.gui.menu.util.MenuUtil; 8 | 9 | import java.util.List; 10 | import java.util.function.Predicate; 11 | 12 | public class DefaultMenuInventory implements MenuInventory { 13 | 14 | protected final String title; 15 | protected final int slots; 16 | protected final List items; 17 | protected final Predicate openAction; 18 | protected final Predicate closeAction; 19 | protected final boolean canIntroduceItems; 20 | 21 | protected DefaultMenuInventory( 22 | String title, int slots, 23 | List items, 24 | Predicate openAction, 25 | Predicate closeAction, 26 | boolean canIntroduceItems 27 | ) { 28 | this.title = title; 29 | this.slots = slots; 30 | this.items = items; 31 | this.openAction = openAction; 32 | this.closeAction = closeAction; 33 | this.canIntroduceItems = canIntroduceItems; 34 | } 35 | 36 | @NotNull 37 | @Override 38 | public String getTitle() { 39 | return title; 40 | } 41 | 42 | @Override 43 | public int getSlots() { 44 | return slots; 45 | } 46 | 47 | @NotNull 48 | @Override 49 | public List getItems() { 50 | return items; 51 | } 52 | 53 | @Override 54 | public void clearItems() { 55 | this.items.clear(); 56 | MenuUtil.fillItemList(this.items, this.slots); 57 | } 58 | 59 | @Override 60 | public void setItem(ItemClickable item) { 61 | this.items.set(item.getSlot(), item); 62 | } 63 | 64 | @Override 65 | public void removeItem(int slot) { 66 | this.items.remove(slot); 67 | } 68 | 69 | @Nullable 70 | @Override 71 | public Predicate getOpenAction() { 72 | return openAction; 73 | } 74 | 75 | @Nullable 76 | @Override 77 | public Predicate getCloseAction() { 78 | return closeAction; 79 | } 80 | 81 | @Override 82 | public boolean canIntroduceItems() { 83 | return canIntroduceItems; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/type/DefaultMenuInventoryBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.type; 2 | 3 | public class DefaultMenuInventoryBuilder 4 | extends MenuInventoryBuilderLayout { 5 | 6 | protected DefaultMenuInventoryBuilder(String title) { 7 | super(title); 8 | } 9 | 10 | protected DefaultMenuInventoryBuilder(String title, int rows) { 11 | super(title, rows); 12 | } 13 | 14 | @Override 15 | protected DefaultMenuInventoryBuilder back() { 16 | return this; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/type/MenuInventory.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.type; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import org.jetbrains.annotations.NotNull; 5 | import org.jetbrains.annotations.Nullable; 6 | import team.unnamed.gui.menu.item.ItemClickable; 7 | 8 | import java.util.List; 9 | import java.util.function.Predicate; 10 | 11 | public interface MenuInventory { 12 | 13 | static MenuInventoryBuilder newBuilder(String title) { 14 | return new DefaultMenuInventoryBuilder(title); 15 | } 16 | 17 | static MenuInventoryBuilder newBuilder(String title, int rows) { 18 | return new DefaultMenuInventoryBuilder(title, rows); 19 | } 20 | 21 | static StringLayoutMenuInventoryBuilder newStringLayoutBuilder(String title) { 22 | return new StringLayoutMenuInventoryBuilder(title); 23 | } 24 | 25 | static StringLayoutMenuInventoryBuilder newStringLayoutBuilder(String title, int rows) { 26 | return new StringLayoutMenuInventoryBuilder(title, rows); 27 | } 28 | 29 | static PaginatedMenuInventoryBuilder newPaginatedBuilder(Class entityType, String title) { 30 | return new PaginatedMenuInventoryBuilder<>(title); 31 | } 32 | 33 | static PaginatedMenuInventoryBuilder newPaginatedBuilder(Class entityType, String title, int rows) { 34 | return new PaginatedMenuInventoryBuilder<>(title, rows); 35 | } 36 | 37 | @NotNull 38 | String getTitle(); 39 | 40 | int getSlots(); 41 | 42 | @NotNull 43 | List getItems(); 44 | 45 | void clearItems(); 46 | 47 | void setItem(ItemClickable item); 48 | 49 | void removeItem(int slot); 50 | 51 | @Nullable Predicate getOpenAction(); 52 | 53 | @Nullable Predicate getCloseAction(); 54 | 55 | boolean canIntroduceItems(); 56 | 57 | default @Nullable ItemClickable getItem(int slot) { 58 | return getItems().get(slot); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/type/MenuInventoryBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.type; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import team.unnamed.gui.menu.item.ItemClickable; 5 | 6 | import java.util.List; 7 | import java.util.function.Predicate; 8 | 9 | public interface MenuInventoryBuilder { 10 | 11 | MenuInventoryBuilder fillItem(ItemClickable item, int from, int to); 12 | 13 | MenuInventoryBuilder fillRow(ItemClickable item, int row); 14 | 15 | MenuInventoryBuilder fillColumn(ItemClickable item, int column); 16 | 17 | MenuInventoryBuilder fillBorders(ItemClickable item); 18 | 19 | MenuInventoryBuilder items(List items); 20 | 21 | MenuInventoryBuilder item(ItemClickable item, int... slots); 22 | 23 | MenuInventoryBuilder item(ItemClickable item); 24 | 25 | MenuInventoryBuilder openAction(Predicate action); 26 | 27 | MenuInventoryBuilder closeAction(Predicate action); 28 | 29 | MenuInventoryBuilder introduceItems(boolean canIntroduceItems); 30 | 31 | Inventory build(); 32 | } 33 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/type/MenuInventoryBuilderLayout.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.type; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import team.unnamed.gui.menu.item.ItemClickable; 5 | import team.unnamed.gui.menu.util.MenuUtil; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.function.Predicate; 10 | 11 | import static team.unnamed.validate.Validate.isNotNull; 12 | import static team.unnamed.validate.Validate.isState; 13 | 14 | abstract class MenuInventoryBuilderLayout 15 | implements MenuInventoryBuilder { 16 | 17 | protected final String title; 18 | protected final int slots; 19 | private final int rows; 20 | 21 | protected List items; 22 | protected Predicate openAction; 23 | protected Predicate closeAction; 24 | protected boolean canIntroduceItems; 25 | 26 | protected MenuInventoryBuilderLayout(String title) { 27 | this(title, 6); 28 | } 29 | 30 | protected MenuInventoryBuilderLayout(String title, int rows) { 31 | isState(rows > 0 && rows <= 6, 32 | "Rows must be major than 0 and minor than 6"); 33 | this.title = isNotNull(title, "Title cannot be null."); 34 | this.slots = rows * 9; 35 | this.rows = rows; 36 | this.items = new ArrayList<>(); 37 | MenuUtil.fillItemList(this.items, this.slots); 38 | } 39 | 40 | @Override 41 | public T fillItem(ItemClickable item, int from, int to) { 42 | isNotNull(item, "Item cannot be null."); 43 | 44 | for (int i = from; i < to; i++) { 45 | this.items.set(i, item.clone(i)); 46 | } 47 | 48 | return back(); 49 | } 50 | 51 | @Override 52 | public T fillRow(ItemClickable item, int row) { 53 | isState(row > 0 && row <= 6, 54 | "Row must be major than 0 and minor than 6"); 55 | isNotNull(item, "Item cannot be null."); 56 | 57 | int indexStart = row == 1 ? 0 : (row - 1) * 9; 58 | 59 | for (int slot = indexStart; slot < indexStart + 9; slot++) { 60 | this.items.set(slot, item.clone(slot)); 61 | } 62 | 63 | return back(); 64 | } 65 | 66 | @Override 67 | public T fillColumn(ItemClickable item, int column) { 68 | isState(column > 0 && column <= 9, 69 | "Column must be major than 0 and minor than 9"); 70 | isNotNull(item, "Item cannot be null."); 71 | 72 | int indexStart = column - 1; 73 | int indexEnd = (slots - 9) + column; 74 | 75 | for (int slot = indexStart; slot <= indexEnd; slot += 9) { 76 | this.items.set(slot, item.clone(slot)); 77 | } 78 | 79 | return back(); 80 | } 81 | 82 | @Override 83 | public T fillBorders(ItemClickable item) { 84 | isNotNull(item, "Item cannot be null."); 85 | isState(rows >= 3, "Cannot fill borders if rows are minor than 3."); 86 | 87 | fillRow(item, 1); 88 | fillRow(item, rows); 89 | fillColumn(item, 1); 90 | fillColumn(item, 9); 91 | 92 | return back(); 93 | } 94 | 95 | @Override 96 | public T items(List items) { 97 | this.items = isNotNull(items, "Items cannot be null."); 98 | return back(); 99 | } 100 | 101 | @Override 102 | public T item(ItemClickable item, int... slots) { 103 | isNotNull(item, "Item cannot be null."); 104 | 105 | for (int slot : slots) { 106 | this.items.set(slot, item.clone(slot)); 107 | } 108 | 109 | return back(); 110 | } 111 | 112 | @Override 113 | public T item(ItemClickable item) { 114 | isNotNull(item, "Item cannot be null."); 115 | 116 | this.items.set(item.getSlot(), item); 117 | 118 | return back(); 119 | } 120 | 121 | @Override 122 | public T openAction(Predicate action) { 123 | isNotNull(action, "Open action cannot be null."); 124 | this.openAction = action; 125 | 126 | return back(); 127 | } 128 | 129 | @Override 130 | public T closeAction(Predicate action) { 131 | isNotNull(action, "Close action cannot be null."); 132 | this.closeAction = action; 133 | 134 | return back(); 135 | } 136 | 137 | @Override 138 | public T introduceItems(boolean canIntroduceItems) { 139 | this.canIntroduceItems = canIntroduceItems; 140 | return back(); 141 | } 142 | 143 | @Override 144 | public Inventory build() { 145 | return internalBuild(new DefaultMenuInventory( 146 | title, slots, items, 147 | openAction, closeAction, canIntroduceItems 148 | )); 149 | } 150 | 151 | protected Inventory internalBuild(MenuInventory menuInventory) { 152 | Inventory inventory = MenuUtil.parseToInventory(menuInventory); 153 | 154 | for (ItemClickable itemClickable : items) { 155 | if (itemClickable == null) { 156 | continue; 157 | } 158 | 159 | inventory.setItem(itemClickable.getSlot(), itemClickable.getItemStack()); 160 | } 161 | 162 | return inventory; 163 | } 164 | 165 | protected abstract T back(); 166 | 167 | } 168 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/type/PaginatedMenuInventory.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.type; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import team.unnamed.gui.menu.item.ItemClickable; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.function.Function; 9 | import java.util.function.Predicate; 10 | 11 | public class PaginatedMenuInventory extends DefaultMenuInventory { 12 | 13 | private final int entitySlotFrom; 14 | private final int availableEntitySlots; 15 | private final List availableSlots; 16 | private final int maxPages; 17 | private final List entities; 18 | private final int currentPage; 19 | private final List layoutLines; 20 | private final Map layoutItems; 21 | private final Function entityParser; 22 | private final Function previousPageItem; 23 | private final Function nextPageItem; 24 | private final ItemClickable itemIfNoEntities; 25 | private final ItemClickable itemIfNoPreviousPage; 26 | private final ItemClickable itemIfNoNextPage; 27 | 28 | protected PaginatedMenuInventory( 29 | String title, int slots, 30 | List items, 31 | Predicate openAction, 32 | Predicate closeAction, 33 | boolean canIntroduceItems, 34 | int entitySlotFrom, int availableEntitySlots, 35 | List availableSlots, List entities, 36 | int currentPage, List layoutLines, 37 | Map layoutItems, 38 | Function entityParser, 39 | Function previousPageItem, 40 | Function nextPageItem, 41 | ItemClickable itemIfNoEntities, 42 | ItemClickable itemIfNoPreviousPage, 43 | ItemClickable itemIfNoNextPage 44 | ) { 45 | super(title, slots, items, openAction, closeAction, canIntroduceItems); 46 | this.entitySlotFrom = entitySlotFrom; 47 | this.availableEntitySlots = availableEntitySlots; 48 | this.availableSlots = availableSlots; 49 | this.maxPages = (int) Math.ceil(entities.size() / (double) availableEntitySlots); 50 | this.entities = entities; 51 | this.currentPage = currentPage; 52 | this.layoutLines = layoutLines; 53 | this.layoutItems = layoutItems; 54 | this.entityParser = entityParser; 55 | this.previousPageItem = previousPageItem; 56 | this.nextPageItem = nextPageItem; 57 | this.itemIfNoEntities = itemIfNoEntities; 58 | this.itemIfNoPreviousPage = itemIfNoPreviousPage; 59 | this.itemIfNoNextPage = itemIfNoNextPage; 60 | } 61 | 62 | public int getEntitySlotFrom() { 63 | return entitySlotFrom; 64 | } 65 | 66 | public List getAvailableSlots() { 67 | return availableSlots; 68 | } 69 | 70 | public int getAvailableEntitySlots() { 71 | return availableEntitySlots; 72 | } 73 | 74 | public int getMaxPages() { 75 | return maxPages; 76 | } 77 | 78 | public int getCurrentPage() { 79 | return currentPage; 80 | } 81 | 82 | public List getEntities() { 83 | return entities; 84 | } 85 | 86 | public List getLayoutLines() { 87 | return layoutLines; 88 | } 89 | 90 | public Map getLayoutItems() { 91 | return layoutItems; 92 | } 93 | 94 | public Function getEntityParser() { 95 | return entityParser; 96 | } 97 | 98 | public Function getPreviousPageItem() { 99 | return previousPageItem; 100 | } 101 | 102 | public Function getNextPageItem() { 103 | return nextPageItem; 104 | } 105 | 106 | public ItemClickable getItemIfNoEntities() { 107 | return itemIfNoEntities; 108 | } 109 | 110 | public ItemClickable getItemIfNoPreviousPage() { 111 | return itemIfNoPreviousPage; 112 | } 113 | 114 | public ItemClickable getItemIfNoNextPage() { 115 | return itemIfNoNextPage; 116 | } 117 | 118 | public PaginatedMenuInventory clone(int page) { 119 | return new PaginatedMenuInventory<>( 120 | title, slots, items, openAction, closeAction, canIntroduceItems, 121 | entitySlotFrom, availableEntitySlots, availableSlots, 122 | entities, page, layoutLines, layoutItems, entityParser, 123 | previousPageItem, nextPageItem, itemIfNoEntities, 124 | itemIfNoPreviousPage, itemIfNoNextPage 125 | ); 126 | } 127 | 128 | } 129 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/type/PaginatedMenuInventoryBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.type; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import team.unnamed.gui.menu.item.ItemClickable; 5 | import team.unnamed.gui.menu.util.MenuUtil; 6 | import team.unnamed.gui.menu.util.PaginatedMenuUtil; 7 | 8 | import java.util.ArrayList; 9 | import java.util.Arrays; 10 | import java.util.Collection; 11 | import java.util.List; 12 | import java.util.function.Function; 13 | 14 | import static team.unnamed.validate.Validate.isNotNull; 15 | 16 | public class PaginatedMenuInventoryBuilder 17 | extends StringLayoutMenuInventoryBuilder { 18 | 19 | private int entitySlotFrom; 20 | private int entitySlotTo; 21 | private Iterable skippedSlots; 22 | private int itemsPerRow; 23 | private List entities; 24 | private Function entityParser; 25 | private Function previousPageItem; 26 | private Function nextPageItem; 27 | private ItemClickable itemIfNoEntities; 28 | private ItemClickable itemIfNoPreviousPage; 29 | private ItemClickable itemIfNoNextPage; 30 | 31 | protected PaginatedMenuInventoryBuilder(String title) { 32 | super(title); 33 | } 34 | 35 | protected PaginatedMenuInventoryBuilder(String title, int rows) { 36 | super(title, rows); 37 | } 38 | 39 | public PaginatedMenuInventoryBuilder bounds(int entitySlotFrom, int entitySlotTo) { 40 | this.entitySlotFrom = entitySlotFrom; 41 | this.entitySlotTo = entitySlotTo; 42 | return this; 43 | } 44 | 45 | public PaginatedMenuInventoryBuilder itemsPerRow(int itemsPerRow) { 46 | this.itemsPerRow = itemsPerRow; 47 | return this; 48 | } 49 | 50 | public PaginatedMenuInventoryBuilder skippedSlots(Iterable skippedSlots) { 51 | this.skippedSlots = skippedSlots; 52 | return this; 53 | } 54 | 55 | public PaginatedMenuInventoryBuilder skippedSlots(Integer... skippedSlots) { 56 | this.skippedSlots = Arrays.asList(skippedSlots); 57 | return this; 58 | } 59 | 60 | public PaginatedMenuInventoryBuilder entities(Collection entities) { 61 | this.entities = new ArrayList<>(entities); 62 | return this; 63 | } 64 | 65 | public PaginatedMenuInventoryBuilder entityParser(Function entityParser) { 66 | this.entityParser = entityParser; 67 | return this; 68 | } 69 | 70 | public PaginatedMenuInventoryBuilder nextPageItem(Function nextPageItem) { 71 | this.nextPageItem = nextPageItem; 72 | return this; 73 | } 74 | 75 | public PaginatedMenuInventoryBuilder previousPageItem(Function previousPageItem) { 76 | this.previousPageItem = previousPageItem; 77 | return this; 78 | } 79 | 80 | public PaginatedMenuInventoryBuilder itemIfNoEntities(ItemClickable itemIfNoEntities) { 81 | this.itemIfNoEntities = isNotNull(itemIfNoEntities, "Item if no entities cannot be null."); 82 | return this; 83 | } 84 | 85 | public PaginatedMenuInventoryBuilder itemIfNoPreviousPage(ItemClickable itemIfNoPreviousPage) { 86 | this.itemIfNoPreviousPage = isNotNull(itemIfNoPreviousPage, 87 | "Item if no previos page cannot be null."); 88 | return this; 89 | } 90 | 91 | public PaginatedMenuInventoryBuilder itemIfNoNextPage(ItemClickable itemIfNoNextPage) { 92 | this.itemIfNoNextPage = isNotNull(itemIfNoNextPage, 93 | "Item if no next page cannot be null."); 94 | return this; 95 | } 96 | 97 | @Override 98 | public Inventory build() { 99 | isNotNull(entityParser, "Entity parser cannot be null."); 100 | isNotNull(entities, "Entities cannot be null."); 101 | isNotNull(nextPageItem, "Next page item cannot be null."); 102 | isNotNull(previousPageItem, "Previous page item cannot be null."); 103 | 104 | int nextIncrement = 9 - itemsPerRow; 105 | List availableSlots = new ArrayList<>(); 106 | int itemsPerRowCounter = 0; 107 | 108 | for (int i = entitySlotFrom; i < entitySlotTo; i++) { 109 | itemsPerRowCounter++; 110 | 111 | boolean isSkippedSlot = false; 112 | 113 | if (skippedSlots != null) { 114 | for (Integer skippedSlot : skippedSlots) { 115 | if (i == skippedSlot) { 116 | isSkippedSlot = true; 117 | break; 118 | } 119 | } 120 | } 121 | 122 | if (!isSkippedSlot) { 123 | availableSlots.add(i); 124 | } 125 | 126 | if (itemsPerRowCounter == itemsPerRow) { 127 | itemsPerRowCounter = 0; 128 | i += nextIncrement; 129 | } 130 | } 131 | 132 | PaginatedMenuInventory paginatedMenuInventory = new PaginatedMenuInventory<>( 133 | title, slots, items, openAction, closeAction, canIntroduceItems, 134 | entitySlotFrom, availableSlots.size(), availableSlots, entities, 1, 135 | layoutLines, layoutItems, entityParser, 136 | previousPageItem, nextPageItem, itemIfNoEntities, 137 | itemIfNoPreviousPage, itemIfNoNextPage 138 | ); 139 | 140 | Inventory inventory = MenuUtil.parseToInventory(paginatedMenuInventory); 141 | return PaginatedMenuUtil.createPage(inventory, paginatedMenuInventory); 142 | } 143 | 144 | @Override 145 | protected PaginatedMenuInventoryBuilder back() { 146 | return this; 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/type/StringLayoutMenuInventoryBuilder.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.type; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import team.unnamed.gui.menu.item.ItemClickable; 5 | 6 | import java.util.*; 7 | 8 | import static team.unnamed.validate.Validate.isNotNull; 9 | import static team.unnamed.validate.Validate.isState; 10 | 11 | public class StringLayoutMenuInventoryBuilder 12 | extends MenuInventoryBuilderLayout { 13 | 14 | protected final Map layoutItems; 15 | protected final List layoutLines; 16 | 17 | protected StringLayoutMenuInventoryBuilder(String title) { 18 | this(title, 6); 19 | } 20 | 21 | protected StringLayoutMenuInventoryBuilder(String title, int rows) { 22 | super(title, rows); 23 | this.layoutLines = new ArrayList<>(rows); 24 | this.layoutItems = new HashMap<>(); 25 | } 26 | 27 | public StringLayoutMenuInventoryBuilder layoutItem(char identifier, ItemClickable item) { 28 | this.layoutItems.put(identifier, isNotNull(item)); 29 | return back(); 30 | } 31 | 32 | public StringLayoutMenuInventoryBuilder layoutLines(Iterable lines) { 33 | for (String line : lines) { 34 | line = line.trim(); 35 | isState(line.length() == 9, 36 | "Cannot add layout line '" + line + "' because length is minor than 9"); 37 | this.layoutLines.add(line.trim()); 38 | } 39 | 40 | return back(); 41 | } 42 | 43 | public StringLayoutMenuInventoryBuilder layoutLines(String... lines) { 44 | return layoutLines(Arrays.asList(lines)); 45 | } 46 | 47 | @Override 48 | public Inventory build() { 49 | int slotIndex = 0; 50 | 51 | for (String layoutLine : this.layoutLines) { 52 | for (char c : layoutLine.toCharArray()) { 53 | ItemClickable itemClickable = this.layoutItems.get(c); 54 | 55 | if (itemClickable == null) { 56 | slotIndex++; 57 | continue; 58 | } 59 | 60 | item(itemClickable.clone(slotIndex)); 61 | } 62 | } 63 | 64 | return super.build(); 65 | } 66 | 67 | @Override 68 | protected StringLayoutMenuInventoryBuilder back() { 69 | return this; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/util/MenuUtil.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.util; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import org.bukkit.inventory.InventoryHolder; 5 | import org.jetbrains.annotations.NotNull; 6 | import team.unnamed.bukkit.ServerVersion; 7 | import team.unnamed.gui.menu.adapt.MenuInventoryWrapper; 8 | import team.unnamed.gui.menu.item.ItemClickable; 9 | import team.unnamed.gui.menu.type.MenuInventory; 10 | 11 | import java.lang.reflect.Constructor; 12 | import java.lang.reflect.InvocationTargetException; 13 | import java.util.List; 14 | 15 | public final class MenuUtil { 16 | 17 | private static final Constructor WRAPPER_CONSTRUCTOR; 18 | 19 | static { 20 | try { 21 | WRAPPER_CONSTRUCTOR = Class.forName( 22 | "team.unnamed.gui.menu." + ServerVersion.CURRENT 23 | + ".MenuInventoryWrapperImpl" 24 | ).getConstructor(InventoryHolder.class, MenuInventory.class); 25 | } catch (ClassNotFoundException | NoSuchMethodException e) { 26 | throw new ExceptionInInitializerError("Your server version isn't supported for ungui."); 27 | } 28 | } 29 | 30 | private MenuUtil() { 31 | // the class shouldn't be instantiated 32 | throw new UnsupportedOperationException(); 33 | } 34 | 35 | public static void fillItemList(List items, int slots) { 36 | for (int i = 0; i < slots; i++) { 37 | items.add(null); 38 | } 39 | } 40 | 41 | public static @NotNull Inventory parseToInventory(MenuInventory menuInventory) { 42 | try { 43 | MenuInventoryWrapper wrapper 44 | = (MenuInventoryWrapper) WRAPPER_CONSTRUCTOR.newInstance( 45 | null, menuInventory); 46 | 47 | return wrapper.getRawInventory(); 48 | } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { 49 | throw new ExceptionInInitializerError( 50 | "An error has occurred while creating menu " 51 | + menuInventory.getTitle()); 52 | } 53 | } 54 | 55 | public static boolean isCustomMenu(Inventory inventory) { 56 | if (inventory == null) { 57 | return false; 58 | } 59 | 60 | InventoryHolder holder = inventory.getHolder(); 61 | 62 | return holder instanceof MenuInventoryWrapper 63 | || inventory instanceof MenuInventoryWrapper; 64 | } 65 | 66 | public static MenuInventoryWrapper getAsWrapper(Inventory inventory) { 67 | InventoryHolder holder = inventory.getHolder(); 68 | 69 | return holder == null ? 70 | (MenuInventoryWrapper) inventory : 71 | (MenuInventoryWrapper) holder; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/util/PaginatedMenuUtil.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.util; 2 | 3 | import org.bukkit.inventory.Inventory; 4 | import team.unnamed.gui.menu.item.ItemClickable; 5 | import team.unnamed.gui.menu.item.action.ItemClickableAction; 6 | import team.unnamed.gui.menu.type.PaginatedMenuInventory; 7 | 8 | import java.util.List; 9 | import java.util.Map; 10 | import java.util.function.Function; 11 | 12 | public final class PaginatedMenuUtil { 13 | 14 | private PaginatedMenuUtil() { 15 | throw new UnsupportedOperationException(); 16 | } 17 | 18 | public static Inventory createPage( 19 | Inventory delegate, 20 | PaginatedMenuInventory menuInventory 21 | ) { 22 | int currentPage = menuInventory.getCurrentPage(); 23 | List entities = menuInventory.getEntities(); 24 | Map layoutItems = menuInventory.getLayoutItems(); 25 | Function entityParser = menuInventory.getEntityParser(); 26 | int entitiesSize = entities.size(); 27 | 28 | List availableSlots = menuInventory.getAvailableSlots(); 29 | int availableEntitySlots = menuInventory.getAvailableEntitySlots(); 30 | int entityIndex = currentPage == 1 ? 0 : availableEntitySlots * (currentPage - 1); 31 | int currentSlot = 0; 32 | int entitySlotIndex = 0; 33 | 34 | ItemClickable itemIfNoEntities = menuInventory.getItemIfNoEntities(); 35 | 36 | for (String layoutLine : menuInventory.getLayoutLines()) { 37 | for (char c : layoutLine.toCharArray()) { 38 | ItemClickable itemClickable = null; 39 | 40 | switch (c) { 41 | case 'e': { 42 | if (entityIndex >= entitiesSize) { 43 | if (itemIfNoEntities != null) 44 | itemClickable = itemIfNoEntities.clone(availableSlots.get(entitySlotIndex++)); 45 | break; 46 | } 47 | 48 | E entity = entities.get(entityIndex++); 49 | itemClickable = entityParser.apply(entity).clone(availableSlots.get(entitySlotIndex++)); 50 | break; 51 | } 52 | case 'n': { 53 | itemClickable = getInteractPageItem( 54 | currentPage < menuInventory.getMaxPages(), 55 | currentPage, currentPage + 1, currentSlot, 56 | menuInventory, menuInventory.getNextPageItem(), 57 | menuInventory.getItemIfNoNextPage() 58 | ); 59 | break; 60 | } 61 | case 'p': { 62 | itemClickable = getInteractPageItem( 63 | currentPage > 1, 64 | currentPage, currentPage - 1, currentSlot, 65 | menuInventory, menuInventory.getPreviousPageItem(), 66 | menuInventory.getItemIfNoPreviousPage() 67 | ); 68 | break; 69 | } 70 | default: { 71 | ItemClickable layoutItem = layoutItems.get(c); 72 | 73 | if (layoutItem != null) { 74 | itemClickable = layoutItem.clone(currentSlot); 75 | } 76 | break; 77 | } 78 | } 79 | 80 | if (itemClickable != null) { 81 | delegate.setItem(itemClickable.getSlot(), itemClickable.getItemStack()); 82 | menuInventory.setItem(itemClickable); 83 | } 84 | 85 | currentSlot++; 86 | } 87 | } 88 | 89 | return delegate; 90 | } 91 | 92 | private static ItemClickable getInteractPageItem( 93 | boolean expression, int currentPage, int newPage, 94 | int currentSlot, 95 | PaginatedMenuInventory menuInventory, 96 | Function pageItem, 97 | ItemClickable orElseItem 98 | ) { 99 | ItemClickable itemClickable = null; 100 | if (expression) { 101 | itemClickable = pageItem.apply(currentPage) 102 | .clone(currentSlot) 103 | .clone(ItemClickableAction.single(event -> { 104 | menuInventory.clearItems(); 105 | Inventory inventory = event.getClickedInventory(); 106 | inventory.clear(); 107 | createPage(inventory, menuInventory.clone(newPage)); 108 | return true; 109 | })); 110 | } else { 111 | if (orElseItem != null) { 112 | itemClickable = orElseItem.clone(currentSlot); 113 | } 114 | } 115 | 116 | return itemClickable; 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /menu/api/src/main/java/team/unnamed/gui/menu/util/Slots.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | public final class Slots { 8 | 9 | private Slots() { 10 | // the class shouldn't be instantiated 11 | throw new UnsupportedOperationException(); 12 | } 13 | 14 | public static List getBorderSlots(int rows) { 15 | if (rows < 3) { 16 | return Collections.emptyList(); 17 | } 18 | 19 | List slots = new ArrayList<>(); 20 | int totalSlots = rows * 9; 21 | slots.addAll(getRowSlots(1)); 22 | slots.addAll(getRowSlots(rows)); 23 | slots.addAll(getColumnSlots(1, totalSlots)); 24 | slots.addAll(getColumnSlots(9, totalSlots)); 25 | 26 | return slots; 27 | } 28 | 29 | public static List getRowSlots(int row) { 30 | List slots = new ArrayList<>(); 31 | int indexStart = row == 1 ? 0 : (row - 1) * 9; 32 | 33 | for (int slot = indexStart; slot < indexStart + 9; slot++) { 34 | slots.add(slot); 35 | } 36 | 37 | return slots; 38 | } 39 | 40 | public static List getColumnSlots(int column, int slots) { 41 | List columnSlots = new ArrayList<>(); 42 | int indexStart = column - 1; 43 | int indexEnd = (slots - 9) + column; 44 | 45 | for (int slot = indexStart; slot <= indexEnd; slot += 9) { 46 | columnSlots.add(slot); 47 | } 48 | 49 | return columnSlots; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /menu/plugin/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.github.johnrengelman.shadow") version("7.1.2") 3 | id("gui.common-conventions") 4 | } 5 | 6 | configure { 7 | toolchain { 8 | languageVersion.set(JavaLanguageVersion.of(17)) 9 | } 10 | } 11 | 12 | dependencies { 13 | compileOnly("org.spigotmc:spigot-api:1.18.2-R0.1-SNAPSHOT") 14 | 15 | implementation(project(":gui-menu-api")) 16 | implementation(project(":gui-item-skull-api")) 17 | implementation(project(":gui-item-api")) 18 | 19 | arrayOf("1_18_R2").forEach { 20 | runtimeOnly(project(":gui-menu-adapt-v$it")) 21 | } 22 | } -------------------------------------------------------------------------------- /menu/plugin/src/main/java/team/unnamed/gui/menu/plugin/MenuPlugin.java: -------------------------------------------------------------------------------- 1 | package team.unnamed.gui.menu.plugin; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.DyeColor; 5 | import org.bukkit.Material; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.inventory.ItemStack; 8 | import org.bukkit.plugin.PluginManager; 9 | import org.bukkit.plugin.java.JavaPlugin; 10 | import team.unnamed.gui.item.ItemBuilder; 11 | import team.unnamed.gui.item.SkullItemBuilder; 12 | import team.unnamed.gui.item.skull.SkinManager; 13 | import team.unnamed.gui.item.skull.SkinProvider; 14 | import team.unnamed.gui.menu.item.ItemClickable; 15 | import team.unnamed.gui.menu.listener.InventoryClickListener; 16 | import team.unnamed.gui.menu.listener.InventoryCloseListener; 17 | import team.unnamed.gui.menu.listener.InventoryOpenListener; 18 | import team.unnamed.gui.menu.type.MenuInventory; 19 | 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import java.util.concurrent.Executors; 23 | 24 | import static team.unnamed.gui.item.util.DecorateItemUtils.stainedPane; 25 | 26 | public class MenuPlugin extends JavaPlugin { 27 | 28 | @Override 29 | public void onEnable() { 30 | PluginManager pluginManager = Bukkit.getPluginManager(); 31 | pluginManager.registerEvents(new InventoryClickListener(), this); 32 | pluginManager.registerEvents(new InventoryOpenListener(), this); 33 | pluginManager.registerEvents(new InventoryCloseListener(this), this); 34 | 35 | String url = "https://textures.minecraft.net/texture/94c29dbcf4162f570e23a1bac185c3f0f79f3fe6fe3515f8ca5537c91da7e6e9"; 36 | 37 | SkinManager skinManager = new SkinManager(Executors.newSingleThreadExecutor()); 38 | 39 | skinManager.fetchSkin( 40 | SkinProvider.MINESKIN, 41 | SkinProvider.Type.URL, 42 | url 43 | ).whenComplete((skin, throwable) -> { 44 | if (throwable != null) { 45 | throwable.printStackTrace(); 46 | } else { 47 | System.out.println("Skin fetched correctly: " + skin); 48 | } 49 | }); 50 | 51 | getCommand("gui").setExecutor((sender, command, label, args) -> { 52 | Player player = (Player) sender; 53 | 54 | switch (args[0]) { 55 | case "default": { 56 | player.openInventory(MenuInventory.newBuilder("Test") 57 | .fillBorders(ItemClickable.onlyItem( 58 | SkullItemBuilder.create(skinManager.getSkin(url)) 59 | .name("sexo") 60 | .build() 61 | )) 62 | .item(ItemClickable.builder(22) 63 | .item(new ItemStack(Material.ENDER_PEARL)) 64 | .action(inventory -> { 65 | player.sendMessage("Testing"); 66 | player.closeInventory(); 67 | return true; 68 | }) 69 | .build()) 70 | .openAction(inventory -> { 71 | player.sendMessage("Opening..."); 72 | return false; 73 | }) 74 | .closeAction(inventory -> { 75 | player.sendMessage("Closing..."); 76 | 77 | return false; 78 | }) 79 | .build()); 80 | break; 81 | } 82 | case "paginated": { 83 | List entities = new ArrayList<>(); 84 | 85 | for (int i = 0; i <= 90; i++) { 86 | entities.add(ItemBuilder.builder(Material.ENDER_PEARL) 87 | .name("Item #" + i) 88 | .build() 89 | ); 90 | } 91 | 92 | ItemClickable decorationItem = ItemClickable.onlyItem( 93 | stainedPane(DyeColor.PINK) 94 | ); 95 | 96 | player.openInventory(MenuInventory 97 | .newPaginatedBuilder(ItemStack.class, "Paginated Test") 98 | .entities(entities) 99 | .itemsPerRow(7) 100 | .entityParser(ItemClickable::onlyItem) 101 | .skippedSlots(10, 16, 28, 34, 37, 38, 42, 43) 102 | .bounds(10, 44) 103 | .itemIfNoPreviousPage(decorationItem) 104 | .itemIfNoNextPage(decorationItem) 105 | .nextPageItem(page -> ItemClickable.onlyItem(ItemBuilder.builder(Material.ARROW) 106 | .name("Next page - " + page) 107 | .build())) 108 | .previousPageItem(page -> ItemClickable.onlyItem(ItemBuilder.builder(Material.ARROW) 109 | .name("Previous page - " + page) 110 | .build())) 111 | .layoutLines( 112 | "xxxxxxxxx", 113 | "xseeeeesx", 114 | "xeeeeeeex", 115 | "xseeeeesx", 116 | "xsseeessx", 117 | "xpxxxxxnx" 118 | ) 119 | .layoutItem('s', ItemClickable.onlyItem(stainedPane(DyeColor.WHITE))) 120 | .layoutItem('x', decorationItem) 121 | .build()); 122 | break; 123 | } 124 | default: break; 125 | } 126 | 127 | return true; 128 | }); 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /menu/plugin/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: ungui 2 | version: 0.0.1 3 | author: UnnamedTeam 4 | api-version: 1.13 5 | main: team.unnamed.gui.menu.plugin.MenuPlugin 6 | commands: 7 | gui: 8 | permission: "test.gui" -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # gui 2 | [![Build Status](https://img.shields.io/github/workflow/status/unnamed/gui/build/main)](https://github.com/unnamed/gui/actions/workflows/build.yml) 3 | [![MIT License](https://img.shields.io/badge/license-MIT-blue)](license.txt) 4 | [![Discord](https://img.shields.io/discord/683899335405994062)](https://discord.gg/xbba2fy) 5 | 6 | ### Documentation 7 | Check out the [documentation](https://unnamed.team/docs/gui). -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "gui" 2 | 3 | pluginManagement { 4 | repositories { 5 | gradlePluginPortal() 6 | maven("https://papermc.io/repo/repository/maven-public/") 7 | } 8 | } 9 | 10 | // item modules 11 | arrayOf("api", "skull-api").forEach { 12 | includePrefixed("item:$it") 13 | } 14 | 15 | // menu modules 16 | arrayOf("api", "plugin").forEach { 17 | includePrefixed("menu:$it") 18 | } 19 | 20 | // menu adapters 21 | arrayOf("1_8_R3", "1_16_R3", "1_17_R1", "1_18_R2", "1_19_R1").forEach { 22 | includePrefixed("menu:adapt:v$it") 23 | } 24 | 25 | fun includePrefixed(name: String) { 26 | val kebabName = name.replace(':', '-') 27 | val path = name.replace(':', '/') 28 | val baseName = "${rootProject.name}-$kebabName" 29 | 30 | include(baseName) 31 | project(":$baseName").projectDir = file(path) 32 | } --------------------------------------------------------------------------------