├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ ├── builds.yml │ ├── pages.yml │ └── pullrequest.yml ├── .gitignore ├── LICENSE ├── README.md ├── api ├── build.gradle.kts └── src │ ├── main │ └── java │ │ └── net │ │ └── pl3x │ │ └── guithium │ │ └── api │ │ ├── Guithium.java │ │ ├── Unsafe.java │ │ ├── action │ │ ├── ActionListener.java │ │ ├── ActionRegistry.java │ │ ├── RegisteredHandler.java │ │ └── actions │ │ │ ├── Action.java │ │ │ ├── Cancellable.java │ │ │ └── player │ │ │ ├── PlayerAction.java │ │ │ ├── PlayerJoinedAction.java │ │ │ └── screen │ │ │ ├── ScreenAction.java │ │ │ ├── ScreenClosedAction.java │ │ │ ├── ScreenOpenedAction.java │ │ │ └── element │ │ │ ├── ElementAction.java │ │ │ ├── ElementClickedAction.java │ │ │ ├── ElementToggledAction.java │ │ │ └── ElementValueChangedAction.java │ │ ├── gui │ │ ├── Screen.java │ │ ├── Vec2.java │ │ ├── Vec4.java │ │ ├── element │ │ │ ├── AbstractElement.java │ │ │ ├── Button.java │ │ │ ├── Checkbox.java │ │ │ ├── Circle.java │ │ │ ├── ClickableElement.java │ │ │ ├── Element.java │ │ │ ├── Gradient.java │ │ │ ├── Image.java │ │ │ ├── LabeledRect.java │ │ │ ├── Line.java │ │ │ ├── Radio.java │ │ │ ├── Rect.java │ │ │ ├── Slider.java │ │ │ ├── Text.java │ │ │ ├── Textbox.java │ │ │ └── ValueElement.java │ │ └── texture │ │ │ ├── Texture.java │ │ │ └── TextureManager.java │ │ ├── json │ │ ├── Gson.java │ │ ├── JsonObjectWrapper.java │ │ ├── JsonSerializable.java │ │ └── adapter │ │ │ ├── ComponentAdapter.java │ │ │ ├── ElementAdapter.java │ │ │ └── ScreenAdapter.java │ │ ├── key │ │ ├── Key.java │ │ └── Keyed.java │ │ ├── network │ │ ├── Connection.java │ │ ├── NetworkHandler.java │ │ ├── PacketListener.java │ │ └── packet │ │ │ ├── CloseScreenPacket.java │ │ │ ├── ElementChangedValuePacket.java │ │ │ ├── ElementClickedPacket.java │ │ │ ├── ElementPacket.java │ │ │ ├── HelloPacket.java │ │ │ ├── OpenScreenPacket.java │ │ │ ├── Packet.java │ │ │ └── TexturesPacket.java │ │ ├── player │ │ ├── PlayerManager.java │ │ └── WrappedPlayer.java │ │ ├── scheduler │ │ ├── AbstractScheduler.java │ │ └── Task.java │ │ └── util │ │ ├── Mathf.java │ │ ├── QuadConsumer.java │ │ └── TriConsumer.java │ └── test │ └── java │ └── net │ └── pl3x │ └── guithium │ └── api │ └── AnnotationTest.java ├── build.gradle.kts ├── docs ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── _config.yml ├── _includes │ ├── footer_custom.html │ ├── head_custom.html │ ├── header_custom.html │ ├── js │ │ └── custom.js │ ├── nav_footer_custom.html │ ├── search_placeholder_custom.html │ └── toc_heading_custom.html ├── _sass │ ├── color_schemes │ │ └── guithium.scss │ └── custom │ │ └── custom.scss ├── api.md ├── api │ ├── element │ │ ├── button.md │ │ ├── checkbox.md │ │ ├── circle.md │ │ ├── gradient.md │ │ ├── image.md │ │ ├── line.md │ │ ├── radio.md │ │ ├── slider.md │ │ ├── text.md │ │ └── textbox.md │ ├── elements.md │ ├── screen.md │ └── texture.md ├── assets │ └── images │ │ ├── fabric.png │ │ ├── favicon.ico │ │ ├── favicon.png │ │ ├── logos.svg │ │ ├── paper.png │ │ └── purpur.png ├── faq.md ├── getting-started │ ├── developers.md │ ├── index.md │ └── installation.md ├── index.md └── integrations.md ├── fabric ├── build.gradle.kts └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── pl3x │ │ │ └── guithium │ │ │ └── fabric │ │ │ ├── GuithiumMod.java │ │ │ ├── gui │ │ │ ├── Gfx.java │ │ │ ├── HudManager.java │ │ │ ├── element │ │ │ │ ├── RenderableButton.java │ │ │ │ ├── RenderableCheckbox.java │ │ │ │ ├── RenderableCircle.java │ │ │ │ ├── RenderableDuck.java │ │ │ │ ├── RenderableGradient.java │ │ │ │ ├── RenderableImage.java │ │ │ │ ├── RenderableLine.java │ │ │ │ ├── RenderableRadio.java │ │ │ │ ├── RenderableSlider.java │ │ │ │ ├── RenderableText.java │ │ │ │ ├── RenderableTextbox.java │ │ │ │ ├── RenderableWidget.java │ │ │ │ └── TextureSwappableWidget.java │ │ │ ├── screen │ │ │ │ ├── AbstractScreen.java │ │ │ │ └── RenderableScreen.java │ │ │ ├── test │ │ │ │ ├── RectWidget.java │ │ │ │ ├── TestScreen.java │ │ │ │ └── TextWidget.java │ │ │ └── texture │ │ │ │ ├── FabricTexture.java │ │ │ │ └── FabricTextureManager.java │ │ │ ├── mixin │ │ │ ├── AbstractWidgetMixin.java │ │ │ ├── GuiMixin.java │ │ │ └── RenderSystemMixin.java │ │ │ ├── network │ │ │ ├── FabricConnection.java │ │ │ ├── FabricNetworkHandler.java │ │ │ └── FabricPacketListener.java │ │ │ ├── scheduler │ │ │ └── Scheduler.java │ │ │ └── util │ │ │ ├── ComponentHelper.java │ │ │ ├── GifDecoder.java │ │ │ ├── Numbers.java │ │ │ └── RenderQueue.java │ └── resources │ │ ├── assets │ │ └── guithium │ │ │ ├── icon.png │ │ │ ├── lang │ │ │ └── en_us.json │ │ │ └── textures │ │ │ └── gui │ │ │ └── sprites │ │ │ └── widget │ │ │ ├── radio.png │ │ │ ├── radio_highlighted.png │ │ │ ├── radio_selected.png │ │ │ └── radio_selected_highlighted.png │ │ ├── fabric.mod.json │ │ ├── guithium.accesswidener │ │ └── guithium.mixins.json │ └── test │ └── java │ └── net │ └── pl3x │ └── guithium │ └── fabric │ └── AnnotationTest.java ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── paper ├── build.gradle.kts └── src │ ├── main │ ├── java │ │ └── net │ │ │ └── pl3x │ │ │ └── guithium │ │ │ └── plugin │ │ │ ├── GuithiumPlugin.java │ │ │ ├── listener │ │ │ └── PaperListener.java │ │ │ ├── network │ │ │ ├── PaperConnection.java │ │ │ ├── PaperNetworkHandler.java │ │ │ └── PaperPacketListener.java │ │ │ └── player │ │ │ ├── PaperPlayer.java │ │ │ └── PaperPlayerManager.java │ └── resources │ │ └── paper-plugin.yml │ └── test │ └── java │ └── net │ └── pl3x │ └── guithium │ └── plugin │ └── AnnotationTest.java └── settings.gradle.kts /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | *.bat text eol=crlf 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: BillyGalbreath 2 | -------------------------------------------------------------------------------- /.github/workflows/builds.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [ push ] 3 | 4 | env: 5 | SNAPSHOT: ${{ github.ref_name != 'master' }} 6 | 7 | jobs: 8 | run: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v4 12 | - uses: actions/setup-java@v4 13 | with: 14 | distribution: temurin 15 | java-version: 21 16 | - uses: gradle/actions/setup-gradle@v4 17 | 18 | - name: Restore gradle.properties 19 | run: | 20 | mkdir -p ~/.gradle/ 21 | echo "${GRADLE_PROPERTIES}" > ~/.gradle/gradle.properties 22 | env: 23 | GRADLE_PROPERTIES: ${{ secrets.GRADLE_PROPERTIES }} 24 | 25 | - name: Read Version Catalog 26 | uses: SebRollen/toml-action@v1.2.0 27 | id: version 28 | with: 29 | file: "gradle/libs.versions.toml" 30 | field: "versions.guithium" 31 | 32 | - name: Set Version Number 33 | run: | 34 | VERSION=${{ steps.version.outputs.value }} 35 | if [ "$SNAPSHOT" == "true" ]; then 36 | VERSION=$VERSION-SNAPSHOT 37 | fi 38 | echo "VERSION=$VERSION" >> $GITHUB_ENV 39 | echo "VERSION is $VERSION" 40 | 41 | - name: Build Release 42 | if: ${{ env.SNAPSHOT != 'true' }} 43 | run: ./gradlew build publish modrinth --stacktrace --no-daemon 44 | env: 45 | MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }} 46 | COMMIT_MESSAGE: ${{ join(github.event.commits.*.message, '
') }} 47 | 48 | - name: Build Snapshot 49 | if: ${{ env.SNAPSHOT == 'true' }} 50 | run: ./gradlew build publish --stacktrace --no-daemon 51 | 52 | - name: Upload Snapshot Artifact 53 | if: ${{ env.SNAPSHOT == 'true' }} 54 | uses: actions/upload-artifact@v4 55 | with: 56 | name: "Guithium-${{ env.VERSION }}" 57 | path: build/libs/*.jar 58 | 59 | - name: Notify Discord 60 | if: ${{ env.SNAPSHOT != 'true' && success() }} 61 | uses: sarisia/actions-status-discord@v1 62 | with: 63 | webhook: ${{ secrets.DISCORD_BUILDS_WEBHOOK }} 64 | nodetail: true 65 | title: New build of Guithium is ready! 66 | description: | 67 | Version ${{ env.VERSION }} 68 | Click [here](https://modrinth.com/mod/guithium) to download! 69 | 70 | - name: Notify Discord 71 | if: ${{ env.SNAPSHOT != 'true' && failure() }} 72 | uses: sarisia/actions-status-discord@v1 73 | with: 74 | webhook: ${{ secrets.DISCORD_BUILDS_WEBHOOK }} 75 | nodetail: true 76 | title: Build Failure! 77 | color: 0xff0000 78 | description: | 79 | Version ${{ env.VERSION }} 80 | Click [here](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) to view the run! 81 | -------------------------------------------------------------------------------- /.github/workflows/pages.yml: -------------------------------------------------------------------------------- 1 | name: Update Docs 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | paths: [ "docs/**" ] 7 | 8 | # Allows you to run this workflow manually from the Actions tab 9 | workflow_dispatch: 10 | 11 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 12 | permissions: 13 | contents: read 14 | pages: write 15 | id-token: write 16 | 17 | # Allow one concurrent deployment 18 | concurrency: 19 | group: "pages" 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | build: 24 | runs-on: ubuntu-latest 25 | defaults: 26 | run: 27 | working-directory: docs 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v4 31 | - name: Setup Ruby 32 | uses: ruby/setup-ruby@v1 33 | with: 34 | ruby-version: '3.3' 35 | bundler-cache: true 36 | cache-version: 0 37 | working-directory: '${{ github.workspace }}/docs' 38 | - name: Bundle install 39 | run: bundle install 40 | env: 41 | JEKYLL_ENV: production 42 | - name: Setup Pages 43 | id: pages 44 | uses: actions/configure-pages@v5 45 | - name: Build with Jekyll 46 | # Outputs to the './_site' directory by default 47 | run: bundle exec jekyll build --baseurl "${{ steps.pages.outputs.base_path }}" 48 | env: 49 | JEKYLL_ENV: production 50 | - name: Upload artifact 51 | # Automatically uploads an artifact from the 'docs/_site' directory by default 52 | uses: actions/upload-pages-artifact@v3 53 | with: 54 | path: docs/_site/ 55 | 56 | deploy: 57 | environment: 58 | name: github-pages 59 | url: ${{ steps.deployment.outputs.page_url }} 60 | runs-on: ubuntu-latest 61 | needs: build 62 | steps: 63 | - name: Deploy to GitHub Pages 64 | id: deployment 65 | uses: actions/deploy-pages@v4 66 | -------------------------------------------------------------------------------- /.github/workflows/pullrequest.yml: -------------------------------------------------------------------------------- 1 | name: Pull Requests 2 | on: [ pull_request ] 3 | 4 | jobs: 5 | run: 6 | if: github.repository != github.event.pull_request.head.repo.full_name 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | - uses: actions/setup-java@v4 11 | with: 12 | distribution: temurin 13 | java-version: 21 14 | - uses: gradle/actions/setup-gradle@v4 15 | - name: Build 16 | run: ./gradlew build --stacktrace --no-daemon 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # User-specific stuff 2 | .idea/ 3 | 4 | *.iml 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | out/ 10 | 11 | # Eclipse 12 | .classpath 13 | .project 14 | .settings/ 15 | plugin/bin/ 16 | api/bin/ 17 | 18 | # Compiled class file 19 | *.class 20 | 21 | # Log file 22 | *.log 23 | 24 | # BlueJ files 25 | *.ctxt 26 | 27 | # Package Files # 28 | *.war 29 | *.nar 30 | *.ear 31 | *.zip 32 | *.tar.gz 33 | *.rar 34 | 35 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 36 | hs_err_pid* 37 | 38 | *~ 39 | 40 | # temporary files which can be created if a process still has a handle open of a deleted file 41 | .fuse_hidden* 42 | 43 | # KDE directory preferences 44 | .directory 45 | 46 | # Linux trash folder which might appear on any partition or disk 47 | .Trash-* 48 | 49 | # .nfs files are created when an open file is removed but is still being accessed 50 | .nfs* 51 | 52 | # General 53 | .DS_Store 54 | .AppleDouble 55 | .LSOverride 56 | 57 | # Icon must end with two \r 58 | Icon 59 | 60 | # Thumbnails 61 | ._* 62 | 63 | # Files that might appear in the root of a volume 64 | .DocumentRevisions-V100 65 | .fseventsd 66 | .Spotlight-V100 67 | .TemporaryItems 68 | .Trashes 69 | .VolumeIcon.icns 70 | .com.apple.timemachine.donotpresent 71 | 72 | # Directories potentially created on remote AFP share 73 | .AppleDB 74 | .AppleDesktop 75 | Network Trash Folder 76 | Temporary Items 77 | .apdisk 78 | 79 | # Windows thumbnail cache files 80 | Thumbs.db 81 | Thumbs.db:encryptable 82 | ehthumbs.db 83 | ehthumbs_vista.db 84 | 85 | # Dump file 86 | *.stackdump 87 | 88 | # Folder config file 89 | [Dd]esktop.ini 90 | 91 | # Recycle Bin used on file shares 92 | $RECYCLE.BIN/ 93 | 94 | # Windows Installer files 95 | *.cab 96 | *.msi 97 | *.msix 98 | *.msm 99 | *.msp 100 | 101 | # Windows shortcuts 102 | *.lnk 103 | 104 | target/ 105 | 106 | pom.xml.tag 107 | pom.xml.releaseBackup 108 | pom.xml.versionsBackup 109 | pom.xml.next 110 | 111 | release.properties 112 | dependency-reduced-pom.xml 113 | buildNumber.properties 114 | .mvn/timing.properties 115 | .mvn/wrapper/maven-wrapper.jar 116 | .flattened-pom.xml 117 | 118 | # Common working directory 119 | run/ 120 | fabric/run/ 121 | build 122 | .gradle 123 | /*.jar 124 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022-2025 William Blake Galbreath (BillyGalbreath) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | `maven-publish` 3 | alias(libs.plugins.fix.javadoc) 4 | } 5 | 6 | java { 7 | withSourcesJar() 8 | withJavadocJar() 9 | } 10 | 11 | repositories { 12 | // not sure what's different about this one, 13 | // but it won't work from settings.gradle.kts 14 | mavenCentral() 15 | } 16 | 17 | dependencies { 18 | compileOnly(libs.adventure.api.get()) 19 | compileOnly(libs.adventure.gson.get()) 20 | 21 | compileOnly(libs.apache.get()) 22 | compileOnly(libs.gson.get()) 23 | compileOnly(libs.guava.get()) 24 | compileOnly(libs.annotations.get()) 25 | compileOnly(libs.slf4j.get()) 26 | } 27 | 28 | tasks { 29 | javadoc { 30 | val name = rootProject.name.replaceFirstChar { it.uppercase() } 31 | val stdopts = options as StandardJavadocDocletOptions 32 | stdopts.encoding = Charsets.UTF_8.name() 33 | stdopts.overview = "src/main/javadoc/overview.html" 34 | stdopts.use() 35 | stdopts.isDocFilesSubDirs = true 36 | stdopts.windowTitle = "$name $version API Documentation" 37 | stdopts.docTitle = "

$name $version API

" 38 | stdopts.header = """""" 39 | stdopts.bottom = "Copyright © 2025 William Blake Galbreath" 40 | stdopts.linkSource(true) 41 | stdopts.addBooleanOption("html5", true) 42 | stdopts.links( 43 | "https://guava.dev/releases/${libs.versions.guava.get()}/api/docs/", 44 | "https://javadoc.io/doc/org.slf4j/slf4j-api/${libs.versions.slf4j.get()}/", 45 | "https://javadoc.io/doc/org.jetbrains/annotations/${libs.versions.annotations.get()}/" 46 | ) 47 | } 48 | 49 | withType { 50 | configureEach { 51 | newLineOnMethodParameters.set(false) 52 | keepOriginal.set(false) 53 | } 54 | } 55 | } 56 | 57 | publishing { 58 | repositories { 59 | maven { 60 | name = "reposilite" 61 | url = uri("https://repo.pl3x.net/public/") 62 | credentials(PasswordCredentials::class) 63 | authentication.create("basic") 64 | } 65 | } 66 | publications { 67 | create("mavenJava") { 68 | groupId = "${project.group}" 69 | artifactId = "${rootProject.name}-${project.name}" 70 | version = "${project.version}" 71 | from(components["java"]) 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/Guithium.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api; 2 | 3 | import net.pl3x.guithium.api.action.ActionRegistry; 4 | import net.pl3x.guithium.api.gui.texture.TextureManager; 5 | import net.pl3x.guithium.api.network.NetworkHandler; 6 | import net.pl3x.guithium.api.player.PlayerManager; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.jetbrains.annotations.NotNull; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | 12 | /** 13 | * The Guithium API. 14 | */ 15 | public interface Guithium { 16 | /** 17 | * The identifier for this mod. 18 | */ 19 | String MOD_ID = "guithium"; 20 | 21 | /** 22 | * The protocol version. 23 | *

24 | * This is used to ensure client and server can correctly talk to each other. 25 | */ 26 | int PROTOCOL = 1; 27 | 28 | /** 29 | * bStats ID number for Guithium. 30 | */ 31 | int BSTATS_ID = 25813; 32 | 33 | /** 34 | * Guithium's internal logger. 35 | *

36 | * For internal use. Please use your own logger. 37 | */ 38 | Logger logger = LoggerFactory.getLogger(StringUtils.capitalize(Guithium.MOD_ID)); 39 | 40 | /** 41 | * Get the Guithium API instance. 42 | * 43 | * @return Instance of Guithium API 44 | */ 45 | @NotNull 46 | static Guithium api() { 47 | return Provider.api(); 48 | } 49 | 50 | /** 51 | * Get the Guithium's version. 52 | * 53 | * @return Guithium's version 54 | */ 55 | @NotNull 56 | String getVersion(); 57 | 58 | /** 59 | * Get the action registry instance. 60 | * 61 | * @return Action registry 62 | */ 63 | @NotNull 64 | ActionRegistry getActionRegistry(); 65 | 66 | /** 67 | * Get the network handler instance. 68 | * 69 | * @return Network handler 70 | */ 71 | @NotNull 72 | NetworkHandler getNetworkHandler(); 73 | 74 | /** 75 | * Get the player manager instance. 76 | * 77 | * @return Player manager 78 | */ 79 | @NotNull 80 | PlayerManager getPlayerManager(); 81 | 82 | /** 83 | * Get the texture manager instance. 84 | * 85 | * @return Texture manager 86 | */ 87 | @NotNull 88 | TextureManager getTextureManager(); 89 | 90 | /** 91 | * The Guithium instance provider. 92 | *

93 | * For internal use. 94 | */ 95 | final class Provider { 96 | static Guithium api; 97 | 98 | private Provider() { 99 | // Empty constructor to pacify javadoc lint 100 | } 101 | 102 | @NotNull 103 | private static Guithium api() { 104 | return Provider.api; 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/Unsafe.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | import org.jetbrains.annotations.NonNls; 9 | 10 | /** 11 | * Unsafe utils 12 | */ 13 | public abstract class Unsafe { 14 | private Unsafe() { 15 | // Empty constructor to pacify javadoc lint 16 | } 17 | 18 | /** 19 | * Cast object to T 20 | * 21 | * @param obj Object to cast 22 | * @param Type to cast to 23 | * @return Object as T 24 | */ 25 | @UnknownNullability 26 | @SuppressWarnings("unchecked") 27 | public static T cast(@UnknownNullability Object obj) { 28 | return (T) obj; 29 | } 30 | 31 | /** 32 | * An element annotated with {@code UnknownNullability} claims that no specific nullability 33 | * should be assumed by static analyzer. The unconditional dereference of the annotated value 34 | * should not trigger a static analysis warning by default (though static analysis tool may have 35 | * an option to perform stricter analysis and issue warnings for {@code @UnknownNullability} as well). 36 | * It's mainly useful at method return types to mark methods that may occasionally 37 | * return {@code null} but in many cases, user knows that in this particular code path 38 | * {@code null} is not possible, so producing a warning would be annoying. 39 | * 40 | * @since 21.0.0 41 | */ 42 | @Documented 43 | @Retention(RetentionPolicy.CLASS) 44 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE, ElementType.TYPE_USE}) 45 | public @interface UnknownNullability { 46 | /** 47 | * Human-readable description of the circumstances, in which the type is nullable. 48 | * 49 | * @return textual reason when the annotated value could be null, for documentation purposes. 50 | */ 51 | @NonNls String value() default ""; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/ActionListener.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Simple interface for tagging all action listeners. 10 | */ 11 | public interface ActionListener { 12 | /** 13 | * An annotation to mark methods as being action handler methods. 14 | */ 15 | @Target(ElementType.METHOD) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @interface ActionHandler { 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/ActionRegistry.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | import java.util.List; 6 | import net.pl3x.guithium.api.Guithium; 7 | import net.pl3x.guithium.api.action.actions.Action; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | /** 11 | * The action registry. 12 | */ 13 | public class ActionRegistry { 14 | /** 15 | * Create a new action registry 16 | */ 17 | public ActionRegistry() { 18 | // Empty constructor to pacify javadoc lint 19 | } 20 | 21 | /** 22 | * Call an action for plugins to listen to. 23 | * 24 | * @param action The action to call 25 | */ 26 | public void callAction(@NotNull Action action) { 27 | for (RegisteredHandler handler : action.getHandlers()) { 28 | try { 29 | handler.execute(action); 30 | } catch (Throwable t) { 31 | Guithium.logger.error(t.getMessage(), t); 32 | } 33 | } 34 | } 35 | 36 | /** 37 | * Registers all the actions in the given listener class. 38 | * 39 | * @param listener Action listener to register 40 | */ 41 | public void register(@NotNull ActionListener listener) { 42 | for (Method method : listener.getClass().getMethods()) { 43 | if (method.getDeclaredAnnotation(ActionListener.ActionHandler.class) == null) { 44 | continue; 45 | } 46 | Class[] params = method.getParameterTypes(); 47 | if (params.length == 0) { 48 | continue; 49 | } 50 | Class action = params[0]; 51 | if (!Action.class.isAssignableFrom(action)) { 52 | continue; 53 | } 54 | try { 55 | Field handlers = action.getDeclaredField("handlers"); 56 | handlers.setAccessible(true); 57 | 58 | @SuppressWarnings("unchecked") 59 | List list = (List) handlers.get(action); 60 | 61 | RegisteredHandler handler = new RegisteredHandler(listener, method); 62 | list.add(handler); 63 | } catch (NoSuchFieldException | IllegalAccessException e) { 64 | throw new RuntimeException(e); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/RegisteredHandler.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | import net.pl3x.guithium.api.action.actions.Action; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Represents a registered action handler. 10 | */ 11 | public class RegisteredHandler { 12 | private final ActionListener listener; 13 | private Method method; 14 | 15 | /** 16 | * Create a new registered action handler. 17 | * 18 | * @param listener Action listener being registered 19 | * @param method Method being registered 20 | */ 21 | public RegisteredHandler(@NotNull ActionListener listener, @NotNull Method method) { 22 | this.listener = listener; 23 | setMethod(method); 24 | } 25 | 26 | /** 27 | * Gets the registered action listener. 28 | * 29 | * @return Action listener 30 | */ 31 | @NotNull 32 | public ActionListener getListener() { 33 | return this.listener; 34 | } 35 | 36 | /** 37 | * Gets the registered method. 38 | * 39 | * @return Action method 40 | */ 41 | @NotNull 42 | public Method getMethod() { 43 | return this.method; 44 | } 45 | 46 | private void setMethod(@NotNull Method method) { 47 | method.setAccessible(true); 48 | this.method = method; 49 | } 50 | 51 | /** 52 | * Execute the method for the given action. 53 | * 54 | * @param action Action to call method on 55 | * @throws InvocationTargetException if the method throws an exception 56 | * @throws IllegalAccessException if this Method object is enforcing Java language access 57 | * control and the underlying method is inaccessible 58 | */ 59 | public void execute(@NotNull Action action) throws InvocationTargetException, IllegalAccessException { 60 | getMethod().invoke(getListener(), action); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/Action.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions; 2 | 3 | import java.util.List; 4 | import net.pl3x.guithium.api.action.RegisteredHandler; 5 | import org.jetbrains.annotations.NotNull; 6 | 7 | /** 8 | * Represents an action. This is similar to Bukkit events. 9 | */ 10 | public abstract class Action { 11 | /** 12 | * Create a new action. 13 | */ 14 | public Action() { 15 | // Empty constructor to pacify javadoc lint 16 | } 17 | 18 | /** 19 | * Get a list of all the registered handlers for this action. 20 | *

21 | * For internal use. 22 | * 23 | * @return List of registered handlers 24 | */ 25 | @NotNull 26 | public abstract List getHandlers(); 27 | } 28 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/Cancellable.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions; 2 | 3 | /** 4 | * Represents a cancellable state. 5 | */ 6 | public interface Cancellable { 7 | /** 8 | * Gets the cancellation state of this action. A cancelled action will not 9 | * be executed in the server, but will still pass to other plugins. 10 | * 11 | * @return True if this action is cancelled 12 | */ 13 | boolean isCancelled(); 14 | 15 | /** 16 | * Sets the cancellation state of this action. A cancelled action will not 17 | * be executed in the server, but will still pass to other plugins. 18 | * 19 | * @param cancelled True if you wish to cancel this action 20 | */ 21 | void setCancelled(boolean cancelled); 22 | } 23 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/PlayerAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player; 2 | 3 | import com.google.common.base.Preconditions; 4 | import net.pl3x.guithium.api.action.actions.Action; 5 | import net.pl3x.guithium.api.player.WrappedPlayer; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Action that fires when a player performs an action. 10 | */ 11 | public abstract class PlayerAction extends Action { 12 | private final WrappedPlayer player; 13 | 14 | /** 15 | * Create a new action for when a player performs an action. 16 | * 17 | * @param player Player that performed the action 18 | */ 19 | public PlayerAction(@NotNull WrappedPlayer player) { 20 | Preconditions.checkNotNull(player, "Player cannot be null."); 21 | this.player = player; 22 | } 23 | 24 | /** 25 | * Get the player that performed this action. 26 | * 27 | * @return Player 28 | */ 29 | @NotNull 30 | public WrappedPlayer getPlayer() { 31 | return this.player; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/PlayerJoinedAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import net.pl3x.guithium.api.action.RegisteredHandler; 6 | import net.pl3x.guithium.api.network.packet.HelloPacket; 7 | import net.pl3x.guithium.api.player.WrappedPlayer; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | /** 11 | * Action that fires when a player joins the server and responds to the {@link HelloPacket}. 12 | *

13 | * This is different from Bukkit's PlayerJoinEvent because with this action 14 | * the player is guaranteed to be ready to receive packets from the server. 15 | */ 16 | public class PlayerJoinedAction extends PlayerAction { 17 | private static final List handlers = new ArrayList<>(); 18 | 19 | /** 20 | * Create a new action for when a player responds to the {@link HelloPacket}. 21 | * 22 | * @param player Player that performed the action 23 | */ 24 | public PlayerJoinedAction(@NotNull WrappedPlayer player) { 25 | super(player); 26 | } 27 | 28 | @Override 29 | @NotNull 30 | public List getHandlers() { 31 | return handlers; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/ScreenAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player.screen; 2 | 3 | import net.pl3x.guithium.api.action.actions.player.PlayerAction; 4 | import net.pl3x.guithium.api.gui.Screen; 5 | import net.pl3x.guithium.api.player.WrappedPlayer; 6 | import org.jetbrains.annotations.NotNull; 7 | 8 | /** 9 | * Action that fires when a screen action is performed. 10 | */ 11 | public abstract class ScreenAction extends PlayerAction { 12 | private final Screen screen; 13 | 14 | /** 15 | * Create a new action for when a screen action is performed. 16 | * 17 | * @param player Player that performed the action 18 | * @param screen Screen action was performed on 19 | */ 20 | public ScreenAction(@NotNull WrappedPlayer player, @NotNull Screen screen) { 21 | super(player); 22 | this.screen = screen; 23 | } 24 | 25 | /** 26 | * Get the screen involved in this action. 27 | * 28 | * @return Screen 29 | */ 30 | @NotNull 31 | public Screen getScreen() { 32 | return this.screen; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/ScreenClosedAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player.screen; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import net.pl3x.guithium.api.action.RegisteredHandler; 6 | import net.pl3x.guithium.api.gui.Screen; 7 | import net.pl3x.guithium.api.player.WrappedPlayer; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | /** 11 | * Action that fires when a screen is closed. 12 | */ 13 | public class ScreenClosedAction extends ScreenAction { 14 | private static final List handlers = new ArrayList<>(); 15 | 16 | /** 17 | * Create a new action for when a screen is closed. 18 | * 19 | * @param player Player that performed the action 20 | * @param screen Screen action was performed on 21 | */ 22 | public ScreenClosedAction(@NotNull WrappedPlayer player, @NotNull Screen screen) { 23 | super(player, screen); 24 | } 25 | 26 | @Override 27 | @NotNull 28 | public List getHandlers() { 29 | return handlers; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/ScreenOpenedAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player.screen; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import net.pl3x.guithium.api.action.RegisteredHandler; 6 | import net.pl3x.guithium.api.gui.Screen; 7 | import net.pl3x.guithium.api.player.WrappedPlayer; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | /** 11 | * Action that fires when a screen is opened. 12 | */ 13 | public class ScreenOpenedAction extends ScreenAction { 14 | private static final List handlers = new ArrayList<>(); 15 | 16 | /** 17 | * Create a new action for when a screen is opened. 18 | * 19 | * @param player Player that performed the action 20 | * @param screen Screen action was performed on 21 | */ 22 | public ScreenOpenedAction(@NotNull WrappedPlayer player, @NotNull Screen screen) { 23 | super(player, screen); 24 | } 25 | 26 | @Override 27 | @NotNull 28 | public List getHandlers() { 29 | return handlers; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/element/ElementAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player.screen.element; 2 | 3 | import net.pl3x.guithium.api.action.actions.player.screen.ScreenAction; 4 | import net.pl3x.guithium.api.gui.Screen; 5 | import net.pl3x.guithium.api.gui.element.Element; 6 | import net.pl3x.guithium.api.player.WrappedPlayer; 7 | import org.jetbrains.annotations.NotNull; 8 | 9 | /** 10 | * Action that fires when an element action is performed. 11 | * 12 | * @param Type of element 13 | */ 14 | public abstract class ElementAction extends ScreenAction { 15 | private final T element; 16 | 17 | /** 18 | * Create a new action for when an element action is performed. 19 | * 20 | * @param player Player that performed the action 21 | * @param screen Screen action was performed on 22 | * @param element Element action was performed on 23 | */ 24 | public ElementAction(@NotNull WrappedPlayer player, @NotNull Screen screen, @NotNull T element) { 25 | super(player, screen); 26 | this.element = element; 27 | } 28 | 29 | /** 30 | * Get the element involved in this action. 31 | * 32 | * @return Element 33 | */ 34 | @NotNull 35 | public T getElement() { 36 | return this.element; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/element/ElementClickedAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player.screen.element; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import net.pl3x.guithium.api.action.RegisteredHandler; 6 | import net.pl3x.guithium.api.action.actions.Cancellable; 7 | import net.pl3x.guithium.api.gui.Screen; 8 | import net.pl3x.guithium.api.gui.element.Element; 9 | import net.pl3x.guithium.api.player.WrappedPlayer; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | /** 13 | * Action that fires when a clickable element is clicked. 14 | * 15 | * @param Type of element 16 | */ 17 | public class ElementClickedAction extends ElementAction implements Cancellable { 18 | private static final List handlers = new ArrayList<>(); 19 | 20 | private boolean cancelled; 21 | 22 | /** 23 | * Create a new action for when a clickable element is clicked. 24 | * 25 | * @param player Player that performed the action 26 | * @param screen Screen action was performed on 27 | * @param element Element action was performed on 28 | */ 29 | public ElementClickedAction(@NotNull WrappedPlayer player, @NotNull Screen screen, @NotNull T element) { 30 | super(player, screen, element); 31 | } 32 | 33 | @Override 34 | public boolean isCancelled() { 35 | return this.cancelled; 36 | } 37 | 38 | @Override 39 | public void setCancelled(boolean cancelled) { 40 | this.cancelled = cancelled; 41 | } 42 | 43 | @Override 44 | @NotNull 45 | public List getHandlers() { 46 | return handlers; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/element/ElementToggledAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player.screen.element; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import net.pl3x.guithium.api.action.RegisteredHandler; 6 | import net.pl3x.guithium.api.action.actions.Cancellable; 7 | import net.pl3x.guithium.api.gui.Screen; 8 | import net.pl3x.guithium.api.gui.element.Element; 9 | import net.pl3x.guithium.api.player.WrappedPlayer; 10 | import org.jetbrains.annotations.NotNull; 11 | 12 | /** 13 | * Action that fires when a checkbox is toggled. 14 | * 15 | * @param Type of element 16 | */ 17 | public class ElementToggledAction extends ElementClickedAction implements Cancellable { 18 | private static final List handlers = new ArrayList<>(); 19 | 20 | private boolean selected; 21 | 22 | /** 23 | * Create a new action for when a togglable element is toggled. 24 | * 25 | * @param player Player that performed the action 26 | * @param screen Screen action was performed on 27 | * @param element Element action was performed on 28 | * @param selected New selected state of element 29 | */ 30 | public ElementToggledAction(@NotNull WrappedPlayer player, @NotNull Screen screen, @NotNull T element, boolean selected) { 31 | super(player, screen, element); 32 | this.selected = selected; 33 | } 34 | 35 | /** 36 | * Get the new selected state of this element. 37 | * 38 | * @return New element selected state 39 | */ 40 | public boolean isSelected() { 41 | return this.selected; 42 | } 43 | 44 | /** 45 | * Set the new selected state of this element. 46 | * 47 | * @param selected New element selected state 48 | */ 49 | public void setSelected(boolean selected) { 50 | this.selected = selected; 51 | } 52 | 53 | @Override 54 | @NotNull 55 | public List getHandlers() { 56 | return handlers; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/action/actions/player/screen/element/ElementValueChangedAction.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.action.actions.player.screen.element; 2 | 3 | import com.google.common.base.Preconditions; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import net.pl3x.guithium.api.action.RegisteredHandler; 7 | import net.pl3x.guithium.api.action.actions.Cancellable; 8 | import net.pl3x.guithium.api.gui.Screen; 9 | import net.pl3x.guithium.api.gui.element.ValueElement; 10 | import net.pl3x.guithium.api.player.WrappedPlayer; 11 | import org.jetbrains.annotations.NotNull; 12 | 13 | /** 14 | * Action that fires when an element's value is changed. 15 | * 16 | * @param Type of element 17 | * @param Type of value 18 | */ 19 | public class ElementValueChangedAction, V> extends ElementClickedAction implements Cancellable { 20 | private static final List handlers = new ArrayList<>(); 21 | 22 | private V value; 23 | 24 | /** 25 | * Create a new action for when an element's value is changed. 26 | * 27 | * @param player Player that performed the action 28 | * @param screen Screen action was performed on 29 | * @param element Element action was performed on 30 | * @param value New value of element 31 | */ 32 | public ElementValueChangedAction(@NotNull WrappedPlayer player, @NotNull Screen screen, @NotNull T element, @NotNull V value) { 33 | super(player, screen, element); 34 | setValue(value); 35 | } 36 | 37 | /** 38 | * Get the new value of this element. 39 | * 40 | * @return New element value 41 | */ 42 | @NotNull 43 | public V getValue() { 44 | return this.value; 45 | } 46 | 47 | /** 48 | * Set the new value of this element. 49 | * 50 | * @param value New element value 51 | */ 52 | public void setValue(@NotNull V value) { 53 | Preconditions.checkNotNull(value, "value cannot be null"); 54 | this.value = value; 55 | } 56 | 57 | @Override 58 | @NotNull 59 | public List getHandlers() { 60 | return handlers; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/gui/Vec2.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.gui; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import net.pl3x.guithium.api.json.Gson; 6 | import net.pl3x.guithium.api.json.JsonObjectWrapper; 7 | import net.pl3x.guithium.api.json.JsonSerializable; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | /** 11 | * Represents a size (x and y) 12 | * 13 | * @param x X value 14 | * @param y Y value 15 | */ 16 | public record Vec2(float x, float y) implements JsonSerializable { 17 | /** 18 | * Vec2 of 0,0 19 | */ 20 | public static final Vec2 ZERO = Vec2.of(0, 0); 21 | 22 | /** 23 | * Vec2 of 1,1 24 | */ 25 | public static final Vec2 ONE = Vec2.of(1, 1); 26 | 27 | /** 28 | * Create a new 2D vector. 29 | * 30 | * @param x X value 31 | * @param y Y value 32 | * @return A new 2D vector 33 | */ 34 | @NotNull 35 | public static Vec2 of(float x, float y) { 36 | return new Vec2(x, y); 37 | } 38 | 39 | /** 40 | * Get the X value. 41 | * 42 | * @return The X value 43 | */ 44 | public float getX() { 45 | return x(); 46 | } 47 | 48 | /** 49 | * Get the Y value. 50 | * 51 | * @return The Y value 52 | */ 53 | public float getY() { 54 | return y(); 55 | } 56 | 57 | @Override 58 | @NotNull 59 | public String toString() { 60 | return String.format("%s%s", getClass().getSimpleName(), Gson.toJson(this)); 61 | } 62 | 63 | @Override 64 | @NotNull 65 | public JsonElement toJson() { 66 | JsonObjectWrapper json = new JsonObjectWrapper(); 67 | json.addProperty("x", getX()); 68 | json.addProperty("y", getY()); 69 | return json.getJsonObject(); 70 | } 71 | 72 | /** 73 | * Create a new 2D vector from Json. 74 | * 75 | * @param json Json representation of a 2D vector 76 | * @return A new 2D vector 77 | */ 78 | @NotNull 79 | public static Vec2 fromJson(@NotNull JsonObject json) { 80 | return new Vec2( 81 | !json.has("x") ? 0 : json.get("x").getAsFloat(), 82 | !json.has("y") ? 0 : json.get("y").getAsFloat() 83 | ); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/gui/Vec4.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.gui; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import net.pl3x.guithium.api.json.Gson; 6 | import net.pl3x.guithium.api.json.JsonObjectWrapper; 7 | import net.pl3x.guithium.api.json.JsonSerializable; 8 | import org.jetbrains.annotations.NotNull; 9 | 10 | /** 11 | * Represents a 4D vector. 12 | * 13 | * @param x X value 14 | * @param y Y value 15 | * @param z Z value 16 | * @param w W value 17 | */ 18 | public record Vec4(float x, float y, float z, float w) implements JsonSerializable { 19 | /** 20 | * Vec4 of 0,0,0,0 21 | */ 22 | public static final Vec4 ZERO = Vec4.of(0, 0, 0, 0); 23 | 24 | /** 25 | * Vec4 of 1,1,1,1 26 | */ 27 | public static final Vec4 ONE = Vec4.of(1, 1, 1, 1); 28 | 29 | /** 30 | * Create a new 4D vector. 31 | * 32 | * @param x X value 33 | * @param y Y value 34 | * @param z Z value 35 | * @param w W value 36 | * @return A new 4D vector 37 | */ 38 | @NotNull 39 | public static Vec4 of(float x, float y, float z, float w) { 40 | return new Vec4(x, y, z, w); 41 | } 42 | 43 | /** 44 | * Get the X value. 45 | * 46 | * @return The X value 47 | */ 48 | public float getX() { 49 | return x(); 50 | } 51 | 52 | /** 53 | * Get the Y value. 54 | * 55 | * @return The Y value 56 | */ 57 | public float getY() { 58 | return y(); 59 | } 60 | 61 | /** 62 | * Get the Z value. 63 | * 64 | * @return The Z value 65 | */ 66 | public float getZ() { 67 | return z(); 68 | } 69 | 70 | /** 71 | * Get the W value. 72 | * 73 | * @return The W value 74 | */ 75 | public float getW() { 76 | return w(); 77 | } 78 | 79 | @Override 80 | @NotNull 81 | public String toString() { 82 | return String.format("%s%s", getClass().getSimpleName(), Gson.toJson(this)); 83 | } 84 | 85 | @Override 86 | @NotNull 87 | public JsonElement toJson() { 88 | JsonObjectWrapper json = new JsonObjectWrapper(); 89 | json.addProperty("x", getX()); 90 | json.addProperty("y", getY()); 91 | json.addProperty("z", getZ()); 92 | json.addProperty("w", getW()); 93 | return json.getJsonObject(); 94 | } 95 | 96 | /** 97 | * Create a new 4D vector from Json. 98 | * 99 | * @param json Json representation of a 4D vector 100 | * @return A new 4D vector 101 | */ 102 | @NotNull 103 | public static Vec4 fromJson(@NotNull JsonObject json) { 104 | return new Vec4( 105 | !json.has("x") ? 0 : json.get("x").getAsFloat(), 106 | !json.has("y") ? 0 : json.get("y").getAsFloat(), 107 | !json.has("z") ? 0 : json.get("z").getAsFloat(), 108 | !json.has("w") ? 0 : json.get("w").getAsFloat() 109 | ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /api/src/main/java/net/pl3x/guithium/api/gui/element/Button.java: -------------------------------------------------------------------------------- 1 | package net.pl3x.guithium.api.gui.element; 2 | 3 | import com.google.common.base.Preconditions; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import java.util.Objects; 7 | import net.pl3x.guithium.api.json.JsonObjectWrapper; 8 | import net.pl3x.guithium.api.key.Key; 9 | import org.jetbrains.annotations.NotNull; 10 | import org.jetbrains.annotations.Nullable; 11 | 12 | /** 13 | * Represents a button element. 14 | */ 15 | public class Button extends LabeledRect