mirror of
https://github.com/FancyInnovations/FancyPlugins.git
synced 2025-12-06 07:43:36 +00:00
Compare commits
80 Commits
59a063500f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f5d5302cc | ||
|
|
dc80615146 | ||
|
|
7fb487a344 | ||
|
|
e837ad89d3 | ||
|
|
47bb6f7a10 | ||
|
|
54572f1736 | ||
|
|
fb79b5eaed | ||
|
|
ef5109444e | ||
|
|
878fee61e7 | ||
|
|
c7fb3b0b92 | ||
|
|
9aecf99744 | ||
|
|
1bdf350594 | ||
|
|
b285b8f364 | ||
|
|
9cba1bfb31 | ||
|
|
0336844633 | ||
|
|
62f387e6b9 | ||
|
|
4ce6acf325 | ||
|
|
1bc13362c1 | ||
|
|
e1c57f8e1c | ||
|
|
bcd526db5b | ||
|
|
a22db1cbb1 | ||
|
|
18518f9c19 | ||
|
|
30898973c3 | ||
|
|
217c4c36cc | ||
|
|
6d130bd93e | ||
|
|
22f5ccca29 | ||
|
|
1422d42322 | ||
|
|
474a1c3e54 | ||
|
|
169ec91269 | ||
|
|
d6dc456f2a | ||
|
|
da7bc075aa | ||
|
|
00be6cc835 | ||
|
|
1919b3da4d | ||
|
|
529821ced6 | ||
|
|
0a6aa9da80 | ||
|
|
d7c6f1bc81 | ||
|
|
a35c2ac786 | ||
|
|
c0998aabdb | ||
|
|
09363fe010 | ||
|
|
6c1ff8a77a | ||
|
|
0d8665e5e5 | ||
|
|
b2416a14b2 | ||
|
|
ec842f7287 | ||
|
|
6fe7cbabbd | ||
|
|
0d378fa951 | ||
|
|
ccf9fe0d59 | ||
|
|
b3fc33cb95 | ||
|
|
e1ba7dd888 | ||
|
|
8735da08a6 | ||
|
|
540b3ad738 | ||
|
|
5c5f82736b | ||
|
|
a2a2d39d7e | ||
|
|
3388ae6d80 | ||
|
|
ab5826be3c | ||
|
|
24c1907eec | ||
|
|
d36af3cd00 | ||
|
|
bfd39c60b0 | ||
|
|
02fa1f0fa6 | ||
|
|
1ee7bdcd98 | ||
|
|
a27fd2e0c4 | ||
|
|
d74fd4bab1 | ||
|
|
7d5b86fd14 | ||
|
|
fb2beeb5b2 | ||
|
|
bbd361ea0d | ||
|
|
d9333f12f5 | ||
|
|
455165b0f6 | ||
|
|
f29bd13387 | ||
|
|
7cd24f18f3 | ||
|
|
9774f57ea6 | ||
|
|
232f041df0 | ||
|
|
47e0714ec7 | ||
|
|
414da48403 | ||
|
|
ac2a4f6e93 | ||
|
|
49f2dfd79a | ||
|
|
bef84f0366 | ||
|
|
1b2ec76eb5 | ||
|
|
a85384df0c | ||
|
|
2df8f839aa | ||
|
|
a74073abd2 | ||
|
|
f71c783163 |
@@ -2,8 +2,9 @@ name: Deploy FancyDialogs (release)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-plugin:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,25 +28,20 @@ jobs:
|
||||
- name: Modify gradlew permissions
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: Build deployment tool
|
||||
run: ./gradlew :tools:deployment:shadowJar
|
||||
|
||||
- name: Build FancyDialogs for Modrinth
|
||||
- name: Build
|
||||
env:
|
||||
RELEASE_CHANNEL: 'release'
|
||||
RELEASE_PLATFORM: 'modrinth'
|
||||
run: ./gradlew :plugins:fancydialogs:shadowJar
|
||||
|
||||
- name: Deploy to Modrinth
|
||||
env:
|
||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run:
|
||||
cd tools/deployment/build/libs &&
|
||||
java -jar deployment.jar modrinth ../../../../plugins/fancydialogs/release_deployment_config.json true
|
||||
- name: Deploy
|
||||
uses: fancyinnovations/fancyverteiler@main
|
||||
with:
|
||||
config_path: "/plugins/fancydialogs/release_deployment_config.json"
|
||||
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
- name: Publish to reposilite (releases)
|
||||
run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||
# - name: Publish to reposilite (releases)
|
||||
# run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||
|
||||
- name: Publish to reposilite (snapshots)
|
||||
run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
# - name: Publish to reposilite (snapshots)
|
||||
# run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
@@ -2,8 +2,9 @@ name: Deploy FancyHolograms v2 (release)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-plugin:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,25 +28,20 @@ jobs:
|
||||
- name: Modify gradlew permissions
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: Build deployment tool
|
||||
run: ./gradlew :tools:deployment:shadowJar
|
||||
|
||||
- name: Build FancyHolograms v2 for Modrinth
|
||||
- name: Build
|
||||
env:
|
||||
RELEASE_CHANNEL: 'release'
|
||||
RELEASE_PLATFORM: 'modrinth'
|
||||
run: ./gradlew :plugins:fancyholograms-v2:shadowJar
|
||||
|
||||
- name: Deploy to Modrinth
|
||||
env:
|
||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run:
|
||||
cd tools/deployment/build/libs &&
|
||||
java -jar deployment.jar modrinth ../../../../plugins/fancyholograms-v2/release_deployment_config.json true
|
||||
- name: Deploy
|
||||
uses: fancyinnovations/fancyverteiler@main
|
||||
with:
|
||||
config_path: "/plugins/fancyholograms-v2/release_deployment_config.json"
|
||||
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
- name: Publish to reposilite (releases)
|
||||
run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||
# - name: Publish to reposilite (releases)
|
||||
# run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||
|
||||
- name: Publish to reposilite (snapshots)
|
||||
run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
# - name: Publish to reposilite (snapshots)
|
||||
# run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
@@ -2,8 +2,9 @@ name: Deploy FancyHolograms (release)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-plugin:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,25 +28,20 @@ jobs:
|
||||
- name: Modify gradlew permissions
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: Build deployment tool
|
||||
run: ./gradlew :tools:deployment:shadowJar
|
||||
|
||||
- name: Build FancyHolograms for Modrinth
|
||||
- name: Build
|
||||
env:
|
||||
RELEASE_CHANNEL: 'release'
|
||||
RELEASE_PLATFORM: 'modrinth'
|
||||
run: ./gradlew :plugins:fancyholograms:shadowJar
|
||||
|
||||
- name: Deploy to Modrinth
|
||||
env:
|
||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run:
|
||||
cd tools/deployment/build/libs &&
|
||||
java -jar deployment.jar modrinth ../../../../plugins/fancyholograms/release_deployment_config.json true
|
||||
- name: Deploy
|
||||
uses: fancyinnovations/fancyverteiler@main
|
||||
with:
|
||||
config_path: "/plugins/fancyholograms/release_deployment_config.json"
|
||||
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
- name: Publish to reposilite (releases)
|
||||
run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||
# - name: Publish to reposilite (releases)
|
||||
# run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||
|
||||
- name: Publish to reposilite (snapshots)
|
||||
run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
# - name: Publish to reposilite (snapshots)
|
||||
# run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
30
.github/workflows/deploy-release-fancynpcs.yml
vendored
30
.github/workflows/deploy-release-fancynpcs.yml
vendored
@@ -2,8 +2,9 @@ name: Deploy FancyNpcs (release)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-plugin:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,25 +28,20 @@ jobs:
|
||||
- name: Modify gradlew permissions
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: Build deployment tool
|
||||
run: ./gradlew :tools:deployment:shadowJar
|
||||
|
||||
- name: Build FancyNpcs for Modrinth
|
||||
- name: Build
|
||||
env:
|
||||
RELEASE_CHANNEL: 'release'
|
||||
RELEASE_PLATFORM: 'modrinth'
|
||||
run: ./gradlew :plugins:fancynpcs:shadowJar
|
||||
|
||||
- name: Deploy to Modrinth
|
||||
env:
|
||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run:
|
||||
cd tools/deployment/build/libs &&
|
||||
java -jar deployment.jar modrinth ../../../../plugins/fancynpcs/release_deployment_config.json true
|
||||
- name: Deploy
|
||||
uses: fancyinnovations/fancyverteiler@main
|
||||
with:
|
||||
config_path: "/plugins/fancynpcs/release_deployment_config.json"
|
||||
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
- name: Publish to reposilite (releases)
|
||||
run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||
# - name: Publish to reposilite (releases)
|
||||
# run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||
|
||||
- name: Publish to reposilite (snapshots)
|
||||
run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
# - name: Publish to reposilite (snapshots)
|
||||
# run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
@@ -2,8 +2,9 @@ name: Deploy FancyDialogs (snapshot)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-fancydialogs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,22 +28,17 @@ jobs:
|
||||
- name: Modify gradlew permissions
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: Build deployment tool
|
||||
run: ./gradlew :tools:deployment:shadowJar
|
||||
|
||||
- name: Build FancyDialogs for Modrinth
|
||||
- name: Build
|
||||
env:
|
||||
RELEASE_CHANNEL: 'snapshot'
|
||||
RELEASE_PLATFORM: 'modrinth'
|
||||
run: ./gradlew :plugins:fancydialogs:shadowJar
|
||||
|
||||
- name: Deploy to Modrinth
|
||||
env:
|
||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run:
|
||||
cd tools/deployment/build/libs &&
|
||||
java -jar deployment.jar modrinth ../../../../plugins/fancydialogs/snapshot_deployment_config.json true
|
||||
- name: Deploy
|
||||
uses: fancyinnovations/fancyverteiler@main
|
||||
with:
|
||||
config_path: "/plugins/fancydialogs/snapshot_deployment_config.json"
|
||||
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
- name: Publish to reposilite (snapshots)
|
||||
run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
# - name: Publish to reposilite (snapshots)
|
||||
# run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
@@ -2,8 +2,9 @@ name: Deploy FancyHolograms v2 (snapshot)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-fancyholograms:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,22 +28,17 @@ jobs:
|
||||
- name: Modify gradlew permissions
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: Build deployment tool
|
||||
run: ./gradlew :tools:deployment:shadowJar
|
||||
|
||||
- name: Build FancyHolograms v2 for Modrinth
|
||||
- name: Build
|
||||
env:
|
||||
RELEASE_CHANNEL: 'snapshot'
|
||||
RELEASE_PLATFORM: 'modrinth'
|
||||
run: ./gradlew :plugins:fancyholograms-v2:shadowJar
|
||||
|
||||
- name: Deploy to Modrinth
|
||||
env:
|
||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run:
|
||||
cd tools/deployment/build/libs &&
|
||||
java -jar deployment.jar modrinth ../../../../plugins/fancyholograms-v2/snapshot_deployment_config.json true
|
||||
- name: Deploy
|
||||
uses: fancyinnovations/fancyverteiler@main
|
||||
with:
|
||||
config_path: "/plugins/fancyholograms-v2/snapshot_deployment_config.json"
|
||||
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
- name: Publish to reposilite (snapshots)
|
||||
run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
# - name: Publish to reposilite (snapshots)
|
||||
# run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
@@ -2,8 +2,9 @@ name: Deploy FancyHolograms (snapshot)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-plugin:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,22 +28,17 @@ jobs:
|
||||
- name: Modify gradlew permissions
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: Build deployment tool
|
||||
run: ./gradlew :tools:deployment:shadowJar
|
||||
|
||||
- name: Build FancyHolograms for Modrinth
|
||||
- name: Build
|
||||
env:
|
||||
RELEASE_CHANNEL: 'snapshot'
|
||||
RELEASE_PLATFORM: 'modrinth'
|
||||
run: ./gradlew :plugins:fancyholograms:shadowJar
|
||||
|
||||
- name: Deploy to Modrinth
|
||||
env:
|
||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run:
|
||||
cd tools/deployment/build/libs &&
|
||||
java -jar deployment.jar modrinth ../../../../plugins/fancyholograms/snapshot_deployment_config.json true
|
||||
- name: Deploy
|
||||
uses: fancyinnovations/fancyverteiler@main
|
||||
with:
|
||||
config_path: "/plugins/fancyholograms/snapshot_deployment_config.json"
|
||||
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
- name: Publish to reposilite (snapshots)
|
||||
run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
# - name: Publish to reposilite (snapshots)
|
||||
# run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
40
.github/workflows/deploy-snapshot-fancynpcs.yml
vendored
40
.github/workflows/deploy-snapshot-fancynpcs.yml
vendored
@@ -2,8 +2,9 @@ name: Deploy FancyNpcs (snapshot)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-plugin:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@@ -27,36 +28,17 @@ jobs:
|
||||
- name: Modify gradlew permissions
|
||||
run: chmod +x ./gradlew
|
||||
|
||||
- name: Build deployment tool
|
||||
run: ./gradlew :tools:deployment:shadowJar
|
||||
|
||||
- name: Build FancyNpcs for Modrinth
|
||||
- name: Build
|
||||
env:
|
||||
RELEASE_CHANNEL: 'snapshot'
|
||||
RELEASE_PLATFORM: 'modrinth'
|
||||
run: ./gradlew :plugins:fancynpcs:shadowJar
|
||||
|
||||
- name: Deploy to Modrinth
|
||||
env:
|
||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
run:
|
||||
cd tools/deployment/build/libs &&
|
||||
java -jar deployment.jar modrinth ../../../../plugins/fancynpcs/snapshot_deployment_config.json true
|
||||
- name: Deploy
|
||||
uses: fancyinnovations/fancyverteiler@main
|
||||
with:
|
||||
config_path: "/plugins/fancynpcs/snapshot_deployment_config.json"
|
||||
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
|
||||
# - name: Build FancyNpcs for Hangar
|
||||
# env:
|
||||
# RELEASE_CHANNEL: 'snapshot'
|
||||
# RELEASE_PLATFORM: 'hangar'
|
||||
# run: ./gradlew :plugins:fancynpcs:shadowJar
|
||||
#
|
||||
# - name: Deploy to Hangar
|
||||
# env:
|
||||
# HANGAR_API_KEY: "${{ secrets.HANGAR_API_KEY }}"
|
||||
# DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||
# run:
|
||||
# cd tools/deployment/build/libs &&
|
||||
# java -jar deployment.jar hangar ../../../../plugins/fancynpcs/snapshot_deployment_config.json true
|
||||
|
||||
- name: Publish to reposilite (snapshots)
|
||||
run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
# - name: Publish to reposilite (snapshots)
|
||||
# run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||
@@ -8,8 +8,8 @@
|
||||
[](https://hangar.papermc.io/Oliver)
|
||||
[]()
|
||||
|
||||
[](https://fancyplugins.de)
|
||||
[](https://docs.fancyplugins.de)
|
||||
[](https://fancyinnovations.com)
|
||||
[](https://docs.fancyinnovations.com)
|
||||
[](https://discord.gg/ZUgYCEJUEx)
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ This is a [monorepo](docs/src/development-guidelines/monorepo.md) for all plugin
|
||||
- Packets: packet handling library (also called FancySitula)
|
||||
|
||||
**Tools:**
|
||||
- Deployment: deploy plugins to platforms like modrinth
|
||||
- Quick E2E: generate a quick end-to-end environment for testing
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
plugins {
|
||||
id("com.gradleup.shadow") version "9.0.0-beta17" apply false
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.17" apply false
|
||||
id("xyz.jpenilla.run-paper") version "2.3.1" apply false
|
||||
id("de.eldoria.plugin-yml.paper") version "0.7.1" apply false
|
||||
id("io.papermc.hangar-publish-plugin") version "0.1.3" apply false
|
||||
id("com.modrinth.minotaur") version "2.+" apply false
|
||||
id("com.gradleup.shadow") version "9.2.2" apply false
|
||||
id("io.papermc.paperweight.userdev") version "2.0.0-beta.19" apply false
|
||||
id("xyz.jpenilla.run-paper") version "3.0.2" apply false
|
||||
id("de.eldoria.plugin-yml.paper") version "0.8.0" apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
||||
93
docs/src/blog/introducing-hytale-plugins.md
Normal file
93
docs/src/blog/introducing-hytale-plugins.md
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
authors:
|
||||
- name: Oliver Schlüter
|
||||
email: oliver@fancyinnovations.com
|
||||
link: https://github.com/OliverSchlueter
|
||||
avatar: https://avatars.githubusercontent.com/u/79666085?v=4
|
||||
|
||||
date: 2025-11-24
|
||||
title: "Introducing Hytale Plugins"
|
||||
description: "The first Hytale plugin by FancyInnovations will be: FancyCore, a powerful plugin that provides a wide range of features and tools for Hytale server owners."
|
||||
---
|
||||
|
||||

|
||||
|
||||
[Hytale](https://hytale.com/) is finally heading into early access, and I couldn’t be more excited. With that, I’m thrilled to announce that **FancyInnovations will be creating server-side plugins for the Hytale ecosystem**.
|
||||
|
||||
The moment I read the [“Hytale is saved!”](https://hytale.com/news/2025/11/hytale-is-saved) announcement, my brain immediately jumped into brainstorming mode.
|
||||
After digging through the currently available information about Hytale modding, one thing became very clear:
|
||||
|
||||
**Hytale needs a plugin that provides a strong set of essential features — a foundation others can build on.**
|
||||
|
||||
And that’s exactly what I’m creating.
|
||||
|
||||
## Introducing FancyCore
|
||||
|
||||
With FancyCore I want to create a platform where gamemode specific plugins can be built on. It will cover many features you probably would expect from a core plugin.
|
||||
|
||||
Let’s look at some features:
|
||||
|
||||
- Teleportation (teleport, teleport request, teleport all, spawn, warps, player homes, …)
|
||||
- World (create, teleport, change day time, weather, spawn protection, …)
|
||||
- Inventory (kits, virtual backpacks, …)
|
||||
- Economy (balance, pay, sell items, shops, …)
|
||||
- Chat (chat format, player-to-player messages, nicknames, help, rules, broadcast, mute chat, clear chat, chat rooms, …)
|
||||
- Moderation (report, warn, kick, mute, ban, chat / command history, vanish, sudo, …)
|
||||
- Permissions (groups, permissions, …)
|
||||
- Server (list online players, uptime, tps, mspt, cpu usage, ram usage, disk usage, …)
|
||||
- Player (gamemode, playtime, fly, heal, feed, god, ping, …)
|
||||
- Easy to use API
|
||||
|
||||
Notable API features:
|
||||
|
||||
- Permissions API
|
||||
- Economy API
|
||||
- Placeholder API
|
||||
|
||||
Other features for the future:
|
||||
|
||||
- Discord integration
|
||||
- Built-in WebUI
|
||||
|
||||
This is a long list of features and not all will be available on day 1.
|
||||
As I am writing this blog post, there is no public Hytale API documentation, so all I can do at the moment is write all the business logic and implement the actual commands and other Hytale specific features as soon as the API documentation is available.
|
||||
|
||||
For now, it will be a big all-in-one plugin, in the future I might create separate plugins for each category, but that's not final yet.
|
||||
|
||||
**FancyCore will be a Hytale only plugin**, I don’t plan to create a Minecraft plugin out of this at the moment.
|
||||
For now the plan is to get FancyCore working for Hytale as soon as possible while, but while keeping a good quality.
|
||||
|
||||
The plugin will be free and open-source, just like all Minecraft plugins. You can already take a look at the new mono-repo for Hytale plugins [here](https://github.com/FancyInnovations/HytalePlugins).
|
||||
Some parts that don’t require the Hytale server dependency are already being worked on.
|
||||
Feel free to take a look and contribute to it if you want.
|
||||
|
||||
Parts of the documentation is also already written (mostly the commands). You can take a look at it here.
|
||||
|
||||
From what I’ve seen, you won’t be able to upload Hytale plugins to Modrinth (just speculations).
|
||||
The only popular platform that supports distribution of Hytale plugins is Curseforge.
|
||||
I'm currently not sure if I want to distribute FancyCore there.
|
||||
In the meanwhile I’ve been programming a little download service myself to distribute Hytale plugins, so they will for sure be available on the fancyinnovations.com website.
|
||||
I know the community is currently working on alternative platforms as well, so we will see how that develops.
|
||||
|
||||
## FancyAnalytics
|
||||
|
||||
Alongside FancyCore, I’ll also be releasing FancyAnalytics for Hytale — a toolset for gathering analytics from your Hytale server or plugins.
|
||||
|
||||
It will include:
|
||||
* A Hytale plugin for collecting metrics such as online players, TPS, entity counts, CPU usage, and more
|
||||
* An SDK for plugin developers to track usage metrics, including support for custom data points
|
||||
|
||||
This gives developers powerful insight into how their plugins are used — and helps server owners better understand performance.
|
||||
|
||||
## Conclusion
|
||||
|
||||
If you’re as excited as I am about Hytale — and FancyCore — then join our Discord community!
|
||||
Assign yourself the “FancyCore” role to get all the latest updates.
|
||||
I'm currently working on it daily and will share progress updates there.
|
||||
|
||||
If you have any suggestions or feature requests for FancyCore, feel free to share them in the `#core-discussion` channel or DM me directly (`real_oliver`).
|
||||
|
||||
There’s also a dedicated channel for general Hytale news.
|
||||
(The release date for early access will be announced this week!)
|
||||
|
||||
*Oliver*
|
||||
2
docs/src/fancycore/api/api.yml
Normal file
2
docs/src/fancycore/api/api.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
icon: code
|
||||
order: 7
|
||||
30
docs/src/fancycore/api/events.md
Normal file
30
docs/src/fancycore/api/events.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
icon: dot
|
||||
order: 9
|
||||
---
|
||||
|
||||
# Events API
|
||||
|
||||
FancyCore has its own event system that allows you to listen to various events that happen in the FancyCore system.
|
||||
|
||||
## Registering an event listener
|
||||
|
||||
Example for registering a listener for the `PlayerReportedEvent`:
|
||||
|
||||
```java
|
||||
EventService eventService = EventService.get();
|
||||
|
||||
eventService.registerListener(PlayerReportedEvent.class, (event) -> {
|
||||
System.out.println("PlayerReportedEvent fired with report id: " + event.getReport().id());
|
||||
});
|
||||
```
|
||||
|
||||
## Available events
|
||||
|
||||
### Player events
|
||||
|
||||
| Event | Description |
|
||||
|-----------------------|-------------------------------------------------------------------------------|
|
||||
| `PlayerModifiedEvent` | Event fired when a player's data is modified (through FancyPlayer's setters). |
|
||||
| `PlayerReportedEvent` | Fired when a player is reported. |
|
||||
| `PlayerPunishedEvent` | Fired when a player receives a punishment (warning, kick, mute or ban). |
|
||||
51
docs/src/fancycore/api/getting-started.md
Normal file
51
docs/src/fancycore/api/getting-started.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
icon: dot
|
||||
order: 10
|
||||
---
|
||||
|
||||
# Getting started
|
||||
|
||||
## Include the API in your project
|
||||
|
||||
To include the FancyCore API in your project, you need to add the following dependency to your `build.gradle.kts` or `pom.xml` file.
|
||||
|
||||
**Gradle:**
|
||||
```kotlin
|
||||
repositories {
|
||||
maven("https://repo.fancyinnovations.com/releases")
|
||||
}
|
||||
```
|
||||
|
||||
```kotlin
|
||||
dependencies {
|
||||
compileOnly("com.fancyinnovations:FancyCore:VERSION")
|
||||
}
|
||||
```
|
||||
|
||||
**Maven:**
|
||||
```xml
|
||||
<repository>
|
||||
<id>fancyinnovations-releases</id>
|
||||
<name>FancyInnovations Repository</name>
|
||||
<url>https://repo.fancyinnovations.com/releases</url>
|
||||
</repository>
|
||||
```
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.fancyinnovations</groupId>
|
||||
<artifactId>FancyCore</artifactId>
|
||||
<version>VERSION</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
Replace `VERSION` with the version of the API you want to use. You can find the latest version on the download pages or in the GitHub releases.
|
||||
|
||||
|
||||
## JavaDocs and help
|
||||
|
||||
You can find the JavaDocs for the FancyDialogs API [here](https://repo.fancyinnovations.com/javadoc/releases/com/fancyinnovations/FancyCore/latest).
|
||||
|
||||
Join the [FancyInnovations Discord](https://discord.gg/ZUgYCEJUEx) for help and support. There is a dedicated channel for help about the api (`#core-api`).
|
||||
```
|
||||
48
docs/src/fancycore/api/placeholders.md
Normal file
48
docs/src/fancycore/api/placeholders.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
icon: dot
|
||||
order: 7
|
||||
---
|
||||
|
||||
# Placeholder API
|
||||
|
||||
FancyCore includes a Placeholders API that allows you to create and manage custom placeholders for use in various plugins.
|
||||
|
||||
## Parse placeholders
|
||||
|
||||
To parse placeholders in a string, use the `PlaceholderService`'s `parse` method. Here's an example:
|
||||
|
||||
```java
|
||||
PlaceholderService placeholderService = PlaceholderService.get();
|
||||
String parsedString = placeholderService.parse(player, "Hello, {player_name}! Your rank is {player_rank}.");
|
||||
```
|
||||
|
||||
## Creating a custom placeholder
|
||||
|
||||
To create a custom placeholder, implement the `PlaceholderProvider` interface and register it with the `PlaceholderService`. Here's an example of creating a simple placeholder that returns a player's rank:
|
||||
|
||||
```java
|
||||
public class PlayerRankPlaceholder implements PlaceholderProvider {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Player Rank Placeholder";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "player_rank";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parse(FancyPlayer player, String input) {
|
||||
return player.getRank().getName();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can then register your placeholder provider with the `PlaceholderService`:
|
||||
|
||||
```java
|
||||
PlaceholderService placeholderService = PlaceholderService.get();
|
||||
placeholderService.registerPlaceholderProvider(new PlayerRankPlaceholder());
|
||||
```
|
||||
38
docs/src/fancycore/api/punishments.md
Normal file
38
docs/src/fancycore/api/punishments.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
icon: dot
|
||||
order: 8
|
||||
---
|
||||
|
||||
# Punishment API
|
||||
|
||||
FancyCore provides a comprehensive Punishment API that allows you to manage player punishments such as warnings, kicks, mutes, and bans.
|
||||
|
||||
## Using the Punishment Service
|
||||
|
||||
With the Punishment Service, you can easily issue various types of punishments to players. Below are examples of how to use the Punishment Service:
|
||||
|
||||
```java
|
||||
PunishmentService punishmentService = PunishmentService.get();
|
||||
|
||||
punishmentService.warnPlayer(player, staff, "reason", duration);
|
||||
|
||||
punishmentService.mutePlayer(player, staff, "reason"); // Permanent mute
|
||||
punishmentService.mutePlayer(player, staff, "reason", 1000*60*60*4); // Temporary mute (4 hours)
|
||||
|
||||
punishmentService.kickPlayer(player, staff, "reason");
|
||||
|
||||
punishmentService.banPlayer(player, staff, "reason", duration); // Permanent ban
|
||||
punishmentService.banPlayer(player, staff, "reason", 1000*60*60*24); // Temporary ban (1 day)
|
||||
```
|
||||
|
||||
You can also retrieve existing punishments for a player:
|
||||
|
||||
```java
|
||||
List<Punishment> punishments = punishmentService.getPunishmentsForPlayer(player);
|
||||
```
|
||||
|
||||
Player reports are also managed through the Punishment Service:
|
||||
|
||||
```java
|
||||
punishmentService.reportPlayer(player, staff, "reason");
|
||||
```
|
||||
2
docs/src/fancycore/changelog/changelog.yml
Normal file
2
docs/src/fancycore/changelog/changelog.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
icon: log
|
||||
order: 5
|
||||
9
docs/src/fancycore/changelog/v0.md
Normal file
9
docs/src/fancycore/changelog/v0.md
Normal file
@@ -0,0 +1,9 @@
|
||||
---
|
||||
icon: dot
|
||||
title: V0
|
||||
order: 1
|
||||
---
|
||||
|
||||
# FancyCore v0.x.x
|
||||
|
||||
|
||||
99
docs/src/fancycore/commands/chat.md
Normal file
99
docs/src/fancycore/commands/chat.md
Normal file
@@ -0,0 +1,99 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Chat
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the chat system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
## Messages
|
||||
|
||||
### Message
|
||||
|
||||
Description: Sends a private message to the specified player.<br/>
|
||||
Syntax: ``/Message (player) (message)`` or ``/Msg (player) (message)``<br/>
|
||||
Permission: ``fancycore.commands.message``
|
||||
|
||||
### Reply
|
||||
|
||||
Description: Replies to the last private message received.<br/>
|
||||
Syntax: ``/Reply (message)`` or ``/R (message)``<br/>
|
||||
Permission: ``fancycore.commands.reply``
|
||||
|
||||
### Message Spy
|
||||
|
||||
Description: Toggles message spying to see private messages between other players.<br/>
|
||||
Syntax: ``/MessageSpy`` or ``/MsgSpy``<br/>
|
||||
Permission: ``fancycore.commands.messagespy``
|
||||
|
||||
### ToggleMessages
|
||||
|
||||
Description: Toggles the ability to receive private messages.<br/>
|
||||
Syntax: ``/ToggleMessages`` or ``/ToggleMsg``<br/>
|
||||
Permission: ``fancycore.commands.togglemessages``
|
||||
|
||||
## Chat rooms
|
||||
|
||||
### CreateChatRoom
|
||||
|
||||
Description: Creates a new chat room with the specified name.<br/>
|
||||
Syntax: ``/CreateChatRoom (name)`` or ``/CCR (name)``<br/>
|
||||
Permission: ``fancycore.commands.createchatroom``
|
||||
|
||||
### JoinChatRoom
|
||||
|
||||
Description: Joins the specified chat room.<br/>
|
||||
Syntax: ``/JoinChatRoom (name)`` or ``/JCR (name)``<br/>
|
||||
Permission: ``fancycore.commands.joinchatroom``
|
||||
|
||||
### LeaveChatRoom
|
||||
|
||||
Description: Leaves the current chat room.<br/>
|
||||
Syntax: ``/LeaveChatRoom`` or ``/LCR``<br/>
|
||||
Permission: ``fancycore.commands.leavechatroom``
|
||||
|
||||
### ListChatRooms
|
||||
|
||||
Description: Lists all available chat rooms on the server.<br/>
|
||||
Syntax: ``/ListChatRooms`` or ``/LCRs``<br/>
|
||||
Permission: ``fancycore.commands.listchatrooms``
|
||||
|
||||
### ChatRoomInfo
|
||||
|
||||
Description: Displays information about the specified chat room.<br/>
|
||||
Syntax: ``/ChatRoomInfo (name)`` or ``/CRInfo (name)``<br/>
|
||||
Permission: ``fancycore.commands.chatroominfo``
|
||||
|
||||
## Chat Management
|
||||
|
||||
### ClearChat
|
||||
|
||||
Description: Clears the chat for all players on the server.<br/>
|
||||
Syntax: ``/ClearChat`` or ``/CC``<br/>
|
||||
Permission: ``fancycore.commands.clearchat``
|
||||
|
||||
### SlowChat
|
||||
|
||||
Description: Sets a slow mode for chat, limiting how often players can send messages.<br/>
|
||||
Syntax: ``/SlowChat (seconds)`` or ``/Slow (seconds)``<br/>
|
||||
Permission: ``fancycore.commands.slowchat``
|
||||
|
||||
### MuteChat
|
||||
|
||||
Description: Mutes the chat for all players, preventing them from sending messages.<br/>
|
||||
Syntax: ``/MuteChat``<br/>
|
||||
Permission: ``fancycore.commands.mutechat``
|
||||
|
||||
### UnmuteChat
|
||||
|
||||
Description: Unmutes the chat, allowing players to send messages again.<br/>
|
||||
Syntax: ``/UnmuteChat``<br/>
|
||||
Permission: ``fancycore.commands.unmutechat``
|
||||
|
||||
|
||||
2
docs/src/fancycore/commands/commands.yml
Normal file
2
docs/src/fancycore/commands/commands.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
order: 9
|
||||
icon: command-palette
|
||||
49
docs/src/fancycore/commands/economy.md
Normal file
49
docs/src/fancycore/commands/economy.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Economy
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the economy system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
### Balance
|
||||
|
||||
Description: Displays the balance of the specified player or your own balance if no player is specified.<br/>
|
||||
Syntax: ``/Balance [player]``<br/>
|
||||
Permission: ``fancycore.commands.balance``
|
||||
|
||||
### Pay
|
||||
|
||||
Description: Transfers a specified amount of money from your balance to another player's balance.<br/>
|
||||
Syntax: ``/Pay (player) (amount)``<br/>
|
||||
Permission: ``fancycore.commands.pay``
|
||||
|
||||
### Set Balance
|
||||
|
||||
Description: Sets the balance of the specified player to a given amount.<br/>
|
||||
Syntax: ``/SetBalance (player) (amount)``<br/>
|
||||
Permission: ``fancycore.commands.setbalance``
|
||||
|
||||
### Add Balance
|
||||
|
||||
Description: Adds a specified amount of money to the balance of the specified player.<br/>
|
||||
Syntax: ``/AddBalance (player) (amount)``<br/>
|
||||
Permission: ``fancycore.commands.addbalance``
|
||||
|
||||
### Remove Balance
|
||||
|
||||
Description: Removes a specified amount of money from the balance of the specified player.<br/>
|
||||
Syntax: ``/RemoveBalance (player) (amount)``<br/>
|
||||
Permission: ``fancycore.commands.removebalance``
|
||||
|
||||
### Top Balances
|
||||
|
||||
Description: Displays a leaderboard of players with the highest balances.<br/>
|
||||
Syntax: ``/TopBalances [page]``<br/>
|
||||
Permission: ``fancycore.commands.topbalances``
|
||||
79
docs/src/fancycore/commands/inventory.md
Normal file
79
docs/src/fancycore/commands/inventory.md
Normal file
@@ -0,0 +1,79 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Inventory
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the inventory system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
## Kits
|
||||
|
||||
### Create Kit
|
||||
|
||||
Description: Creates a new kit with the specified name. It contains all items in your inventory<br/>
|
||||
Syntax: ``/CreateKit (name)``<br/>
|
||||
Permission: ``fancycore.commands.createkit``
|
||||
|
||||
### Delete Kit
|
||||
|
||||
Description: Deletes the specified kit.<br/>
|
||||
Syntax: ``/DeleteKit (name)``<br/>
|
||||
Permission: ``fancycore.commands.deletekit``
|
||||
|
||||
### Give Kit
|
||||
|
||||
Description: Gives the specified kit to the targeted player(s).<br/>
|
||||
Syntax: ``/Kit (name) [player]``<br/>
|
||||
Permission: ``fancycore.commands.kit.(name)``
|
||||
|
||||
### List Kits
|
||||
|
||||
Description: Lists all available kits.<br/>
|
||||
Syntax: ``/Kits`` or ``/ListKits``<br/>
|
||||
Permission: ``fancycore.commands.listkits``
|
||||
|
||||
## Backpacks
|
||||
|
||||
### Open Backpack
|
||||
|
||||
Description: Opens the specified backpack of the targeted player.<br/>
|
||||
Syntax: ``/Backpack (name) [player]``<br/>
|
||||
Permission: ``fancycore.commands.backpack``
|
||||
|
||||
### Create Backpack
|
||||
|
||||
Description: Creates a new backpack with the specified name and size.<br/>
|
||||
Syntax: ``/CreateBackpack (name) (size)``<br/>
|
||||
Permission: ``fancycore.commands.createbackpack``
|
||||
|
||||
### Delete Backpack
|
||||
|
||||
Description: Deletes the specified backpack.<br/>
|
||||
Syntax: ``/DeleteBackpack (name)``<br/>
|
||||
Permission: ``fancycore.commands.deletebackpack``
|
||||
|
||||
### List Backpacks
|
||||
|
||||
Description: Lists all available backpacks.<br/>
|
||||
Syntax: ``/Backpacks`` or ``/ListBackpacks``<br/>
|
||||
Permission: ``fancycore.commands.listbackpacks``
|
||||
|
||||
## Utilities
|
||||
|
||||
### Clear Inventory
|
||||
|
||||
Description: Clears the inventory of the targeted player(s).<br/>
|
||||
Syntax: ``/ClearInventory [player]``<br/>
|
||||
Permission: ``fancycore.commands.clearinventory``
|
||||
|
||||
### Open another Player's Inventory
|
||||
|
||||
Description: Opens the inventory of the targeted player.<br/>
|
||||
Syntax: ``/OpenInventory (player)`` or ``/Invsee (player)``<br/>
|
||||
Permission: ``fancycore.commands.openinventory``
|
||||
110
docs/src/fancycore/commands/moderation.md
Normal file
110
docs/src/fancycore/commands/moderation.md
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Moderation
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the moderation system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
## Report
|
||||
|
||||
### Report a Player
|
||||
|
||||
Description: Reports a player for misconduct.<br/>
|
||||
Syntax: ``/Report (player) [reason]``<br/>
|
||||
Permission: ``fancycore.commands.report``
|
||||
|
||||
### List Reports
|
||||
|
||||
Description: Lists all active player reports.<br/>
|
||||
Syntax: ``/Reports list``<br/>
|
||||
Permission: ``fancycore.commands.reports.list``
|
||||
|
||||
### View Report Details
|
||||
|
||||
Description: Views details of a specific report.<br/>
|
||||
Syntax: ``/Reports view (reportID)``<br/>
|
||||
Permission: ``fancycore.commands.reports.view``
|
||||
|
||||
### Close Report
|
||||
|
||||
Description: Closes a specific report.<br/>
|
||||
Syntax: ``/Reports close (reportID)``<br/>
|
||||
Permission: ``fancycore.commands.reports.close``
|
||||
|
||||
## Warn
|
||||
|
||||
### Warn a Player
|
||||
|
||||
Description: Issues a warning to a player.<br/>
|
||||
Syntax: ``/Warn (player) [reason]``<br/>
|
||||
Permission: ``fancycore.commands.warn``
|
||||
|
||||
## Mute
|
||||
|
||||
### Mute a Player
|
||||
|
||||
Description: Mutes a player, preventing them from sending chat messages.<br/>
|
||||
Syntax: ``/Mute (player) [reason]``<br/>
|
||||
Permission: ``fancycore.commands.mute``
|
||||
|
||||
### Temporary Mute a Player
|
||||
|
||||
Description: Temporarily mutes a player for a specified duration.<br/>
|
||||
Syntax: ``/Tempmute (player) (duration) [reason]``<br/>
|
||||
Permission: ``fancycore.commands.tempmute``
|
||||
|
||||
### Unmute a Player
|
||||
|
||||
Description: Unmutes a player.<br/>
|
||||
Syntax: ``/Unmute (player)``<br/>
|
||||
Permission: ``fancycore.commands.unmute``
|
||||
|
||||
|
||||
## Kick
|
||||
|
||||
### Kick a Player
|
||||
|
||||
Description: Kicks a player from the server.<br/>
|
||||
Syntax: ``/Kick (player) [reason]``<br/>
|
||||
Permission: ``fancycore.commands.kick``
|
||||
|
||||
## Ban
|
||||
|
||||
### Ban a Player
|
||||
|
||||
Description: Bans a player from the server.<br/>
|
||||
Syntax: ``/Ban (player) [reason]``<br/>
|
||||
Permission: ``fancycore.commands.ban``
|
||||
|
||||
### Temporary Ban a Player
|
||||
|
||||
Description: Temporarily bans a player from the server for a specified duration.<br/>
|
||||
Syntax: ``/Tempban (player) (duration) [reason]``<br/>
|
||||
Permission: ``fancycore.commands.tempban``
|
||||
|
||||
### Unban a Player
|
||||
|
||||
Description: Unbans a player from the server.<br/>
|
||||
Syntax: ``/Unban (player)``<br/>
|
||||
Permission: ``fancycore.commands.unban``
|
||||
|
||||
## Logs
|
||||
|
||||
### View Moderation Logs
|
||||
|
||||
Description: Views the moderation logs.<br/>
|
||||
Syntax: ``/Modlogs [player]``<br/>
|
||||
Permission: ``fancycore.commands.modlogs``
|
||||
|
||||
### View Chat Logs
|
||||
|
||||
Description: Views the chat logs.<br/>
|
||||
Syntax: ``/Chatlogs [player] [--withCommands]``<br/>
|
||||
Permission: ``fancycore.commands.chatlogs``
|
||||
107
docs/src/fancycore/commands/permissions.md
Normal file
107
docs/src/fancycore/commands/permissions.md
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Permissions
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the permissions system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
## Groups
|
||||
|
||||
### Create Group
|
||||
|
||||
Description: Creates a new group with the specified name.<br/>
|
||||
Syntax: ``/Groups create (name)``<br/>
|
||||
Permission: ``fancycore.commands.creategroup``
|
||||
|
||||
### Delete Group
|
||||
|
||||
Description: Deletes the specified permission group.<br/>
|
||||
Syntax: ``/Groups delete (name)``<br/>
|
||||
Permission: ``fancycore.commands.deletegroup``
|
||||
|
||||
### List Groups
|
||||
|
||||
Description: Lists all available permission groups.<br/>
|
||||
Syntax: ``/Groups list``<br/>
|
||||
Permission: ``fancycore.commands.listgroups``
|
||||
|
||||
### Info Group
|
||||
|
||||
Description: Displays information about the specified permission group.<br/>
|
||||
Syntax: ``/Groups info (name)``<br/>
|
||||
Permission: ``fancycore.commands.infogroup``
|
||||
|
||||
### Set Parent Group
|
||||
|
||||
Description: Sets the parent group for the specified permission group.<br/>
|
||||
Syntax: ``/Groups parent (group) set (parent)``<br/>
|
||||
Permission: ``fancycore.commands.setparentgroup``
|
||||
|
||||
### Add Permission to Group
|
||||
|
||||
Description: Adds the specified permission to the permission group.<br/>
|
||||
Syntax: ``/Groups permission (group) add (permission)``<br/>
|
||||
Permission: ``fancycore.commands.addpermtogroup``
|
||||
|
||||
### Remove Permission from Group
|
||||
|
||||
Description: Removes the specified permission from the permission group.<br/>
|
||||
Syntax: ``/Groups permission (group) remove (permission)``<br/>
|
||||
Permission: ``fancycore.commands.removepermfromgroup``
|
||||
|
||||
### Set Prefix for Group
|
||||
|
||||
Description: Sets the prefix for the specified permission group.<br/>
|
||||
Syntax: ``/Groups prefix (group) set (prefix)``<br/>
|
||||
Permission: ``fancycore.commands.setprefixforgroup``
|
||||
|
||||
### Set Suffix for Group
|
||||
|
||||
Description: Sets the suffix for the specified permission group.<br/>
|
||||
Syntax: ``/Groups suffix (group) set (suffix)``<br/>
|
||||
Permission: ``fancycore.commands.setsuffixforgroup``
|
||||
|
||||
### Add Player to Group
|
||||
|
||||
Description: Adds the specified player to the permission group.<br/>
|
||||
Syntax: ``/Groups player (player) add (group)``<br/>
|
||||
Permission: ``fancycore.commands.addplayertogroup``
|
||||
|
||||
### Remove Player from Group
|
||||
|
||||
Description: Removes the specified player from the permission group.<br/>
|
||||
Syntax: ``/Groups player (player) remove (group)``<br/>
|
||||
Permission: ``fancycore.commands.removeplayerfromgroup``
|
||||
|
||||
## Player Permissions
|
||||
|
||||
### Add Permission to Player
|
||||
|
||||
Description: Adds the specified permission to the targeted player.<br/>
|
||||
Syntax: ``/Permission add (permission) [player]``<br/>
|
||||
Permission: ``fancycore.commands.addpermtoplayer``
|
||||
|
||||
### Remove Permission from Player
|
||||
|
||||
Description: Removes the specified permission from the targeted player.<br/>
|
||||
Syntax: ``/Permission remove (permission) [player]``<br/>
|
||||
Permission: ``fancycore.commands.removepermfromplayer``
|
||||
|
||||
### Check Player Permission
|
||||
|
||||
Description: Checks if the targeted player has the specified permission.<br/>
|
||||
Syntax: ``/Permission check (permission) [player]``<br/>
|
||||
Permission: ``fancycore.commands.checkplayerperm``
|
||||
|
||||
### List Player Permissions
|
||||
|
||||
Description: Lists all permissions of the targeted player.<br/>
|
||||
Syntax: ``/Permission list [player]``<br/>
|
||||
Permission: ``fancycore.commands.listplayerperms``
|
||||
91
docs/src/fancycore/commands/player.md
Normal file
91
docs/src/fancycore/commands/player.md
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Player
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the player system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
### Gamemode
|
||||
|
||||
Description: Changes the gamemode of a player.<br/>
|
||||
Syntax: ``/Gamemode (gamemode) [player]`` or ``/GM (gamemode)``<br/>
|
||||
Permission: ``fancycore.commands.gamemode``
|
||||
|
||||
### Gamemode explorer
|
||||
|
||||
Description: Changes the gamemode of a player to explorer mode.<br/>
|
||||
Syntax: ``/gme [player]``<br/>
|
||||
Permission: ``fancycore.commands.gamemode``
|
||||
|
||||
### Gamemode creative
|
||||
|
||||
Description: Changes the gamemode of a player to creative mode.<br/>
|
||||
Syntax: ``/gmc [player]``<br/>
|
||||
Permission: ``fancycore.commands.gamemode``
|
||||
|
||||
### Fly
|
||||
|
||||
Description: Toggles fly mode for a player.<br/>
|
||||
Syntax: ``/Fly [player]``<br/>
|
||||
Permission: ``fancycore.commands.fly``
|
||||
|
||||
### Speed
|
||||
|
||||
Description: Sets the walk and fly speed of a player.<br/>
|
||||
Syntax: ``/Speed (speed) [player]``<br/>
|
||||
Permission: ``fancycore.commands.speed``
|
||||
|
||||
### Heal
|
||||
|
||||
Description: Heals a player to full health.<br/>
|
||||
Syntax: ``/Heal [player]``<br/>
|
||||
Permission: ``fancycore.commands.heal``
|
||||
|
||||
### Feed
|
||||
|
||||
Description: Feeds a player to full hunger.<br/>
|
||||
Syntax: ``/Feed [player]``<br/>
|
||||
Permission: ``fancycore.commands.feed``
|
||||
|
||||
### God mode
|
||||
|
||||
Description: Toggles god mode for a player.<br/>
|
||||
Syntax: ``/God [player]``<br/>
|
||||
Permission: ``fancycore.commands.god``
|
||||
|
||||
### Vanish
|
||||
|
||||
Description: Toggles vanish mode for a player.<br/>
|
||||
Syntax: ``/Vanish [player]``<br/>
|
||||
Permission: ``fancycore.commands.vanish``
|
||||
|
||||
### Playtime
|
||||
|
||||
Description: Displays the playtime of a player.<br/>
|
||||
Syntax: ``/Playtime [player]``<br/>
|
||||
Permission: ``fancycore.commands.playtime``
|
||||
|
||||
### Seen
|
||||
|
||||
Description: Displays the last seen time of a player.<br/>
|
||||
Syntax: ``/Seen (player)``<br/>
|
||||
Permission: ``fancycore.commands.seen``
|
||||
|
||||
### Near
|
||||
|
||||
Description: Lists players near the command sender within a specified radius.<br/>
|
||||
Syntax: ``/Near [radius]``<br/>
|
||||
Permission: ``fancycore.commands.near``
|
||||
|
||||
### Ping
|
||||
|
||||
Description: Displays the ping of a player.<br/>
|
||||
Syntax: ``/Ping [player]``<br/>
|
||||
Permission: ``fancycore.commands.ping``
|
||||
91
docs/src/fancycore/commands/server.md
Normal file
91
docs/src/fancycore/commands/server.md
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Server
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the server system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
## Server control
|
||||
|
||||
### Restart
|
||||
|
||||
Description: Restarts the server after a specified delay.<br/>
|
||||
Syntax: ``/Restart (delay)``<br/>
|
||||
Permission: ``fancycore.commands.restart``
|
||||
|
||||
### Stop
|
||||
|
||||
Description: Stops the server after a specified delay.<br/>
|
||||
Syntax: ``/Stop (delay)``<br/>
|
||||
Permission: ``fancycore.commands.stop``
|
||||
|
||||
### Save All
|
||||
|
||||
Description: Forces the server to save all data immediately.<br/>
|
||||
Syntax: ``/SaveAll``<br/>
|
||||
Permission: ``fancycore.commands.saveall``
|
||||
|
||||
## Server health
|
||||
|
||||
### Health
|
||||
|
||||
Description: Displays an overview of the server's health status.<br/>
|
||||
Syntax: ``/Health``<br/>
|
||||
Permission: ``fancycore.commands.health``
|
||||
|
||||
### TPS
|
||||
|
||||
Description: Displays the current ticks per second (TPS) of the server.<br/>
|
||||
Syntax: ``/Health tps``<br/>
|
||||
Permission: ``fancycore.commands.health.tps``
|
||||
|
||||
### Memory
|
||||
|
||||
Description: Displays the current memory usage of the server.<br/>
|
||||
Syntax: ``/Health memory``<br/>
|
||||
Permission: ``fancycore.commands.health.memory``
|
||||
|
||||
### Uptime
|
||||
|
||||
Description: Displays the server's uptime since the last restart.<br/>
|
||||
Syntax: ``/Health uptime``<br/>
|
||||
Permission: ``fancycore.commands.health.uptime``
|
||||
|
||||
### CPU Usage
|
||||
|
||||
Description: Displays the current CPU usage of the server.<br/>
|
||||
Syntax: ``/Health cpu``<br/>
|
||||
Permission: ``fancycore.commands.health.cpu``
|
||||
|
||||
### Entity Count
|
||||
|
||||
Description: Displays the total number of entities currently loaded on the server.<br/>
|
||||
Syntax: ``/Health entities``<br/>
|
||||
Permission: ``fancycore.commands.health.entities``
|
||||
|
||||
### Player Count
|
||||
|
||||
Description: Displays the current number of players online on the server.<br/>
|
||||
Syntax: ``/Health players``<br/>
|
||||
Permission: ``fancycore.commands.health.players``
|
||||
|
||||
## Players
|
||||
|
||||
### List online players
|
||||
|
||||
Description: Lists all players currently online on the server.<br/>
|
||||
Syntax: ``/OnlinePlayers``<br/>
|
||||
Permission: ``fancycore.commands.onlineplayers``
|
||||
|
||||
### List all registered players
|
||||
|
||||
Description: Lists all players registered on the server.<br/>
|
||||
Syntax: ``/RegisteredPlayers``<br/>
|
||||
Permission: ``fancycore.commands.registeredplayers``
|
||||
129
docs/src/fancycore/commands/teleportation.md
Normal file
129
docs/src/fancycore/commands/teleportation.md
Normal file
@@ -0,0 +1,129 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Teleportation
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the teleportation system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
## Player Teleportation
|
||||
|
||||
### Teleport to another player
|
||||
|
||||
Description: Teleports you or the specified player to another player's location.<br/>
|
||||
Syntax: ``/TP (target player) [destination player]`` or ``/Teleport (target player) [destination player]``<br/>
|
||||
Permission: ``fancycore.commands.tp``
|
||||
|
||||
### Teleport another player to you
|
||||
|
||||
Description: Teleports the specified player to your location.<br/>
|
||||
Syntax: ``/TPHere (player)`` or ``/TeleportHere (player)``<br/>
|
||||
Permission: ``fancycore.commands.tphere``
|
||||
|
||||
### Teleport all players to you
|
||||
|
||||
Description: Teleports all players on the server to your location.<br/>
|
||||
Syntax: ``/TPAll`` or ``/TeleportAll``<br/>
|
||||
Permission: ``fancycore.commands.tpall``
|
||||
|
||||
### Teleport to specific coordinates
|
||||
|
||||
Description: Teleports you to the specified coordinates<br/>
|
||||
Syntax: ``/TPPos (x) (y) (z) [world]`` or ``/TeleportPos (x) (y) (z) [world]``<br/>
|
||||
Permission: ``fancycore.commands.tppos``
|
||||
|
||||
### Request teleport to another player
|
||||
|
||||
Description: Sends a teleport request to another player to teleport to their location.<br/>
|
||||
Syntax: ``/TPR (player)``, ``/TPRequest (player)`` or ``/TeleportRequest (player)``<br/>
|
||||
Permission: ``fancycore.commands.tprequest``
|
||||
|
||||
### Accept teleport request
|
||||
|
||||
Description: Accepts a pending teleport request from another player.<br/>
|
||||
Syntax: ``/TPA [player]``, ``/TPAccept [player]`` or ``/TeleportAccept [player]``<br/>
|
||||
Permission: ``fancycore.commands.tpaccept``
|
||||
|
||||
### Deny teleport request
|
||||
|
||||
Description: Denies a pending teleport request from another player.<br/>
|
||||
Syntax: ``/TPD [player]``, ``/TPDeny [player]`` or ``/TeleportDeny [player]``<br/>
|
||||
Permission: ``fancycore.commands.tpdeny``
|
||||
|
||||
### Teleport back to previous location
|
||||
|
||||
Description: Teleports you back to your previous location before your last teleport.<br/>
|
||||
Syntax: ``/Back``<br/>
|
||||
Permission: ``fancycore.commands.back``
|
||||
|
||||
### Teleport to last death location
|
||||
|
||||
Description: Teleports you to the location where you last died.<br/>
|
||||
Syntax: ``/DeathBack``, ``/DeathTP`` or ``/DeathTeleport``<br/>
|
||||
Permission: ``fancycore.commands.deathback``
|
||||
|
||||
## Spawn
|
||||
|
||||
### Set spawn point
|
||||
|
||||
Description: Sets the server's spawn point to your current location.<br/>
|
||||
Syntax: ``/SetSpawn``<br/>
|
||||
Permission: ``fancycore.commands.setspawn``
|
||||
|
||||
### Teleport to spawn point
|
||||
|
||||
Description: Teleports you to the server's spawn point.<br/>
|
||||
Syntax: ``/Spawn``<br/>
|
||||
Permission: ``fancycore.commands.spawn``
|
||||
|
||||
## Warps
|
||||
|
||||
### Create a warp point
|
||||
|
||||
Description: Creates a warp point at your current location with the specified name.<br/>
|
||||
Syntax: ``/CreateWarp (name)``<br/>
|
||||
Permission: ``fancycore.commands.createwarp``
|
||||
|
||||
### Delete a warp point
|
||||
|
||||
Description: Deletes the warp point with the specified name.<br/>
|
||||
Syntax: ``/DeleteWarp (name)``<br/>
|
||||
Permission: ``fancycore.commands.deletewarp``
|
||||
|
||||
### Teleport to a warp point
|
||||
|
||||
Description: Teleports you to the warp point with the specified name.<br/>
|
||||
Syntax: ``/Warp (name)``<br/>
|
||||
Permission: ``fancycore.commands.warp.(name)``
|
||||
|
||||
### List all warp points
|
||||
|
||||
Description: Lists all available warp points on the server.<br/>
|
||||
Syntax: ``/ListWarps``, ``/Warps``<br/>
|
||||
Permission: ``fancycore.commands.listwarps``
|
||||
|
||||
## Homes
|
||||
|
||||
### Set home point
|
||||
|
||||
Description: Sets your home point to your current location.<br/>
|
||||
Syntax: ``/SetHome (name)``<br/>
|
||||
Permission: ``fancycore.commands.sethome``
|
||||
|
||||
### Delete home point
|
||||
|
||||
Description: Deletes your home point with the specified name.<br/>
|
||||
Syntax: ``/DeleteHome (name)``<br/>
|
||||
Permission: ``fancycore.commands.deletehome``
|
||||
|
||||
### Teleport to home point
|
||||
|
||||
Description: Teleports you to your home point with the specified name or the first home if no name is provided.<br/>
|
||||
Syntax: ``/Home [name]``<br/>
|
||||
Permission: ``fancycore.commands.home``
|
||||
59
docs/src/fancycore/commands/world.md
Normal file
59
docs/src/fancycore/commands/world.md
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
icon: dot
|
||||
title: World
|
||||
---
|
||||
|
||||

|
||||
|
||||
# Commands for the world management system
|
||||
|
||||
!!!warning
|
||||
The command list is not complete and not all commands are properly documented yet.
|
||||
Some commands might not be implemented yet.
|
||||
!!!
|
||||
|
||||
## World Management
|
||||
|
||||
### Create a new world
|
||||
|
||||
Description: Creates a new world with the specified name.<br/>
|
||||
Syntax: ``/CreateWorld (world name) [type]``<br/>
|
||||
Permission: ``fancycore.commands.createworld``
|
||||
|
||||
### Copy an existing world
|
||||
|
||||
Description: Creates a copy of the specified world.<br/>
|
||||
Syntax: ``/CopyWorld (source world name) (new world name)``<br/>
|
||||
Permission: ``fancycore.commands.copyworld``
|
||||
|
||||
### Delete an existing world
|
||||
|
||||
Description: Deletes the specified world from the server.<br/>
|
||||
Syntax: ``/DeleteWorld (world name)``<br/>
|
||||
Permission: ``fancycore.commands.deleteworld``
|
||||
|
||||
### List all worlds
|
||||
|
||||
Description: Lists all available worlds on the server.<br/>
|
||||
Syntax: ``/ListWorlds``, ``/Worlds``<br/>
|
||||
Permission: ``fancycore.commands.listworlds``
|
||||
|
||||
### Teleport to a world
|
||||
|
||||
Description: Teleports you to the specified world.<br/>
|
||||
Syntax: ``/World (world name)``<br/>
|
||||
Permission: ``fancycore.commands.world``
|
||||
|
||||
## Utility Commands
|
||||
|
||||
### Set weather
|
||||
|
||||
Description: Sets the weather in the current world.<br/>
|
||||
Syntax: ``/SetWeather (sun|rain)``<br/>
|
||||
Permission: ``fancycore.commands.setweather``
|
||||
|
||||
### Set time
|
||||
|
||||
Description: Sets the time of day in the current world.<br/>
|
||||
Syntax: ``/SetTime (time)``<br/>
|
||||
Permission: ``fancycore.commands.settime``
|
||||
33
docs/src/fancycore/fancycore.md
Normal file
33
docs/src/fancycore/fancycore.md
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: FancyCore [Hytale]
|
||||
icon: package
|
||||
order: 90
|
||||
---
|
||||
|
||||
#
|
||||
|
||||

|
||||
|
||||
!!!
|
||||
Essential features every Hytale server needs. From permission management over world management to economy and more.
|
||||
!!!
|
||||
|
||||
## Features
|
||||
|
||||
With FancyCore, you get a wide variety of features that are essential for running a Hytale server:
|
||||
|
||||
- **Permissions**: permission management system to control access to commands and features
|
||||
- **Economy**: robust economy system with virtual currency, shops, and trading
|
||||
- **Chat**: advanced chat management with channels, formatting, nicknames and msgs
|
||||
- **Moderation**: tools for server admins including bans, kicks, warnings, and logs
|
||||
- **World**: create and manage multiple worlds with different settings and environments
|
||||
- **Inventory**: manage player inventories, kits and player backpacks
|
||||
- **Teleportation**: spawn point, warps, player homes, and teleport requests
|
||||
- **Player**: utility commands such as fly, speed, gamemode, heal, and more
|
||||
- **Server**: view server stats and manage plugins
|
||||
- **API**: comprehensive API for developers to extend and customize FancyCore
|
||||
- **And much more!**
|
||||
|
||||
FancyCore is designed to provide all the essential features needed to build a successful Hytale server, while being easy to use and highly customizable.
|
||||
We are trying to get a usable version out as soon as possible.
|
||||
If you don't want to miss any updates, join our [Discord](https://discord.gg/ZUgYCEJUEx) and assign yourself the "FancyCore" role.
|
||||
10
docs/src/fancycore/faq.md
Normal file
10
docs/src/fancycore/faq.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
order: 6
|
||||
icon: book
|
||||
---
|
||||
# FAQ
|
||||
|
||||
### Is FancyCore available for Minecraft?
|
||||
|
||||
No, FancyCore is a Hytale only plugin. There are no plans to make it available for Minecraft at this time.
|
||||
|
||||
29
docs/src/fancycore/getting-started.md
Normal file
29
docs/src/fancycore/getting-started.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
order: 10
|
||||
icon: info
|
||||
---
|
||||
# Getting started
|
||||
|
||||
!!!danger
|
||||
Be aware that this plugin is only made for Hytale servers. Only the latest version of Hytale is supported.
|
||||
!!!
|
||||
|
||||
## Installation
|
||||
|
||||
To install FancyCore, you need to download the latest version from one of the following sources:
|
||||
|
||||
[!button size="s" icon="download" iconAlign="left" text="SOON" target="blank"]()
|
||||
|
||||
!!!warning
|
||||
It's not yet decided on which platforms FancyCore will be available.
|
||||
You keep an eye on the discord server for updates: [FancyInnovations Discord](https://discord.gg/ZUgYCEJUEx)
|
||||
!!!
|
||||
|
||||
After downloading the plugin, you can install it by placing the downloaded file in the `plugins` folder of your server.
|
||||
|
||||
Restart your server and you are ready to go!
|
||||
|
||||
To check if the plugin is installed correctly, you can use the command `/fancycore version`. If the plugin is installed correctly, it will show you the version of the plugin.
|
||||
|
||||
You can now learn more about the commands in the `Commands` section of the documentation or learn how to configure the plugin in the `Tutorials` section.
|
||||
The API documentation can be found in the `Api` section.
|
||||
14
docs/src/fancycore/placeholders/placeholders.md
Normal file
14
docs/src/fancycore/placeholders/placeholders.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
order: 8
|
||||
icon: paste
|
||||
---
|
||||
|
||||
# Placeholders
|
||||
|
||||
FancyCore provides a set of built-in placeholders that can be used in various parts of the system.
|
||||
You can use placeholders in almost any text field within FancyCore.
|
||||
FancyCore also offers an API for creating and parse placeholders programmatically, read more about it in the [API documentation](../api/placeholders.md).
|
||||
|
||||
## Built-in Placeholders
|
||||
|
||||
* [Player related placeholders](player.md)
|
||||
19
docs/src/fancycore/placeholders/player.md
Normal file
19
docs/src/fancycore/placeholders/player.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
icon: dot
|
||||
title: Player
|
||||
---
|
||||
|
||||
# Player placeholders
|
||||
|
||||
| Name | Identfier | Description | Examples outputs |
|
||||
|------------------------------------------|---------------------------|------------------------------------------------------------|----------------------------------------|
|
||||
| Player balance (formatted) | `player_balance` | Displays the player's current balance (formatted) | "0", "123", "123.45", "13,123.97" |
|
||||
| Player balance (raw) | `player_balance_raw` | Displays the player's current balance (raw) | "0", "123", "123.45", "13123.9417" |
|
||||
| Player chat color (hex) | `player_chat_color` | Displays the player's chat color in hex format | "#FF0000", "#00FF00", "#0000FF" |
|
||||
| Player first time joined | `player_first_joined` | Displays the date and time the player first joined | "2023-01-01 12:00:00" |
|
||||
| Player first time joined (raw timestamp) | `player_first_joined_raw` | Displays the raw timestamp of when the player first joined | "1672531200" |
|
||||
| Player name | `player_name` | Displays the player's name | "Simon", "OliverHD" |
|
||||
| Player nickname | `player_nickname` | Displays the player's nickname | "Oli" |
|
||||
| Player play time (formatted) | `player_play_time` | Displays the player's total play time (formatted) | "0s", "5m 30s", "2h 15m" |
|
||||
| Player play time (ms) | `player_play_time_ms` | Displays the player's total play time in milliseconds | "0", "330000", "8100000" |
|
||||
| Player UUID | `player_uuid` | Displays the player's UUID | "9b605d04-5a59-4353-bba3-2ddf570eb38a" |
|
||||
2
docs/src/fancycore/tutorials/tutorials.yml
Normal file
2
docs/src/fancycore/tutorials/tutorials.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
order: 7
|
||||
icon: mortar-board
|
||||
23
docs/src/fancydialogs/changelog/v1.md
Normal file
23
docs/src/fancydialogs/changelog/v1.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
icon: dot
|
||||
order: 2
|
||||
---
|
||||
|
||||
|
||||

|
||||
|
||||
#
|
||||
|
||||
## v1.0.1 [!badge variant="info" text="2025-11-23"] [!badge variant="danger" text="Hotfix"]
|
||||
|
||||
- Fixed player kick issue when no button or action is defined. ([#147](https://github.com/FancyInnovations/FancyPlugins/issues/147))
|
||||
|
||||
## v1.0.0 [!badge variant="info" text="2025-11-23"]
|
||||
|
||||
- Create dialogs using the [JSON schema](https://docs.fancyinnovations.com/fancydialogs/tutorials/json-schema/)
|
||||
- PlaceholderAPI and MiniMessage support in dialog texts
|
||||
- Execute actions when dialog buttons are clicked
|
||||
- Open a dialog when the user joins the server for the first time (see `welcome_dialog_id` in the config)
|
||||
- A quick actions dialog which can be opened with the `/qa` or `/quickactions` commands
|
||||
- FancyNpcs ingegration to open dialogs when interacting with NPCs (see [docs](https://docs.fancyinnovations.com/fancydialogs/tutorials/open-dialog-npc-action/))
|
||||
- API for other plugins to open dialogs (see [docs](https://docs.fancyinnovations.com/fancydialogs/api/getting-started/))
|
||||
@@ -71,7 +71,7 @@ Unregisters a dialog by its ID.
|
||||
|
||||
## Joined Players Cache
|
||||
|
||||
## Clear joined players cache
|
||||
### Clear joined players cache
|
||||
|
||||
Clears the cache of players who have joined a dialog.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: FancyDialogs [WIP]
|
||||
title: FancyDialogs
|
||||
icon: browser
|
||||
order: 90
|
||||
---
|
||||
@@ -21,11 +21,6 @@ FancyDialogs uses the new dialog feature, Minecraft introduced in **1.21.6** and
|
||||
The plugin will only for **Paper** servers on **1.21.6** or newer!
|
||||
!!!
|
||||
|
||||
!!!warning
|
||||
FancyDialogs is still in development and some features are not yet implemented.
|
||||
See the [TODO](#todo) section for more information.
|
||||
!!!
|
||||
|
||||
**Core advantages of FancyDialogs:**
|
||||
- Simple custom dialog creation (in JSON format or in code)
|
||||
- A lot of different dialog components (text, buttons, input fields, etc.)
|
||||
@@ -52,17 +47,3 @@ Common use cases are:
|
||||
- Confirmation dialogs for critical actions
|
||||
- Shop UIs (replacing inventories UIs)
|
||||
- Dialogs for quests
|
||||
|
||||
## TODO
|
||||
|
||||
- [X] Create dialogs in JSON format
|
||||
- [X] Create dialogs in code
|
||||
- [X] Customize dialog content and buttons
|
||||
- [X] Open dialogs for players (via commands or code)
|
||||
- [X] Welcome dialog for new players
|
||||
- [X] FancyNpcs integration (open_dialog action)
|
||||
- [X] Confirmation and notice dialogs (API)
|
||||
- [x] Add button action system
|
||||
- [ ] Add support for the quick action hotkey
|
||||
- [ ] Add tutorial features
|
||||
- [ ] Add input controls
|
||||
|
||||
@@ -9,6 +9,10 @@ The following examples show how to use FancyDialogs in different ways. They are
|
||||
|
||||
Almost all examples are made by the community. If you have a nice example that you want to share, feel free come to our discord server and show it to us.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
icon: dot
|
||||
order: 9
|
||||
order: 7
|
||||
---
|
||||
|
||||
# Open dialog npc action
|
||||
|
||||
13
docs/src/fancydialogs/tutorials/quick-actions.md
Normal file
13
docs/src/fancydialogs/tutorials/quick-actions.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
icon: dot
|
||||
order: 8
|
||||
---
|
||||
|
||||
# Quick actions
|
||||
|
||||
FancyDialogs doesn't support the quick-actions hotkey, but has a command to open a quick action dialog.
|
||||
To open the quick actions dialog, use the command: `/qa` or `/quickactions`.
|
||||
|
||||
You can customize the quick actions dialog in the `plugins/FancyDialogs/data/dialogs/quick_actions.json` file.
|
||||
|
||||
If you want to disable the quick actions dialog, you can set the `disable-quick-actions-dialog` option to true in the `plugins/FancyDialogs/featureFlags.yml` file.
|
||||
16
docs/src/fancydialogs/tutorials/welcome-dialog.md
Normal file
16
docs/src/fancydialogs/tutorials/welcome-dialog.md
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
icon: dot
|
||||
order: 9
|
||||
---
|
||||
|
||||
# Welcome dialog
|
||||
|
||||
You can configure a dialog to be shown to players when they join the server for the first time.
|
||||
A default welcome dialog is included with FancyDialogs, but you can customize it or create your own welcome dialog.
|
||||
|
||||
You can find the default welcome dialog in the `plugins/FancyDialogs/data/dialogs/welcome.json` file.
|
||||
Feel free to edit this file to customize the welcome dialog to your liking.
|
||||
|
||||
If you want to use another dialog as the welcome dialog, you can change the id in the `plugins/FancyDialogs/config.yml` file by changing the `welcome_dialog_id` option to the ID of your desired dialog.
|
||||
|
||||
To completely disable the welcome dialog, you can set the `disable-welcome-dialog` to true in the `plugins/FancyDialogs/featureFlags.yml` file.
|
||||
@@ -7,6 +7,17 @@ order: 2
|
||||
|
||||
#
|
||||
|
||||
## v2.8.1 [!badge variant="info" text="2025-11-25"]
|
||||
|
||||
- Removed support for 1.19.4
|
||||
- Fixed npcs randomly disappearing
|
||||
- Fixed skin mirroring for 1.21.9
|
||||
- Added inverted permission check for `need_permission` action (use prefix `!` to invert)
|
||||
- Added `/npc rotate <npc> <yaw> <pitch>` command to set NPC orientation
|
||||
- Added `swing_arm_on_update` config option
|
||||
- Added `use-minecraft-usercache` feature flag
|
||||
|
||||
|
||||
## v2.8.0 [!badge variant="info" text="2025-10-10"]
|
||||
|
||||
- Added support for 1.21.9 and 1.21.10
|
||||
|
||||
@@ -177,6 +177,13 @@ Teleports NPC to specified location.
|
||||
- **Syntax**: `/npc move_to (npc) (x) (y) (z) [world] [--look-in-my-direction]`
|
||||
- **Permissions**: `fancynpcs.command.npc.move_to`
|
||||
|
||||
### Rotate npc
|
||||
|
||||
Sets the yaw and pitch of the specified NPC.
|
||||
|
||||
- **Syntax**: `/npc rotate (npc) (yaw) (pitch)`
|
||||
- **Permissions**: `fancynpcs.command.npc.rotate`
|
||||
|
||||
### Center npc location
|
||||
|
||||
Centers the NPC to the specified location.
|
||||
|
||||
@@ -122,6 +122,10 @@ Syntax: `need_permission (permission)`
|
||||
|
||||
Example: `/npc action (npc) (trigger) add need_permission my.cool.permission`
|
||||
|
||||
!!!info
|
||||
If you add the `!` prefix to the permission, the action will be inverted. This means that the action list will be canceled if the player has the permission.
|
||||
!!!
|
||||
|
||||
### play_sound
|
||||
|
||||
Plays a sound to the player. This action is useful for creating audio feedback for the player when interacting with the NPC.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 269 KiB |
BIN
docs/src/static/fancydialogs/examples/reunionsmp-1.png
Normal file
BIN
docs/src/static/fancydialogs/examples/reunionsmp-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 717 KiB |
BIN
docs/src/static/fancydialogs/examples/reunionsmp-2.png
Normal file
BIN
docs/src/static/fancydialogs/examples/reunionsmp-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 616 KiB |
BIN
docs/src/static/logos-and-banners/fancycore-banner.png
Normal file
BIN
docs/src/static/logos-and-banners/fancycore-banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 171 KiB |
BIN
docs/src/static/logos-and-banners/fancycore-logo.png
Normal file
BIN
docs/src/static/logos-and-banners/fancycore-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
@@ -1,6 +1,5 @@
|
||||
fancylibVersion=37
|
||||
fancysitulaVersion=0.0.13
|
||||
jdbVersion=1.0.1
|
||||
plugintestsVersion=1.0.0
|
||||
org.gradle.parallel=false
|
||||
org.gradle.caching=true
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -57,6 +57,13 @@ public class Translator {
|
||||
}
|
||||
|
||||
for (File langFile : langFiles) {
|
||||
if (!langFile.isFile()) {
|
||||
continue;
|
||||
}
|
||||
if (!langFile.getName().endsWith(".yml")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
languages.add(loadLanguageFile(langFile));
|
||||
}
|
||||
|
||||
|
||||
1
libraries/config/VERSION
Normal file
1
libraries/config/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
1.0.0
|
||||
@@ -14,7 +14,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.20-R0.1-SNAPSHOT")
|
||||
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||
compileOnly("org.jetbrains:annotations:26.0.2")
|
||||
|
||||
@@ -24,9 +24,41 @@ dependencies {
|
||||
}
|
||||
|
||||
tasks {
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
name = "fancyinnovationsReleases"
|
||||
url = uri("https://repo.fancyinnovations.com/releases")
|
||||
credentials(PasswordCredentials::class)
|
||||
authentication {
|
||||
isAllowInsecureProtocol = true
|
||||
create<BasicAuthentication>("basic")
|
||||
}
|
||||
}
|
||||
|
||||
maven {
|
||||
name = "fancyinnovationsSnapshots"
|
||||
url = uri("https://repo.fancyinnovations.com/snapshots")
|
||||
credentials(PasswordCredentials::class)
|
||||
authentication {
|
||||
isAllowInsecureProtocol = true
|
||||
create<BasicAuthentication>("basic")
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
groupId = "de.oliver"
|
||||
artifactId = "config"
|
||||
version = getCFGVersion()
|
||||
from(project.components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compileJava {
|
||||
options.encoding = Charsets.UTF_8.name()
|
||||
options.release.set(21)
|
||||
options.release.set(17) //TODO change to 21, once 1.19.4 support is dropped
|
||||
}
|
||||
|
||||
java {
|
||||
@@ -47,5 +79,9 @@ tasks {
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17)) //TODO change to 21, once 1.19.4 support is dropped
|
||||
}
|
||||
|
||||
fun getCFGVersion(): String {
|
||||
return file("VERSION").readText()
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package com.fancyinnovations.config;
|
||||
|
||||
import com.google.gson.*;
|
||||
import de.oliver.fancyanalytics.logger.ExtendedFancyLogger;
|
||||
import de.oliver.fancyanalytics.logger.properties.ThrowableProperty;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ConfigJSON {
|
||||
|
||||
private final ExtendedFancyLogger logger;
|
||||
private final File configFile;
|
||||
private final Map<String, ConfigField<?>> fields;
|
||||
private final Map<String, Object> values;
|
||||
private final Gson gson;
|
||||
|
||||
public ConfigJSON(ExtendedFancyLogger logger, String configFilePath) {
|
||||
this.logger = logger;
|
||||
this.configFile = new File(configFilePath);
|
||||
this.fields = new ConcurrentHashMap<>();
|
||||
this.values = new ConcurrentHashMap<>();
|
||||
this.gson = new GsonBuilder()
|
||||
.serializeNulls()
|
||||
.setPrettyPrinting()
|
||||
.create();
|
||||
}
|
||||
|
||||
public void addField(ConfigField<?> field) {
|
||||
fields.put(field.path(), field);
|
||||
}
|
||||
|
||||
public Map<String, ConfigField<?>> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public <T> T get(String path) {
|
||||
ConfigField<?> field = fields.get(path);
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (field.forceDefault()) {
|
||||
return (T) field.defaultValue();
|
||||
}
|
||||
|
||||
Object value = values.computeIfAbsent(path, k -> field.defaultValue());
|
||||
return (T) field.type().cast(value);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
if (!configFile.exists()) {
|
||||
try {
|
||||
File parent = configFile.getParentFile();
|
||||
if (parent != null && !parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
if (!configFile.createNewFile()) {
|
||||
logger.error("Failed to create config file: " + configFile.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Error creating config file: " + configFile.getAbsolutePath(), ThrowableProperty.of(e));
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject root = new JsonObject();
|
||||
for (ConfigField<?> field : fields.values()) {
|
||||
setDefault(root, field);
|
||||
}
|
||||
|
||||
saveJson(root);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject root;
|
||||
try (FileReader reader = new FileReader(configFile)) {
|
||||
JsonElement parsed = JsonParser.parseReader(reader);
|
||||
if (parsed == null || !parsed.isJsonObject()) {
|
||||
root = new JsonObject();
|
||||
} else {
|
||||
root = parsed.getAsJsonObject();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("Error reading config file: " + configFile.getAbsolutePath(), ThrowableProperty.of(e));
|
||||
root = new JsonObject();
|
||||
}
|
||||
|
||||
boolean dirty = false;
|
||||
|
||||
for (Map.Entry<String, ConfigField<?>> entry : fields.entrySet()) {
|
||||
String path = entry.getKey();
|
||||
ConfigField<?> field = entry.getValue();
|
||||
|
||||
if (field.forRemoval()) {
|
||||
if (isSet(root, path)) {
|
||||
logger.debug("Removing path '" + path + "' from config");
|
||||
removePath(root, path);
|
||||
dirty = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonElement elem = getElement(root, path);
|
||||
if (elem != null && !elem.isJsonNull()) {
|
||||
try {
|
||||
Object deserialized = gson.fromJson(elem, (Type) field.type());
|
||||
if (deserialized != null && field.type().isInstance(deserialized)) {
|
||||
values.put(path, deserialized);
|
||||
} else {
|
||||
// Attempt numeric conversions: gson may deserialize numbers as Double
|
||||
Object converted = tryConvertNumber(deserialized, field.type());
|
||||
if (converted != null) {
|
||||
values.put(path, converted);
|
||||
} else {
|
||||
logger.warn("Value for path '" + path + "' is not of type '" + field.type().getSimpleName() + "'");
|
||||
setDefault(root, field);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
} catch (JsonSyntaxException | ClassCastException ex) {
|
||||
logger.warn("Failed to parse value for path '" + path + "': " + ex.getMessage());
|
||||
setDefault(root, field);
|
||||
dirty = true;
|
||||
}
|
||||
} else {
|
||||
logger.debug("Path '" + path + "' not found in config");
|
||||
setDefault(root, field);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty) {
|
||||
saveJson(root);
|
||||
}
|
||||
}
|
||||
|
||||
private void setDefault(JsonObject root, ConfigField<?> field) {
|
||||
logger.debug("Setting default value for path '" + field.path() + "': " + field.defaultValue());
|
||||
JsonElement elem = gson.toJsonTree(field.defaultValue(), (Type) field.type());
|
||||
setElement(root, field.path(), elem);
|
||||
// JSON does not support inline comments; descriptions are not stored.
|
||||
}
|
||||
|
||||
private void saveJson(JsonObject root) {
|
||||
try (FileWriter writer = new FileWriter(configFile)) {
|
||||
gson.toJson(root, writer);
|
||||
} catch (IOException e) {
|
||||
logger.error("Error saving config file: " + configFile.getAbsolutePath(), ThrowableProperty.of(e));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility: get JsonElement at dot-separated path, or null if absent
|
||||
*/
|
||||
private JsonElement getElement(JsonObject root, String path) {
|
||||
String[] parts = path.split("\\.");
|
||||
JsonElement current = root;
|
||||
for (String p : parts) {
|
||||
if (!current.isJsonObject()) return null;
|
||||
JsonObject obj = current.getAsJsonObject();
|
||||
if (!obj.has(p)) return null;
|
||||
current = obj.get(p);
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility: set JsonElement at dot-separated path, creating intermediate objects
|
||||
*/
|
||||
private void setElement(JsonObject root, String path, JsonElement value) {
|
||||
String[] parts = path.split("\\.");
|
||||
JsonObject current = root;
|
||||
for (int i = 0; i < parts.length - 1; i++) {
|
||||
String p = parts[i];
|
||||
if (!current.has(p) || !current.get(p).isJsonObject()) {
|
||||
JsonObject child = new JsonObject();
|
||||
current.add(p, child);
|
||||
current = child;
|
||||
} else {
|
||||
current = current.getAsJsonObject(p);
|
||||
}
|
||||
}
|
||||
current.add(parts[parts.length - 1], value);
|
||||
}
|
||||
|
||||
private boolean isSet(JsonObject root, String path) {
|
||||
return getElement(root, path) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a path (dot-separated) from the JSON object
|
||||
*/
|
||||
private void removePath(JsonObject root, String path) {
|
||||
String[] parts = path.split("\\.");
|
||||
JsonObject current = root;
|
||||
for (int i = 0; i < parts.length - 1; i++) {
|
||||
String p = parts[i];
|
||||
if (!current.has(p) || !current.get(p).isJsonObject()) {
|
||||
return;
|
||||
}
|
||||
current = current.getAsJsonObject(p);
|
||||
}
|
||||
current.remove(parts[parts.length - 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to convert numeric values (e.g., Double) to the requested numeric target type
|
||||
*/
|
||||
private Object tryConvertNumber(Object value, Class<?> target) {
|
||||
if (!(value instanceof Number)) return null;
|
||||
Number num = (Number) value;
|
||||
if (target == Integer.class || target == int.class) {
|
||||
return num.intValue();
|
||||
} else if (target == Long.class || target == long.class) {
|
||||
return num.longValue();
|
||||
} else if (target == Double.class || target == double.class) {
|
||||
return num.doubleValue();
|
||||
} else if (target == Float.class || target == float.class) {
|
||||
return num.floatValue();
|
||||
} else if (target == Short.class || target == short.class) {
|
||||
return num.shortValue();
|
||||
} else if (target == Byte.class || target == byte.class) {
|
||||
return num.byteValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
1
libraries/jdb/VERSION
Normal file
1
libraries/jdb/VERSION
Normal file
@@ -0,0 +1 @@
|
||||
1.0.4
|
||||
@@ -1,11 +1,11 @@
|
||||
plugins {
|
||||
id("java")
|
||||
id("maven-publish")
|
||||
id("com.github.johnrengelman.shadow")
|
||||
id("com.gradleup.shadow")
|
||||
}
|
||||
|
||||
group = "de.oliver"
|
||||
version = findProperty("jdbVersion") as String
|
||||
version = getJDBVersion()
|
||||
description = "Library for storing JSON data locally"
|
||||
|
||||
java {
|
||||
@@ -55,7 +55,7 @@ tasks {
|
||||
create<MavenPublication>("maven") {
|
||||
groupId = "de.oliver"
|
||||
artifactId = "JDB"
|
||||
version = findProperty("jdbVersion") as String
|
||||
version = getJDBVersion()
|
||||
from(project.components["java"])
|
||||
}
|
||||
}
|
||||
@@ -85,3 +85,7 @@ tasks {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
fun getJDBVersion(): String {
|
||||
return file("VERSION").readText()
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -16,7 +17,7 @@ import java.util.Map;
|
||||
* The JDB class provides a simple JSON document-based storage system in a specified directory.
|
||||
*/
|
||||
public class JDB {
|
||||
private final static Gson GSON = new GsonBuilder()
|
||||
public final static Gson GSON = new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.disableHtmlEscaping()
|
||||
.create();
|
||||
@@ -24,6 +25,7 @@ public class JDB {
|
||||
private static final String FILE_EXTENSION = ".json";
|
||||
private final @NotNull String basePath;
|
||||
private final @NotNull File baseDirectory;
|
||||
private final JIndex index;
|
||||
|
||||
/**
|
||||
* Constructs a new JDB instance with the specified base path.
|
||||
@@ -33,6 +35,8 @@ public class JDB {
|
||||
public JDB(@NotNull String basePath) {
|
||||
this.basePath = basePath;
|
||||
this.baseDirectory = new File(basePath);
|
||||
|
||||
this.index = JIndex.load("jdb_index", basePath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,6 +51,13 @@ public class JDB {
|
||||
public <T> T get(@NotNull String path, @NotNull Class<T> clazz) throws IOException {
|
||||
File documentFile = new File(baseDirectory, createFilePath(path));
|
||||
if (!documentFile.exists()) {
|
||||
|
||||
// Check index for alternative path
|
||||
if (index.indexMap().containsKey(path)) {
|
||||
String indexPath = index.indexMap().get(path);
|
||||
return get(indexPath, clazz);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
BufferedReader bufferedReader = Files.newBufferedReader(documentFile.toPath());
|
||||
@@ -95,6 +106,26 @@ public class JDB {
|
||||
return documents;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of documents in the specified directory path.
|
||||
*
|
||||
* @param path the relative directory path
|
||||
* @return the number of documents in the directory
|
||||
*/
|
||||
public int countDocuments(@NotNull String path) {
|
||||
File directory = new File(baseDirectory, path);
|
||||
if (!directory.exists()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
File[] files = directory.listFiles();
|
||||
if (files == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return files.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given value as a document at the specified path.
|
||||
*
|
||||
@@ -113,12 +144,40 @@ public class JDB {
|
||||
Files.write(documentFile.toPath(), json.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the given value as a document at the specified path and indexes it under additional paths.
|
||||
*/
|
||||
public <T> void set(@NotNull String path, @NotNull T value, String... indexPaths) throws IOException {
|
||||
set(path, value);
|
||||
for (String indexPath : indexPaths) {
|
||||
indexDocument(indexPath, path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indexes a document by mapping the original path to the index path.
|
||||
*
|
||||
* @param originalPath the original relative path (excluding .json extension) of the document
|
||||
* @param indexPath the index relative path (excluding .json extension) to map to the original document
|
||||
*/
|
||||
public void indexDocument(@NotNull String originalPath, @NotNull String indexPath) {
|
||||
index.indexMap().put(originalPath, indexPath);
|
||||
index.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the document(s) at the specified path.
|
||||
*
|
||||
* @param path the relative path (excluding .json extension) of the document(s) to be deleted
|
||||
*/
|
||||
public void delete(@NotNull String path) {
|
||||
for (Map.Entry<String, String> entry : new HashSet<>(index.indexMap().entrySet())) {
|
||||
if (entry.getKey().equals(path) || entry.getValue().equals(path)) {
|
||||
index.indexMap().remove(entry.getKey());
|
||||
index.save();
|
||||
}
|
||||
}
|
||||
|
||||
File file = new File(baseDirectory, path);
|
||||
if (file.isDirectory()) {
|
||||
deleteDirectory(file);
|
||||
|
||||
41
libraries/jdb/src/main/java/de/oliver/jdb/JIndex.java
Normal file
41
libraries/jdb/src/main/java/de/oliver/jdb/JIndex.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package de.oliver.jdb;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public record JIndex(
|
||||
String name,
|
||||
@SerializedName("base_path") String basePath,
|
||||
@SerializedName("index_map") Map<String, String> indexMap // key -> original path
|
||||
) {
|
||||
|
||||
public static JIndex load(String name, String basePath) {
|
||||
File indexFile = new File(basePath, name + ".json");
|
||||
if (!indexFile.exists()) {
|
||||
return new JIndex(name, basePath, new ConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
try (var reader = Files.newBufferedReader(indexFile.toPath())) {
|
||||
return JDB.GSON.fromJson(reader, JIndex.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new JIndex(name, basePath, new ConcurrentHashMap<>());
|
||||
}
|
||||
}
|
||||
|
||||
public void save() {
|
||||
File indexFile = new File(basePath, name + ".json");
|
||||
|
||||
String json = JDB.GSON.toJson(this);
|
||||
try {
|
||||
Files.write(indexFile.toPath(), json.getBytes());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -110,6 +110,23 @@ public class JDBTest {
|
||||
assertTrue(result.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCountDocuments() throws IOException {
|
||||
// Prepare
|
||||
String basePath = "./test_files/";
|
||||
JDB jdb = new JDB(basePath);
|
||||
String path = "test_files";
|
||||
jdb.set(path + "/obj1", "Test message 1");
|
||||
jdb.set(path + "/obj2", "Test message 2");
|
||||
jdb.set(path + "/obj3", "Test message 3");
|
||||
|
||||
// Act
|
||||
int count = jdb.countDocuments(path);
|
||||
|
||||
// Assert
|
||||
assertEquals(3, count);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetNewObject() throws IOException {
|
||||
// Prepare
|
||||
|
||||
@@ -21,6 +21,7 @@ dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
|
||||
|
||||
implementation(project(":libraries:packets:packets-api"))
|
||||
implementation(project(":libraries:packets:implementations:1_21_11"))
|
||||
implementation(project(":libraries:packets:implementations:1_21_9"))
|
||||
implementation(project(":libraries:packets:implementations:1_21_6"))
|
||||
implementation(project(":libraries:packets:implementations:1_21_5"))
|
||||
|
||||
23
libraries/packets/implementations/1_21_11/build.gradle.kts
Normal file
23
libraries/packets/implementations/1_21_11/build.gradle.kts
Normal file
@@ -0,0 +1,23 @@
|
||||
plugins {
|
||||
id("java-library")
|
||||
id("io.papermc.paperweight.userdev")
|
||||
}
|
||||
|
||||
paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.MOJANG_PRODUCTION
|
||||
|
||||
dependencies {
|
||||
paperweight.paperDevBundle("1.21.11-rc2-R0.1-SNAPSHOT")
|
||||
compileOnly(project(":libraries:packets:packets-api"))
|
||||
|
||||
testImplementation(project(":libraries:packets"))
|
||||
testImplementation(project(":libraries:packets:packets-api"))
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.12.2")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.12.2")
|
||||
testImplementation("org.junit.platform:junit-platform-console-standalone:1.12.2")
|
||||
}
|
||||
|
||||
tasks {
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundAddEntityPacket;
|
||||
import de.oliver.fancysitula.api.utils.AngelConverter;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class ClientboundAddEntityPacketImpl extends FS_ClientboundAddEntityPacket {
|
||||
|
||||
public ClientboundAddEntityPacketImpl(int entityId, UUID entityUUID, EntityType entityType, double x, double y, double z, float yaw, float pitch, float headYaw, int velocityX, int velocityY, int velocityZ, int data) {
|
||||
super(entityId, entityUUID, entityType, x, y, z, yaw, pitch, headYaw, velocityX, velocityY, velocityZ, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
net.minecraft.world.entity.EntityType<?> vanillaType = BuiltInRegistries.ENTITY_TYPE.getValue(CraftNamespacedKey.toMinecraft(entityType.getKey()));
|
||||
|
||||
return new ClientboundAddEntityPacket(
|
||||
entityId,
|
||||
entityUUID,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
AngelConverter.degreesToVanillaByte(pitch),
|
||||
AngelConverter.degreesToVanillaByte(yaw),
|
||||
vanillaType,
|
||||
data,
|
||||
new Vec3(velocityX, velocityY, velocityZ),
|
||||
AngelConverter.degreesToVanillaByte(headYaw)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundAddEntityPacket packet = (ClientboundAddEntityPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundClearDialogPacket;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import net.minecraft.network.protocol.common.ClientboundClearDialogPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public class ClientboundClearDialogPacketImpl extends FS_ClientboundClearDialogPacket {
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
return ClientboundClearDialogPacket.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundClearDialogPacket packet = (ClientboundClearDialogPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundCreateOrUpdateTeamPacket;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.scores.PlayerTeam;
|
||||
import net.minecraft.world.scores.Scoreboard;
|
||||
import net.minecraft.world.scores.Team;
|
||||
|
||||
public class ClientboundCreateOrUpdateTeamPacketImpl extends FS_ClientboundCreateOrUpdateTeamPacket {
|
||||
|
||||
private static final Scoreboard SCOREBOARD = new Scoreboard();
|
||||
|
||||
public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, CreateTeam createTeam) {
|
||||
super(teamName, createTeam);
|
||||
}
|
||||
|
||||
public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, RemoveTeam removeTeam) {
|
||||
super(teamName, removeTeam);
|
||||
}
|
||||
|
||||
public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, UpdateTeam updateTeam) {
|
||||
super(teamName, updateTeam);
|
||||
}
|
||||
|
||||
public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, AddEntity addEntity) {
|
||||
super(teamName, addEntity);
|
||||
}
|
||||
|
||||
public ClientboundCreateOrUpdateTeamPacketImpl(String teamName, RemoveEntity removeEntity) {
|
||||
super(teamName, removeEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
return switch (method) {
|
||||
case CREATE_TEAM -> createCreateTeamPacket();
|
||||
case REMOVE_TEAM -> createRemoveTeamPacket();
|
||||
case UPDATE_TEAM -> createUpdateTeamPacket();
|
||||
case ADD_ENTITY -> createAddEntityPacket();
|
||||
case REMOVE_ENTITY -> createRemoveEntityPacket();
|
||||
};
|
||||
}
|
||||
|
||||
private Object createCreateTeamPacket() {
|
||||
if (createTeam == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName);
|
||||
playerTeam.setDisplayName(PaperAdventure.asVanilla(createTeam.getDisplayName()));
|
||||
playerTeam.setAllowFriendlyFire(createTeam.isAllowFriendlyFire());
|
||||
playerTeam.setSeeFriendlyInvisibles(createTeam.isCanSeeFriendlyInvisibles());
|
||||
playerTeam.setNameTagVisibility(Team.Visibility.valueOf(createTeam.getNameTagVisibility().getName()));
|
||||
playerTeam.setCollisionRule(PlayerTeam.CollisionRule.valueOf(createTeam.getCollisionRule().getName()));
|
||||
playerTeam.setColor(ChatFormatting.getById(createTeam.getColor().getId()));
|
||||
playerTeam.setPlayerPrefix(PaperAdventure.asVanilla(createTeam.getPrefix()));
|
||||
playerTeam.setPlayerSuffix(PaperAdventure.asVanilla(createTeam.getSuffix()));
|
||||
for (String entity : createTeam.getEntities()) {
|
||||
playerTeam.getPlayers().add(entity);
|
||||
}
|
||||
|
||||
return ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, true);
|
||||
}
|
||||
|
||||
private Object createRemoveTeamPacket() {
|
||||
if (removeTeam == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName);
|
||||
return ClientboundSetPlayerTeamPacket.createRemovePacket(playerTeam);
|
||||
}
|
||||
|
||||
private Object createUpdateTeamPacket() {
|
||||
if (updateTeam == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName);
|
||||
playerTeam.setDisplayName(PaperAdventure.asVanilla(updateTeam.getDisplayName()));
|
||||
playerTeam.setAllowFriendlyFire(updateTeam.isAllowFriendlyFire());
|
||||
playerTeam.setSeeFriendlyInvisibles(updateTeam.isCanSeeFriendlyInvisibles());
|
||||
playerTeam.setNameTagVisibility(Team.Visibility.valueOf(updateTeam.getNameTagVisibility().getName()));
|
||||
playerTeam.setCollisionRule(PlayerTeam.CollisionRule.valueOf(updateTeam.getCollisionRule().getName()));
|
||||
playerTeam.setColor(ChatFormatting.getById(updateTeam.getColor().getId()));
|
||||
playerTeam.setPlayerPrefix(PaperAdventure.asVanilla(updateTeam.getPrefix()));
|
||||
playerTeam.setPlayerSuffix(PaperAdventure.asVanilla(updateTeam.getSuffix()));
|
||||
|
||||
return ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, true);
|
||||
}
|
||||
|
||||
private Object createAddEntityPacket() {
|
||||
if (addEntity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName);
|
||||
for (String entity : addEntity.getEntities()) {
|
||||
playerTeam.getPlayers().add(entity);
|
||||
}
|
||||
return ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(playerTeam, addEntity.getEntities(), ClientboundSetPlayerTeamPacket.Action.ADD);
|
||||
}
|
||||
|
||||
private Object createRemoveEntityPacket() {
|
||||
if (removeEntity == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PlayerTeam playerTeam = new PlayerTeam(SCOREBOARD, teamName);
|
||||
for (String entity : removeEntity.getEntities()) {
|
||||
playerTeam.getPlayers().add(entity);
|
||||
}
|
||||
return ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(playerTeam, removeEntity.getEntities(), ClientboundSetPlayerTeamPacket.Action.REMOVE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundSetPlayerTeamPacket packet = (ClientboundSetPlayerTeamPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundPlayerInfoRemovePacket;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ClientboundPlayerInfoRemovePacketImpl extends FS_ClientboundPlayerInfoRemovePacket {
|
||||
|
||||
public ClientboundPlayerInfoRemovePacketImpl(List<UUID> uuids) {
|
||||
super(uuids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
return new ClientboundPlayerInfoRemovePacket(uuids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundPlayerInfoRemovePacket packet = (ClientboundPlayerInfoRemovePacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundPlayerInfoUpdatePacket;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.GameProfileImpl;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.GameType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
|
||||
public class ClientboundPlayerInfoUpdatePacketImpl extends FS_ClientboundPlayerInfoUpdatePacket {
|
||||
|
||||
public ClientboundPlayerInfoUpdatePacketImpl(EnumSet<Action> actions, List<Entry> entries) {
|
||||
super(actions, entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> vanillaActions = EnumSet.noneOf(ClientboundPlayerInfoUpdatePacket.Action.class);
|
||||
for (FS_ClientboundPlayerInfoUpdatePacket.Action action : actions) {
|
||||
vanillaActions.add(ClientboundPlayerInfoUpdatePacket.Action.valueOf(action.name()));
|
||||
}
|
||||
|
||||
List<ClientboundPlayerInfoUpdatePacket.Entry> entries = new ArrayList<>();
|
||||
for (Entry entry : this.entries) {
|
||||
entries.add(new ClientboundPlayerInfoUpdatePacket.Entry(
|
||||
entry.uuid(),
|
||||
GameProfileImpl.asVanilla(entry.profile()),
|
||||
entry.listed(),
|
||||
entry.latency(),
|
||||
GameType.byId(entry.gameMode().getId()),
|
||||
PaperAdventure.asVanilla(entry.displayName()),
|
||||
true,
|
||||
-1,
|
||||
null // TODO: Add ChatSession support
|
||||
));
|
||||
}
|
||||
|
||||
return new ClientboundPlayerInfoUpdatePacket(vanillaActions, entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundPlayerInfoUpdatePacket packet = (ClientboundPlayerInfoUpdatePacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundRemoveEntitiesPacket;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClientboundRemoveEntitiesPacketImpl extends FS_ClientboundRemoveEntitiesPacket {
|
||||
|
||||
/**
|
||||
* @param entityIds IDs of the entities to remove
|
||||
*/
|
||||
public ClientboundRemoveEntitiesPacketImpl(List<Integer> entityIds) {
|
||||
super(entityIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
int[] ids = new int[this.entityIds.size()];
|
||||
for (int i = 0; i < this.entityIds.size(); i++) {
|
||||
ids[i] = this.entityIds.get(i);
|
||||
}
|
||||
|
||||
return new ClientboundRemoveEntitiesPacket(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundRemoveEntitiesPacket packet = (ClientboundRemoveEntitiesPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundRotateHeadPacket;
|
||||
import de.oliver.fancysitula.api.utils.AngelConverter;
|
||||
import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
public class ClientboundRotateHeadPacketImpl extends FS_ClientboundRotateHeadPacket {
|
||||
|
||||
public ClientboundRotateHeadPacketImpl(int entityId, float headYaw) {
|
||||
super(entityId, headYaw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
ClientboundRotateHeadPacket packet = null;
|
||||
|
||||
try {
|
||||
packet = ReflectionUtils.createUnsafeInstance(ClientboundRotateHeadPacket.class);
|
||||
ReflectionUtils.setFinalField(packet, "entityId", entityId);
|
||||
ReflectionUtils.setFinalField(packet, "yHeadRot", AngelConverter.degreesToVanillaByte(headYaw));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundRotateHeadPacket packet = (ClientboundRotateHeadPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundSetEntityDataPacket;
|
||||
import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.craftbukkit.block.CraftBlockState;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ClientboundSetEntityDataPacketImpl extends FS_ClientboundSetEntityDataPacket {
|
||||
|
||||
public ClientboundSetEntityDataPacketImpl(int entityId, List<EntityData> entityData) {
|
||||
super(entityId, entityData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
List<SynchedEntityData.DataValue<?>> dataValues = new ArrayList<>();
|
||||
for (EntityData data : entityData) {
|
||||
try {
|
||||
Class<?> entityClass = Class.forName(data.getAccessor().entityClassName());
|
||||
net.minecraft.network.syncher.EntityDataAccessor<Object> accessor = ReflectionUtils.getStaticField(entityClass, data.getAccessor().accessorFieldName());
|
||||
|
||||
Object vanillaValue = data.getValue();
|
||||
|
||||
if (data.getValue() == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data.getValue() instanceof Component c) {
|
||||
vanillaValue = PaperAdventure.asVanilla(c);
|
||||
}
|
||||
|
||||
if (data.getValue() instanceof ItemStack i) {
|
||||
vanillaValue = net.minecraft.world.item.ItemStack.fromBukkitCopy(i);
|
||||
}
|
||||
|
||||
if (data.getValue() instanceof BlockState b) {
|
||||
vanillaValue = ((CraftBlockState) b).getHandle();
|
||||
}
|
||||
|
||||
dataValues.add(SynchedEntityData.DataValue.create(accessor, vanillaValue));
|
||||
} catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return new ClientboundSetEntityDataPacket(entityId, dataValues);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundSetEntityDataPacket packet = (ClientboundSetEntityDataPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundSetEquipmentPacket;
|
||||
import de.oliver.fancysitula.api.utils.FS_EquipmentSlot;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.EquipmentSlot;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ClientboundSetEquipmentPacketImpl extends FS_ClientboundSetEquipmentPacket {
|
||||
|
||||
public ClientboundSetEquipmentPacketImpl(int entityId, Map<FS_EquipmentSlot, ItemStack> equipment) {
|
||||
super(entityId, equipment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
List<Pair<net.minecraft.world.entity.EquipmentSlot, net.minecraft.world.item.ItemStack>> slots = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<FS_EquipmentSlot, ItemStack> entry : equipment.entrySet()) {
|
||||
EquipmentSlot equipmentSlot = net.minecraft.world.entity.EquipmentSlot.byName(entry.getKey().name().toLowerCase());
|
||||
net.minecraft.world.item.ItemStack itemStack = CraftItemStack.asNMSCopy(entry.getValue());
|
||||
|
||||
slots.add(Pair.of(equipmentSlot, itemStack));
|
||||
}
|
||||
|
||||
return new ClientboundSetEquipmentPacket(entityId, slots);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundSetEquipmentPacket packet = (ClientboundSetEquipmentPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundSetPassengersPacket;
|
||||
import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClientboundSetPassengersPacketImpl extends FS_ClientboundSetPassengersPacket {
|
||||
|
||||
public ClientboundSetPassengersPacketImpl(int entityId, List<Integer> passengers) {
|
||||
super(entityId, passengers);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
int[] passengers = new int[this.passengers.size()];
|
||||
for (int i = 0; i < this.passengers.size(); i++) {
|
||||
passengers[i] = this.passengers.get(i);
|
||||
}
|
||||
|
||||
try {
|
||||
ClientboundSetPassengersPacket packet = ReflectionUtils.createUnsafeInstance(ClientboundSetPassengersPacket.class);
|
||||
ReflectionUtils.setFinalField(packet, "vehicle", entityId);
|
||||
ReflectionUtils.setFinalField(packet, "passengers", passengers);
|
||||
return packet;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundSetPassengersPacket packet = (ClientboundSetPassengersPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.dialogs.FS_CommonDialogData;
|
||||
import de.oliver.fancysitula.api.dialogs.FS_Dialog;
|
||||
import de.oliver.fancysitula.api.dialogs.FS_DialogAction;
|
||||
import de.oliver.fancysitula.api.dialogs.actions.FS_CommonButtonData;
|
||||
import de.oliver.fancysitula.api.dialogs.actions.FS_DialogActionButton;
|
||||
import de.oliver.fancysitula.api.dialogs.actions.FS_DialogCustomAction;
|
||||
import de.oliver.fancysitula.api.dialogs.body.FS_DialogBody;
|
||||
import de.oliver.fancysitula.api.dialogs.body.FS_DialogItemBody;
|
||||
import de.oliver.fancysitula.api.dialogs.body.FS_DialogTextBody;
|
||||
import de.oliver.fancysitula.api.dialogs.inputs.*;
|
||||
import de.oliver.fancysitula.api.dialogs.types.FS_ConfirmationDialog;
|
||||
import de.oliver.fancysitula.api.dialogs.types.FS_DialogListDialog;
|
||||
import de.oliver.fancysitula.api.dialogs.types.FS_MultiActionDialog;
|
||||
import de.oliver.fancysitula.api.dialogs.types.FS_NoticeDialog;
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundShowDialogPacket;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.protocol.common.ClientboundShowDialogPacket;
|
||||
import net.minecraft.resources.Identifier;
|
||||
import net.minecraft.server.dialog.*;
|
||||
import net.minecraft.server.dialog.action.Action;
|
||||
import net.minecraft.server.dialog.action.CustomAll;
|
||||
import net.minecraft.server.dialog.body.DialogBody;
|
||||
import net.minecraft.server.dialog.body.ItemBody;
|
||||
import net.minecraft.server.dialog.body.PlainMessage;
|
||||
import net.minecraft.server.dialog.input.*;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class ClientboundShowDialogPacketImpl extends FS_ClientboundShowDialogPacket {
|
||||
|
||||
public ClientboundShowDialogPacketImpl(FS_Dialog dialog) {
|
||||
super(dialog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
Holder<Dialog> holder = Holder.direct(toNms(dialog));
|
||||
return new ClientboundShowDialogPacket(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundShowDialogPacket packet = (ClientboundShowDialogPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
|
||||
private Dialog toNms(FS_Dialog dialog) {
|
||||
if (dialog instanceof FS_NoticeDialog notice) {
|
||||
return noticeToNms(notice);
|
||||
} else if (dialog instanceof FS_ConfirmationDialog confirmation) {
|
||||
return confirmationToNms(confirmation);
|
||||
} else if (dialog instanceof FS_DialogListDialog dialogList) {
|
||||
return dialogListToNms(dialogList);
|
||||
} else if (dialog instanceof FS_MultiActionDialog multiActionDialog) {
|
||||
return multiActionDialogToNms(multiActionDialog);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Dialog noticeToNms(FS_NoticeDialog notice) {
|
||||
CommonDialogData common = commonToNms(notice.getDialogData());
|
||||
ActionButton actionButton = actionButtonToNms(notice.getActionButton());
|
||||
|
||||
return new NoticeDialog(common, actionButton);
|
||||
}
|
||||
|
||||
private Dialog confirmationToNms(FS_ConfirmationDialog notice) {
|
||||
CommonDialogData common = commonToNms(notice.getDialogData());
|
||||
ActionButton yes = actionButtonToNms(notice.getYesButton());
|
||||
ActionButton no = actionButtonToNms(notice.getNoButton());
|
||||
|
||||
return new ConfirmationDialog(common, yes, no);
|
||||
}
|
||||
|
||||
private Dialog dialogListToNms(FS_DialogListDialog dialogList) {
|
||||
CommonDialogData common = commonToNms(dialogList.getDialogData());
|
||||
List<Holder<Dialog>> dialogs = new ArrayList<>();
|
||||
|
||||
for (FS_Dialog dialog : dialogList.getDialogs()) {
|
||||
dialogs.add(Holder.direct(toNms(dialog)));
|
||||
}
|
||||
|
||||
HolderSet<Dialog> dialogSet = HolderSet.direct(dialogs);
|
||||
|
||||
Optional<ActionButton> exitButton = dialogList.getExitButton() != null ?
|
||||
Optional.of(actionButtonToNms(dialogList.getExitButton())) :
|
||||
Optional.empty();
|
||||
|
||||
return new DialogListDialog(common, dialogSet, exitButton, dialogList.getColumns(), dialogList.getButtonWidth());
|
||||
}
|
||||
|
||||
private Dialog multiActionDialogToNms(FS_MultiActionDialog multiActionDialog) {
|
||||
CommonDialogData common = commonToNms(multiActionDialog.getDialogData());
|
||||
List<ActionButton> actionButtons = new ArrayList<>();
|
||||
|
||||
for (FS_DialogActionButton actionButton : multiActionDialog.getActions()) {
|
||||
actionButtons.add(actionButtonToNms(actionButton));
|
||||
}
|
||||
|
||||
Optional<ActionButton> exitAction = multiActionDialog.getExitAction() != null ?
|
||||
Optional.of(actionButtonToNms(multiActionDialog.getExitAction())) :
|
||||
Optional.empty();
|
||||
|
||||
return new MultiActionDialog(common, actionButtons, exitAction, multiActionDialog.getColumns());
|
||||
}
|
||||
|
||||
private CommonDialogData commonToNms(FS_CommonDialogData dialogData) {
|
||||
Component title = PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(dialogData.getTitle()));
|
||||
|
||||
Optional<Component> externalTitle = dialogData.getExternalTitle() != null ?
|
||||
Optional.of(PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(dialogData.getExternalTitle()))) :
|
||||
Optional.empty();
|
||||
|
||||
return new CommonDialogData(
|
||||
title,
|
||||
externalTitle,
|
||||
dialogData.isCanCloseWithEscape(),
|
||||
dialogData.isPause(),
|
||||
actionToNms(dialogData.getAfterAction()),
|
||||
bodyToNms(dialogData.getBody()),
|
||||
inputsToNms(dialogData.getInputs())
|
||||
);
|
||||
}
|
||||
|
||||
private DialogAction actionToNms(FS_DialogAction dialogAction) {
|
||||
return switch (dialogAction) {
|
||||
case CLOSE -> DialogAction.CLOSE;
|
||||
case NONE -> DialogAction.NONE;
|
||||
case WAIT_FOR_RESPONSE -> DialogAction.WAIT_FOR_RESPONSE;
|
||||
};
|
||||
}
|
||||
|
||||
private List<DialogBody> bodyToNms(List<FS_DialogBody> bodies) {
|
||||
List<DialogBody> nmsBodies = new ArrayList<>();
|
||||
|
||||
for (FS_DialogBody body : bodies) {
|
||||
if (body instanceof FS_DialogTextBody textBody) {
|
||||
nmsBodies.add(new PlainMessage(
|
||||
PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(textBody.getText())),
|
||||
textBody.getWidth()
|
||||
));
|
||||
} else if (body instanceof FS_DialogItemBody itemBody) {
|
||||
Optional<PlainMessage> description = itemBody.getDescription() != null ?
|
||||
Optional.of(new PlainMessage(
|
||||
PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(itemBody.getDescription().getText())),
|
||||
itemBody.getDescription().getWidth()
|
||||
)) :
|
||||
Optional.empty();
|
||||
|
||||
nmsBodies.add(new ItemBody(
|
||||
CraftItemStack.asNMSCopy(itemBody.getItem()),
|
||||
description,
|
||||
itemBody.isShowDecorations(),
|
||||
itemBody.isShowTooltip(),
|
||||
itemBody.getWidth(),
|
||||
itemBody.getHeight()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return nmsBodies;
|
||||
}
|
||||
|
||||
private List<Input> inputsToNms(List<FS_DialogInput> inputs) {
|
||||
List<Input> nmsInputs = new ArrayList<>();
|
||||
|
||||
for (FS_DialogInput input : inputs) {
|
||||
String key = input.getKey();
|
||||
|
||||
InputControl control = null;
|
||||
if (input.getControl() instanceof FS_DialogBooleanInput booleanInput) {
|
||||
control = new BooleanInput(
|
||||
PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(booleanInput.getLabel())),
|
||||
booleanInput.isInitial(),
|
||||
booleanInput.getOnTrue(),
|
||||
booleanInput.getOnFalse()
|
||||
);
|
||||
} else if (input.getControl() instanceof FS_DialogNumberRangeInput numberRangeInput) {
|
||||
control = new NumberRangeInput(
|
||||
numberRangeInput.getWidth(),
|
||||
PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(numberRangeInput.getLabel())),
|
||||
numberRangeInput.getLabelFormat(),
|
||||
new NumberRangeInput.RangeInfo(
|
||||
numberRangeInput.getStart(),
|
||||
numberRangeInput.getEnd(),
|
||||
numberRangeInput.getInitial() != null ? Optional.of(numberRangeInput.getInitial()) : Optional.empty(),
|
||||
numberRangeInput.getStep() != null ? Optional.of(numberRangeInput.getStep()) : Optional.empty()
|
||||
)
|
||||
);
|
||||
} else if (input.getControl() instanceof FS_DialogSingleOptionInput singleOptionInput) {
|
||||
List<SingleOptionInput.Entry> nmsEntries = new ArrayList<>();
|
||||
for (FS_DialogSingleOptionInput.Entry entry : singleOptionInput.getEntries()) {
|
||||
nmsEntries.add(new SingleOptionInput.Entry(
|
||||
entry.getId(),
|
||||
entry.getDisplay() != null ? Optional.of(PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(entry.getDisplay()))) : Optional.empty(),
|
||||
entry.isInitial()
|
||||
));
|
||||
}
|
||||
|
||||
control = new SingleOptionInput(
|
||||
singleOptionInput.getWidth(),
|
||||
nmsEntries,
|
||||
PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(singleOptionInput.getLabel())),
|
||||
singleOptionInput.isLabelVisible()
|
||||
);
|
||||
} else if (input.getControl() instanceof FS_DialogTextInput textInput) {
|
||||
control = new TextInput(
|
||||
textInput.getWidth(),
|
||||
PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(textInput.getLabel())),
|
||||
textInput.isLabelVisible(),
|
||||
textInput.getInitial(),
|
||||
textInput.getMaxLength(),
|
||||
Optional.empty()
|
||||
);
|
||||
}
|
||||
|
||||
nmsInputs.add(new Input(key, control));
|
||||
}
|
||||
|
||||
return nmsInputs;
|
||||
}
|
||||
|
||||
private ActionButton actionButtonToNms(FS_DialogActionButton actionButton) {
|
||||
CommonButtonData buttonData = commonButtonDataToNms(actionButton.getButtonData());
|
||||
|
||||
Action action = null;
|
||||
if (actionButton.getAction() instanceof FS_DialogCustomAction customAction) {
|
||||
Key idKey = Key.key("fancysitula", customAction.getId());
|
||||
Identifier idLocation = PaperAdventure.asVanilla(idKey);
|
||||
|
||||
Optional<CompoundTag> additions;
|
||||
if (customAction.getAdditions() != null) {
|
||||
CompoundTag tag = new CompoundTag();
|
||||
customAction.getAdditions().forEach(tag::putString);
|
||||
additions = Optional.of(tag);
|
||||
} else {
|
||||
additions = Optional.empty();
|
||||
}
|
||||
|
||||
action = new CustomAll(idLocation, additions);
|
||||
}
|
||||
|
||||
Optional<Action> optionalAction = action != null ?
|
||||
Optional.of(action) :
|
||||
Optional.empty();
|
||||
|
||||
return new ActionButton(buttonData, optionalAction);
|
||||
}
|
||||
|
||||
private CommonButtonData commonButtonDataToNms(FS_CommonButtonData commonButtonData) {
|
||||
Component label = PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(commonButtonData.getLabel()));
|
||||
Optional<Component> tooltip = commonButtonData.getTooltip() != null ?
|
||||
Optional.of(PaperAdventure.asVanilla(MiniMessage.miniMessage().deserialize(commonButtonData.getTooltip()))) :
|
||||
Optional.empty();
|
||||
int width = commonButtonData.getWidth();
|
||||
|
||||
return new CommonButtonData(label, tooltip, width);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.entities.FS_RealPlayer;
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundTeleportEntityPacket;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.utils.VanillaPlayerAdapter;
|
||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.PositionMoveRotation;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class ClientboundTeleportEntityPacketImpl extends FS_ClientboundTeleportEntityPacket {
|
||||
|
||||
public ClientboundTeleportEntityPacketImpl(int entityId, double x, double y, double z, float yaw, float pitch, boolean onGround) {
|
||||
super(entityId, x, y, z, yaw, pitch, onGround);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createPacket() {
|
||||
ClientboundTeleportEntityPacket packet = new ClientboundTeleportEntityPacket(
|
||||
entityId,
|
||||
new PositionMoveRotation(
|
||||
new Vec3(x, y, z),
|
||||
Vec3.ZERO,
|
||||
yaw,
|
||||
pitch
|
||||
),
|
||||
Set.of(),
|
||||
onGround
|
||||
);
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendPacketTo(FS_RealPlayer player) {
|
||||
ClientboundTeleportEntityPacket packet = (ClientboundTeleportEntityPacket) createPacket();
|
||||
|
||||
ServerPlayer vanillaPlayer = VanillaPlayerAdapter.asVanilla(player.getBukkitPlayer());
|
||||
vanillaPlayer.connection.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.utils;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import de.oliver.fancysitula.api.utils.FS_GameProfile;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class GameProfileImpl {
|
||||
|
||||
public static GameProfile asVanilla(FS_GameProfile gameProfile) {
|
||||
GameProfile gf = new GameProfile(gameProfile.getUUID(), gameProfile.getName());
|
||||
|
||||
for (Map.Entry<String, FS_GameProfile.Property> entry : gameProfile.getProperties().entrySet()) {
|
||||
FS_GameProfile.Property property = entry.getValue();
|
||||
|
||||
gf.properties().put(entry.getKey(), new com.mojang.authlib.properties.Property(property.name(), property.value(), property.signature()));
|
||||
}
|
||||
|
||||
return gf;
|
||||
}
|
||||
|
||||
public static FS_GameProfile fromVanilla(GameProfile gameProfile) {
|
||||
FS_GameProfile fsGameProfile = new FS_GameProfile(gameProfile.id(), gameProfile.name());
|
||||
|
||||
for (Map.Entry<String, com.mojang.authlib.properties.Property> entry : gameProfile.properties().entries()) {
|
||||
com.mojang.authlib.properties.Property property = entry.getValue();
|
||||
|
||||
fsGameProfile.getProperties().put(entry.getKey(), new FS_GameProfile.Property(property.name(), property.value(), property.signature()));
|
||||
}
|
||||
|
||||
return fsGameProfile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.utils;
|
||||
|
||||
import de.oliver.fancysitula.api.packets.FS_ServerboundCustomClickActionPacket;
|
||||
import de.oliver.fancysitula.api.packets.FS_ServerboundPacket;
|
||||
import de.oliver.fancysitula.api.utils.FS_PacketListener;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import net.minecraft.nbt.StringTag;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.common.ServerboundCustomClickActionPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PacketListenerImpl extends FS_PacketListener {
|
||||
|
||||
private static final String PIPELINE_NAME = "fancysitula-packet-injector";
|
||||
|
||||
public PacketListenerImpl(FS_ServerboundPacket.Type packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(Player player) {
|
||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
||||
|
||||
Channel channel = serverPlayer.connection.connection.channel;
|
||||
|
||||
if (channel.pipeline().get(PIPELINE_NAME) != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
channel.pipeline().addAfter("decoder", PIPELINE_NAME, new MessageToMessageDecoder<Packet<?>>() {
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, Packet<?> msg, List<Object> out) {
|
||||
out.add(msg);
|
||||
|
||||
FS_ServerboundPacket.Type packetType = getPacketType(msg);
|
||||
if (packetType == null) {
|
||||
return; // Unsupported packet type
|
||||
}
|
||||
|
||||
if (packet == FS_ServerboundPacket.Type.ALL) {
|
||||
FS_ServerboundPacket fsPacket = convert(packetType, msg);
|
||||
PacketReceivedEvent packetReceivedEvent = new PacketReceivedEvent(fsPacket, player);
|
||||
listeners.forEach(listener -> listener.accept(packetReceivedEvent));
|
||||
return;
|
||||
}
|
||||
|
||||
if (packet == packetType) {
|
||||
FS_ServerboundPacket fsPacket = convert(packetType, msg);
|
||||
PacketReceivedEvent packetReceivedEvent = new PacketReceivedEvent(fsPacket, player);
|
||||
listeners.forEach(listener -> listener.accept(packetReceivedEvent));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private FS_ServerboundPacket.Type getPacketType(Packet<?> packet) {
|
||||
String className = packet.getClass().getSimpleName();
|
||||
for (FS_ServerboundPacket.Type type : FS_ServerboundPacket.Type.values()) {
|
||||
if (type.getPacketClassName().equalsIgnoreCase(className)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private FS_ServerboundPacket convert(FS_ServerboundPacket.Type type, Packet<?> packet) {
|
||||
switch (type) {
|
||||
case CUSTOM_CLICK_ACTION -> {
|
||||
ServerboundCustomClickActionPacket customClickActionPacket = (ServerboundCustomClickActionPacket) packet;
|
||||
|
||||
Map<String, String> payload = new HashMap<>();
|
||||
if (customClickActionPacket.payload().isPresent() && customClickActionPacket.payload().get().asCompound().isPresent()) {
|
||||
customClickActionPacket.payload().get().asCompound().get().forEach((k, v) -> {
|
||||
if (v.getType().getName().equals(StringTag.TYPE.getName())) {
|
||||
if (v.asString().isPresent()) {
|
||||
payload.put(k, v.asString().get());
|
||||
}
|
||||
} else if (v.getType().getName().equals(net.minecraft.nbt.ByteTag.TYPE.getName())) {
|
||||
if (v.asBoolean().isPresent()) {
|
||||
payload.put(k, String.valueOf(v.asBoolean().get()));
|
||||
} else if (v.asByte().isPresent()) {
|
||||
payload.put(k, String.valueOf(v.asByte().get()));
|
||||
}
|
||||
} else {
|
||||
payload.put(k, v.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return new FS_ServerboundCustomClickActionPacket(
|
||||
type,
|
||||
PaperAdventure.asAdventure(customClickActionPacket.id()),
|
||||
payload
|
||||
);
|
||||
}
|
||||
// Add more cases for other packet types as needed
|
||||
default -> throw new IllegalArgumentException("Unsupported packet type: " + type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_11.utils;
|
||||
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class VanillaPlayerAdapter {
|
||||
|
||||
public static ServerPlayer asVanilla(Player p) {
|
||||
return ((CraftPlayer) p).getHandle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.utils.AngelConverter;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundAddEntityPacketImpl;
|
||||
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
class ClientboundAddEntityPacketImplTest {
|
||||
|
||||
//TODO: Fix this test (registry problems)
|
||||
// @Test
|
||||
void createPacket() {
|
||||
int entityId = 10000;
|
||||
UUID entityUUID = UUID.randomUUID();
|
||||
EntityType entityType = EntityType.PIG;
|
||||
|
||||
double x = 5;
|
||||
double y = 57;
|
||||
double z = 203;
|
||||
|
||||
float yaw = 142;
|
||||
float pitch = 247;
|
||||
float headYaw = 90;
|
||||
|
||||
int velocityX = 0;
|
||||
int velocityY = 0;
|
||||
int velocityZ = 0;
|
||||
|
||||
int data = 0;
|
||||
|
||||
ClientboundAddEntityPacketImpl packet = new ClientboundAddEntityPacketImpl(
|
||||
entityId,
|
||||
entityUUID,
|
||||
entityType,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
yaw,
|
||||
pitch,
|
||||
headYaw,
|
||||
velocityX,
|
||||
velocityY,
|
||||
velocityZ,
|
||||
data
|
||||
);
|
||||
|
||||
ClientboundAddEntityPacket createdPacket = (ClientboundAddEntityPacket) packet.createPacket();
|
||||
|
||||
assert createdPacket.getId() == entityId;
|
||||
assert createdPacket.getUUID().equals(entityUUID);
|
||||
assert createdPacket.getType().getDescriptionId().equals(entityType.getKey().getKey());
|
||||
assert createdPacket.getX() == x;
|
||||
assert createdPacket.getY() == y;
|
||||
assert createdPacket.getZ() == z;
|
||||
assert createdPacket.getYRot() == AngelConverter.degreesToVanillaByte(yaw);
|
||||
assert createdPacket.getXRot() == AngelConverter.degreesToVanillaByte(pitch);
|
||||
assert createdPacket.getYHeadRot() == AngelConverter.degreesToVanillaByte(headYaw);
|
||||
assert createdPacket.getMovement().x == velocityX;
|
||||
assert createdPacket.getMovement().y == velocityY;
|
||||
assert createdPacket.getMovement().z == velocityZ;
|
||||
assert createdPacket.getData() == data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundClearDialogPacketImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ClientboundClearDialogPacketImplTest {
|
||||
|
||||
@Test
|
||||
void createPacket() {
|
||||
ClientboundClearDialogPacketImpl packet = new ClientboundClearDialogPacketImpl();
|
||||
assert packet.createPacket() != null : "Packet creation failed";
|
||||
// assert packet.equals(ClientboundClearDialogPacket.INSTANCE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundPlayerInfoRemovePacketImpl;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
class ClientboundPlayerInfoRemovePacketImplTest {
|
||||
|
||||
@Test
|
||||
void createPacket() {
|
||||
List<UUID> uuids = List.of(UUID.randomUUID(), UUID.randomUUID());
|
||||
|
||||
ClientboundPlayerInfoRemovePacketImpl packet = new ClientboundPlayerInfoRemovePacketImpl(uuids);
|
||||
ClientboundPlayerInfoRemovePacket vanillaPacket = (ClientboundPlayerInfoRemovePacket) packet.createPacket();
|
||||
|
||||
for (UUID uuid : uuids) {
|
||||
assert vanillaPacket.profileIds().contains(uuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundPlayerInfoUpdatePacket;
|
||||
import de.oliver.fancysitula.api.utils.FS_GameProfile;
|
||||
import de.oliver.fancysitula.api.utils.FS_GameType;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundPlayerInfoUpdatePacketImpl;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
class ClientboundPlayerInfoUpdatePacketImplTest {
|
||||
|
||||
@Test
|
||||
void createPacket() {
|
||||
// Setup packet
|
||||
EnumSet<FS_ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.noneOf(FS_ClientboundPlayerInfoUpdatePacket.Action.class);
|
||||
actions.add(FS_ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||
actions.add(FS_ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME);
|
||||
actions.add(FS_ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED);
|
||||
|
||||
FS_GameProfile gameProfile = new FS_GameProfile(UUID.randomUUID(), "Test name");
|
||||
boolean listed = true;
|
||||
int latency = 42;
|
||||
FS_GameType gameMode = FS_GameType.SURVIVAL;
|
||||
Component displayName = Component.text("Test displayname");
|
||||
|
||||
List<FS_ClientboundPlayerInfoUpdatePacket.Entry> entries = new ArrayList<>();
|
||||
entries.add(new FS_ClientboundPlayerInfoUpdatePacket.Entry(
|
||||
gameProfile.getUUID(),
|
||||
gameProfile,
|
||||
listed,
|
||||
latency,
|
||||
gameMode,
|
||||
displayName
|
||||
));
|
||||
|
||||
ClientboundPlayerInfoUpdatePacketImpl packet = new ClientboundPlayerInfoUpdatePacketImpl(actions, entries);
|
||||
|
||||
ClientboundPlayerInfoUpdatePacket createdPacket = (ClientboundPlayerInfoUpdatePacket) packet.createPacket();
|
||||
|
||||
assert createdPacket.entries().size() == 1;
|
||||
assert createdPacket.actions().size() == 3;
|
||||
|
||||
// check entry
|
||||
ClientboundPlayerInfoUpdatePacket.Entry entry = createdPacket.entries().getFirst();
|
||||
assert entry.profile().id().equals(gameProfile.getUUID());
|
||||
assert entry.profile().name().equals(gameProfile.getName());
|
||||
assert entry.listed() == listed;
|
||||
assert entry.latency() == latency;
|
||||
assert entry.gameMode().getId() == gameMode.getId();
|
||||
|
||||
// check actions
|
||||
assert createdPacket.actions().contains(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
||||
assert createdPacket.actions().contains(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME);
|
||||
assert createdPacket.actions().contains(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundRemoveEntitiesPacketImpl;
|
||||
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class ClientboundRemoveEntitiesPacketImplTest {
|
||||
|
||||
@Test
|
||||
void createPacket() {
|
||||
List<Integer> entityIds = List.of(95, 120, 154, 187);
|
||||
|
||||
ClientboundRemoveEntitiesPacketImpl packet = new ClientboundRemoveEntitiesPacketImpl(entityIds);
|
||||
ClientboundRemoveEntitiesPacket createdPacket = (ClientboundRemoveEntitiesPacket) packet.createPacket();
|
||||
|
||||
assert createdPacket.getEntityIds().size() == entityIds.size();
|
||||
assert createdPacket.getEntityIds().containsAll(entityIds);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundRotateHeadPacketImpl;
|
||||
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ClientboundRotateHeadPacketImplTest {
|
||||
|
||||
@Test
|
||||
void createPacket() throws Exception {
|
||||
int entityId = 184;
|
||||
float headYaw = 45;
|
||||
|
||||
ClientboundRotateHeadPacketImpl packet = new ClientboundRotateHeadPacketImpl(entityId, (byte) headYaw);
|
||||
ClientboundRotateHeadPacket createdPacket = (ClientboundRotateHeadPacket) packet.createPacket();
|
||||
|
||||
assert ReflectionUtils.getField(createdPacket, "entityId").equals(entityId);
|
||||
assert createdPacket.getYHeadRot() == headYaw;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundSetEntityDataPacket;
|
||||
import de.oliver.fancysitula.api.utils.entityData.FS_TextDisplayData;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetEntityDataPacketImpl;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class ClientboundSetEntityDataPacketImplTest {
|
||||
|
||||
//TODO: Fix this test (using registry)
|
||||
// @Test
|
||||
void createPacket() {
|
||||
int entityId = 712;
|
||||
List<FS_ClientboundSetEntityDataPacket.EntityData> entityData = List.of(
|
||||
new FS_ClientboundSetEntityDataPacket.EntityData(
|
||||
FS_TextDisplayData.TEXT,
|
||||
"Hello, World!"
|
||||
)
|
||||
);
|
||||
|
||||
ClientboundSetEntityDataPacketImpl packet = new ClientboundSetEntityDataPacketImpl(entityId, entityData);
|
||||
ClientboundSetEntityDataPacket createdPacket = (ClientboundSetEntityDataPacket) packet.createPacket();
|
||||
|
||||
assert createdPacket.id() == entityId;
|
||||
assert createdPacket.packedItems().size() == 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.utils.FS_EquipmentSlot;
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetEquipmentPacketImpl;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
class ClientboundSetEquipmentPacketImplTest {
|
||||
|
||||
//TODO: Fix this test (registry problems)
|
||||
// @Test
|
||||
void createPacket() {
|
||||
// Setup packet
|
||||
Map<FS_EquipmentSlot, ItemStack> equipment = Map.of(
|
||||
FS_EquipmentSlot.MAINHAND, new ItemStack(Material.DIAMOND_SWORD),
|
||||
FS_EquipmentSlot.OFFHAND, new ItemStack(Material.SHIELD),
|
||||
FS_EquipmentSlot.HEAD, new ItemStack(Material.DIAMOND_HELMET)
|
||||
);
|
||||
|
||||
ClientboundSetEquipmentPacketImpl packet = new ClientboundSetEquipmentPacketImpl(42, equipment);
|
||||
ClientboundSetEquipmentPacket createdPacket = (ClientboundSetEquipmentPacket) packet.createPacket();
|
||||
|
||||
assert createdPacket.getEntity() == 42;
|
||||
assert createdPacket.getSlots().size() == 3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetPassengersPacketImpl;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ClientboundSetPassengersPacketImplTest {
|
||||
|
||||
@Test
|
||||
void createPacket() {
|
||||
// Setup packet
|
||||
int vehicleID = 712;
|
||||
List<Integer> passengers = new ArrayList<>();
|
||||
passengers.add(571);
|
||||
passengers.add(572);
|
||||
|
||||
ClientboundSetPassengersPacketImpl packet = new ClientboundSetPassengersPacketImpl(vehicleID, passengers);
|
||||
ClientboundSetPassengersPacket createdPacket = (ClientboundSetPassengersPacket) packet.createPacket();
|
||||
|
||||
// Check packet
|
||||
assert createdPacket.getVehicle() == vehicleID;
|
||||
assert createdPacket.getPassengers().length == 2;
|
||||
assert createdPacket.getPassengers()[0] == 571;
|
||||
assert createdPacket.getPassengers()[1] == 572;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundTeleportEntityPacketImpl;
|
||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class ClientboundTeleportEntityPacketImplTest {
|
||||
|
||||
@Test
|
||||
void createPacket() {
|
||||
int entityId = 4313;
|
||||
double x = 15.0;
|
||||
double y = 57.0;
|
||||
double z = -27.0;
|
||||
float yaw = 90.0f;
|
||||
float pitch = 45.0f;
|
||||
boolean onGround = true;
|
||||
|
||||
ClientboundTeleportEntityPacketImpl packet = new ClientboundTeleportEntityPacketImpl(entityId, x, y, z, yaw, pitch, onGround);
|
||||
ClientboundTeleportEntityPacket createdPacket = (ClientboundTeleportEntityPacket) packet.createPacket();
|
||||
|
||||
assert createdPacket != null;
|
||||
assert createdPacket.id() == entityId;
|
||||
assert createdPacket.change().position().x == x;
|
||||
assert createdPacket.change().position().y == y;
|
||||
assert createdPacket.change().position().z == z;
|
||||
assert createdPacket.change().xRot() == pitch;
|
||||
assert createdPacket.change().yRot() == yaw;
|
||||
assert createdPacket.onGround() == onGround;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.utils.AngelConverter;
|
||||
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
|
||||
@@ -56,9 +56,9 @@ class ClientboundAddEntityPacketImplTest {
|
||||
assert createdPacket.getYRot() == AngelConverter.degreesToVanillaByte(yaw);
|
||||
assert createdPacket.getXRot() == AngelConverter.degreesToVanillaByte(pitch);
|
||||
assert createdPacket.getYHeadRot() == AngelConverter.degreesToVanillaByte(headYaw);
|
||||
assert createdPacket.getXa() == velocityX;
|
||||
assert createdPacket.getYa() == velocityY;
|
||||
assert createdPacket.getZa() == velocityZ;
|
||||
assert createdPacket.getMovement().x == velocityX;
|
||||
assert createdPacket.getMovement().y == velocityY;
|
||||
assert createdPacket.getMovement().z == velocityZ;
|
||||
assert createdPacket.getData() == data;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundPlayerInfoUpdatePacket;
|
||||
import de.oliver.fancysitula.api.utils.FS_GameProfile;
|
||||
@@ -47,8 +47,8 @@ class ClientboundPlayerInfoUpdatePacketImplTest {
|
||||
|
||||
// check entry
|
||||
ClientboundPlayerInfoUpdatePacket.Entry entry = createdPacket.entries().getFirst();
|
||||
assert entry.profile().getId().equals(gameProfile.getUUID());
|
||||
assert entry.profile().getName().equals(gameProfile.getName());
|
||||
assert entry.profile().id().equals(gameProfile.getUUID());
|
||||
assert entry.profile().name().equals(gameProfile.getName());
|
||||
assert entry.listed() == listed;
|
||||
assert entry.latency() == latency;
|
||||
assert entry.gameMode().getId() == gameMode.getId();
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.utils.reflections.ReflectionUtils;
|
||||
import net.minecraft.network.protocol.game.ClientboundRotateHeadPacket;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.packets.FS_ClientboundSetEntityDataPacket;
|
||||
import de.oliver.fancysitula.api.utils.entityData.FS_TextDisplayData;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import de.oliver.fancysitula.api.utils.FS_EquipmentSlot;
|
||||
import net.minecraft.network.protocol.game.ClientboundSetEquipmentPacket;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import net.minecraft.network.protocol.game.ClientboundSetPassengersPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -1,4 +1,4 @@
|
||||
package de.oliver.fancysitula.versions.v1_21_6.packets;
|
||||
package de.oliver.fancysitula.versions.v1_21_9.packets;
|
||||
|
||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -7,6 +7,7 @@ import java.util.List;
|
||||
|
||||
public enum ServerVersion {
|
||||
|
||||
v1_21_11("1.21.11 Release Candidate 2", 774),
|
||||
v1_21_10("1.21.10", 773),
|
||||
v1_21_9("1.21.9", 773),
|
||||
v1_21_8("1.21.8", 772),
|
||||
|
||||
@@ -28,6 +28,9 @@ public class PacketFactory {
|
||||
List<FS_ClientboundPlayerInfoUpdatePacket.Entry> entries
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundPlayerInfoUpdatePacketImpl(actions, entries);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundPlayerInfoUpdatePacketImpl(actions, entries);
|
||||
}
|
||||
@@ -73,6 +76,9 @@ public class PacketFactory {
|
||||
int velocityZ,
|
||||
int data) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundAddEntityPacketImpl(entityId, entityUUID, entityType, x, y, z, yaw, pitch, headYaw, velocityX, velocityY, velocityZ, data);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundAddEntityPacketImpl(entityId, entityUUID, entityType, x, y, z, yaw, pitch, headYaw, velocityX, velocityY, velocityZ, data);
|
||||
}
|
||||
@@ -105,6 +111,9 @@ public class PacketFactory {
|
||||
List<UUID> uuids
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundPlayerInfoRemovePacketImpl(uuids);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundPlayerInfoRemovePacketImpl(uuids);
|
||||
}
|
||||
@@ -137,6 +146,9 @@ public class PacketFactory {
|
||||
List<Integer> entityIds
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundRemoveEntitiesPacketImpl(entityIds);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundRemoveEntitiesPacketImpl(entityIds);
|
||||
}
|
||||
@@ -181,6 +193,9 @@ public class PacketFactory {
|
||||
boolean onGround
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundTeleportEntityPacketImpl(entityId, x, y, z, yaw, pitch, onGround);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundTeleportEntityPacketImpl(entityId, x, y, z, yaw, pitch, onGround);
|
||||
}
|
||||
@@ -215,6 +230,9 @@ public class PacketFactory {
|
||||
float headYaw
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundRotateHeadPacketImpl(entityId, headYaw);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundRotateHeadPacketImpl(entityId, headYaw);
|
||||
}
|
||||
@@ -249,6 +267,9 @@ public class PacketFactory {
|
||||
List<FS_ClientboundSetEntityDataPacket.EntityData> entityData
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetEntityDataPacketImpl(entityId, entityData);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundSetEntityDataPacketImpl(entityId, entityData);
|
||||
}
|
||||
@@ -283,6 +304,9 @@ public class PacketFactory {
|
||||
Map<FS_EquipmentSlot, ItemStack> equipment
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetEquipmentPacketImpl(entityId, equipment);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundSetEquipmentPacketImpl(entityId, equipment);
|
||||
}
|
||||
@@ -317,6 +341,9 @@ public class PacketFactory {
|
||||
List<Integer> passengers
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundSetPassengersPacketImpl(entityId, passengers);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundSetPassengersPacketImpl(entityId, passengers);
|
||||
}
|
||||
@@ -354,6 +381,9 @@ public class PacketFactory {
|
||||
FS_ClientboundCreateOrUpdateTeamPacket.CreateTeam createTeam
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, createTeam);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, createTeam);
|
||||
}
|
||||
@@ -390,6 +420,9 @@ public class PacketFactory {
|
||||
FS_ClientboundCreateOrUpdateTeamPacket.RemoveTeam removeTeam
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, removeTeam);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, removeTeam);
|
||||
}
|
||||
@@ -426,6 +459,9 @@ public class PacketFactory {
|
||||
FS_ClientboundCreateOrUpdateTeamPacket.UpdateTeam updateTeam
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, updateTeam);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, updateTeam);
|
||||
}
|
||||
@@ -462,6 +498,9 @@ public class PacketFactory {
|
||||
FS_ClientboundCreateOrUpdateTeamPacket.AddEntity addEntity
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, addEntity);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, addEntity);
|
||||
}
|
||||
@@ -498,6 +537,9 @@ public class PacketFactory {
|
||||
FS_ClientboundCreateOrUpdateTeamPacket.RemoveEntity removeEntity
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, removeEntity);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundCreateOrUpdateTeamPacketImpl(teamName, removeEntity);
|
||||
}
|
||||
@@ -531,6 +573,9 @@ public class PacketFactory {
|
||||
FS_Dialog dialog
|
||||
) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundShowDialogPacketImpl(dialog);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundShowDialogPacketImpl(dialog);
|
||||
}
|
||||
@@ -549,6 +594,9 @@ public class PacketFactory {
|
||||
*/
|
||||
public FS_ClientboundClearDialogPacket createClearDialogPacket() {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.packets.ClientboundClearDialogPacketImpl();
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.packets.ClientboundClearDialogPacketImpl();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@ public class PacketListenerFactory {
|
||||
|
||||
public FS_PacketListener createPacketListener(FS_ServerboundPacket.Type packet) {
|
||||
switch (ServerVersion.getCurrentVersion()) {
|
||||
case v1_21_11 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_11.utils.PacketListenerImpl(packet);
|
||||
}
|
||||
case v1_21_9, v1_21_10 -> {
|
||||
return new de.oliver.fancysitula.versions.v1_21_9.utils.PacketListenerImpl(packet);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user