diff --git a/.config/checkstyle/checkstyle.xml b/.config/checkstyle/checkstyle.xml
new file mode 100644
index 00000000..eaf0a660
--- /dev/null
+++ b/.config/checkstyle/checkstyle.xml
@@ -0,0 +1,491 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.config/checkstyle/suppressions.xml b/.config/checkstyle/suppressions.xml
new file mode 100644
index 00000000..24b61959
--- /dev/null
+++ b/.config/checkstyle/suppressions.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.config/spotbugs/suppressions.xml b/.config/spotbugs/suppressions.xml
new file mode 100644
index 00000000..2ab22102
--- /dev/null
+++ b/.config/spotbugs/suppressions.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..a87d264c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,11 @@
+#
+# https://help.github.com/articles/dealing-with-line-endings/
+#
+# Linux start script should use lf
+/gradlew text eol=lf
+
+# These are Windows script files and should use crlf
+*.bat text eol=crlf
+
+# Binary files should be left untouched
+*.jar binary
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 96fb9219..00000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-name: Bug Report
-about: Report the problem that has occurred in our project.
-title: "[BUG] "
-labels: bug
-assignees: ''
----
-
-**Describe the bug**
-A clear and concise description of the bug.
-
-**To Reproduce**
-Steps to reproduce the behavior:
-1. Set '...' in config to '...'
-2. Do in game '....'
-3. See error
-
-**Expected behavior**
-A clear and concise description of what you expected to happen.
-
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
-
-**Server Info (please complete the following information):**
- - All Limbo plugins versions:
- - [e.g. LimboAPI 1.0.4-SNAPSHOT, downloaded from https://github.com/Elytrium/LimboAPI/actions/runs/xxxxxx]
- - [e.g. LimboFilter 1.0.3-rc3, downloaded from https://github.com/Elytrium/LimboAPI/actions/runs/xxxxxx]
-
- - /velocity dump link [e.g. https://dump.velocitypowered.com/abcdef.json]
-
-**Additional context**
-Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 00000000..23be9630
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,78 @@
+# Borrowed from ViaVersion
+name: Bug Report
+description: Report a bug or console error
+labels: [ Unconfirmed ]
+
+body:
+ - type: markdown
+ attributes:
+ value: |
+ **Before reporting a bug, please see if using master/dev builds from https://modrinth.com/plugin/limboapi/ fixes your issue.**
+ Whenever you see fit, you can upload images or videos to any of the text fields.
+ - type: textarea
+ attributes:
+ label: "`/velocity dump` Output"
+ description: |
+ Run `/velocity dump` in the console or in the chat, then attach produced report file here or upload it to the mclo.gs.
+ value: |
+ ```
+ Attach report file here or put the mclo.gs link or text here.
+ ```
+ placeholder: Please do not remove the grave accents; simply replace the line of text in the middle.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Console Error
+ description: |
+ If you encounter warnings/errors in your console, **paste them with https://mclo.gs/ and put the paste link here**.
+ If the error is small/less than 10 lines, you may put it directly into this field.
+ value: |
+ ```
+ Put the mclo.gs link or text here.
+ ```
+ placeholder: Please do not remove the grave accents; simply replace the line of text in the middle.
+ validations:
+ required: false
+ - type: textarea
+ attributes:
+ label: Bug Description
+ description: |
+ Describe the unexpected behavior.
+ If you want to attach screenshots, use the comment field at the bottom of the page.
+ placeholder: |
+ Example: "Changed uuid causes tamed parrots and cats cannot be sat down."
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Steps to Reproduce
+ description: |
+ List the steps on how we can reproduce the issue. Make sure we can easily understand what you mean with each step.
+ placeholder: |
+ Example:
+ 1. Подключиться к оффлайн серверу с LimboAuth с лицензионного клиента
+ 2. Приручить кота
+ 3. При правом клике кота нельзя посадить
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Expected Behavior
+ description: |
+ Describe what exactly you expected to happen.
+ placeholder: |
+ Example: "Кот должен сесть."
+ validations:
+ required: true
+ - type: checkboxes
+ attributes:
+ label: Checklist
+ description: Make sure you have followed each of the steps outlined here.
+ options:
+ - label: I have included a Velocity dump.
+ required: true
+ - label: If applicable, I have included a paste (**not a screenshot**) of the error.
+ required: true
+ - label: I have tried the latest build(s) from https://modrinth.com/plugin/limboapi/ and the issue still persists.
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..9c646613
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,9 @@
+# Borrowed from ViaVersion
+blank_issues_enabled: false
+contact_links:
+ - name: Dev builds
+ url: https://modrinth.com/plugin/limboapi/
+ about: Before reporting a bug, please check if using master/dev builds from our modrinth page fixes your issue.
+ - name: Discord
+ url: https://discord.gg/sxVzYv2dbR
+ about: For smaller issues or questions, you can also join our Discord server.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index 5c4c3e89..00000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-name: Feature Request
-about: Suggest an idea to improve our project.
-title: "[ENHANCEMENT] "
-labels: enhancement
-assignees: ''
----
-
-**Describe the feature you'd like to have implemented**
-A clear and concise description of what you want to be added.
-
-**Is your feature request related to an existing problem? Please describe.**
-A clear and concise description of what the problem is.
-
-**Additional context**
-Add any other context or screenshots about the feature request here.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 00000000..8ab2b460
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,36 @@
+# Borrowed from ViaVersion
+name: Feature Request
+description: Suggest a feature to be added
+labels: [ Feature Request ]
+
+body:
+ - type: textarea
+ attributes:
+ label: Problem Description
+ description: |
+ Describe the issue you are facing or why you need the feature to be added.
+ placeholder: |
+ I am always frustrated with...
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Solution Description
+ description: |
+ Describe the solution you would like to see.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Alternatives
+ description: |
+ Describe alternatives you have considered.
+ validations:
+ required: false
+ - type: textarea
+ attributes:
+ label: Additional Info
+ description: |
+ Does the feature apply to any specific version or environment?
+ validations:
+ required: false
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index 5e2a94dc..00000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: Java CI with Gradle
-
-on:
- push:
- branches:
- - master
- pull_request:
- branches:
- - master
-
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4.2.2
- - name: Set up JDK
- uses: actions/setup-java@v4.7.0
- with:
- distribution: adopt
- java-version: 21
- - name: Build LimboAPI
- run: ./gradlew build
- - name: Upload LimboAPI
- uses: actions/upload-artifact@v4.6.2
- with:
- name: LimboAPI
- path: "*/build/libs/*.jar"
- - uses: dev-drprasad/delete-tag-and-release@v0.2.1
- if: ${{ github.event_name == 'push' }}
- with:
- delete_release: true
- tag_name: dev-build
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Find git version
- id: git-version
- run: echo "id=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- - name: Find correct JAR
- if: ${{ github.event_name == 'push' }}
- id: find-jar
- run: |
- output="$(find plugin/build/libs/ ! -name "*-javadoc.jar" ! -name "*-sources.jar" -type f -printf "%f\n")"
- echo "::set-output name=jarname::$output"
- - name: Release the build
- if: ${{ github.event_name == 'push' }}
- uses: ncipollo/release-action@v1
- with:
- artifacts: plugin/build/libs/${{ steps.find-jar.outputs.jarname }}
- body: ${{ join(github.event.commits.*.message, '\n') }}
- prerelease: true
- name: Dev-build ${{ steps.git-version.outputs.id }}
- tag: dev-build
- - name: Upload to Modrinth
- if: ${{ github.event_name == 'push' }}
- uses: RubixDev/modrinth-upload@v1.0.0
- with:
- token: ${{ secrets.MODRINTH_TOKEN }}
- file_path: plugin/build/libs/${{ steps.find-jar.outputs.jarname }}
- name: Dev-build ${{ steps.git-version.outputs.id }}
- version: ${{ steps.git-version.outputs.id }}
- changelog: ${{ join(github.event.commits.*.message, '\n') }}
- game_versions: 1.7.2
- release_type: beta
- loaders: velocity
- featured: false
- project_id: TZOteSf2
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
new file mode 100644
index 00000000..15d6aa0a
--- /dev/null
+++ b/.github/workflows/gradle.yml
@@ -0,0 +1,34 @@
+name: Java CI with Gradle
+
+on: [ push, pull_request ]
+
+jobs:
+ build:
+ # Only run on PRs if the source branch is on a different repo. We do not need to run everything twice. (From ViaVersion)
+ if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout sources
+ uses: actions/checkout@v4.2.2
+ - name: Cache Minecraft reports
+ uses: actions/cache@v4.1.2
+ with:
+ path: |
+ plugin/build/minecraft/
+ plugin/build/generated/minecraft/mappings/
+ key: minecraft-${{ hashFiles('gradle.properties') }} # Cache key is based on gradle.properties because of gameVersions property
+ - name: Setup Java
+ uses: actions/setup-java@v4.5.0
+ with:
+ distribution: temurin
+ java-version: 21
+ cache: gradle
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v3.3.2
+ - name: Build with Gradle
+ run: ./gradlew build
+ - name: Upload a Build Artifact
+ uses: actions/upload-artifact@v4.4.3
+ with:
+ name: LimboAPI
+ path: "build/libs/limboapi-*.jar"
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 00000000..53718c90
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,32 @@
+name: Publish to Modrinth
+
+on:
+ push:
+ branches: [ master ]
+
+jobs:
+ publish:
+ if: github.repository_owner == 'Elytrium'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout sources
+ uses: actions/checkout@v4.2.2
+ - name: Cache Minecraft reports
+ uses: actions/cache@v4.1.2
+ with:
+ path: |
+ plugin/build/minecraft/
+ plugin/build/generated/minecraft/mappings/
+ key: minecraft-${{ hashFiles('gradle.properties') }} # Cache key is based on gradle.properties because of gameVersions property
+ - name: Setup Java
+ uses: actions/setup-java@v4.5.0
+ with:
+ distribution: temurin
+ java-version: 21
+ cache: gradle
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v3.3.2
+ - name: Publish
+ env:
+ MODRINTH_TOKEN: ${{ secrets.MODRINTH_TOKEN }}
+ run: ./gradlew build modrinth
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index 091ef034..00000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-name: Java CI with Gradle
-
-on:
- release:
- types: [published]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4.2.2
- - name: Set up JDK
- uses: actions/setup-java@v4.7.0
- with:
- distribution: adopt
- java-version: 21
- - name: Build LimboAPI
- run: ./gradlew build
- - name: Upload LimboAPI
- uses: actions/upload-artifact@v4.6.2
- with:
- name: LimboAPI
- path: "*/build/libs/*.jar"
- - name: Find correct JAR
- id: find-jar
- run: |
- output="$(find plugin/build/libs/ ! -name "*-javadoc.jar" ! -name "*-sources.jar" -type f -printf "%f\n")"
- echo "::set-output name=jarname::$output"
- - name: Upload to the GitHub release
- uses: actions/upload-release-asset@v1
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- upload_url: ${{ github.event.release.upload_url }}
- asset_path: plugin/build/libs/${{ steps.find-jar.outputs.jarname }}
- asset_name: ${{ steps.find-jar.outputs.jarname }}
- asset_content_type: application/java-archive
- - name: Upload to Modrinth
- uses: RubixDev/modrinth-upload@v1.0.0
- with:
- token: ${{ secrets.MODRINTH_TOKEN }}
- file_path: plugin/build/libs/${{ steps.find-jar.outputs.jarname }}
- name: Release ${{ github.event.release.tag_name }}
- version: ${{ github.event.release.tag_name }}
- changelog: ${{ github.event.release.body }}
- game_versions: 1.7.2
- release_type: release
- loaders: velocity
- featured: true
- project_id: TZOteSf2
diff --git a/.gitignore b/.gitignore
index a8e27a8a..095f3435 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,25 +1,65 @@
-# IntelliJ user-specific stuff
-.idea/
-*.iml
-
+### Java ###
# Compiled class file
*.class
# Log file
*.log
-# Package Files
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
*.jar
+*.war
+*.nar
+*.ear
*.zip
*.tar.gz
*.rar
-# Virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
+replay_pid*
+
+### JetBrains ###
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/*
+
+!.idea/codeStyles
+!.idea/runConfigurations
+
+*.iml
+modules.xml
+*.ipr
+
+# File-based project format
+*.iws
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+### Linux ###
*~
-# Temporary files which can be created if a process still has a handle open of a deleted file
+# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
@@ -31,13 +71,14 @@ hs_err_pid*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
+### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
-Icon
+Icon
# Thumbnails
._*
@@ -58,6 +99,11 @@ Network Trash Folder
Temporary Items
.apdisk
+### macOS Patch ###
+# iCloud generated files
+*.icloud
+
+### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
@@ -83,15 +129,29 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk
-# Gradle
+### Gradle ###
.gradle
-build/
-
-# Gradle Patch
**/build/
+!src/**/build/
-# Common working directory
-run/
+# Ignore Gradle GUI config
+gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
+
+# Avoid ignore Gradle wrappper properties
+!gradle-wrapper.properties
+
+# Cache of project
+.gradletasknamecache
+
+# Eclipse Gradle plugin generated files
+# Eclipse Core
+.project
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+### Gradle Patch ###
+# Java heap dump
+*.hprof
diff --git a/HEADER.txt b/HEADER.txt
index 99a4f73c..21d1055b 100644
--- a/HEADER.txt
+++ b/HEADER.txt
@@ -1,14 +1,17 @@
-Copyright (C) 2021 - 2025 Elytrium
+/*
+ * Copyright (C) $YEAR Elytrium
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
diff --git a/HEADER_MCPROTOCOLLIB.txt b/HEADER_MCPROTOCOLLIB.txt
index 47e87ed8..b021bc57 100644
--- a/HEADER_MCPROTOCOLLIB.txt
+++ b/HEADER_MCPROTOCOLLIB.txt
@@ -1,21 +1,13 @@
-This file is part of MCProtocolLib, licensed under the MIT License (MIT).
+/*
+ * This file is part of MCProtocolLib, licensed under the MIT License.
+ *
+ * Copyright (C) 2013-2021 Steveice10
+ * Copyright (C) 2021-2024 GeyserMC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
-Copyright (C) 2013-2021 Steveice10
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/HEADER_MIXED.txt b/HEADER_MIXED.txt
index 74b3acbb..29b3c73a 100644
--- a/HEADER_MIXED.txt
+++ b/HEADER_MIXED.txt
@@ -1,31 +1,34 @@
-Copyright (C) 2021 - 2025 Elytrium
+/*
+ * Copyright (C) $YEAR Elytrium
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ * This file contains some parts of Velocity, licensed under the GPLv3 License.
+ *
+ * Copyright (C) $YEAR Velocity Contributors
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-
-This file contains some parts of Velocity, licensed under the AGPLv3 License (AGPLv3).
-
-Copyright (C) 2018 Velocity Contributors
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
\ No newline at end of file
diff --git a/api/HEADER.txt b/api/HEADER.txt
index e54013e9..2f42957a 100644
--- a/api/HEADER.txt
+++ b/api/HEADER.txt
@@ -1,4 +1,7 @@
-Copyright (C) 2021 - 2025 Elytrium
+/*
+ * Copyright (C) $YEAR Elytrium
+ *
+ * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
+ * reference the LICENSE file in the api top-level directory.
+ */
-The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
-reference the LICENSE file in the api top-level directory.
\ No newline at end of file
diff --git a/api/build.gradle b/api/build.gradle
index a6e298c4..120bfe35 100644
--- a/api/build.gradle
+++ b/api/build.gradle
@@ -1,89 +1,67 @@
-//file:noinspection GroovyAssignabilityCheck
+//file:noinspection VulnerableLibrariesLocal
-plugins {
- id("java-library")
+plugins() {
id("maven-publish")
}
-compileJava() {
- getOptions().getRelease().set(17)
- getOptions().setEncoding("UTF-8")
+group = "net.elytrium.limboapi"
+
+java() {
+ withSourcesJar()
+ withJavadocJar()
}
dependencies() {
- compileOnly("com.velocitypowered:velocity-api:$velocityVersion")
- api("net.elytrium.commons:config:$elytriumCommonsVersion")
- api("net.elytrium.commons:utils:$elytriumCommonsVersion")
- api("net.elytrium.commons:velocity:$elytriumCommonsVersion")
- api("net.elytrium.commons:kyori:$elytriumCommonsVersion")
- api("net.kyori:adventure-nbt:$adventureVersion")
+ api(libs.velocity.api)
+ api("net.kyori:adventure-nbt:4.25.0")
+ api("it.unimi.dsi:fastutil:8.5.18")
- compileOnly("com.github.spotbugs:spotbugs-annotations:$spotbugsVersion")
-}
+ compileOnly("net.elytrium.commons:config:1.2.3")
+ shadowApi("net.elytrium.commons:utils:1.2.3")
+ shadowApi("net.elytrium.commons:velocity:1.2.3")
+ shadowApi("net.elytrium.commons:kyori:1.2.3")
-license() {
- matching(includes: ["**/mcprotocollib/**"]) {
- header = rootProject.file("HEADER_MCPROTOCOLLIB.txt")
- }
-
- header = file("HEADER.txt")
+ compileOnly("com.github.spotbugs:spotbugs-annotations:4.7.3")
}
+//spotless() {
+// //matching(includes: ["**/mcprotocollib/**"]) {
+// // header = rootProject.file("HEADER_MCPROTOCOLLIB.txt")
+// //}
+//
+// java() {
+// licenseHeaderFile(file("HEADER.txt"))
+// }
+//}
+
javadoc() {
+ def options = options as StandardJavadocDocletOptions
options.setEncoding("UTF-8")
options.setSource("17")
- options.links("https://docs.oracle.com/en/java/javase/11/docs/api/")
options.addStringOption("Xdoclint:none", "-quiet")
- if (JavaVersion.current() >= JavaVersion.VERSION_1_9 && JavaVersion.current() < JavaVersion.VERSION_12) {
- options.addBooleanOption("-no-module-directories", true)
- }
-}
-
-tasks.register("sourcesJar", Jar) {
- archiveClassifier = "sources"
- from(sourceSets.main.getAllSource())
-}
-
-tasks.register("javadocJar", Jar) {
- archiveClassifier = "javadoc"
- from(javadoc)
+ options.links("https://docs.oracle.com/en/java/javase/17/docs/api/", "https://jd.papermc.io/velocity/3.4.0/", "https://jd.advntr.dev/nbt/4.25.0/")
+ options.tags(
+ "apiNote:a:API Note:",
+ "implSpec:a:Implementation Requirements:",
+ "implNote:a:Implementation Note:",
+ "sinceMinecraft:a:Since Minecraft:"
+ )
}
publishing() {
repositories() {
- maven {
- credentials {
- setUsername(System.getenv("ELYTRIUM_MAVEN_USERNAME"))
- setPassword(System.getenv("ELYTRIUM_MAVEN_PASSWORD"))
+ maven() {
+ name = "elytrium"
+ url = "https://maven.elytrium.net/repo/"
+ credentials() {
+ username = System.getenv("ELYTRIUM_MAVEN_USERNAME")
+ password = System.getenv("ELYTRIUM_MAVEN_PASSWORD")
}
-
- setName("elytrium-repo")
- setUrl("https://maven.elytrium.net/repo/")
}
}
publications.create("publication", MavenPublication) {
+ // TODO pom
from(components.java)
-
- artifact(javadocJar)
- artifact(sourcesJar)
}
}
-
-artifacts() {
- archives(javadocJar)
- archives(sourcesJar)
-}
-
-sourceSets.main.java.srcDir(
- getTasks().register("generateTemplates", Copy) {
- task -> {
- String version = getVersion().contains("-") ? "${getVersion()} (git-${getCurrentShortRevision()})" : getVersion()
- task.getInputs().properties("version": version)
- task.from(file("src/main/templates")).into(getLayout().getBuildDirectory().dir("generated/sources/templates"))
- task.expand("version": version)
- }
- }.map {
- it.getOutputs()
- }
-)
diff --git a/api/src/main/java/net/elytrium/limboapi/api/Limbo.java b/api/src/main/java/net/elytrium/limboapi/api/Limbo.java
index 5f9d4cbb..9540b2a8 100644
--- a/api/src/main/java/net/elytrium/limboapi/api/Limbo.java
+++ b/api/src/main/java/net/elytrium/limboapi/api/Limbo.java
@@ -11,10 +11,9 @@
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.proxy.Player;
import java.util.function.Supplier;
-import net.elytrium.limboapi.api.command.LimboCommandMeta;
-import net.elytrium.limboapi.api.player.GameMode;
+import net.elytrium.limboapi.api.world.player.GameMode;
import net.elytrium.limboapi.api.protocol.PacketDirection;
-import net.elytrium.limboapi.api.protocol.packets.PacketMapping;
+import net.elytrium.limboapi.api.protocol.PacketMapping;
public interface Limbo {
@@ -46,7 +45,15 @@ public interface Limbo {
Limbo setMaxSuppressPacketLength(int maxSuppressPacketLength);
- Limbo registerCommand(LimboCommandMeta commandMeta);
+ /**
+ * @deprecated Use {@link #registerCommand(CommandMeta)} in conjunction with {@link com.velocitypowered.api.command.CommandManager#metaBuilder(String)}
+ */
+ @Deprecated(forRemoval = true)
+ default Limbo registerCommand(net.elytrium.limboapi.api.command.LimboCommandMeta commandMeta) {
+ return this.registerCommand((CommandMeta) commandMeta);
+ }
+
+ Limbo registerCommand(CommandMeta commandMeta);
Limbo registerCommand(CommandMeta commandMeta, Command command);
diff --git a/api/src/main/java/net/elytrium/limboapi/api/LimboFactory.java b/api/src/main/java/net/elytrium/limboapi/api/LimboFactory.java
index 2d2e9373..dd764402 100644
--- a/api/src/main/java/net/elytrium/limboapi/api/LimboFactory.java
+++ b/api/src/main/java/net/elytrium/limboapi/api/LimboFactory.java
@@ -13,242 +13,250 @@
import java.io.InputStream;
import java.nio.file.Path;
import java.util.Map;
-import net.elytrium.limboapi.api.chunk.BuiltInBiome;
-import net.elytrium.limboapi.api.chunk.Dimension;
-import net.elytrium.limboapi.api.chunk.VirtualBiome;
-import net.elytrium.limboapi.api.chunk.VirtualBlock;
-import net.elytrium.limboapi.api.chunk.VirtualBlockEntity;
-import net.elytrium.limboapi.api.chunk.VirtualChunk;
-import net.elytrium.limboapi.api.chunk.VirtualWorld;
-import net.elytrium.limboapi.api.file.BuiltInWorldFileType;
-import net.elytrium.limboapi.api.file.WorldFile;
-import net.elytrium.limboapi.api.material.Block;
-import net.elytrium.limboapi.api.material.Item;
-import net.elytrium.limboapi.api.material.VirtualItem;
+import net.elytrium.limboapi.api.world.WorldVersion;
+import net.elytrium.limboapi.api.world.chunk.biome.BuiltInBiome;
+import net.elytrium.limboapi.api.world.chunk.Dimension;
+import net.elytrium.limboapi.api.world.chunk.biome.VirtualBiome;
+import net.elytrium.limboapi.api.world.chunk.block.VirtualBlock;
+import net.elytrium.limboapi.api.world.chunk.blockentity.VirtualBlockEntity;
+import net.elytrium.limboapi.api.world.chunk.VirtualChunk;
+import net.elytrium.limboapi.api.world.VirtualWorld;
+import net.elytrium.limboapi.api.world.BuiltInWorldFileType;
+import net.elytrium.limboapi.api.world.WorldFile;
+import net.elytrium.limboapi.api.world.chunk.block.Block;
+import net.elytrium.limboapi.api.world.item.Item;
+import net.elytrium.limboapi.api.world.item.VirtualItem;
import net.elytrium.limboapi.api.protocol.PreparedPacket;
-import net.elytrium.limboapi.api.protocol.item.ItemComponentMap;
-import net.elytrium.limboapi.api.protocol.packets.PacketFactory;
+import net.elytrium.limboapi.api.world.item.datacomponent.DataComponentMap;
+import net.elytrium.limboapi.api.protocol.PacketFactory;
import net.kyori.adventure.nbt.CompoundBinaryTag;
+import org.checkerframework.checker.nullness.qual.Nullable;
public interface LimboFactory {
/**
- * Creates new virtual block from Block enum.
+ * Creates new virtual block from Block enum
*
- * @param block Block from Block enum.
+ * @param block Block from Block enum
*
- * @return new virtual block.
+ * @return new virtual block
*/
VirtualBlock createSimpleBlock(Block block);
/**
- * Creates new virtual block from id and data.
+ * Creates new virtual block from id and data
*
- * @param legacyID Legacy block id. (1.12.2 and lower)
+ * @param legacyId Legacy block id (1.12.2 and lower)
*
- * @return new virtual block.
+ * @return new virtual block
*/
- VirtualBlock createSimpleBlock(short legacyID);
+ VirtualBlock createSimpleBlock(short legacyId);
/**
- * Creates new virtual block from id and data.
+ * Creates new virtual block from id and data
*
- * @param modernID Modern block id.
+ * @param modernId Modern block id
*
- * @return new virtual block.
+ * @return new virtual block
*/
- VirtualBlock createSimpleBlock(String modernID);
+ VirtualBlock createSimpleBlock(String modernId);
/**
- * Creates new virtual block from id and data.
+ * Creates new virtual block from id and data
*
- * @param modernID Modern block id.
- * @param properties Modern properties like {"waterlogged": "true"}.
+ * @param modernId Modern block id
+ * @param properties Modern properties like {"waterlogged": "true"}
*
- * @return new virtual block.
+ * @return new virtual block
*/
- VirtualBlock createSimpleBlock(String modernID, Map properties);
+ VirtualBlock createSimpleBlock(String modernId, @Nullable Map properties);
/**
- * Creates new virtual block from id and data.
+ * Creates new virtual block from id and data
*
- * @param legacyID Block id.
- * @param modern Use the latest supported version ids or 1.12.2 and lower.
+ * @param id Block id
+ * @param modern Use the latest supported version ids or 1.12.2 and lower
*
- * @return new virtual block.
+ * @return new virtual block
*/
- VirtualBlock createSimpleBlock(short legacyID, boolean modern);
+ VirtualBlock createSimpleBlock(short id, boolean modern);
+
+ @Deprecated(forRemoval = true)
+ default VirtualBlock createSimpleBlock(boolean solid, boolean air, boolean motionBlocking, short id) {
+ return this.createSimpleBlock(id, air, solid, motionBlocking);
+ }
/**
- * Creates new virtual customizable block.
+ * Creates new virtual customizable block
*
- * @param solid Defines if the block is solid or not.
- * @param air Defines if the block is the air.
- * @param motionBlocking Defines if the block blocks motions. (1.14+)
- * @param id Block protocol id.
+ * @param blockStateId Block protocol id
+ * @param air Defines if the block is the air
+ * @param solid Defines if the block is solid
+ * @param motionBlocking Defines if the block blocks motions (1.14+)
*
- * @return new virtual block.
+ * @return new virtual block
*/
- VirtualBlock createSimpleBlock(boolean solid, boolean air, boolean motionBlocking, short id);
+ VirtualBlock createSimpleBlock(short blockStateId, boolean air, boolean solid, boolean motionBlocking);
+
+ @Deprecated(forRemoval = true)
+ default VirtualBlock createSimpleBlock(boolean solid, boolean air, boolean motionBlocking, String modernId, Map properties) {
+ return this.createSimpleBlock(modernId, properties, air, solid, motionBlocking);
+ }
/**
- * Creates new virtual customizable block.
+ * Creates new virtual customizable block
*
- * @param solid Defines if the block is solid or not.
- * @param air Defines if the block is the air.
- * @param motionBlocking Defines if the block blocks motions. (1.14+)
- * @param modernID Block id.
- * @param properties Modern properties like {"waterlogged": "true"}.
+ * @param modernId Block id
+ * @param properties Modern properties like {"waterlogged": "true"}
+ * @param air Defines if the block is the air
+ * @param solid Defines if the block is solid
+ * @param motionBlocking Defines if the block blocks motions (1.14+)
*
- * @return new virtual block.
+ * @return new virtual block
*/
- VirtualBlock createSimpleBlock(boolean solid, boolean air, boolean motionBlocking, String modernID, Map properties);
+ VirtualBlock createSimpleBlock(String modernId, Map properties, boolean air, boolean solid, boolean motionBlocking);
/**
- * Creates new virtual world.
+ * Creates new virtual world
*
* @param dimension World dimension.
- * @param posX Spawn location. (X)
- * @param posY Spawn location. (Y)
- * @param posZ Spawn location. (Z)
- * @param yaw Spawn rotation. (Yaw)
- * @param pitch Spawn rotation. (Pitch)
+ * @param posX Spawn location x
+ * @param posY Spawn location y
+ * @param posZ Spawn location z
+ * @param yaw Spawn rotation yaw
+ * @param pitch Spawn rotation pitch
*
- * @return new virtual world.
+ * @return new virtual world
*/
VirtualWorld createVirtualWorld(Dimension dimension, double posX, double posY, double posZ, float yaw, float pitch);
/**
- * Creates new virtual chunk with plain biomes set as default.
- * You need to provide the chunk location, you can get it using {@code blockCoordinate >> 4}.
+ * Creates new virtual chunk with plain biomes set as default
+ * You need to provide the chunk location, you can get it using {@code blockCoordinate >> 4}
*
- * @param posX Chunk location. (X)
- * @param posZ Chunk location. (Z)
+ * @param posX Chunk position by X
+ * @param posZ Chunk position by Z
*
- * @return new virtual chunk.
+ * @return new virtual chunk
*/
@Deprecated
VirtualChunk createVirtualChunk(int posX, int posZ);
/**
- * Creates new virtual chunk.
- * You need to provide the chunk location, you can get it using {@code blockCoordinate >> 4}.
+ * Creates new virtual chunk
+ * You need to provide the chunk location, you can get it using {@code blockCoordinate >> 4}
*
- * @param posX Chunk location. (X)
- * @param posZ Chunk location. (Z)
- * @param defaultBiome Default biome to fill it.
+ * @param posX Chunk position by X
+ * @param posZ Chunk position by Z
+ * @param defaultBiome Default biome to fill it
*
* @return new virtual chunk.
*/
VirtualChunk createVirtualChunk(int posX, int posZ, VirtualBiome defaultBiome);
/**
- * Creates new virtual chunk.
- * You need to provide the chunk location, you can get it using ({@code block_coordinate >> 4})
+ * Creates new virtual chunk
+ * You need to provide the chunk location, you can get it using {@code blockCoordinate >> 4}
*
- * @param posX Chunk location. (X)
- * @param posZ Chunk location. (Z)
- * @param defaultBiome Default biome to fill it.
+ * @param posX Chunk position by X
+ * @param posZ Chunk position by Z
+ * @param defaultBiome Default biome to fill it
*
- * @return new virtual chunk.
+ * @return new virtual chunk
*/
VirtualChunk createVirtualChunk(int posX, int posZ, BuiltInBiome defaultBiome);
/**
- * Creates new virtual server.
+ * Creates new virtual server
*
- * @param world Virtual world.
+ * @param world Virtual world
*
- * @return new virtual server.
+ * @return new virtual server
*/
Limbo createLimbo(VirtualWorld world);
-
/**
- * Releases a thread after PreparedPacket#build executions.
- * Used to free compression libraries.
+ * Releases the thread after {@link PreparedPacket#build()} executions.
+ *
+ * Used to free compression libraries
*/
void releasePreparedPacketThread(Thread thread);
/**
- * Creates new prepared packet builder.
+ * Creates new prepared packet builder
*
- * @return new prepared packet.
+ * @return new prepared packet
*/
PreparedPacket createPreparedPacket();
/**
- * Creates new prepared packet builder.
+ * Creates new prepared packet builder
*
- * @param minVersion Minimum version to prepare.
- * @param maxVersion Maximum version to prepare.
+ * @param minVersion Minimum version to prepare
+ * @param maxVersion Maximum version to prepare
*
- * @return new prepared packet.
+ * @return new prepared packet
*/
PreparedPacket createPreparedPacket(ProtocolVersion minVersion, ProtocolVersion maxVersion);
/**
- * Creates new prepared packet builder for the CONFIG state.
+ * Creates new prepared packet builder for the CONFIG state
*
- * @return new prepared packet.
+ * @return new prepared packet
*/
PreparedPacket createConfigPreparedPacket();
/**
- * Creates new prepared packet builder for the CONFIG state.
+ * Creates new prepared packet builder for the CONFIG state
*
- * @param minVersion Minimum version to prepare.
- * @param maxVersion Maximum version to prepare.
+ * @param minVersion Minimum version to prepare
+ * @param maxVersion Maximum version to prepare
*
- * @return new prepared packet.
+ * @return new prepared packet
*/
PreparedPacket createConfigPreparedPacket(ProtocolVersion minVersion, ProtocolVersion maxVersion);
/**
- * Pass the player to the next Login Limbo, without spawning at current Limbo.
+ * Pass the player to the next Login Limbo, without spawning at current Limbo
*
- * @param player Player to pass.
+ * @param player Player to pass
*/
void passLoginLimbo(Player player);
- /**
- * Creates new virtual item from Item enum.
- *
- * @param item Item from item enum.
- *
- * @return new virtual item.
- */
VirtualItem getItem(Item item);
+ VirtualItem getItem(String modernId);
+
+ VirtualItem getItem(ProtocolVersion version, short id);
+
+ VirtualItem getItem(WorldVersion version, short id);
+
+ VirtualItem getLegacyItem(short legacyId);
+
/**
- * Creates new virtual item from Item enum.
- *
- * @param itemID Modern item identifier.
- *
- * @return new virtual item.
+ * @return new data component map
*/
- VirtualItem getItem(String itemID);
+ DataComponentMap createDataComponentMap();
+
+ @Deprecated(forRemoval = true)
+ default VirtualBlockEntity getBlockEntity(String entityId) {
+ return this.getBlockEntityFromModernId(entityId);
+ }
/**
- * Creates new virtual item from Item enum.
- *
- * @param itemLegacyID Legacy item ID
- *
- * @return new virtual item.
+ * @param modernId Should be prefixed with minecraft namespace
*/
- VirtualItem getLegacyItem(int itemLegacyID);
+ @Nullable
+ VirtualBlockEntity getBlockEntityFromModernId(String modernId);
/**
- * Creates new item component map.
- *
- * @return new item component map
+ * @return Block entity using legacy id or null (used in 1.9-1.10, e.g., DLDetector instead of daylight_detector)
*/
- ItemComponentMap createItemComponentMap();
-
- VirtualBlockEntity getBlockEntity(String entityID);
+ @Nullable
+ VirtualBlockEntity getBlockEntityFromLegacyId(String legacyId);
/**
- * A factory to instantiate Minecraft packet objects.
+ * A factory to instantiate Minecraft packet objects
*/
PacketFactory getPacketFactory();
@@ -265,7 +273,6 @@ public interface LimboFactory {
*/
WorldFile openWorldFile(BuiltInWorldFileType apiType, Path file) throws IOException;
-
/**
* Opens world file (a.k.a. schematic file)
*
@@ -275,7 +282,6 @@ public interface LimboFactory {
*/
WorldFile openWorldFile(BuiltInWorldFileType apiType, InputStream stream) throws IOException;
-
/**
* Opens world file (a.k.a. schematic file)
*
diff --git a/api/src/main/java/net/elytrium/limboapi/api/LimboSessionHandler.java b/api/src/main/java/net/elytrium/limboapi/api/LimboSessionHandler.java
index ce0212a4..5e4e2b3e 100644
--- a/api/src/main/java/net/elytrium/limboapi/api/LimboSessionHandler.java
+++ b/api/src/main/java/net/elytrium/limboapi/api/LimboSessionHandler.java
@@ -7,7 +7,7 @@
package net.elytrium.limboapi.api;
-import net.elytrium.limboapi.api.player.LimboPlayer;
+import net.elytrium.limboapi.api.world.player.LimboPlayer;
public interface LimboSessionHandler {
@@ -19,11 +19,11 @@ default void onConfig(Limbo server, LimboPlayer player) {
}
- default void onMove(double posX, double posY, double posZ) {
+ default void onMove(double posX, double posY, double posZ, float yaw, float pitch) {
}
- default void onMove(double posX, double posY, double posZ, float yaw, float pitch) {
+ default void onMove(double posX, double posY, double posZ) {
}
@@ -35,7 +35,7 @@ default void onGround(boolean onGround) {
}
- default void onTeleport(int teleportID) {
+ default void onTeleport(int teleportId) {
}
@@ -44,7 +44,7 @@ default void onChat(String chat) {
}
/**
- * @param packet Any velocity built-in packet or any packet registered via {@link Limbo#registerPacket}.
+ * @param packet Any velocity built-in packet or any packet registered via {@link Limbo#registerPacket}
*/
default void onGeneric(Object packet) {
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/BlockEntityVersion.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/BlockEntityVersion.java
deleted file mode 100644
index f134e8e4..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/BlockEntityVersion.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk;
-
-import com.velocitypowered.api.network.ProtocolVersion;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.Set;
-import net.elytrium.limboapi.api.utils.EnumUniverse;
-
-public enum BlockEntityVersion {
- LEGACY(EnumSet.range(ProtocolVersion.MINECRAFT_1_7_2, ProtocolVersion.MINECRAFT_1_18_2)),
- MINECRAFT_1_19(EnumSet.of(ProtocolVersion.MINECRAFT_1_19)),
- MINECRAFT_1_19_1(EnumSet.of(ProtocolVersion.MINECRAFT_1_19_1)),
- MINECRAFT_1_19_3(EnumSet.of(ProtocolVersion.MINECRAFT_1_19_3)),
- MINECRAFT_1_19_4(EnumSet.of(ProtocolVersion.MINECRAFT_1_19_4)),
- MINECRAFT_1_20(EnumSet.of(ProtocolVersion.MINECRAFT_1_20)),
- MINECRAFT_1_20_2(EnumSet.of(ProtocolVersion.MINECRAFT_1_20_2)),
- MINECRAFT_1_20_3(EnumSet.of(ProtocolVersion.MINECRAFT_1_20_3)),
- MINECRAFT_1_20_5(EnumSet.of(ProtocolVersion.MINECRAFT_1_20_5)),
- MINECRAFT_1_21(EnumSet.of(ProtocolVersion.MINECRAFT_1_21)),
- MINECRAFT_1_21_2(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_2)),
- MINECRAFT_1_21_4(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_4)),
- MINECRAFT_1_21_5(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_5)),
- MINECRAFT_1_21_6(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_6)),
- MINECRAFT_1_21_7(EnumSet.of(ProtocolVersion.MINECRAFT_1_21_7));
-
- private static final EnumMap MC_VERSION_TO_ITEM_VERSIONS = new EnumMap<>(ProtocolVersion.class);
- private static final Map KEY_LOOKUP = Map.copyOf(EnumUniverse.createProtocolLookup(values()));
-
- private final Set versions;
-
- BlockEntityVersion(ProtocolVersion... versions) {
- this.versions = EnumSet.copyOf(Arrays.asList(versions));
- }
-
- BlockEntityVersion(Set versions) {
- this.versions = versions;
- }
-
- public ProtocolVersion getMinSupportedVersion() {
- return this.versions.iterator().next();
- }
-
- public Set getVersions() {
- return this.versions;
- }
-
- static {
- for (BlockEntityVersion version : BlockEntityVersion.values()) {
- for (ProtocolVersion protocolVersion : version.getVersions()) {
- MC_VERSION_TO_ITEM_VERSIONS.put(protocolVersion, version);
- }
- }
- }
-
- public static BlockEntityVersion parse(String from) {
- return KEY_LOOKUP.getOrDefault(from, LEGACY);
- }
-
- public static BlockEntityVersion from(ProtocolVersion protocolVersion) {
- return MC_VERSION_TO_ITEM_VERSIONS.get(protocolVersion);
- }
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualBlock.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualBlock.java
deleted file mode 100644
index c2de5c24..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualBlock.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk;
-
-import com.velocitypowered.api.network.ProtocolVersion;
-import net.elytrium.limboapi.api.material.WorldVersion;
-
-public interface VirtualBlock {
-
- short getModernID();
-
- String getModernStringID();
-
- @Deprecated
- short getID(ProtocolVersion version);
-
- short getBlockID(WorldVersion version);
-
- short getBlockID(ProtocolVersion version);
-
- boolean isSupportedOn(ProtocolVersion version);
-
- boolean isSupportedOn(WorldVersion version);
-
- short getBlockStateID(ProtocolVersion version);
-
- boolean isSolid();
-
- boolean isAir();
-
- boolean isMotionBlocking();
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualBlockEntity.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualBlockEntity.java
deleted file mode 100644
index d7f43050..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualBlockEntity.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk;
-
-import com.velocitypowered.api.network.ProtocolVersion;
-import net.kyori.adventure.nbt.CompoundBinaryTag;
-
-public interface VirtualBlockEntity {
-
- int getID(ProtocolVersion version);
-
- int getID(BlockEntityVersion version);
-
- boolean isSupportedOn(ProtocolVersion version);
-
- boolean isSupportedOn(BlockEntityVersion version);
-
- String getModernID();
-
- Entry getEntry(int posX, int posY, int posZ, CompoundBinaryTag nbt);
-
- interface Entry {
-
- VirtualBlockEntity getBlockEntity();
-
- int getPosX();
-
- int getPosY();
-
- int getPosZ();
-
- CompoundBinaryTag getNbt();
-
- int getID(ProtocolVersion version);
-
- int getID(BlockEntityVersion version);
-
- boolean isSupportedOn(ProtocolVersion version);
-
- boolean isSupportedOn(BlockEntityVersion version);
- }
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualChunk.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualChunk.java
deleted file mode 100644
index 3a91bd38..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualChunk.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk;
-
-import net.elytrium.limboapi.api.chunk.data.ChunkSnapshot;
-import net.kyori.adventure.nbt.CompoundBinaryTag;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
-import org.checkerframework.common.value.qual.IntRange;
-
-public interface VirtualChunk {
-
- void setBlock(int posX, int posY, int posZ, @Nullable VirtualBlock block);
-
- void setBlockEntity(int posX, int posY, int posZ, @Nullable CompoundBinaryTag nbt, @Nullable VirtualBlockEntity blockEntity);
-
- void setBlockEntity(VirtualBlockEntity.Entry blockEntityEntry);
-
- @NonNull
- VirtualBlock getBlock(int posX, int posY, int posZ);
-
- void setBiome2D(int posX, int posZ, @NonNull VirtualBiome biome);
-
- void setBiome3D(int posX, int posY, int posZ, @NonNull VirtualBiome biome);
-
- @NonNull
- VirtualBiome getBiome(int posX, int posY, int posZ);
-
- void setBlockLight(int posX, int posY, int posZ, byte light);
-
- byte getBlockLight(int posX, int posY, int posZ);
-
- void setSkyLight(int posX, int posY, int posZ, byte light);
-
- byte getSkyLight(int posX, int posY, int posZ);
-
- void fillBlockLight(@IntRange(from = 0, to = 15) int level);
-
- void fillSkyLight(@IntRange(from = 0, to = 15) int level);
-
- int getPosX();
-
- int getPosZ();
-
- ChunkSnapshot getFullChunkSnapshot();
-
- ChunkSnapshot getPartialChunkSnapshot(long previousUpdate);
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualWorld.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualWorld.java
deleted file mode 100644
index ccf1d040..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/VirtualWorld.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk;
-
-import java.util.List;
-import net.kyori.adventure.nbt.CompoundBinaryTag;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
-import org.checkerframework.common.value.qual.IntRange;
-
-public interface VirtualWorld {
-
- void setBlockEntity(int posX, int posY, int posZ, @Nullable CompoundBinaryTag nbt, @Nullable VirtualBlockEntity blockEntity);
-
- @NonNull
- VirtualBlock getBlock(int posX, int posY, int posZ);
-
- void setBiome2d(int posX, int posZ, @NonNull VirtualBiome biome);
-
- void setBiome3d(int posX, int posY, int posZ, @NonNull VirtualBiome biome);
-
- VirtualBiome getBiome(int posX, int posY, int posZ);
-
- byte getBlockLight(int posX, int posY, int posZ);
-
- void setBlockLight(int posX, int posY, int posZ, byte light);
-
- void fillBlockLight(@IntRange(from = 0, to = 15) int level);
-
- void fillSkyLight(@IntRange(from = 0, to = 15) int level);
-
- List getChunks();
-
- List> getOrderedChunks();
-
- @Nullable
- VirtualChunk getChunk(int posX, int posZ);
-
- VirtualChunk getChunkOrNew(int posX, int posZ);
-
- @NonNull
- Dimension getDimension();
-
- double getSpawnX();
-
- double getSpawnY();
-
- double getSpawnZ();
-
- float getYaw();
-
- float getPitch();
-
- void setBlock(int posX, int posY, int posZ, @Nullable VirtualBlock block);
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/data/BlockSection.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/data/BlockSection.java
deleted file mode 100644
index ac273b9f..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/data/BlockSection.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk.data;
-
-import net.elytrium.limboapi.api.chunk.VirtualBlock;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
-public interface BlockSection {
-
- void setBlockAt(int posX, int posY, int posZ, @Nullable VirtualBlock block);
-
- VirtualBlock getBlockAt(int posX, int posY, int posZ);
-
- BlockSection getSnapshot();
-
- long getLastUpdate();
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/data/BlockStorage.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/data/BlockStorage.java
deleted file mode 100644
index e4eaa2db..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/data/BlockStorage.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk.data;
-
-import com.velocitypowered.api.network.ProtocolVersion;
-import net.elytrium.limboapi.api.chunk.VirtualBlock;
-import org.checkerframework.checker.nullness.qual.NonNull;
-
-public interface BlockStorage {
-
- void write(Object byteBufObject, ProtocolVersion version, int pass);
-
- void set(int posX, int posY, int posZ, @NonNull VirtualBlock block);
-
- @NonNull
- VirtualBlock get(int posX, int posY, int posZ);
-
- int getDataLength(ProtocolVersion version);
-
- BlockStorage copy();
-
- static int index(int posX, int posY, int posZ) {
- return posY << 8 | posZ << 4 | posX;
- }
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/data/ChunkSnapshot.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/data/ChunkSnapshot.java
deleted file mode 100644
index 3f0bd274..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/data/ChunkSnapshot.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk.data;
-
-import java.util.List;
-import net.elytrium.limboapi.api.chunk.VirtualBiome;
-import net.elytrium.limboapi.api.chunk.VirtualBlock;
-import net.elytrium.limboapi.api.chunk.VirtualBlockEntity;
-
-public interface ChunkSnapshot {
-
- VirtualBlock getBlock(int posX, int posY, int posZ);
-
- int getPosX();
-
- int getPosZ();
-
- boolean isFullChunk();
-
- BlockSection[] getSections();
-
- LightSection[] getLight();
-
- VirtualBiome[] getBiomes();
-
- List getBlockEntityEntries();
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/chunk/data/LightSection.java b/api/src/main/java/net/elytrium/limboapi/api/chunk/data/LightSection.java
deleted file mode 100644
index 1b70f7ce..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/chunk/data/LightSection.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.chunk.data;
-
-import net.elytrium.limboapi.api.mcprotocollib.NibbleArray3D;
-
-public interface LightSection {
-
- void setBlockLight(int posX, int posY, int posZ, byte light);
-
- NibbleArray3D getBlockLight();
-
- byte getBlockLight(int posX, int posY, int posZ);
-
- void setSkyLight(int posX, int posY, int posZ, byte light);
-
- NibbleArray3D getSkyLight();
-
- byte getSkyLight(int posX, int posY, int posZ);
-
- long getLastUpdate();
-
- LightSection copy();
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/command/LimboCommandMeta.java b/api/src/main/java/net/elytrium/limboapi/api/command/LimboCommandMeta.java
index aea94b35..cc2331a4 100644
--- a/api/src/main/java/net/elytrium/limboapi/api/command/LimboCommandMeta.java
+++ b/api/src/main/java/net/elytrium/limboapi/api/command/LimboCommandMeta.java
@@ -7,22 +7,26 @@
package net.elytrium.limboapi.api.command;
-import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.tree.CommandNode;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.CommandSource;
import java.util.Collection;
+import java.util.Collections;
import java.util.Objects;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
+/**
+ * @deprecated Use {@link CommandMeta}
+ */
+@Deprecated(forRemoval = true)
public class LimboCommandMeta implements CommandMeta {
@NonNull
private final Collection aliases;
@NonNull
private final Collection> hints;
- @Nullable // Why?..
+ @Nullable
private final Object plugin;
public LimboCommandMeta(@NonNull Collection aliases) {
@@ -35,7 +39,7 @@ public LimboCommandMeta(@NonNull Collection aliases, @Nullable Collectio
public LimboCommandMeta(@NonNull Collection aliases, @Nullable Collection> hints, @Nullable Object plugin) {
this.aliases = aliases;
- this.hints = Objects.requireNonNullElse(hints, ImmutableList.of());
+ this.hints = Objects.requireNonNullElse(hints, Collections.emptyList());
this.plugin = plugin;
}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/event/LoginLimboRegisterEvent.java b/api/src/main/java/net/elytrium/limboapi/api/event/LoginLimboRegisterEvent.java
index 9fff7127..979835d4 100644
--- a/api/src/main/java/net/elytrium/limboapi/api/event/LoginLimboRegisterEvent.java
+++ b/api/src/main/java/net/elytrium/limboapi/api/event/LoginLimboRegisterEvent.java
@@ -7,24 +7,27 @@
package net.elytrium.limboapi.api.event;
-import com.google.common.base.Preconditions;
+import com.velocitypowered.api.event.annotation.AwaitingEvent;
import com.velocitypowered.api.event.player.KickedFromServerEvent;
import com.velocitypowered.api.proxy.Player;
+import java.util.Objects;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Function;
/**
- * This event is fired during login process before the player has been authenticated, e.g. to enable or disable custom authentication.
+ * This event is fired during a login process before the player has been authenticated, e.g., to enable or disable custom authentication
*/
+@AwaitingEvent
public class LoginLimboRegisterEvent {
private final Player player;
private final Queue onJoinCallbacks;
+
private Function onKickCallback;
public LoginLimboRegisterEvent(Player player) {
- this.player = Preconditions.checkNotNull(player, "player");
+ this.player = Objects.requireNonNull(player, "player");
this.onJoinCallbacks = new LinkedBlockingQueue<>();
}
@@ -43,7 +46,6 @@ public Queue getOnJoinCallbacks() {
return this.onJoinCallbacks;
}
-
public Function getOnKickCallback() {
return this.onKickCallback;
}
@@ -55,7 +57,7 @@ public void addOnJoinCallback(Runnable callback) {
/**
* @deprecated Use {@link LoginLimboRegisterEvent#addOnJoinCallback(Runnable)} instead
*/
- @Deprecated
+ @Deprecated(forRemoval = true)
public void addCallback(Runnable callback) {
this.onJoinCallbacks.add(callback);
}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/material/VirtualItem.java b/api/src/main/java/net/elytrium/limboapi/api/material/VirtualItem.java
deleted file mode 100644
index 020a6412..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/material/VirtualItem.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.material;
-
-import com.velocitypowered.api.network.ProtocolVersion;
-
-public interface VirtualItem {
-
- short getID(ProtocolVersion version);
-
- short getID(WorldVersion version);
-
- boolean isSupportedOn(ProtocolVersion version);
-
- boolean isSupportedOn(WorldVersion version);
-
- String getModernID();
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/material/WorldVersion.java b/api/src/main/java/net/elytrium/limboapi/api/material/WorldVersion.java
deleted file mode 100644
index b87c8947..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/material/WorldVersion.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.material;
-
-import com.velocitypowered.api.network.ProtocolVersion;
-import java.util.Arrays;
-import java.util.EnumMap;
-import java.util.EnumSet;
-import java.util.Map;
-import java.util.Set;
-import net.elytrium.limboapi.api.utils.EnumUniverse;
-
-public enum WorldVersion {
- LEGACY(EnumSet.range(ProtocolVersion.MINECRAFT_1_7_2, ProtocolVersion.MINECRAFT_1_12_2)),
- MINECRAFT_1_13(ProtocolVersion.MINECRAFT_1_13),
- MINECRAFT_1_13_2(ProtocolVersion.MINECRAFT_1_13_1, ProtocolVersion.MINECRAFT_1_13_2),
- MINECRAFT_1_14(EnumSet.range(ProtocolVersion.MINECRAFT_1_14, ProtocolVersion.MINECRAFT_1_14_4)),
- MINECRAFT_1_15(EnumSet.range(ProtocolVersion.MINECRAFT_1_15, ProtocolVersion.MINECRAFT_1_15_2)),
- MINECRAFT_1_16(ProtocolVersion.MINECRAFT_1_16, ProtocolVersion.MINECRAFT_1_16_1),
- MINECRAFT_1_16_2(EnumSet.range(ProtocolVersion.MINECRAFT_1_16_2, ProtocolVersion.MINECRAFT_1_16_4)),
- MINECRAFT_1_17(EnumSet.range(ProtocolVersion.MINECRAFT_1_17, ProtocolVersion.MINECRAFT_1_18_2)),
- MINECRAFT_1_19(EnumSet.range(ProtocolVersion.MINECRAFT_1_19, ProtocolVersion.MINECRAFT_1_19_1)),
- MINECRAFT_1_19_3(ProtocolVersion.MINECRAFT_1_19_3),
- MINECRAFT_1_19_4(EnumSet.range(ProtocolVersion.MINECRAFT_1_19_4, ProtocolVersion.MINECRAFT_1_20)),
- MINECRAFT_1_20(EnumSet.range(ProtocolVersion.MINECRAFT_1_20, ProtocolVersion.MINECRAFT_1_20_2)),
- MINECRAFT_1_20_3(ProtocolVersion.MINECRAFT_1_20_3),
- MINECRAFT_1_20_5(EnumSet.range(ProtocolVersion.MINECRAFT_1_20_5, ProtocolVersion.MINECRAFT_1_21)),
- MINECRAFT_1_21_2(ProtocolVersion.MINECRAFT_1_21_2),
- MINECRAFT_1_21_4(ProtocolVersion.MINECRAFT_1_21_4),
- MINECRAFT_1_21_5(ProtocolVersion.MINECRAFT_1_21_5),
- MINECRAFT_1_21_6(ProtocolVersion.MINECRAFT_1_21_6),
- MINECRAFT_1_21_7(EnumSet.range(ProtocolVersion.MINECRAFT_1_21_7, ProtocolVersion.MAXIMUM_VERSION));
-
- private static final EnumMap MC_VERSION_TO_ITEM_VERSIONS = new EnumMap<>(ProtocolVersion.class);
- private static final Map KEY_LOOKUP = Map.copyOf(EnumUniverse.createProtocolLookup(values()));
-
- private final Set versions;
-
- WorldVersion(ProtocolVersion... versions) {
- this.versions = EnumSet.copyOf(Arrays.asList(versions));
- }
-
- WorldVersion(Set versions) {
- this.versions = versions;
- }
-
- public ProtocolVersion getMinSupportedVersion() {
- return this.versions.iterator().next();
- }
-
- public Set getVersions() {
- return this.versions;
- }
-
- static {
- for (WorldVersion version : WorldVersion.values()) {
- for (ProtocolVersion protocolVersion : version.getVersions()) {
- MC_VERSION_TO_ITEM_VERSIONS.put(protocolVersion, version);
- }
- }
- }
-
- public static WorldVersion parse(String from) {
- return KEY_LOOKUP.getOrDefault(from, LEGACY);
- }
-
- public static WorldVersion from(ProtocolVersion protocolVersion) {
- return MC_VERSION_TO_ITEM_VERSIONS.get(protocolVersion);
- }
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/player/LimboPlayer.java b/api/src/main/java/net/elytrium/limboapi/api/player/LimboPlayer.java
deleted file mode 100644
index 32ab256f..00000000
--- a/api/src/main/java/net/elytrium/limboapi/api/player/LimboPlayer.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2021 - 2025 Elytrium
- *
- * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
- * reference the LICENSE file in the api top-level directory.
- */
-
-package net.elytrium.limboapi.api.player;
-
-import com.velocitypowered.api.proxy.Player;
-import com.velocitypowered.api.proxy.server.RegisteredServer;
-import java.awt.image.BufferedImage;
-import java.util.concurrent.ScheduledExecutorService;
-import net.elytrium.limboapi.api.Limbo;
-import net.elytrium.limboapi.api.material.VirtualItem;
-import net.elytrium.limboapi.api.protocol.item.ItemComponentMap;
-import net.kyori.adventure.nbt.CompoundBinaryTag;
-
-public interface LimboPlayer {
-
- void writePacket(Object packetObj);
-
- void writePacketAndFlush(Object packetObj);
-
- void flushPackets();
-
- void closeWith(Object packetObj);
-
- ScheduledExecutorService getScheduledExecutor();
-
- void sendImage(BufferedImage image);
-
- void sendImage(BufferedImage image, boolean sendItem);
-
- void sendImage(int mapID, BufferedImage image);
-
- void sendImage(int mapID, BufferedImage image, boolean sendItem);
-
- void sendImage(int mapID, BufferedImage image, boolean sendItem, boolean resize);
-
- void setInventory(VirtualItem item, int count);
-
- void setInventory(VirtualItem item, int slot, int count);
-
- void setInventory(int slot, VirtualItem item, int count, int data, CompoundBinaryTag nbt);
-
- void setInventory(int slot, VirtualItem item, int count, int data, ItemComponentMap map);
-
- void setGameMode(GameMode gameMode);
-
- void teleport(double posX, double posY, double posZ, float yaw, float pitch);
-
- void disableFalling();
-
- void enableFalling();
-
- void disconnect();
-
- void disconnect(RegisteredServer server);
-
- void sendAbilities();
-
- void sendAbilities(int abilities, float flySpeed, float walkSpeed);
-
- void sendAbilities(byte abilities, float flySpeed, float walkSpeed);
-
- byte getAbilities();
-
- GameMode getGameMode();
-
- Limbo getServer();
-
- Player getProxyPlayer();
-
- int getPing();
-
- void setWorldTime(long ticks);
-}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/protocol/PacketFactory.java b/api/src/main/java/net/elytrium/limboapi/api/protocol/PacketFactory.java
new file mode 100644
index 00000000..8fb9ea45
--- /dev/null
+++ b/api/src/main/java/net/elytrium/limboapi/api/protocol/PacketFactory.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2021 - 2025 Elytrium
+ *
+ * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
+ * reference the LICENSE file in the api top-level directory.
+ */
+
+package net.elytrium.limboapi.api.protocol;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import java.util.Map;
+import net.elytrium.limboapi.api.protocol.data.EntityData;
+import net.elytrium.limboapi.api.world.chunk.Dimension;
+import net.elytrium.limboapi.api.world.chunk.blockentity.VirtualBlockEntity;
+import net.elytrium.limboapi.api.world.chunk.ChunkSnapshot;
+import net.elytrium.limboapi.api.world.item.VirtualItem;
+import net.elytrium.limboapi.api.world.WorldVersion;
+import net.elytrium.limboapi.api.world.item.datacomponent.DataComponentMap;
+import net.elytrium.limboapi.api.protocol.data.AbilityFlags;
+import net.elytrium.limboapi.api.protocol.data.MapData;
+import net.kyori.adventure.nbt.CompoundBinaryTag;
+import net.kyori.adventure.text.Component;
+import org.checkerframework.checker.nullness.qual.NonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public interface PacketFactory {
+
+ @Deprecated(forRemoval = true)
+ default Object createChangeGameStatePacket(int event, float param) {
+ return this.createGameEventPacket(event, param);
+ }
+
+ Object createGameEventPacket(int event, float param);
+
+ /**
+ * @see #prepareCompleteChunkDataPacket(ProtocolVersion, ProtocolVersion, PreparedPacket, ChunkSnapshot, Dimension)
+ */
+ default void prepareCompleteChunkDataPacket(PreparedPacket packet, ChunkSnapshot chunkSnapshot, Dimension dimension) {
+ this.prepareCompleteChunkDataPacket(ProtocolVersion.MINIMUM_VERSION, ProtocolVersion.MAXIMUM_VERSION, packet, chunkSnapshot, dimension);
+ }
+
+ /**
+ * @see #prepareCompleteChunkDataPacket(ProtocolVersion, ProtocolVersion, PreparedPacket, ChunkSnapshot, Dimension)
+ */
+ default void prepareCompleteChunkDataPacket(ProtocolVersion minPrepareVersion, ProtocolVersion maxPrepareVersion, PreparedPacket packet, ChunkSnapshot chunkSnapshot, Dimension dimension) {
+ this.prepareCompleteChunkDataPacket(minPrepareVersion, maxPrepareVersion, packet, chunkSnapshot, dimension.hasSkyLight(), dimension.getMaxSections());
+ }
+
+ /**
+ * @see #prepareCompleteChunkDataPacket(ProtocolVersion, ProtocolVersion, PreparedPacket, ChunkSnapshot, Dimension)
+ */
+ default void prepareCompleteChunkDataPacket(PreparedPacket packet, ChunkSnapshot chunkSnapshot, boolean hasSkyLight, int maxSections) {
+ this.prepareCompleteChunkDataPacket(ProtocolVersion.MINIMUM_VERSION, ProtocolVersion.MAXIMUM_VERSION, packet, chunkSnapshot, hasSkyLight, maxSections);
+ }
+
+ /**
+ * Prepares a complete chunk that includes various packets depending on the protocol version:
+ *
+ *
{@link #createLightUpdatePacket(ChunkSnapshot, boolean) Light Update Packet} - for versions [1.14-1.17.1]
+ *
{@link #createBlockEntityDataPacket(VirtualBlockEntity.Entry) Block Entity Data Packet} - for versions [1.7.2-1.9.2]
+ *
{@link #createUpdateSignPacket(VirtualBlockEntity.Entry) Update Sign Packet} - for versions [1.7.2-1.9.2], if applicable
+ *
+ */
+ void prepareCompleteChunkDataPacket(ProtocolVersion minPrepareVersion, ProtocolVersion maxPrepareVersion, PreparedPacket packet, ChunkSnapshot chunkSnapshot, boolean hasSkyLight, int maxSections);
+
+ default Object createChunkDataPacket(ChunkSnapshot chunkSnapshot, Dimension dimension) {
+ return this.createChunkDataPacket(chunkSnapshot, dimension.hasSkyLight(), dimension.getMaxSections());
+ }
+
+ Object createChunkDataPacket(ChunkSnapshot chunkSnapshot, boolean hasSkyLight, int maxSections);
+
+ /**
+ * @sinceMinecraft 1.14
+ */
+ default Object createLightUpdatePacket(ChunkSnapshot chunkSnapshot, Dimension dimension) {
+ return this.createLightUpdatePacket(chunkSnapshot, dimension.hasSkyLight());
+ }
+
+ /**
+ * @sinceMinecraft 1.14
+ */
+ Object createLightUpdatePacket(ChunkSnapshot chunkSnapshot, boolean hasSkyLight);
+
+ Object createBlockEntityDataPacket(VirtualBlockEntity.Entry entry);
+
+ /**
+ * @param lines length should be exactly 4
+ *
+ * @deprecated Used only in [1.7.2-1.9.2]
+ */
+ @Deprecated
+ Object createUpdateSignPacket(int posX, int posY, int posZ, @NonNull Component @NonNull [] lines);
+
+ /**
+ * @deprecated Used only in [1.7.2-1.9.2]
+ */
+ @Deprecated
+ Object createUpdateSignPacket(VirtualBlockEntity.Entry entry);
+
+ Object createChunkUnloadPacket(int posX, int posZ);
+
+ /**
+ * @deprecated Use {@link PacketFactory#createDefaultSpawnPositionPacket(String, int, int, int, float, float)}
+ */
+ @Deprecated
+ Object createDefaultSpawnPositionPacket(int posX, int posY, int posZ, float angle);
+
+ Object createDefaultSpawnPositionPacket(String dimension, int posX, int posY, int posZ, float yaw, float pitch);
+
+ Object createMapDataPacket(int mapId, byte scale, MapData mapData);
+
+ /**
+ * @param id Entity id
+ * @param data See {@link EntityData} for all possible data types available
+ */
+ Object createEntityDataPacket(int id, EntityData data);
+
+ /**
+ * @param abilities See {@link AbilityFlags} (e.g. {@code AbilityFlags.ALLOW_FLYING | AbilityFlags.CREATIVE_MODE})
+ */
+ Object createPlayerAbilitiesPacket(int abilities, float flyingSpeed, float walkingSpeed);
+
+ /**
+ * @param abilities See {@link AbilityFlags} (e.g. {@code AbilityFlags.ALLOW_FLYING | AbilityFlags.CREATIVE_MODE})
+ */
+ Object createPlayerAbilitiesPacket(byte abilities, float flyingSpeed, float walkingSpeed);
+
+ @Deprecated(forRemoval = true)
+ default Object createPositionRotationPacket(double posX, double posY, double posZ, float yaw, float pitch, boolean onGround, int teleportId, boolean dismountVehicle) {
+ return this.createPlayerPositionPacket(posX, posY, posZ, yaw, pitch, onGround, teleportId, dismountVehicle);
+ }
+
+ Object createPlayerPositionPacket(double posX, double posY, double posZ, float yaw, float pitch, boolean onGround, int teleportId, boolean dismountVehicle);
+
+ Object createSetExperiencePacket(float experienceProgress, int experienceLevel, int totalExperience);
+
+ @Deprecated(forRemoval = true)
+ default Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count, int data, @Nullable CompoundBinaryTag nbt) {
+ return this.createSetSlotPacket(containerId, slot, item, count, (short) data, nbt);
+ }
+
+ @Deprecated(forRemoval = true)
+ default Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count, int data, @Nullable DataComponentMap map) {
+ return this.createSetSlotPacket(containerId, slot, item, count, (short) data, map);
+ }
+
+ Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count);
+
+ Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count, @Nullable CompoundBinaryTag nbt);
+
+ Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count, @Nullable DataComponentMap map);
+
+ Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count, short data);
+
+ Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count, short data, @Nullable CompoundBinaryTag nbt);
+
+ Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count, short data, @Nullable DataComponentMap map);
+
+ Object createSetSlotPacket(int containerId, int slot, VirtualItem item, int count, short data, @Nullable CompoundBinaryTag nbt, @Nullable DataComponentMap map);
+
+ @Deprecated(forRemoval = true)
+ default Object createTimeUpdatePacket(long gameTime, long dayTime) {
+ return this.createSetTimePacket(gameTime, dayTime);
+ }
+
+ Object createSetTimePacket(long gameTime, long dayTime);
+
+ @Deprecated(forRemoval = true)
+ default Object createUpdateViewPositionPacket(int posX, int posZ) {
+ return this.createSetChunkCacheCenter(posX, posZ);
+ }
+
+ /**
+ * @sinceMinecraft 1.14
+ */
+ Object createSetChunkCacheCenter(int posX, int posZ);
+
+ Object createUpdateTagsPacket(WorldVersion version);
+
+ Object createUpdateTagsPacket(ProtocolVersion version);
+
+ /**
+ * @sinceMinecraft 1.13
+ */
+ Object createUpdateTagsPacket(Map> tags);
+}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/protocol/packets/PacketMapping.java b/api/src/main/java/net/elytrium/limboapi/api/protocol/PacketMapping.java
similarity index 91%
rename from api/src/main/java/net/elytrium/limboapi/api/protocol/packets/PacketMapping.java
rename to api/src/main/java/net/elytrium/limboapi/api/protocol/PacketMapping.java
index 2f138150..0b74049a 100644
--- a/api/src/main/java/net/elytrium/limboapi/api/protocol/packets/PacketMapping.java
+++ b/api/src/main/java/net/elytrium/limboapi/api/protocol/PacketMapping.java
@@ -5,7 +5,7 @@
* reference the LICENSE file in the api top-level directory.
*/
-package net.elytrium.limboapi.api.protocol.packets;
+package net.elytrium.limboapi.api.protocol;
import com.velocitypowered.api.network.ProtocolVersion;
import org.checkerframework.checker.nullness.qual.Nullable;
@@ -29,10 +29,15 @@ public PacketMapping(int id, ProtocolVersion protocolVersion, @Nullable Protocol
this.encodeOnly = encodeOnly;
}
+ @Deprecated(forRemoval = true)
public int getID() {
return this.id;
}
+ public int getId() {
+ return this.id;
+ }
+
public ProtocolVersion getProtocolVersion() {
return this.protocolVersion;
}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/protocol/data/AbilityFlags.java b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/AbilityFlags.java
new file mode 100644
index 00000000..18977c87
--- /dev/null
+++ b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/AbilityFlags.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2021 - 2025 Elytrium
+ *
+ * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
+ * reference the LICENSE file in the api top-level directory.
+ */
+
+package net.elytrium.limboapi.api.protocol.data;
+
+/**
+ * For PlayerAbilities packet
+ */
+public class AbilityFlags {
+
+ public static final int INVULNERABLE = 0b0001;
+ public static final int FLYING = 0b0010;
+ public static final int ALLOW_FLYING = 0b0100;
+ public static final int CREATIVE_MODE = 0b1000;
+}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/protocol/packets/data/BiomeData.java b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/BiomeData.java
similarity index 68%
rename from api/src/main/java/net/elytrium/limboapi/api/protocol/packets/data/BiomeData.java
rename to api/src/main/java/net/elytrium/limboapi/api/protocol/data/BiomeData.java
index 73c286d7..c14bcb30 100644
--- a/api/src/main/java/net/elytrium/limboapi/api/protocol/packets/data/BiomeData.java
+++ b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/BiomeData.java
@@ -5,35 +5,35 @@
* reference the LICENSE file in the api top-level directory.
*/
-package net.elytrium.limboapi.api.protocol.packets.data;
+package net.elytrium.limboapi.api.protocol.data;
import java.util.HashMap;
import java.util.Map;
-import net.elytrium.limboapi.api.chunk.VirtualBiome;
-import net.elytrium.limboapi.api.chunk.data.ChunkSnapshot;
+import net.elytrium.limboapi.api.world.chunk.biome.VirtualBiome;
+import net.elytrium.limboapi.api.world.chunk.ChunkSnapshot;
/**
- * For ChunkData packet.
+ * For ChunkData packet
*/
public class BiomeData {
private final int[] post115Biomes = new int[1024];
- private final byte[] pre115Biomes = new byte[256];
+ private final int[] pre115Biomes = new int[256];
public BiomeData(ChunkSnapshot chunk) {
- VirtualBiome[] biomes = chunk.getBiomes();
+ VirtualBiome[] biomes = chunk.biomes();
for (int i = 0; i < biomes.length; ++i) {
- this.post115Biomes[i] = biomes[i].getID();
+ this.post115Biomes[i] = biomes[i].getId();
}
- // Down sample 4x4x4 3D biomes to 2D XZ.
+ // Down sample 4x4x4 3D biomes to 2D XZ
Map samples = new HashMap<>(64);
for (int posX = 0; posX < 16; posX += 4) {
for (int posZ = 0; posZ < 16; posZ += 4) {
samples.clear();
for (int posY = 0; posY < 256; posY += 16) {
VirtualBiome biome = biomes[/*SimpleChunk.getBiomeIndex(posX, posY, posZ)*/(posY >> 2 & 63) << 4 | (posZ >> 2 & 3) << 2 | posX >> 2 & 3];
- samples.put(biome.getID(), samples.getOrDefault(biome.getID(), 0) + 1);
+ samples.put(biome.getId(), samples.getOrDefault(biome.getId(), 0) + 1);
}
int id = samples.entrySet()
.stream()
@@ -42,7 +42,7 @@ public BiomeData(ChunkSnapshot chunk) {
.getKey();
for (int i = posX; i < posX + 4; ++i) {
for (int j = posZ; j < posZ + 4; ++j) {
- this.pre115Biomes[(j << 4) + i] = (byte) id;
+ this.pre115Biomes[(j << 4) + i] = id;
}
}
}
@@ -53,7 +53,7 @@ public int[] getPost115Biomes() {
return this.post115Biomes;
}
- public byte[] getPre115Biomes() {
+ public int[] getPre115Biomes() {
return this.pre115Biomes;
}
}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/protocol/data/BlockPos.java b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/BlockPos.java
new file mode 100644
index 00000000..270e9345
--- /dev/null
+++ b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/BlockPos.java
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2021 - 2024 Elytrium
+ *
+ * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
+ * reference the LICENSE file in the api top-level directory.
+ */
+
+package net.elytrium.limboapi.api.protocol.data;
+
+public record BlockPos(int posX, int posY, int posZ) implements EntityData.Particle.VibrationParticle.PositionSource {
+
+}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/protocol/data/ComponentHolder.java b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/ComponentHolder.java
new file mode 100644
index 00000000..80f2e373
--- /dev/null
+++ b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/ComponentHolder.java
@@ -0,0 +1,67 @@
+package net.elytrium.limboapi.api.protocol.data;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import java.util.ServiceLoader;
+import net.kyori.adventure.nbt.BinaryTag;
+import net.kyori.adventure.text.Component;
+
+public class ComponentHolder {
+
+ public static final Codec CODEC = ServiceLoader.load(Codec.class, ComponentHolder.class.getClassLoader()).iterator().next();
+
+ private final Component component;
+ private final String json;
+ private final BinaryTag binaryTag;
+
+ public ComponentHolder(Component component) {
+ this.component = component;
+ this.json = null;
+ this.binaryTag = null;
+ }
+
+ public ComponentHolder(String json) {
+ this.component = null;
+ this.json = json;
+ this.binaryTag = null;
+ }
+
+ public ComponentHolder(BinaryTag binaryTag) {
+ this.component = null;
+ this.json = null;
+ this.binaryTag = binaryTag;
+ }
+
+ public Component getComponent(ProtocolVersion version) {
+ Component component = this.component;
+ if (component == null) {
+ if (this.json != null) {
+ return ComponentHolder.CODEC.json2Component(version, this.json);
+ } else if (this.binaryTag != null) {
+ return ComponentHolder.CODEC.binaryTag2Component(version, this.binaryTag);
+ }
+ }
+
+ return component;
+ }
+
+ public String getJson(ProtocolVersion version) {
+ String json = this.json;
+ return json == null ? ComponentHolder.CODEC.component2Json(version, this.getComponent(version)) : json;
+ }
+
+ public BinaryTag getBinaryTag(ProtocolVersion version) {
+ BinaryTag binaryTag = this.binaryTag;
+ return binaryTag == null ? ComponentHolder.CODEC.component2BinaryTag(version, this.getComponent(version)) : binaryTag;
+ }
+
+ public interface Codec {
+
+ Component json2Component(ProtocolVersion version, String json);
+
+ Component binaryTag2Component(ProtocolVersion version, BinaryTag binaryTag);
+
+ String component2Json(ProtocolVersion version, Component component);
+
+ BinaryTag component2BinaryTag(ProtocolVersion version, Component component);
+ }
+}
diff --git a/api/src/main/java/net/elytrium/limboapi/api/protocol/data/EntityData.java b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/EntityData.java
new file mode 100644
index 00000000..d1dbbbc6
--- /dev/null
+++ b/api/src/main/java/net/elytrium/limboapi/api/protocol/data/EntityData.java
@@ -0,0 +1,698 @@
+/*
+ * Copyright (C) 2021 - 2024 Elytrium
+ *
+ * The LimboAPI (excluding the LimboAPI plugin) is licensed under the terms of the MIT License. For more details,
+ * reference the LICENSE file in the api top-level directory.
+ */
+
+package net.elytrium.limboapi.api.protocol.data;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
+import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.OptionalInt;
+import java.util.UUID;
+import net.elytrium.limboapi.api.world.item.datacomponent.type.PaintingVariant;
+import net.elytrium.limboapi.api.world.item.datacomponent.type.ResolvableProfile;
+import net.elytrium.limboapi.api.world.item.datacomponent.type.data.Holder;
+import net.elytrium.limboapi.api.world.item.datacomponent.type.data.HolderSet;
+import net.elytrium.limboapi.api.world.player.LimboPlayer;
+import net.kyori.adventure.nbt.CompoundBinaryTag;
+import net.kyori.adventure.nbt.EndBinaryTag;
+import org.checkerframework.checker.index.qual.Positive;
+import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.NullMarked;
+
+/**
+ * The value can be one of the following data types (note that some are version-specific):
+ *