mirror of
https://github.com/FancyInnovations/FancyPlugins.git
synced 2025-12-06 07:43:36 +00:00
Compare commits
52 Commits
a2a2d39d7e
...
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 | ||
|
|
f71c783163 |
@@ -2,8 +2,9 @@ name: Deploy FancyDialogs (release)
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-plugin:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -27,25 +28,20 @@ jobs:
|
|||||||
- name: Modify gradlew permissions
|
- name: Modify gradlew permissions
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build deployment tool
|
- name: Build
|
||||||
run: ./gradlew :tools:deployment:shadowJar
|
|
||||||
|
|
||||||
- name: Build FancyDialogs for Modrinth
|
|
||||||
env:
|
env:
|
||||||
RELEASE_CHANNEL: 'release'
|
RELEASE_CHANNEL: 'release'
|
||||||
RELEASE_PLATFORM: 'modrinth'
|
|
||||||
run: ./gradlew :plugins:fancydialogs:shadowJar
|
run: ./gradlew :plugins:fancydialogs:shadowJar
|
||||||
|
|
||||||
- name: Deploy to Modrinth
|
- name: Deploy
|
||||||
env:
|
uses: fancyinnovations/fancyverteiler@main
|
||||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
with:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
config_path: "/plugins/fancydialogs/release_deployment_config.json"
|
||||||
run:
|
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||||
cd tools/deployment/build/libs &&
|
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
java -jar deployment.jar modrinth ../../../../plugins/fancydialogs/release_deployment_config.json true
|
|
||||||
|
|
||||||
- name: Publish to reposilite (releases)
|
# - name: Publish to reposilite (releases)
|
||||||
run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
# run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||||
|
|
||||||
- name: Publish to reposilite (snapshots)
|
# - name: Publish to reposilite (snapshots)
|
||||||
run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
# run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||||
@@ -2,8 +2,9 @@ name: Deploy FancyHolograms v2 (release)
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-plugin:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -27,25 +28,20 @@ jobs:
|
|||||||
- name: Modify gradlew permissions
|
- name: Modify gradlew permissions
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build deployment tool
|
- name: Build
|
||||||
run: ./gradlew :tools:deployment:shadowJar
|
|
||||||
|
|
||||||
- name: Build FancyHolograms v2 for Modrinth
|
|
||||||
env:
|
env:
|
||||||
RELEASE_CHANNEL: 'release'
|
RELEASE_CHANNEL: 'release'
|
||||||
RELEASE_PLATFORM: 'modrinth'
|
|
||||||
run: ./gradlew :plugins:fancyholograms-v2:shadowJar
|
run: ./gradlew :plugins:fancyholograms-v2:shadowJar
|
||||||
|
|
||||||
- name: Deploy to Modrinth
|
- name: Deploy
|
||||||
env:
|
uses: fancyinnovations/fancyverteiler@main
|
||||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
with:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
config_path: "/plugins/fancyholograms-v2/release_deployment_config.json"
|
||||||
run:
|
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||||
cd tools/deployment/build/libs &&
|
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
java -jar deployment.jar modrinth ../../../../plugins/fancyholograms-v2/release_deployment_config.json true
|
|
||||||
|
|
||||||
- name: Publish to reposilite (releases)
|
# - name: Publish to reposilite (releases)
|
||||||
run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
# run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||||
|
|
||||||
- name: Publish to reposilite (snapshots)
|
# - name: Publish to reposilite (snapshots)
|
||||||
run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
# run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||||
@@ -2,8 +2,9 @@ name: Deploy FancyHolograms (release)
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-plugin:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -27,25 +28,20 @@ jobs:
|
|||||||
- name: Modify gradlew permissions
|
- name: Modify gradlew permissions
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build deployment tool
|
- name: Build
|
||||||
run: ./gradlew :tools:deployment:shadowJar
|
|
||||||
|
|
||||||
- name: Build FancyHolograms for Modrinth
|
|
||||||
env:
|
env:
|
||||||
RELEASE_CHANNEL: 'release'
|
RELEASE_CHANNEL: 'release'
|
||||||
RELEASE_PLATFORM: 'modrinth'
|
|
||||||
run: ./gradlew :plugins:fancyholograms:shadowJar
|
run: ./gradlew :plugins:fancyholograms:shadowJar
|
||||||
|
|
||||||
- name: Deploy to Modrinth
|
- name: Deploy
|
||||||
env:
|
uses: fancyinnovations/fancyverteiler@main
|
||||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
with:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
config_path: "/plugins/fancyholograms/release_deployment_config.json"
|
||||||
run:
|
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||||
cd tools/deployment/build/libs &&
|
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
java -jar deployment.jar modrinth ../../../../plugins/fancyholograms/release_deployment_config.json true
|
|
||||||
|
|
||||||
- name: Publish to reposilite (releases)
|
# - name: Publish to reposilite (releases)
|
||||||
run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
# run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||||
|
|
||||||
- name: Publish to reposilite (snapshots)
|
# - name: Publish to reposilite (snapshots)
|
||||||
run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
# 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:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-plugin:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -27,25 +28,20 @@ jobs:
|
|||||||
- name: Modify gradlew permissions
|
- name: Modify gradlew permissions
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build deployment tool
|
- name: Build
|
||||||
run: ./gradlew :tools:deployment:shadowJar
|
|
||||||
|
|
||||||
- name: Build FancyNpcs for Modrinth
|
|
||||||
env:
|
env:
|
||||||
RELEASE_CHANNEL: 'release'
|
RELEASE_CHANNEL: 'release'
|
||||||
RELEASE_PLATFORM: 'modrinth'
|
|
||||||
run: ./gradlew :plugins:fancynpcs:shadowJar
|
run: ./gradlew :plugins:fancynpcs:shadowJar
|
||||||
|
|
||||||
- name: Deploy to Modrinth
|
- name: Deploy
|
||||||
env:
|
uses: fancyinnovations/fancyverteiler@main
|
||||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
with:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
config_path: "/plugins/fancynpcs/release_deployment_config.json"
|
||||||
run:
|
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||||
cd tools/deployment/build/libs &&
|
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
java -jar deployment.jar modrinth ../../../../plugins/fancynpcs/release_deployment_config.json true
|
|
||||||
|
|
||||||
- name: Publish to reposilite (releases)
|
# - name: Publish to reposilite (releases)
|
||||||
run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
# run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsReleasesRepository
|
||||||
|
|
||||||
- name: Publish to reposilite (snapshots)
|
# - name: Publish to reposilite (snapshots)
|
||||||
run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
# run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||||
@@ -2,8 +2,9 @@ name: Deploy FancyDialogs (snapshot)
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-fancydialogs:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -27,22 +28,17 @@ jobs:
|
|||||||
- name: Modify gradlew permissions
|
- name: Modify gradlew permissions
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build deployment tool
|
- name: Build
|
||||||
run: ./gradlew :tools:deployment:shadowJar
|
|
||||||
|
|
||||||
- name: Build FancyDialogs for Modrinth
|
|
||||||
env:
|
env:
|
||||||
RELEASE_CHANNEL: 'snapshot'
|
RELEASE_CHANNEL: 'snapshot'
|
||||||
RELEASE_PLATFORM: 'modrinth'
|
|
||||||
run: ./gradlew :plugins:fancydialogs:shadowJar
|
run: ./gradlew :plugins:fancydialogs:shadowJar
|
||||||
|
|
||||||
- name: Deploy to Modrinth
|
- name: Deploy
|
||||||
env:
|
uses: fancyinnovations/fancyverteiler@main
|
||||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
with:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
config_path: "/plugins/fancydialogs/snapshot_deployment_config.json"
|
||||||
run:
|
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||||
cd tools/deployment/build/libs &&
|
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
java -jar deployment.jar modrinth ../../../../plugins/fancydialogs/snapshot_deployment_config.json true
|
|
||||||
|
|
||||||
- name: Publish to reposilite (snapshots)
|
# - name: Publish to reposilite (snapshots)
|
||||||
run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
# run: ./gradlew :plugins:fancydialogs:fd-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||||
@@ -2,8 +2,9 @@ name: Deploy FancyHolograms v2 (snapshot)
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-fancyholograms:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -27,22 +28,17 @@ jobs:
|
|||||||
- name: Modify gradlew permissions
|
- name: Modify gradlew permissions
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build deployment tool
|
- name: Build
|
||||||
run: ./gradlew :tools:deployment:shadowJar
|
|
||||||
|
|
||||||
- name: Build FancyHolograms v2 for Modrinth
|
|
||||||
env:
|
env:
|
||||||
RELEASE_CHANNEL: 'snapshot'
|
RELEASE_CHANNEL: 'snapshot'
|
||||||
RELEASE_PLATFORM: 'modrinth'
|
|
||||||
run: ./gradlew :plugins:fancyholograms-v2:shadowJar
|
run: ./gradlew :plugins:fancyholograms-v2:shadowJar
|
||||||
|
|
||||||
- name: Deploy to Modrinth
|
- name: Deploy
|
||||||
env:
|
uses: fancyinnovations/fancyverteiler@main
|
||||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
with:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
config_path: "/plugins/fancyholograms-v2/snapshot_deployment_config.json"
|
||||||
run:
|
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||||
cd tools/deployment/build/libs &&
|
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
java -jar deployment.jar modrinth ../../../../plugins/fancyholograms-v2/snapshot_deployment_config.json true
|
|
||||||
|
|
||||||
- name: Publish to reposilite (snapshots)
|
# - name: Publish to reposilite (snapshots)
|
||||||
run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
# run: ./gradlew :plugins:fancyholograms-v2:api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||||
@@ -2,8 +2,9 @@ name: Deploy FancyHolograms (snapshot)
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-plugin:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -27,22 +28,17 @@ jobs:
|
|||||||
- name: Modify gradlew permissions
|
- name: Modify gradlew permissions
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build deployment tool
|
- name: Build
|
||||||
run: ./gradlew :tools:deployment:shadowJar
|
|
||||||
|
|
||||||
- name: Build FancyHolograms for Modrinth
|
|
||||||
env:
|
env:
|
||||||
RELEASE_CHANNEL: 'snapshot'
|
RELEASE_CHANNEL: 'snapshot'
|
||||||
RELEASE_PLATFORM: 'modrinth'
|
|
||||||
run: ./gradlew :plugins:fancyholograms:shadowJar
|
run: ./gradlew :plugins:fancyholograms:shadowJar
|
||||||
|
|
||||||
- name: Deploy to Modrinth
|
- name: Deploy
|
||||||
env:
|
uses: fancyinnovations/fancyverteiler@main
|
||||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
with:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
config_path: "/plugins/fancyholograms/snapshot_deployment_config.json"
|
||||||
run:
|
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||||
cd tools/deployment/build/libs &&
|
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
java -jar deployment.jar modrinth ../../../../plugins/fancyholograms/snapshot_deployment_config.json true
|
|
||||||
|
|
||||||
- name: Publish to reposilite (snapshots)
|
# - name: Publish to reposilite (snapshots)
|
||||||
run: ./gradlew :plugins:fancyholograms:fh-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
# 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:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy-plugin:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@@ -27,36 +28,17 @@ jobs:
|
|||||||
- name: Modify gradlew permissions
|
- name: Modify gradlew permissions
|
||||||
run: chmod +x ./gradlew
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
- name: Build deployment tool
|
- name: Build
|
||||||
run: ./gradlew :tools:deployment:shadowJar
|
|
||||||
|
|
||||||
- name: Build FancyNpcs for Modrinth
|
|
||||||
env:
|
env:
|
||||||
RELEASE_CHANNEL: 'snapshot'
|
RELEASE_CHANNEL: 'snapshot'
|
||||||
RELEASE_PLATFORM: 'modrinth'
|
|
||||||
run: ./gradlew :plugins:fancynpcs:shadowJar
|
run: ./gradlew :plugins:fancynpcs:shadowJar
|
||||||
|
|
||||||
- name: Deploy to Modrinth
|
- name: Deploy
|
||||||
env:
|
uses: fancyinnovations/fancyverteiler@main
|
||||||
MODRINTH_API_KEY: ${{ secrets.MODRINTH_API_KEY }}
|
with:
|
||||||
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
config_path: "/plugins/fancynpcs/snapshot_deployment_config.json"
|
||||||
run:
|
modrinth_api_key: ${{ secrets.MODRINTH_API_KEY }}
|
||||||
cd tools/deployment/build/libs &&
|
discord_webhook_url: ${{ secrets.DISCORD_WEBHOOK_URL }}
|
||||||
java -jar deployment.jar modrinth ../../../../plugins/fancynpcs/snapshot_deployment_config.json true
|
|
||||||
|
|
||||||
# - name: Build FancyNpcs for Hangar
|
# - name: Publish to reposilite (snapshots)
|
||||||
# env:
|
# run: ./gradlew :plugins:fancynpcs:fn-api:publishAllPublicationsToFancyinnovationsSnapshotsRepository
|
||||||
# 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
|
|
||||||
@@ -35,7 +35,6 @@ This is a [monorepo](docs/src/development-guidelines/monorepo.md) for all plugin
|
|||||||
- Packets: packet handling library (also called FancySitula)
|
- Packets: packet handling library (also called FancySitula)
|
||||||
|
|
||||||
**Tools:**
|
**Tools:**
|
||||||
- Deployment: deploy plugins to platforms like modrinth
|
|
||||||
- Quick E2E: generate a quick end-to-end environment for testing
|
- Quick E2E: generate a quick end-to-end environment for testing
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@@ -15,12 +15,5 @@ allprojects {
|
|||||||
maven("https://repo.papermc.io/repository/maven-public/")
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
maven("https://repo.fancyinnovations.com/releases")
|
maven("https://repo.fancyinnovations.com/releases")
|
||||||
maven(url = "https://jitpack.io")
|
maven(url = "https://jitpack.io")
|
||||||
maven("https://maven-prs.papermc.io/Paper/pr13194") {
|
|
||||||
name = "Maven for PR #13194" // https://github.com/PaperMC/Paper/pull/13194
|
|
||||||
mavenContent {
|
|
||||||
includeModule("io.papermc.paper", "dev-bundle")
|
|
||||||
includeModule("io.papermc.paper", "paper-api")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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
|
## Joined Players Cache
|
||||||
|
|
||||||
## Clear joined players cache
|
### Clear joined players cache
|
||||||
|
|
||||||
Clears the cache of players who have joined a dialog.
|
Clears the cache of players who have joined a dialog.
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: FancyDialogs [WIP]
|
title: FancyDialogs
|
||||||
icon: browser
|
icon: browser
|
||||||
order: 90
|
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!
|
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:**
|
**Core advantages of FancyDialogs:**
|
||||||
- Simple custom dialog creation (in JSON format or in code)
|
- Simple custom dialog creation (in JSON format or in code)
|
||||||
- A lot of different dialog components (text, buttons, input fields, etc.)
|
- A lot of different dialog components (text, buttons, input fields, etc.)
|
||||||
@@ -52,17 +47,3 @@ Common use cases are:
|
|||||||
- Confirmation dialogs for critical actions
|
- Confirmation dialogs for critical actions
|
||||||
- Shop UIs (replacing inventories UIs)
|
- Shop UIs (replacing inventories UIs)
|
||||||
- Dialogs for quests
|
- 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.
|
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
|
icon: dot
|
||||||
order: 9
|
order: 7
|
||||||
---
|
---
|
||||||
|
|
||||||
# Open dialog npc action
|
# 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"]
|
## v2.8.0 [!badge variant="info" text="2025-10-10"]
|
||||||
|
|
||||||
- Added support for 1.21.9 and 1.21.10
|
- Added support for 1.21.9 and 1.21.10
|
||||||
|
|||||||
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
|
fancylibVersion=37
|
||||||
fancysitulaVersion=0.0.13
|
fancysitulaVersion=0.0.13
|
||||||
jdbVersion=1.0.1
|
|
||||||
plugintestsVersion=1.0.0
|
plugintestsVersion=1.0.0
|
||||||
org.gradle.parallel=false
|
org.gradle.parallel=false
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
1
libraries/config/VERSION
Normal file
1
libraries/config/VERSION
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1.0.0
|
||||||
@@ -14,7 +14,7 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
compileOnly("org.jetbrains:annotations:26.0.2")
|
compileOnly("org.jetbrains:annotations:26.0.2")
|
||||||
|
|
||||||
@@ -24,9 +24,41 @@ dependencies {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
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 {
|
compileJava {
|
||||||
options.encoding = Charsets.UTF_8.name()
|
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 {
|
java {
|
||||||
@@ -47,5 +79,9 @@ tasks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
java {
|
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 {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
id("maven-publish")
|
id("maven-publish")
|
||||||
id("com.github.johnrengelman.shadow")
|
id("com.gradleup.shadow")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "de.oliver"
|
group = "de.oliver"
|
||||||
version = findProperty("jdbVersion") as String
|
version = getJDBVersion()
|
||||||
description = "Library for storing JSON data locally"
|
description = "Library for storing JSON data locally"
|
||||||
|
|
||||||
java {
|
java {
|
||||||
@@ -55,7 +55,7 @@ tasks {
|
|||||||
create<MavenPublication>("maven") {
|
create<MavenPublication>("maven") {
|
||||||
groupId = "de.oliver"
|
groupId = "de.oliver"
|
||||||
artifactId = "JDB"
|
artifactId = "JDB"
|
||||||
version = findProperty("jdbVersion") as String
|
version = getJDBVersion()
|
||||||
from(project.components["java"])
|
from(project.components["java"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,3 +85,7 @@ tasks {
|
|||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getJDBVersion(): String {
|
||||||
|
return file("VERSION").readText()
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import java.io.File;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
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.
|
* The JDB class provides a simple JSON document-based storage system in a specified directory.
|
||||||
*/
|
*/
|
||||||
public class JDB {
|
public class JDB {
|
||||||
private final static Gson GSON = new GsonBuilder()
|
public final static Gson GSON = new GsonBuilder()
|
||||||
.setPrettyPrinting()
|
.setPrettyPrinting()
|
||||||
.disableHtmlEscaping()
|
.disableHtmlEscaping()
|
||||||
.create();
|
.create();
|
||||||
@@ -24,6 +25,7 @@ public class JDB {
|
|||||||
private static final String FILE_EXTENSION = ".json";
|
private static final String FILE_EXTENSION = ".json";
|
||||||
private final @NotNull String basePath;
|
private final @NotNull String basePath;
|
||||||
private final @NotNull File baseDirectory;
|
private final @NotNull File baseDirectory;
|
||||||
|
private final JIndex index;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new JDB instance with the specified base path.
|
* Constructs a new JDB instance with the specified base path.
|
||||||
@@ -33,6 +35,8 @@ public class JDB {
|
|||||||
public JDB(@NotNull String basePath) {
|
public JDB(@NotNull String basePath) {
|
||||||
this.basePath = basePath;
|
this.basePath = basePath;
|
||||||
this.baseDirectory = new File(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 {
|
public <T> T get(@NotNull String path, @NotNull Class<T> clazz) throws IOException {
|
||||||
File documentFile = new File(baseDirectory, createFilePath(path));
|
File documentFile = new File(baseDirectory, createFilePath(path));
|
||||||
if (!documentFile.exists()) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
BufferedReader bufferedReader = Files.newBufferedReader(documentFile.toPath());
|
BufferedReader bufferedReader = Files.newBufferedReader(documentFile.toPath());
|
||||||
@@ -95,6 +106,26 @@ public class JDB {
|
|||||||
return documents;
|
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.
|
* Saves the given value as a document at the specified path.
|
||||||
*
|
*
|
||||||
@@ -113,12 +144,40 @@ public class JDB {
|
|||||||
Files.write(documentFile.toPath(), json.getBytes());
|
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.
|
* Deletes the document(s) at the specified path.
|
||||||
*
|
*
|
||||||
* @param path the relative path (excluding .json extension) of the document(s) to be deleted
|
* @param path the relative path (excluding .json extension) of the document(s) to be deleted
|
||||||
*/
|
*/
|
||||||
public void delete(@NotNull String path) {
|
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);
|
File file = new File(baseDirectory, path);
|
||||||
if (file.isDirectory()) {
|
if (file.isDirectory()) {
|
||||||
deleteDirectory(file);
|
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());
|
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
|
@Test
|
||||||
public void testSetNewObject() throws IOException {
|
public void testSetNewObject() throws IOException {
|
||||||
// Prepare
|
// Prepare
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ plugins {
|
|||||||
paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.MOJANG_PRODUCTION
|
paperweight.reobfArtifactConfiguration = io.papermc.paperweight.userdev.ReobfArtifactConfiguration.MOJANG_PRODUCTION
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
paperweight.paperDevBundle("25w45a-R0.1-SNAPSHOT")
|
paperweight.paperDevBundle("1.21.11-rc2-R0.1-SNAPSHOT")
|
||||||
compileOnly(project(":libraries:packets:packets-api"))
|
compileOnly(project(":libraries:packets:packets-api"))
|
||||||
|
|
||||||
testImplementation(project(":libraries:packets"))
|
testImplementation(project(":libraries:packets"))
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import java.util.List;
|
|||||||
|
|
||||||
public enum ServerVersion {
|
public enum ServerVersion {
|
||||||
|
|
||||||
v1_21_11("1.21.11", 774),
|
v1_21_11("1.21.11 Release Candidate 2", 774),
|
||||||
v1_21_10("1.21.10", 773),
|
v1_21_10("1.21.10", 773),
|
||||||
v1_21_9("1.21.9", 773),
|
v1_21_9("1.21.9", 773),
|
||||||
v1_21_8("1.21.8", 772),
|
v1_21_8("1.21.8", 772),
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
- Fixed player kick issue when no button or action is defined. ([#147](https://github.com/FancyInnovations/FancyPlugins/issues/147))
|
||||||
@@ -1 +1 @@
|
|||||||
0.0.31
|
1.0.1.37
|
||||||
@@ -45,12 +45,12 @@ dependencies {
|
|||||||
implementation(project(":libraries:common"))
|
implementation(project(":libraries:common"))
|
||||||
implementation(project(":libraries:jdb"))
|
implementation(project(":libraries:jdb"))
|
||||||
implementation(project(":libraries:config"))
|
implementation(project(":libraries:config"))
|
||||||
implementation("de.oliver.FancyAnalytics:java-sdk:0.0.4")
|
implementation("de.oliver.FancyAnalytics:java-sdk:0.0.5")
|
||||||
implementation("de.oliver.FancyAnalytics:mc-api:0.1.11")
|
implementation("de.oliver.FancyAnalytics:mc-api:0.1.12")
|
||||||
implementation("de.oliver.FancyAnalytics:logger:0.0.8")
|
implementation("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
|
|
||||||
compileOnly(project(":plugins:fancynpcs:fn-api"))
|
compileOnly(project(":plugins:fancynpcs:fn-api"))
|
||||||
compileOnly("org.lushplugins:ChatColorHandler:6.0.3")
|
compileOnly("org.lushplugins:ChatColorHandler:6.0.0")
|
||||||
implementation("io.github.revxrsal:lamp.common:4.0.0-rc.12")
|
implementation("io.github.revxrsal:lamp.common:4.0.0-rc.12")
|
||||||
implementation("io.github.revxrsal:lamp.bukkit:4.0.0-rc.12")
|
implementation("io.github.revxrsal:lamp.bukkit:4.0.0-rc.12")
|
||||||
|
|
||||||
@@ -85,14 +85,14 @@ paper {
|
|||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
runServer {
|
runServer {
|
||||||
minecraftVersion("1.21.10")
|
minecraftVersion("1.21.11-rc2")
|
||||||
|
|
||||||
downloadPlugins {
|
downloadPlugins {
|
||||||
modrinth("fancynpcs", "2.8.0")
|
// modrinth("fancynpcs", "2.8.0")
|
||||||
// hangar("ViaVersion", "5.3.2")
|
// hangar("ViaVersion", "5.3.2")
|
||||||
// hangar("ViaBackwards", "5.3.2")
|
// hangar("ViaBackwards", "5.3.2")
|
||||||
// modrinth("multiverse-core", "4.3.11")
|
// modrinth("multiverse-core", "4.3.11")
|
||||||
hangar("PlaceholderAPI", "2.11.6")
|
// hangar("PlaceholderAPI", "2.11.6")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ dependencies {
|
|||||||
compileOnly(project(":libraries:common"))
|
compileOnly(project(":libraries:common"))
|
||||||
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
|
|
||||||
implementation("org.lushplugins:ChatColorHandler:6.0.3")
|
implementation("org.lushplugins:ChatColorHandler:6.0.0")
|
||||||
|
|
||||||
implementation("org.jetbrains:annotations:24.0.0")
|
implementation("org.jetbrains:annotations:24.0.0")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
{
|
{
|
||||||
"project_name": "FancyDialogs",
|
"project_name": "FancyDialogs",
|
||||||
"project_id": "Sx6YwpnK",
|
"plugin_jar_path": "/plugins/fancydialogs/build/libs/FancyDialogs-%VERSION%.jar",
|
||||||
"plugin_jar_path": "../../../../plugins/fancydialogs/build/libs/FancyDialogs-%VERSION%.jar",
|
"changelog_path": "/plugins/fancydialogs/CHANGELOG.md",
|
||||||
"changelog_path": "../../../../plugins/fancydialogs/CHANGELOG.md",
|
"version_path": "/plugins/fancydialogs/VERSION",
|
||||||
"version_path": "../../../../plugins/fancydialogs/VERSION",
|
"modrinth": {
|
||||||
"supported_versions": [
|
"project_id": "Sx6YwpnK",
|
||||||
"1.21.6",
|
"supported_versions": [
|
||||||
"1.21.7",
|
"1.21.6",
|
||||||
"1.21.8",
|
"1.21.7",
|
||||||
"1.21.9",
|
"1.21.8",
|
||||||
"1.21.10",
|
"1.21.9",
|
||||||
"1.21.11"
|
"1.21.10",
|
||||||
],
|
"1.21.11"
|
||||||
"channel": "RELEASE",
|
],
|
||||||
"loaders": [
|
"channel": "release",
|
||||||
"paper",
|
"loaders": [
|
||||||
"folia"
|
"paper",
|
||||||
],
|
"folia"
|
||||||
"featured": false
|
],
|
||||||
|
"featured": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,23 @@
|
|||||||
{
|
{
|
||||||
"project_name": "FancyDialogs",
|
"project_name": "FancyDialogs",
|
||||||
"project_id": "Sx6YwpnK",
|
"plugin_jar_path": "/plugins/fancydialogs/build/libs/FancyDialogs-%VERSION%.jar",
|
||||||
"plugin_jar_path": "../../../../plugins/fancydialogs/build/libs/FancyDialogs-%VERSION%.jar",
|
"changelog_path": "/plugins/fancydialogs/CHANGELOG-SNAPSHOT.md",
|
||||||
"changelog_path": "../../../../plugins/fancydialogs/CHANGELOG-SNAPSHOT.md",
|
"version_path": "/plugins/fancydialogs/VERSION",
|
||||||
"version_path": "../../../../plugins/fancydialogs/VERSION",
|
"modrinth": {
|
||||||
"supported_versions": [
|
"project_id": "Sx6YwpnK",
|
||||||
"1.21.6",
|
"supported_versions": [
|
||||||
"1.21.7",
|
"1.21.6",
|
||||||
"1.21.8",
|
"1.21.7",
|
||||||
"1.21.9",
|
"1.21.8",
|
||||||
"1.21.10"
|
"1.21.9",
|
||||||
],
|
"1.21.10",
|
||||||
"channel": "BETA",
|
"1.21.11-rc2"
|
||||||
"loaders": [
|
],
|
||||||
"paper",
|
"channel": "beta",
|
||||||
"folia"
|
"loaders": [
|
||||||
],
|
"paper",
|
||||||
"featured": false
|
"folia"
|
||||||
|
],
|
||||||
|
"featured": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ import com.fancyinnovations.fancydialogs.api.data.inputs.DialogInput;
|
|||||||
import com.fancyinnovations.fancydialogs.api.data.inputs.DialogSelect;
|
import com.fancyinnovations.fancydialogs.api.data.inputs.DialogSelect;
|
||||||
import com.fancyinnovations.fancydialogs.api.data.inputs.DialogTextField;
|
import com.fancyinnovations.fancydialogs.api.data.inputs.DialogTextField;
|
||||||
import de.oliver.fancysitula.api.dialogs.FS_CommonDialogData;
|
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.FS_DialogAction;
|
||||||
import de.oliver.fancysitula.api.dialogs.actions.FS_CommonButtonData;
|
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_DialogActionButton;
|
||||||
@@ -18,6 +19,7 @@ import de.oliver.fancysitula.api.dialogs.body.FS_DialogBody;
|
|||||||
import de.oliver.fancysitula.api.dialogs.body.FS_DialogTextBody;
|
import de.oliver.fancysitula.api.dialogs.body.FS_DialogTextBody;
|
||||||
import de.oliver.fancysitula.api.dialogs.inputs.*;
|
import de.oliver.fancysitula.api.dialogs.inputs.*;
|
||||||
import de.oliver.fancysitula.api.dialogs.types.FS_MultiActionDialog;
|
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.entities.FS_RealPlayer;
|
||||||
import de.oliver.fancysitula.factories.FancySitula;
|
import de.oliver.fancysitula.factories.FancySitula;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@@ -35,7 +37,7 @@ public class DialogImpl extends Dialog {
|
|||||||
super(id, data);
|
super(id, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FS_MultiActionDialog buildForPlayer(Player player) {
|
private FS_Dialog buildForPlayer(Player player) {
|
||||||
List<FS_DialogBody> body = new ArrayList<>();
|
List<FS_DialogBody> body = new ArrayList<>();
|
||||||
for (DialogBodyData bodyData : data.body()) {
|
for (DialogBodyData bodyData : data.body()) {
|
||||||
FS_DialogTextBody fsDialogTextBody = new FS_DialogTextBody(
|
FS_DialogTextBody fsDialogTextBody = new FS_DialogTextBody(
|
||||||
@@ -109,6 +111,30 @@ public class DialogImpl extends Dialog {
|
|||||||
actions.add(fsDialogActionButton);
|
actions.add(fsDialogActionButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actions.isEmpty()) {
|
||||||
|
return new FS_NoticeDialog(
|
||||||
|
new FS_CommonDialogData(
|
||||||
|
ChatColorHandler.translate(data.title(), player, ParserTypes.placeholder()),
|
||||||
|
ChatColorHandler.translate(data.title(), player, ParserTypes.placeholder()),
|
||||||
|
data.canCloseWithEscape(),
|
||||||
|
false,
|
||||||
|
FS_DialogAction.CLOSE,
|
||||||
|
body,
|
||||||
|
inputs
|
||||||
|
),
|
||||||
|
new FS_DialogActionButton(
|
||||||
|
new FS_CommonButtonData(
|
||||||
|
"Close",
|
||||||
|
null,
|
||||||
|
150 // default button width
|
||||||
|
),
|
||||||
|
new FS_DialogCustomAction(
|
||||||
|
"fancydialogs_dialog_action--none",
|
||||||
|
Map.of())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return new FS_MultiActionDialog(
|
return new FS_MultiActionDialog(
|
||||||
new FS_CommonDialogData(
|
new FS_CommonDialogData(
|
||||||
ChatColorHandler.translate(data.title(), player, ParserTypes.placeholder()),
|
ChatColorHandler.translate(data.title(), player, ParserTypes.placeholder()),
|
||||||
@@ -118,53 +144,6 @@ public class DialogImpl extends Dialog {
|
|||||||
FS_DialogAction.CLOSE,
|
FS_DialogAction.CLOSE,
|
||||||
body,
|
body,
|
||||||
inputs
|
inputs
|
||||||
// List.of(
|
|
||||||
// new FS_DialogInput(
|
|
||||||
// "input1",
|
|
||||||
// new FS_DialogTextInput(
|
|
||||||
// 200,
|
|
||||||
// "Enter something",
|
|
||||||
// true,
|
|
||||||
// "default text",
|
|
||||||
// 100,
|
|
||||||
// null
|
|
||||||
// )
|
|
||||||
// ),
|
|
||||||
// new FS_DialogInput(
|
|
||||||
// "input2",
|
|
||||||
// new FS_DialogBooleanInput(
|
|
||||||
// "input2",
|
|
||||||
// false,
|
|
||||||
// "true",
|
|
||||||
// "false"
|
|
||||||
// )
|
|
||||||
// ),
|
|
||||||
// new FS_DialogInput(
|
|
||||||
// "input3",
|
|
||||||
// new FS_DialogNumberRangeInput(
|
|
||||||
// 200,
|
|
||||||
// "Number Input",
|
|
||||||
// "options.generic_value",
|
|
||||||
// 0,
|
|
||||||
// 100,
|
|
||||||
// 50.f,
|
|
||||||
// 1.0f
|
|
||||||
// )
|
|
||||||
// ),
|
|
||||||
// new FS_DialogInput(
|
|
||||||
// "input4",
|
|
||||||
// new FS_DialogSingleOptionInput(
|
|
||||||
// 200,
|
|
||||||
// List.of(
|
|
||||||
// new FS_DialogSingleOptionInput.Entry("option1", "Option 1", true),
|
|
||||||
// new FS_DialogSingleOptionInput.Entry("option2", "Option 2", false),
|
|
||||||
// new FS_DialogSingleOptionInput.Entry("option3", "Option 3", false)
|
|
||||||
// ),
|
|
||||||
// "Select an option",
|
|
||||||
// true
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
),
|
),
|
||||||
actions, // actions
|
actions, // actions
|
||||||
null,
|
null,
|
||||||
|
|||||||
@@ -46,6 +46,10 @@ public class CustomClickActionPacketListener {
|
|||||||
String dialogId = packet.getPayload().get("dialog_id");
|
String dialogId = packet.getPayload().get("dialog_id");
|
||||||
String buttonId = packet.getPayload().get("button_id");
|
String buttonId = packet.getPayload().get("button_id");
|
||||||
|
|
||||||
|
if (dialogId == null || buttonId == null) {
|
||||||
|
return; // Missing necessary information
|
||||||
|
}
|
||||||
|
|
||||||
new DialogButtonClickedEvent(event.player(), dialogId, buttonId, packet.getPayload()).callEvent();
|
new DialogButtonClickedEvent(event.player(), dialogId, buttonId, packet.getPayload()).callEvent();
|
||||||
|
|
||||||
if (dialogId.startsWith("confirmation_dialog_")) {
|
if (dialogId.startsWith("confirmation_dialog_")) {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ With this plugin you can create holograms with customizable properties like:
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Paper **1.19.4** - **1.21.8** with **Java 21** (or higher) is required. Plugin should also work on **Paper** forks.
|
Paper **1.20** - **1.21.8** with **Java 21** (or higher) is required. Plugin should also work on **Paper** forks.
|
||||||
|
|
||||||
**Spigot** is **not** supported.
|
**Spigot** is **not** supported.
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.8.0.157
|
2.8.0.165
|
||||||
@@ -4,7 +4,7 @@ plugins {
|
|||||||
id("com.gradleup.shadow")
|
id("com.gradleup.shadow")
|
||||||
}
|
}
|
||||||
|
|
||||||
val minecraftVersion = "1.19.4"
|
val minecraftVersion = "1.20"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("io.papermc.paper:paper-api:$minecraftVersion-R0.1-SNAPSHOT")
|
compileOnly("io.papermc.paper:paper-api:$minecraftVersion-R0.1-SNAPSHOT")
|
||||||
@@ -12,7 +12,7 @@ dependencies {
|
|||||||
compileOnly(project(":libraries:common"))
|
compileOnly(project(":libraries:common"))
|
||||||
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
|
|
||||||
implementation("org.lushplugins:ChatColorHandler:6.0.3")
|
implementation("org.lushplugins:ChatColorHandler:6.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ dependencies {
|
|||||||
implementation(project(":plugins:fancyholograms-v2:implementation_1_20_4", configuration = "reobf"))
|
implementation(project(":plugins:fancyholograms-v2:implementation_1_20_4", configuration = "reobf"))
|
||||||
implementation(project(":plugins:fancyholograms-v2:implementation_1_20_2", configuration = "reobf"))
|
implementation(project(":plugins:fancyholograms-v2:implementation_1_20_2", configuration = "reobf"))
|
||||||
implementation(project(":plugins:fancyholograms-v2:implementation_1_20_1", configuration = "reobf"))
|
implementation(project(":plugins:fancyholograms-v2:implementation_1_20_1", configuration = "reobf"))
|
||||||
implementation(project(":plugins:fancyholograms-v2:implementation_1_19_4", configuration = "reobf"))
|
|
||||||
|
|
||||||
rootProject.subprojects
|
rootProject.subprojects
|
||||||
.filter { it.path.startsWith(":libraries:packets:implementations") }
|
.filter { it.path.startsWith(":libraries:packets:implementations") }
|
||||||
@@ -49,12 +48,12 @@ dependencies {
|
|||||||
implementation(project(":libraries:common"))
|
implementation(project(":libraries:common"))
|
||||||
implementation(project(":libraries:jdb"))
|
implementation(project(":libraries:jdb"))
|
||||||
implementation(project(":libraries:config"))
|
implementation(project(":libraries:config"))
|
||||||
implementation("de.oliver.FancyAnalytics:java-sdk:0.0.4")
|
implementation("de.oliver.FancyAnalytics:java-sdk:0.0.5")
|
||||||
implementation("de.oliver.FancyAnalytics:mc-api:0.1.11")
|
implementation("de.oliver.FancyAnalytics:mc-api:0.1.12")
|
||||||
implementation("de.oliver.FancyAnalytics:logger:0.0.8")
|
implementation("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
|
|
||||||
compileOnly(project(":plugins:fancynpcs:fn-api"))
|
compileOnly(project(":plugins:fancynpcs:fn-api"))
|
||||||
compileOnly("org.lushplugins:ChatColorHandler:6.0.3")
|
compileOnly("org.lushplugins:ChatColorHandler:6.0.0")
|
||||||
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
|
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +90,7 @@ paper {
|
|||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
runServer {
|
runServer {
|
||||||
minecraftVersion("1.21.10")
|
minecraftVersion("1.21.11-rc2")
|
||||||
|
|
||||||
downloadPlugins {
|
downloadPlugins {
|
||||||
// modrinth("fancynpcs", "2.5.2")
|
// modrinth("fancynpcs", "2.5.2")
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id("java-library")
|
|
||||||
id("io.papermc.paperweight.userdev")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val minecraftVersion = "1.19.4"
|
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
paperweight.paperDevBundle("$minecraftVersion-R0.1-SNAPSHOT")
|
|
||||||
|
|
||||||
implementation(project(":plugins:fancyholograms-v2:api"))
|
|
||||||
implementation(project(":libraries:common"))
|
|
||||||
compileOnly("com.viaversion:viaversion-api:5.2.1")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
tasks {
|
|
||||||
named("assemble") {
|
|
||||||
dependsOn(named("reobfJar"))
|
|
||||||
}
|
|
||||||
|
|
||||||
javadoc {
|
|
||||||
options.encoding = Charsets.UTF_8.name()
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava {
|
|
||||||
options.encoding = Charsets.UTF_8.name()
|
|
||||||
|
|
||||||
options.release.set(17)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,271 +0,0 @@
|
|||||||
package de.oliver.fancyholograms.hologram.version;
|
|
||||||
|
|
||||||
import com.mojang.math.Transformation;
|
|
||||||
import de.oliver.fancyholograms.api.data.*;
|
|
||||||
import de.oliver.fancyholograms.api.events.HologramHideEvent;
|
|
||||||
import de.oliver.fancyholograms.api.events.HologramShowEvent;
|
|
||||||
import de.oliver.fancyholograms.api.hologram.Hologram;
|
|
||||||
import de.oliver.fancylib.ReflectionUtils;
|
|
||||||
import io.papermc.paper.adventure.PaperAdventure;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundRemoveEntitiesPacket;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundTeleportEntityPacket;
|
|
||||||
import net.minecraft.network.syncher.EntityDataAccessor;
|
|
||||||
import net.minecraft.network.syncher.SynchedEntityData.DataItem;
|
|
||||||
import net.minecraft.network.syncher.SynchedEntityData.DataValue;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.util.Brightness;
|
|
||||||
import net.minecraft.world.entity.Display;
|
|
||||||
import net.minecraft.world.entity.Display.TextDisplay;
|
|
||||||
import net.minecraft.world.entity.EntityType;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.joml.Quaternionf;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import static de.oliver.fancylib.ReflectionUtils.getValue;
|
|
||||||
|
|
||||||
public final class Hologram1_19_4 extends Hologram {
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private Display display;
|
|
||||||
|
|
||||||
public Hologram1_19_4(@NotNull final HologramData data) {
|
|
||||||
super(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEntityId() {
|
|
||||||
return display.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public @Nullable org.bukkit.entity.Display getDisplayEntity() {
|
|
||||||
return display != null ? (org.bukkit.entity.Display) display.getBukkitEntity() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void create() {
|
|
||||||
final var location = data.getLocation();
|
|
||||||
if (location.getWorld() == null) {
|
|
||||||
return; // no location data, cannot be created
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerLevel world = ((CraftWorld) location.getWorld()).getHandle();
|
|
||||||
|
|
||||||
switch (data.getType()) {
|
|
||||||
case TEXT -> this.display = new Display.TextDisplay(EntityType.TEXT_DISPLAY, world);
|
|
||||||
case BLOCK -> this.display = new Display.BlockDisplay(EntityType.BLOCK_DISPLAY, world);
|
|
||||||
case ITEM -> this.display = new Display.ItemDisplay(EntityType.ITEM_DISPLAY, world);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data instanceof DisplayHologramData dd) {
|
|
||||||
final var DATA_INTERPOLATION_DURATION_ID = ReflectionUtils.getStaticValue(Display.class, MappingKeys1_19_4.DATA_INTERPOLATION_DURATION_ID.getMapping());
|
|
||||||
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_INTERPOLATION_DURATION_ID, dd.getInterpolationDuration());
|
|
||||||
|
|
||||||
final var DATA_INTERPOLATION_START_DELTA_TICKS_ID = ReflectionUtils.getStaticValue(Display.class, MappingKeys1_19_4.DATA_INTERPOLATION_START_DELTA_TICKS_ID.getMapping());
|
|
||||||
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_INTERPOLATION_START_DELTA_TICKS_ID, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete() {
|
|
||||||
this.display = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update() {
|
|
||||||
final var display = this.display;
|
|
||||||
if (display == null) {
|
|
||||||
return; // doesn't exist, nothing to update
|
|
||||||
}
|
|
||||||
|
|
||||||
// location data
|
|
||||||
final var location = data.getLocation();
|
|
||||||
if (!location.isWorldLoaded()) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
display.setPosRaw(location.x(), location.y(), location.z());
|
|
||||||
display.setYRot(location.getYaw());
|
|
||||||
display.setXRot(location.getPitch());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (display instanceof TextDisplay textDisplay && data instanceof TextHologramData textData) {
|
|
||||||
// line width
|
|
||||||
final var DATA_LINE_WIDTH_ID = ReflectionUtils.getStaticValue(TextDisplay.class, MappingKeys1_19_4.DATA_LINE_WIDTH_ID.getMapping());
|
|
||||||
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_LINE_WIDTH_ID, Hologram.LINE_WIDTH);
|
|
||||||
|
|
||||||
// background
|
|
||||||
final var DATA_BACKGROUND_COLOR_ID = ReflectionUtils.getStaticValue(TextDisplay.class, MappingKeys1_19_4.DATA_BACKGROUND_COLOR_ID.getMapping());
|
|
||||||
|
|
||||||
final var background = textData.getBackground();
|
|
||||||
if (background == null) {
|
|
||||||
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, TextDisplay.INITIAL_BACKGROUND);
|
|
||||||
} else if (background == Hologram.TRANSPARENT) {
|
|
||||||
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, 0);
|
|
||||||
} else {
|
|
||||||
display.getEntityData().set((EntityDataAccessor<Integer>) DATA_BACKGROUND_COLOR_ID, background.asARGB());
|
|
||||||
}
|
|
||||||
|
|
||||||
// text shadow
|
|
||||||
if (textData.hasTextShadow()) {
|
|
||||||
textDisplay.setFlags((byte) (textDisplay.getFlags() | TextDisplay.FLAG_SHADOW));
|
|
||||||
} else {
|
|
||||||
textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_SHADOW));
|
|
||||||
}
|
|
||||||
|
|
||||||
// text alignment
|
|
||||||
if (textData.getTextAlignment() == org.bukkit.entity.TextDisplay.TextAlignment.LEFT) {
|
|
||||||
textDisplay.setFlags((byte) (textDisplay.getFlags() | TextDisplay.FLAG_ALIGN_LEFT));
|
|
||||||
} else {
|
|
||||||
textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_ALIGN_LEFT));
|
|
||||||
}
|
|
||||||
|
|
||||||
// see through
|
|
||||||
if (textData.isSeeThrough()) {
|
|
||||||
textDisplay.setFlags((byte) (textDisplay.getFlags() | TextDisplay.FLAG_SEE_THROUGH));
|
|
||||||
} else {
|
|
||||||
textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_SEE_THROUGH));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (textData.getTextAlignment() == org.bukkit.entity.TextDisplay.TextAlignment.RIGHT) {
|
|
||||||
textDisplay.setFlags((byte) (textDisplay.getFlags() | TextDisplay.FLAG_ALIGN_RIGHT));
|
|
||||||
} else {
|
|
||||||
textDisplay.setFlags((byte) (textDisplay.getFlags() & ~TextDisplay.FLAG_ALIGN_RIGHT));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if (display instanceof Display.ItemDisplay itemDisplay && data instanceof ItemHologramData itemData) {
|
|
||||||
// item
|
|
||||||
itemDisplay.setItemStack(ItemStack.fromBukkitCopy(itemData.getItemStack()));
|
|
||||||
|
|
||||||
} else if (display instanceof Display.BlockDisplay blockDisplay && data instanceof BlockHologramData blockData) {
|
|
||||||
Block block = BuiltInRegistries.BLOCK.get(ResourceLocation.of("minecraft:" + blockData.getBlock().name().toLowerCase(), ':'));
|
|
||||||
blockDisplay.setBlockState(block.defaultBlockState());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data instanceof DisplayHologramData displayData) {
|
|
||||||
// billboard data
|
|
||||||
display.setBillboardConstraints(switch (displayData.getBillboard()) {
|
|
||||||
case FIXED -> Display.BillboardConstraints.FIXED;
|
|
||||||
case VERTICAL -> Display.BillboardConstraints.VERTICAL;
|
|
||||||
case HORIZONTAL -> Display.BillboardConstraints.HORIZONTAL;
|
|
||||||
case CENTER -> Display.BillboardConstraints.CENTER;
|
|
||||||
});
|
|
||||||
|
|
||||||
// brightness
|
|
||||||
if (displayData.getBrightness() != null) {
|
|
||||||
display.setBrightnessOverride(new Brightness(displayData.getBrightness().getBlockLight(), displayData.getBrightness().getSkyLight()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// entity scale AND MORE!
|
|
||||||
display.setTransformation(new Transformation(
|
|
||||||
displayData.getTranslation(),
|
|
||||||
new Quaternionf(),
|
|
||||||
displayData.getScale(),
|
|
||||||
new Quaternionf())
|
|
||||||
);
|
|
||||||
|
|
||||||
// entity shadow
|
|
||||||
display.setShadowRadius(displayData.getShadowRadius());
|
|
||||||
display.setShadowStrength(displayData.getShadowStrength());
|
|
||||||
|
|
||||||
// view range
|
|
||||||
display.setViewRange(displayData.getVisibilityDistance());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean show(@NotNull final Player player) {
|
|
||||||
if (!new HologramShowEvent(this, player).callEvent()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.display == null) {
|
|
||||||
create(); // try to create it if it doesn't exist every time
|
|
||||||
}
|
|
||||||
|
|
||||||
final var display = this.display;
|
|
||||||
if (display == null) {
|
|
||||||
return false; // could not be created, nothing to show
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.getLocation().getWorld().getName().equals(player.getLocation().getWorld().getName())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
|
|
||||||
// TODO: cache player protocol version
|
|
||||||
// TODO: fix this
|
|
||||||
// final var protocolVersion = FancyHologramsPlugin.get().isUsingViaVersion() ? Via.getAPI().getPlayerVersion(player) : MINIMUM_PROTOCOL_VERSION;
|
|
||||||
// if (protocolVersion < MINIMUM_PROTOCOL_VERSION) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
|
|
||||||
serverPlayer.connection.send(new ClientboundAddEntityPacket(display));
|
|
||||||
this.viewers.add(player.getUniqueId());
|
|
||||||
refreshHologram(player);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hide(@NotNull final Player player) {
|
|
||||||
if (!new HologramHideEvent(this, player).callEvent()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
final var display = this.display;
|
|
||||||
if (display == null) {
|
|
||||||
return false; // doesn't exist, nothing to hide
|
|
||||||
}
|
|
||||||
|
|
||||||
((CraftPlayer) player).getHandle().connection.send(new ClientboundRemoveEntitiesPacket(display.getId()));
|
|
||||||
|
|
||||||
this.viewers.remove(player.getUniqueId());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void refresh(@NotNull final Player player) {
|
|
||||||
final var display = this.display;
|
|
||||||
if (display == null) {
|
|
||||||
return; // doesn't exist, nothing to refresh
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isViewer(player)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
((CraftPlayer) player).getHandle().connection.send(new ClientboundTeleportEntityPacket(display));
|
|
||||||
|
|
||||||
if (display instanceof TextDisplay textDisplay) {
|
|
||||||
textDisplay.setText(PaperAdventure.asVanilla(getShownText(player)));
|
|
||||||
}
|
|
||||||
|
|
||||||
final var values = new ArrayList<DataValue<?>>();
|
|
||||||
|
|
||||||
//noinspection unchecked
|
|
||||||
for (final var item : ((Int2ObjectMap<DataItem<?>>) getValue(display.getEntityData(), "e")).values()) {
|
|
||||||
values.add(item.value());
|
|
||||||
}
|
|
||||||
|
|
||||||
((CraftPlayer) player).getHandle().connection.send(new ClientboundSetEntityDataPacket(display.getId(), values));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
package de.oliver.fancyholograms.hologram.version;
|
|
||||||
|
|
||||||
public enum MappingKeys1_19_4 {
|
|
||||||
|
|
||||||
DATA_INTERPOLATION_DURATION_ID("r"),
|
|
||||||
DATA_INTERPOLATION_START_DELTA_TICKS_ID("q"),
|
|
||||||
DATA_LINE_WIDTH_ID("aL"),
|
|
||||||
DATA_BACKGROUND_COLOR_ID("aM"),
|
|
||||||
;
|
|
||||||
|
|
||||||
private final String mapping;
|
|
||||||
|
|
||||||
MappingKeys1_19_4(String mapping) {
|
|
||||||
this.mapping = mapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMapping() {
|
|
||||||
return mapping;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +1,36 @@
|
|||||||
{
|
{
|
||||||
"project_name": "FancyHolograms",
|
"project_name": "FancyHolograms",
|
||||||
"project_id": "5QNgOj66",
|
"plugin_jar_path": "/plugins/fancyholograms-v2/build/libs/FancyHolograms-%VERSION%.jar",
|
||||||
"plugin_jar_path": "../../../../plugins/fancyholograms-v2/build/libs/FancyHolograms-%VERSION%.jar",
|
"changelog_path": "/plugins/fancyholograms-v2/CHANGELOG.md",
|
||||||
"changelog_path": "../../../../plugins/fancyholograms-v2/CHANGELOG.md",
|
"version_path": "/plugins/fancyholograms-v2/VERSION",
|
||||||
"version_path": "../../../../plugins/fancyholograms-v2/VERSION",
|
"modrinth": {
|
||||||
"supported_versions": [
|
"project_id": "5QNgOj66",
|
||||||
"1.19.4",
|
"supported_versions": [
|
||||||
"1.20",
|
"1.20",
|
||||||
"1.20.1",
|
"1.20.1",
|
||||||
"1.20.2",
|
"1.20.2",
|
||||||
"1.20.3",
|
"1.20.3",
|
||||||
"1.20.4",
|
"1.20.4",
|
||||||
"1.20.5",
|
"1.20.5",
|
||||||
"1.20.6",
|
"1.20.6",
|
||||||
"1.21",
|
"1.21",
|
||||||
"1.21.1",
|
"1.21.1",
|
||||||
"1.21.2",
|
"1.21.2",
|
||||||
"1.21.3",
|
"1.21.3",
|
||||||
"1.21.4",
|
"1.21.4",
|
||||||
"1.21.5",
|
"1.21.5",
|
||||||
"1.21.6",
|
"1.21.6",
|
||||||
"1.21.7",
|
"1.21.7",
|
||||||
"1.21.8",
|
"1.21.8",
|
||||||
"1.21.9",
|
"1.21.9",
|
||||||
"1.21.10",
|
"1.21.10",
|
||||||
"1.21.11"
|
"1.21.11"
|
||||||
],
|
],
|
||||||
"channel": "RELEASE",
|
"channel": "release",
|
||||||
"loaders": [
|
"loaders": [
|
||||||
"paper",
|
"paper",
|
||||||
"folia"
|
"folia"
|
||||||
],
|
],
|
||||||
"featured": true
|
"featured": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,34 +1,36 @@
|
|||||||
{
|
{
|
||||||
"project_name": "FancyHolograms",
|
"project_name": "FancyHolograms",
|
||||||
"project_id": "5QNgOj66",
|
"plugin_jar_path": "/plugins/fancyholograms-v2/build/libs/FancyHolograms-%VERSION%.jar",
|
||||||
"plugin_jar_path": "../../../../plugins/fancyholograms-v2/build/libs/FancyHolograms-%VERSION%.jar",
|
"changelog_path": "/plugins/fancyholograms-v2/CHANGELOG-SNAPSHOT.md",
|
||||||
"changelog_path": "../../../../plugins/fancyholograms-v2/CHANGELOG-SNAPSHOT.md",
|
"version_path": "/plugins/fancyholograms-v2/VERSION",
|
||||||
"version_path": "../../../../plugins/fancyholograms-v2/VERSION",
|
"modrinth": {
|
||||||
"supported_versions": [
|
"project_id": "5QNgOj66",
|
||||||
"1.19.4",
|
"supported_versions": [
|
||||||
"1.20",
|
"1.20",
|
||||||
"1.20.1",
|
"1.20.1",
|
||||||
"1.20.2",
|
"1.20.2",
|
||||||
"1.20.3",
|
"1.20.3",
|
||||||
"1.20.4",
|
"1.20.4",
|
||||||
"1.20.5",
|
"1.20.5",
|
||||||
"1.20.6",
|
"1.20.6",
|
||||||
"1.21",
|
"1.21",
|
||||||
"1.21.1",
|
"1.21.1",
|
||||||
"1.21.2",
|
"1.21.2",
|
||||||
"1.21.3",
|
"1.21.3",
|
||||||
"1.21.4",
|
"1.21.4",
|
||||||
"1.21.5",
|
"1.21.5",
|
||||||
"1.21.6",
|
"1.21.6",
|
||||||
"1.21.7",
|
"1.21.7",
|
||||||
"1.21.8",
|
"1.21.8",
|
||||||
"1.21.9",
|
"1.21.9",
|
||||||
"1.21.10"
|
"1.21.10",
|
||||||
],
|
"1.21.11-rc2"
|
||||||
"channel": "BETA",
|
],
|
||||||
"loaders": [
|
"channel": "beta",
|
||||||
"paper",
|
"loaders": [
|
||||||
"folia"
|
"paper",
|
||||||
],
|
"folia"
|
||||||
"featured": false
|
],
|
||||||
|
"featured": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,10 @@ import de.oliver.fancyholograms.api.hologram.Hologram;
|
|||||||
import de.oliver.fancyholograms.commands.FancyHologramsCMD;
|
import de.oliver.fancyholograms.commands.FancyHologramsCMD;
|
||||||
import de.oliver.fancyholograms.commands.FancyHologramsTestCMD;
|
import de.oliver.fancyholograms.commands.FancyHologramsTestCMD;
|
||||||
import de.oliver.fancyholograms.commands.HologramCMD;
|
import de.oliver.fancyholograms.commands.HologramCMD;
|
||||||
import de.oliver.fancyholograms.hologram.version.*;
|
import de.oliver.fancyholograms.hologram.version.Hologram1_20_1;
|
||||||
|
import de.oliver.fancyholograms.hologram.version.Hologram1_20_2;
|
||||||
|
import de.oliver.fancyholograms.hologram.version.Hologram1_20_4;
|
||||||
|
import de.oliver.fancyholograms.hologram.version.HologramImpl;
|
||||||
import de.oliver.fancyholograms.listeners.*;
|
import de.oliver.fancyholograms.listeners.*;
|
||||||
import de.oliver.fancyholograms.storage.FlatFileHologramStorage;
|
import de.oliver.fancyholograms.storage.FlatFileHologramStorage;
|
||||||
import de.oliver.fancyholograms.storage.converter.FHConversionRegistry;
|
import de.oliver.fancyholograms.storage.converter.FHConversionRegistry;
|
||||||
@@ -109,7 +112,7 @@ public final class FancyHolograms extends JavaPlugin implements FancyHologramsPl
|
|||||||
final var adapter = resolveHologramAdapter();
|
final var adapter = resolveHologramAdapter();
|
||||||
|
|
||||||
if (adapter == null) {
|
if (adapter == null) {
|
||||||
List<String> supportedVersions = new ArrayList<>(List.of("1.19.4", "1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4"));
|
List<String> supportedVersions = new ArrayList<>(List.of("1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4"));
|
||||||
supportedVersions.addAll(ServerVersion.getSupportedVersions());
|
supportedVersions.addAll(ServerVersion.getSupportedVersions());
|
||||||
|
|
||||||
fancyLogger.warn("""
|
fancyLogger.warn("""
|
||||||
@@ -268,7 +271,6 @@ public final class FancyHolograms extends JavaPlugin implements FancyHologramsPl
|
|||||||
case "1.20.3", "1.20.4" -> Hologram1_20_4::new;
|
case "1.20.3", "1.20.4" -> Hologram1_20_4::new;
|
||||||
case "1.20.2" -> Hologram1_20_2::new;
|
case "1.20.2" -> Hologram1_20_2::new;
|
||||||
case "1.20", "1.20.1" -> Hologram1_20_1::new;
|
case "1.20", "1.20.1" -> Hologram1_20_1::new;
|
||||||
case "1.19.4" -> Hologram1_19_4::new;
|
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
HologramManagerImpl(@NotNull final FancyHolograms plugin, @NotNull final Function<HologramData, Hologram> adapter) {
|
HologramManagerImpl(@NotNull final FancyHolograms plugin, @NotNull final Function<HologramData, Hologram> adapter) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.adapter = adapter;
|
this.adapter = adapter;
|
||||||
hologramLoadLogging = plugin.getHologramConfiguration().isHologramLoadLogging();
|
this.hologramLoadLogging = plugin.getHologramConfiguration().isHologramLoadLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -102,7 +102,7 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
* @param hologram The hologram to remove.
|
* @param hologram The hologram to remove.
|
||||||
*/
|
*/
|
||||||
public void removeHologram(@NotNull final Hologram hologram) {
|
public void removeHologram(@NotNull final Hologram hologram) {
|
||||||
removeHologram(hologram.getData().getName());
|
this.removeHologram(hologram.getData().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,7 +122,7 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FancyHolograms.get().getHologramThread().submit(() -> plugin.getHologramStorage().delete(hologram));
|
FancyHolograms.get().getHologramThread().submit(() -> this.plugin.getHologramStorage().delete(hologram));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -142,44 +142,48 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void saveHolograms() {
|
public void saveHolograms() {
|
||||||
if (!isLoaded) {
|
if (!this.isLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.getHologramStorage().saveBatch(getPersistentHolograms(), false);
|
this.plugin.getHologramStorage().saveBatch(this.getPersistentHolograms(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadHolograms() {
|
public void loadHolograms() {
|
||||||
List<Hologram> allLoaded = new ArrayList<>();
|
FancyHolograms.get().getHologramThread().submit(() -> {
|
||||||
|
List<Hologram> allLoaded = new ArrayList<>();
|
||||||
|
|
||||||
for (World world : Bukkit.getWorlds()) {
|
for (World world : Bukkit.getWorlds()) {
|
||||||
Collection<Hologram> loaded = plugin.getHologramStorage().loadAll(world.getName());
|
Collection<Hologram> loaded = this.plugin.getHologramStorage().loadAll(world.getName());
|
||||||
loaded.forEach(this::addHologram);
|
loaded.forEach(this::addHologram);
|
||||||
|
|
||||||
allLoaded.addAll(loaded);
|
allLoaded.addAll(loaded);
|
||||||
}
|
}
|
||||||
isLoaded = true;
|
this.isLoaded = true;
|
||||||
|
|
||||||
FancyHolograms.get().getHologramThread().submit(() -> Bukkit.getPluginManager().callEvent(new HologramsLoadedEvent(ImmutableList.copyOf(allLoaded))));
|
Bukkit.getPluginManager().callEvent(new HologramsLoadedEvent(ImmutableList.copyOf(allLoaded)));
|
||||||
|
if (this.hologramLoadLogging) FancyHolograms.get().getFancyLogger().info(String.format("Loaded %d holograms for all loaded worlds", allLoaded.size()));
|
||||||
if (hologramLoadLogging) FancyHolograms.get().getFancyLogger().info(String.format("Loaded %d holograms for all loaded worlds", allLoaded.size()));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLoaded() {
|
public boolean isLoaded() {
|
||||||
return isLoaded;
|
return this.isLoaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadHolograms(String world) {
|
public void loadHolograms(String world) {
|
||||||
ImmutableList<Hologram> loaded = ImmutableList.copyOf(plugin.getHologramStorage().loadAll(world));
|
FancyHolograms.get().getHologramThread().submit(() -> {
|
||||||
loaded.forEach(this::addHologram);
|
ImmutableList<Hologram> loaded = ImmutableList.copyOf(this.plugin.getHologramStorage().loadAll(world));
|
||||||
|
loaded.forEach(this::addHologram);
|
||||||
|
|
||||||
isLoaded = true;
|
this.isLoaded = true;
|
||||||
|
|
||||||
Bukkit.getPluginManager().callEvent(new HologramsLoadedEvent(ImmutableList.copyOf(loaded)));
|
Bukkit.getPluginManager().callEvent(new HologramsLoadedEvent(ImmutableList.copyOf(loaded)));
|
||||||
|
|
||||||
if (hologramLoadLogging) FancyHolograms.get().getFancyLogger().info(String.format("Loaded %d holograms for world %s", loaded.size(), world));
|
if (this.hologramLoadLogging)
|
||||||
|
FancyHolograms.get().getFancyLogger().info(String.format("Loaded %d holograms for world %s", loaded.size(), world));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,9 +192,9 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
* This method is intended to be called internally by the plugin.
|
* This method is intended to be called internally by the plugin.
|
||||||
*/
|
*/
|
||||||
void initializeTasks() {
|
void initializeTasks() {
|
||||||
ScheduledExecutorService hologramThread = plugin.getHologramThread();
|
ScheduledExecutorService hologramThread = this.plugin.getHologramThread();
|
||||||
hologramThread.submit(() -> {
|
hologramThread.submit(() -> {
|
||||||
loadHolograms();
|
this.loadHolograms();
|
||||||
|
|
||||||
hologramThread.scheduleAtFixedRate(() -> {
|
hologramThread.scheduleAtFixedRate(() -> {
|
||||||
for (final Hologram hologram : this.plugin.getHologramsManager().getHolograms()) {
|
for (final Hologram hologram : this.plugin.getHologramsManager().getHolograms()) {
|
||||||
@@ -198,7 +202,7 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
hologram.forceUpdateShownStateFor(player);
|
hologram.forceUpdateShownStateFor(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 0, plugin.getHologramConfiguration().getUpdateVisibilityInterval() * 50L, TimeUnit.MILLISECONDS);
|
}, 0, this.plugin.getHologramConfiguration().getUpdateVisibilityInterval() * 50L, TimeUnit.MILLISECONDS);
|
||||||
});
|
});
|
||||||
|
|
||||||
final var updateTimes = CacheBuilder.newBuilder()
|
final var updateTimes = CacheBuilder.newBuilder()
|
||||||
@@ -208,7 +212,7 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
hologramThread.scheduleAtFixedRate(() -> {
|
hologramThread.scheduleAtFixedRate(() -> {
|
||||||
final var time = System.currentTimeMillis();
|
final var time = System.currentTimeMillis();
|
||||||
|
|
||||||
for (final var hologram : getHolograms()) {
|
for (final var hologram : this.getHolograms()) {
|
||||||
HologramData data = hologram.getData();
|
HologramData data = hologram.getData();
|
||||||
if (data.hasChanges()) {
|
if (data.hasChanges()) {
|
||||||
hologram.forceUpdate();
|
hologram.forceUpdate();
|
||||||
@@ -225,7 +229,7 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
hologramThread.scheduleWithFixedDelay(() -> {
|
hologramThread.scheduleWithFixedDelay(() -> {
|
||||||
final var time = System.currentTimeMillis();
|
final var time = System.currentTimeMillis();
|
||||||
|
|
||||||
for (final var hologram : getHolograms()) {
|
for (final var hologram : this.getHolograms()) {
|
||||||
if (hologram.getData() instanceof TextHologramData textData) {
|
if (hologram.getData() instanceof TextHologramData textData) {
|
||||||
final var interval = textData.getTextUpdateInterval();
|
final var interval = textData.getTextUpdateInterval();
|
||||||
if (interval < 1) {
|
if (interval < 1) {
|
||||||
@@ -250,8 +254,8 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
* Reloads holograms by clearing the existing holograms and loading them again from the plugin's configuration.
|
* Reloads holograms by clearing the existing holograms and loading them again from the plugin's configuration.
|
||||||
*/
|
*/
|
||||||
public void reloadHolograms() {
|
public void reloadHolograms() {
|
||||||
unloadHolograms();
|
this.unloadHolograms();
|
||||||
loadHolograms();
|
this.loadHolograms();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unloadHolograms() {
|
public void unloadHolograms() {
|
||||||
@@ -278,7 +282,7 @@ public final class HologramManagerImpl implements HologramManager {
|
|||||||
final var online = List.copyOf(Bukkit.getOnlinePlayers());
|
final var online = List.copyOf(Bukkit.getOnlinePlayers());
|
||||||
|
|
||||||
FancyHolograms.get().getHologramThread().submit(() -> {
|
FancyHolograms.get().getHologramThread().submit(() -> {
|
||||||
List<Hologram> h = getPersistentHolograms().stream()
|
List<Hologram> h = this.getPersistentHolograms().stream()
|
||||||
.filter(hologram -> hologram.getData().getLocation().getWorld().getName().equals(world))
|
.filter(hologram -> hologram.getData().getLocation().getWorld().getName().equals(world))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
3.0.0-SNAPSHOT.10
|
3.0.0-SNAPSHOT.16
|
||||||
@@ -46,14 +46,14 @@ dependencies {
|
|||||||
implementation(project(":libraries:config"))
|
implementation(project(":libraries:config"))
|
||||||
implementation(project(":libraries:packets"))
|
implementation(project(":libraries:packets"))
|
||||||
implementation(project(":libraries:packets:packets-api"))
|
implementation(project(":libraries:packets:packets-api"))
|
||||||
implementation("de.oliver.FancyAnalytics:java-sdk:0.0.4")
|
implementation("de.oliver.FancyAnalytics:java-sdk:0.0.5")
|
||||||
implementation("de.oliver.FancyAnalytics:mc-api:0.1.11")
|
implementation("de.oliver.FancyAnalytics:mc-api:0.1.12")
|
||||||
implementation("de.oliver.FancyAnalytics:logger:0.0.8")
|
implementation("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
|
|
||||||
implementation("io.github.revxrsal:lamp.common:4.0.0-rc.12")
|
implementation("io.github.revxrsal:lamp.common:4.0.0-rc.12")
|
||||||
implementation("io.github.revxrsal:lamp.bukkit:4.0.0-rc.12")
|
implementation("io.github.revxrsal:lamp.bukkit:4.0.0-rc.12")
|
||||||
compileOnly(project(":plugins:fancynpcs:fn-api"))
|
compileOnly(project(":plugins:fancynpcs:fn-api"))
|
||||||
compileOnly("org.lushplugins:ChatColorHandler:6.0.3")
|
compileOnly("org.lushplugins:ChatColorHandler:6.0.0")
|
||||||
compileOnly("com.viaversion:viaversion-api:5.2.1")
|
compileOnly("com.viaversion:viaversion-api:5.2.1")
|
||||||
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
|
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
|
||||||
}
|
}
|
||||||
@@ -96,7 +96,7 @@ paper {
|
|||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
runServer {
|
runServer {
|
||||||
minecraftVersion("1.21.10")
|
minecraftVersion("1.21.11-rc2")
|
||||||
|
|
||||||
downloadPlugins {
|
downloadPlugins {
|
||||||
modrinth("fancynpcs", "2.7.0")
|
modrinth("fancynpcs", "2.7.0")
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ plugins {
|
|||||||
id("com.gradleup.shadow")
|
id("com.gradleup.shadow")
|
||||||
}
|
}
|
||||||
|
|
||||||
val minecraftVersion = "1.19.4"
|
val minecraftVersion = "1.20"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("io.papermc.paper:paper-api:$minecraftVersion-R0.1-SNAPSHOT")
|
compileOnly("io.papermc.paper:paper-api:$minecraftVersion-R0.1-SNAPSHOT")
|
||||||
@@ -13,7 +13,7 @@ dependencies {
|
|||||||
compileOnly(project(":libraries:jdb"))
|
compileOnly(project(":libraries:jdb"))
|
||||||
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
|
|
||||||
implementation("org.lushplugins:ChatColorHandler:6.0.3")
|
implementation("org.lushplugins:ChatColorHandler:6.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
@@ -1,29 +1,31 @@
|
|||||||
{
|
{
|
||||||
"project_name": "FancyHolograms",
|
"project_name": "FancyHolograms",
|
||||||
"project_id": "5QNgOj66",
|
"plugin_jar_path": "/plugins/fancyholograms/build/libs/FancyHolograms-%VERSION%.jar",
|
||||||
"plugin_jar_path": "../../../../plugins/fancyholograms/build/libs/FancyHolograms-%VERSION%.jar",
|
"changelog_path": "/plugins/fancyholograms/CHANGELOG.md",
|
||||||
"changelog_path": "../../../../plugins/fancyholograms/CHANGELOG.md",
|
"version_path": "/plugins/fancyholograms/VERSION",
|
||||||
"version_path": "../../../../plugins/fancyholograms/VERSION",
|
"modrinth": {
|
||||||
"supported_versions": [
|
"project_id": "5QNgOj66",
|
||||||
"1.20.5",
|
"supported_versions": [
|
||||||
"1.20.6",
|
"1.20.5",
|
||||||
"1.21",
|
"1.20.6",
|
||||||
"1.21.1",
|
"1.21",
|
||||||
"1.21.2",
|
"1.21.1",
|
||||||
"1.21.3",
|
"1.21.2",
|
||||||
"1.21.4",
|
"1.21.3",
|
||||||
"1.21.5",
|
"1.21.4",
|
||||||
"1.21.6",
|
"1.21.5",
|
||||||
"1.21.7",
|
"1.21.6",
|
||||||
"1.21.8",
|
"1.21.7",
|
||||||
"1.21.9",
|
"1.21.8",
|
||||||
"1.21.10",
|
"1.21.9",
|
||||||
"1.21.11"
|
"1.21.10",
|
||||||
],
|
"1.21.11"
|
||||||
"channel": "RELEASE",
|
],
|
||||||
"loaders": [
|
"channel": "release",
|
||||||
"paper",
|
"loaders": [
|
||||||
"folia"
|
"paper",
|
||||||
],
|
"folia"
|
||||||
"featured": true
|
],
|
||||||
|
"featured": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,31 @@
|
|||||||
{
|
{
|
||||||
"project_name": "FancyHolograms",
|
"project_name": "FancyHolograms",
|
||||||
"project_id": "5QNgOj66",
|
"plugin_jar_path": "/plugins/fancyholograms/build/libs/FancyHolograms-%VERSION%.jar",
|
||||||
"plugin_jar_path": "../../../../plugins/fancyholograms/build/libs/FancyHolograms-%VERSION%.jar",
|
"changelog_path": "/plugins/fancyholograms/CHANGELOG-SNAPSHOT.md",
|
||||||
"changelog_path": "../../../../plugins/fancyholograms/CHANGELOG-SNAPSHOT.md",
|
"version_path": "/plugins/fancyholograms/VERSION",
|
||||||
"version_path": "../../../../plugins/fancyholograms/VERSION",
|
"modrinth": {
|
||||||
"supported_versions": [
|
"project_id": "5QNgOj66",
|
||||||
"1.20.5",
|
"supported_versions": [
|
||||||
"1.20.6",
|
"1.20.5",
|
||||||
"1.21",
|
"1.20.6",
|
||||||
"1.21.1",
|
"1.21",
|
||||||
"1.21.2",
|
"1.21.1",
|
||||||
"1.21.3",
|
"1.21.2",
|
||||||
"1.21.4",
|
"1.21.3",
|
||||||
"1.21.5",
|
"1.21.4",
|
||||||
"1.21.6",
|
"1.21.5",
|
||||||
"1.21.7",
|
"1.21.6",
|
||||||
"1.21.8",
|
"1.21.7",
|
||||||
"1.21.9",
|
"1.21.8",
|
||||||
"1.21.10"
|
"1.21.9",
|
||||||
],
|
"1.21.10",
|
||||||
"channel": "ALPHA",
|
"1.21.11-rc2"
|
||||||
"loaders": [
|
],
|
||||||
"paper",
|
"channel": "alpha",
|
||||||
"folia"
|
"loaders": [
|
||||||
],
|
"paper",
|
||||||
"featured": false
|
"folia"
|
||||||
|
],
|
||||||
|
"featured": false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -76,6 +76,11 @@ public class SetLineCMD implements Subcommand {
|
|||||||
|
|
||||||
index--;
|
index--;
|
||||||
|
|
||||||
|
if (args.length < 5) {
|
||||||
|
MessageHelper.error(player, "Please provide text for the line");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
String text = "";
|
String text = "";
|
||||||
for (int i = 4; i < args.length; i++) {
|
for (int i = 4; i < args.length; i++) {
|
||||||
text += args[i] + " ";
|
text += args[i] + " ";
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
- Added support for 1.21.11
|
- Removed support for 1.19.4
|
||||||
|
- Fixed npcs randomly disappearing
|
||||||
- Fixed skin mirroring for 1.21.9
|
- Fixed skin mirroring for 1.21.9
|
||||||
- Added inverted permission check for `need_permission` action (use prefix `!` to invert)
|
- Added inverted permission check for `need_permission` action (use prefix `!` to invert)
|
||||||
- Added `/npc rotate <npc> <yaw> <pitch>` command to set NPC orientation
|
- Added `/npc rotate <npc> <yaw> <pitch>` command to set NPC orientation
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ Check out **[images section](#images)** down below.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Paper **1.19.4** - **1.21.11** with **Java 21** (or higher) is required. Plugin should also work on **Paper** forks.
|
Paper **1.20** - **1.21.11** with **Java 21** (or higher) is required. Plugin should also work on **Paper** forks.
|
||||||
|
|
||||||
**Spigot** is **not** supported.
|
**Spigot** is **not** supported.
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2.8.0.307
|
2.8.1.317
|
||||||
@@ -43,7 +43,6 @@ dependencies {
|
|||||||
implementation(project(":plugins:fancynpcs:implementation_1_20_2", configuration = "reobf"))
|
implementation(project(":plugins:fancynpcs:implementation_1_20_2", configuration = "reobf"))
|
||||||
implementation(project(":plugins:fancynpcs:implementation_1_20_1", configuration = "reobf"))
|
implementation(project(":plugins:fancynpcs:implementation_1_20_1", configuration = "reobf"))
|
||||||
implementation(project(":plugins:fancynpcs:implementation_1_20", configuration = "reobf"))
|
implementation(project(":plugins:fancynpcs:implementation_1_20", configuration = "reobf"))
|
||||||
implementation(project(":plugins:fancynpcs:implementation_1_19_4", configuration = "reobf"))
|
|
||||||
|
|
||||||
rootProject.subprojects
|
rootProject.subprojects
|
||||||
.filter { it.path.startsWith(":libraries:packets:implementations") }
|
.filter { it.path.startsWith(":libraries:packets:implementations") }
|
||||||
@@ -54,9 +53,9 @@ dependencies {
|
|||||||
implementation(project(":libraries:jdb"))
|
implementation(project(":libraries:jdb"))
|
||||||
implementation(project(":libraries:plugin-tests"))
|
implementation(project(":libraries:plugin-tests"))
|
||||||
implementation(project(":libraries:config"))
|
implementation(project(":libraries:config"))
|
||||||
compileOnly("org.lushplugins:ChatColorHandler:6.0.3")
|
compileOnly("org.lushplugins:ChatColorHandler:6.0.0")
|
||||||
implementation("de.oliver.FancyAnalytics:java-sdk:0.0.4")
|
implementation("de.oliver.FancyAnalytics:java-sdk:0.0.5")
|
||||||
implementation("de.oliver.FancyAnalytics:mc-api:0.1.11")
|
implementation("de.oliver.FancyAnalytics:mc-api:0.1.12")
|
||||||
implementation("de.oliver.FancyAnalytics:logger:0.0.8")
|
implementation("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
implementation("org.incendo:cloud-core:2.0.0")
|
implementation("org.incendo:cloud-core:2.0.0")
|
||||||
implementation("org.incendo:cloud-paper:2.0.0-beta.13")
|
implementation("org.incendo:cloud-paper:2.0.0-beta.13")
|
||||||
@@ -96,7 +95,7 @@ paper {
|
|||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
runServer {
|
runServer {
|
||||||
minecraftVersion("1.21.10")
|
minecraftVersion("1.21.11-rc2")
|
||||||
|
|
||||||
downloadPlugins {
|
downloadPlugins {
|
||||||
// hangar("ViaVersion", "5.4.0")
|
// hangar("ViaVersion", "5.4.0")
|
||||||
|
|||||||
@@ -4,15 +4,16 @@ plugins {
|
|||||||
id("com.gradleup.shadow")
|
id("com.gradleup.shadow")
|
||||||
}
|
}
|
||||||
|
|
||||||
val minecraftVersion = "1.19.4"
|
val minecraftVersion = "1.20"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("io.papermc.paper:paper-api:$minecraftVersion-R0.1-SNAPSHOT")
|
compileOnly("io.papermc.paper:paper-api:$minecraftVersion-R0.1-SNAPSHOT")
|
||||||
|
|
||||||
compileOnly(project(":libraries:common"))
|
compileOnly(project(":libraries:common"))
|
||||||
|
compileOnly(project(":libraries:config"))
|
||||||
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
compileOnly("de.oliver.FancyAnalytics:logger:0.0.8")
|
||||||
|
|
||||||
implementation("org.lushplugins:ChatColorHandler:6.0.3")
|
implementation("org.lushplugins:ChatColorHandler:6.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.oliver.fancynpcs.api;
|
package de.oliver.fancynpcs.api;
|
||||||
|
|
||||||
|
import com.fancyinnovations.config.featureflags.FeatureFlagConfig;
|
||||||
import de.oliver.fancyanalytics.logger.ExtendedFancyLogger;
|
import de.oliver.fancyanalytics.logger.ExtendedFancyLogger;
|
||||||
import de.oliver.fancylib.serverSoftware.schedulers.FancyScheduler;
|
import de.oliver.fancylib.serverSoftware.schedulers.FancyScheduler;
|
||||||
import de.oliver.fancylib.translations.Translator;
|
import de.oliver.fancylib.translations.Translator;
|
||||||
@@ -32,8 +33,8 @@ public interface FancyNpcsPlugin {
|
|||||||
ScheduledExecutorService getNpcThread();
|
ScheduledExecutorService getNpcThread();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new thread with the given name and runnable.
|
* Creates a new thread with the given name and runnable.
|
||||||
* Warning: Do not use this method, it is for internal use only.
|
* Warning: Do not use this method, it is for internal use only.
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
Thread newThread(String name, Runnable runnable);
|
Thread newThread(String name, Runnable runnable);
|
||||||
@@ -44,6 +45,8 @@ public interface FancyNpcsPlugin {
|
|||||||
|
|
||||||
FancyNpcsConfig getFancyNpcConfig();
|
FancyNpcsConfig getFancyNpcConfig();
|
||||||
|
|
||||||
|
FeatureFlagConfig getFeatureFlagConfig();
|
||||||
|
|
||||||
NpcManager getNpcManager();
|
NpcManager getNpcManager();
|
||||||
|
|
||||||
AttributeManager getAttributeManager();
|
AttributeManager getAttributeManager();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package de.oliver.fancynpcs.api;
|
package de.oliver.fancynpcs.api;
|
||||||
|
|
||||||
import de.oliver.fancylib.RandomUtils;
|
import de.oliver.fancylib.RandomUtils;
|
||||||
|
import de.oliver.fancylib.serverSoftware.ServerSoftware;
|
||||||
import de.oliver.fancylib.translations.Translator;
|
import de.oliver.fancylib.translations.Translator;
|
||||||
import de.oliver.fancynpcs.api.actions.ActionTrigger;
|
import de.oliver.fancynpcs.api.actions.ActionTrigger;
|
||||||
import de.oliver.fancynpcs.api.actions.NpcAction;
|
import de.oliver.fancynpcs.api.actions.NpcAction;
|
||||||
@@ -18,6 +19,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public abstract class Npc {
|
public abstract class Npc {
|
||||||
|
|
||||||
@@ -110,6 +112,15 @@ public abstract class Npc {
|
|||||||
|
|
||||||
if (shouldBeVisible && !wasVisible) {
|
if (shouldBeVisible && !wasVisible) {
|
||||||
spawn(player);
|
spawn(player);
|
||||||
|
|
||||||
|
// Respawn the npc to fix visibility issues on Folia
|
||||||
|
if (ServerSoftware.isFolia() && FancyNpcsPlugin.get().getFeatureFlagConfig().getFeatureFlag("enable-folia-visibility-fix").isEnabled()) {
|
||||||
|
FancyNpcsPlugin.get().getNpcThread().schedule(() -> {
|
||||||
|
remove(player);
|
||||||
|
spawn(player);
|
||||||
|
}, 100, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
} else if (!shouldBeVisible && wasVisible) {
|
} else if (!shouldBeVisible && wasVisible) {
|
||||||
remove(player);
|
remove(player);
|
||||||
}
|
}
|
||||||
@@ -185,7 +196,7 @@ public abstract class Npc {
|
|||||||
|
|
||||||
// actions
|
// actions
|
||||||
ActionExecutor.execute(actionTrigger, this, player);
|
ActionExecutor.execute(actionTrigger, this, player);
|
||||||
|
|
||||||
if (actionTrigger == ActionTrigger.LEFT_CLICK || actionTrigger == ActionTrigger.RIGHT_CLICK) {
|
if (actionTrigger == ActionTrigger.LEFT_CLICK || actionTrigger == ActionTrigger.RIGHT_CLICK) {
|
||||||
ActionExecutor.execute(ActionTrigger.ANY_CLICK, this, player);
|
ActionExecutor.execute(ActionTrigger.ANY_CLICK, this, player);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
plugins {
|
|
||||||
id("java-library")
|
|
||||||
id("io.papermc.paperweight.userdev")
|
|
||||||
}
|
|
||||||
|
|
||||||
val minecraftVersion = "1.19.4"
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
paperweight.paperDevBundle("$minecraftVersion-R0.1-SNAPSHOT")
|
|
||||||
|
|
||||||
compileOnly(project(":plugins:fancynpcs:fn-api"))
|
|
||||||
compileOnly(project(":libraries:common"))
|
|
||||||
compileOnly("org.lushplugins:ChatColorHandler:5.1.6") // KEEP, newer versions require Java 21
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
tasks {
|
|
||||||
named("assemble") {
|
|
||||||
dependsOn(named("reobfJar"))
|
|
||||||
}
|
|
||||||
|
|
||||||
javadoc {
|
|
||||||
options.encoding = Charsets.UTF_8.name()
|
|
||||||
}
|
|
||||||
|
|
||||||
compileJava {
|
|
||||||
options.encoding = Charsets.UTF_8.name()
|
|
||||||
options.release = 17
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
java {
|
|
||||||
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4;
|
|
||||||
|
|
||||||
public enum MappingKeys1_19_4 {
|
|
||||||
|
|
||||||
ENTITY_TYPE__FACTORY("bA"),
|
|
||||||
SYNCHED_ENTITY_DATA__ITEMS_BY_ID("e"),
|
|
||||||
CLIENTBOUND_TELEPORT_ENTITY_PACKET__X("b"),
|
|
||||||
CLIENTBOUND_TELEPORT_ENTITY_PACKET__Y("c"),
|
|
||||||
CLIENTBOUND_TELEPORT_ENTITY_PACKET__Z("d"),
|
|
||||||
CLIENTBOUND_PLAYER_INFO_UPDATE_PACKET__ENTRIES("b"),
|
|
||||||
PANDA__DATA_ID_FLAGS("ca"),
|
|
||||||
;
|
|
||||||
|
|
||||||
private final String mapping;
|
|
||||||
|
|
||||||
MappingKeys1_19_4(String mapping) {
|
|
||||||
this.mapping = mapping;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMapping() {
|
|
||||||
return mapping;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,391 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.mojang.authlib.GameProfile;
|
|
||||||
import com.mojang.authlib.properties.Property;
|
|
||||||
import com.mojang.datafixers.util.Pair;
|
|
||||||
import de.oliver.fancylib.ReflectionUtils;
|
|
||||||
import de.oliver.fancynpcs.api.FancyNpcsPlugin;
|
|
||||||
import de.oliver.fancynpcs.api.Npc;
|
|
||||||
import de.oliver.fancynpcs.api.NpcAttribute;
|
|
||||||
import de.oliver.fancynpcs.api.NpcData;
|
|
||||||
import de.oliver.fancynpcs.api.events.NpcSpawnEvent;
|
|
||||||
import de.oliver.fancynpcs.api.utils.NpcEquipmentSlot;
|
|
||||||
import io.papermc.paper.adventure.PaperAdventure;
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.network.chat.Component;
|
|
||||||
import net.minecraft.network.protocol.game.*;
|
|
||||||
import net.minecraft.network.syncher.SynchedEntityData;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.server.level.ServerLevel;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import net.minecraft.server.network.ServerLoginPacketListenerImpl;
|
|
||||||
import net.minecraft.world.entity.Display;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.EntityType;
|
|
||||||
import net.minecraft.world.entity.EquipmentSlot;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.scores.PlayerTeam;
|
|
||||||
import net.minecraft.world.scores.Scoreboard;
|
|
||||||
import net.minecraft.world.scores.Team;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.CraftServer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.CraftWorld;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.util.CraftNamespacedKey;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.lushplugins.chatcolorhandler.ModernChatColorHandler;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class Npc_1_19_4 extends Npc {
|
|
||||||
|
|
||||||
private final String localName;
|
|
||||||
private final UUID uuid;
|
|
||||||
private Entity npc;
|
|
||||||
private Display.TextDisplay sittingVehicle;
|
|
||||||
|
|
||||||
public Npc_1_19_4(NpcData data) {
|
|
||||||
super(data);
|
|
||||||
|
|
||||||
this.localName = generateLocalName();
|
|
||||||
this.uuid = UUID.randomUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void create() {
|
|
||||||
MinecraftServer minecraftServer = ((CraftServer) Bukkit.getServer()).getServer();
|
|
||||||
ServerLevel serverLevel = ((CraftWorld) data.getLocation().getWorld()).getHandle();
|
|
||||||
GameProfile gameProfile = new GameProfile(uuid, localName);
|
|
||||||
|
|
||||||
if (data.getType() == org.bukkit.entity.EntityType.PLAYER) {
|
|
||||||
npc = new ServerPlayer(minecraftServer, serverLevel, new GameProfile(uuid, ""));
|
|
||||||
((ServerPlayer) npc).gameProfile = gameProfile;
|
|
||||||
} else {
|
|
||||||
EntityType<?> nmsType = BuiltInRegistries.ENTITY_TYPE.get(CraftNamespacedKey.toMinecraft(data.getType().getKey()));
|
|
||||||
EntityType.EntityFactory factory = (EntityType.EntityFactory) ReflectionUtils.getValue(nmsType, MappingKeys1_19_4.ENTITY_TYPE__FACTORY.getMapping()); // EntityType.factory
|
|
||||||
npc = factory.create(nmsType, serverLevel);
|
|
||||||
isTeamCreated.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void spawn(Player player) {
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
|
|
||||||
if (npc == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data.getLocation().getWorld().getName().equalsIgnoreCase(serverPlayer.getLevel().getWorld().getName())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.getSkinData() != null && data.getSkinData().hasTexture()) {
|
|
||||||
String value = data.getSkinData().getTextureValue();
|
|
||||||
String signature = data.getSkinData().getTextureSignature();
|
|
||||||
|
|
||||||
((ServerPlayer) npc).getGameProfile().getProperties().replaceValues(
|
|
||||||
"textures",
|
|
||||||
ImmutableList.of(new Property("textures", value, signature))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
NpcSpawnEvent spawnEvent = new NpcSpawnEvent(this, player);
|
|
||||||
spawnEvent.callEvent();
|
|
||||||
if (spawnEvent.isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (npc instanceof ServerPlayer npcPlayer) {
|
|
||||||
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.noneOf(ClientboundPlayerInfoUpdatePacket.Action.class);
|
|
||||||
actions.add(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER);
|
|
||||||
actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME);
|
|
||||||
if (data.isShowInTab()) {
|
|
||||||
actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientboundPlayerInfoUpdatePacket playerInfoPacket = new ClientboundPlayerInfoUpdatePacket(actions, List.of(npcPlayer));
|
|
||||||
if (data.isMirrorSkin()) {
|
|
||||||
handleMirroredSkin(playerInfoPacket, serverPlayer);
|
|
||||||
}
|
|
||||||
serverPlayer.connection.send(playerInfoPacket);
|
|
||||||
|
|
||||||
if (data.isSpawnEntity()) {
|
|
||||||
npc.setPos(data.getLocation().x(), data.getLocation().y(), data.getLocation().z());
|
|
||||||
ClientboundAddPlayerPacket spawnPlayerPacket = new ClientboundAddPlayerPacket(npcPlayer);
|
|
||||||
serverPlayer.connection.send(spawnPlayerPacket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientboundAddEntityPacket addEntityPacket = new ClientboundAddEntityPacket(npc);
|
|
||||||
serverPlayer.connection.send(addEntityPacket);
|
|
||||||
|
|
||||||
isVisibleForPlayer.put(player.getUniqueId(), true);
|
|
||||||
|
|
||||||
int removeNpcsFromPlayerlistDelay = FancyNpcsPlugin.get().getFancyNpcConfig().getRemoveNpcsFromPlayerlistDelay();
|
|
||||||
if (!data.isShowInTab() && removeNpcsFromPlayerlistDelay > 0) {
|
|
||||||
FancyNpcsPlugin.get().getNpcThread().schedule(() -> {
|
|
||||||
ClientboundPlayerInfoRemovePacket playerInfoRemovePacket = new ClientboundPlayerInfoRemovePacket(List.of(npc.getUUID()));
|
|
||||||
serverPlayer.connection.send(playerInfoRemovePacket);
|
|
||||||
}, removeNpcsFromPlayerlistDelay, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
update(player);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove(Player player) {
|
|
||||||
if (npc == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
|
|
||||||
if (npc instanceof ServerPlayer npcPlayer) {
|
|
||||||
ClientboundPlayerInfoRemovePacket playerInfoRemovePacket = new ClientboundPlayerInfoRemovePacket(List.of((npcPlayer.getUUID())));
|
|
||||||
serverPlayer.connection.send(playerInfoRemovePacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove entity
|
|
||||||
ClientboundRemoveEntitiesPacket removeEntitiesPacket = new ClientboundRemoveEntitiesPacket(npc.getId());
|
|
||||||
serverPlayer.connection.send(removeEntitiesPacket);
|
|
||||||
|
|
||||||
// remove sitting vehicle
|
|
||||||
if (sittingVehicle != null) {
|
|
||||||
ClientboundRemoveEntitiesPacket removeSittingVehiclePacket = new ClientboundRemoveEntitiesPacket(sittingVehicle.getId());
|
|
||||||
serverPlayer.connection.send(removeSittingVehiclePacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
isVisibleForPlayer.put(serverPlayer.getUUID(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void lookAt(Player player, Location location) {
|
|
||||||
if (npc == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
|
|
||||||
npc.setRot(location.getYaw(), location.getPitch());
|
|
||||||
npc.setYHeadRot(location.getYaw());
|
|
||||||
npc.setXRot(location.getPitch());
|
|
||||||
npc.setYRot(location.getYaw());
|
|
||||||
|
|
||||||
ClientboundTeleportEntityPacket teleportEntityPacket = new ClientboundTeleportEntityPacket(npc);
|
|
||||||
serverPlayer.connection.send(teleportEntityPacket);
|
|
||||||
|
|
||||||
float angelMultiplier = 256f / 360f;
|
|
||||||
ClientboundRotateHeadPacket rotateHeadPacket = new ClientboundRotateHeadPacket(npc, (byte) (location.getYaw() * angelMultiplier));
|
|
||||||
serverPlayer.connection.send(rotateHeadPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(Player player, boolean swingArm) {
|
|
||||||
if (npc == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isVisibleForPlayer.getOrDefault(player.getUniqueId(), false)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
|
|
||||||
PlayerTeam team = new PlayerTeam(new Scoreboard(), "npc-" + localName);
|
|
||||||
team.getPlayers().clear();
|
|
||||||
team.getPlayers().add(npc instanceof ServerPlayer npcPlayer ? npcPlayer.getGameProfile().getName() : npc.getStringUUID());
|
|
||||||
team.setColor(PaperAdventure.asVanilla(data.getGlowingColor()));
|
|
||||||
if (!data.isCollidable()) {
|
|
||||||
team.setCollisionRule(Team.CollisionRule.NEVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
net.kyori.adventure.text.Component displayName = ModernChatColorHandler.translate(data.getDisplayName(), serverPlayer.getBukkitEntity());
|
|
||||||
Component vanillaComponent = PaperAdventure.asVanilla(displayName);
|
|
||||||
if (!(npc instanceof ServerPlayer)) {
|
|
||||||
npc.setCustomName(vanillaComponent);
|
|
||||||
npc.setCustomNameVisible(true);
|
|
||||||
} else {
|
|
||||||
npc.setCustomName(null);
|
|
||||||
npc.setCustomNameVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.getDisplayName().equalsIgnoreCase("<empty>")) {
|
|
||||||
team.setNameTagVisibility(Team.Visibility.NEVER);
|
|
||||||
npc.setCustomName(null);
|
|
||||||
npc.setCustomNameVisible(false);
|
|
||||||
} else {
|
|
||||||
team.setNameTagVisibility(Team.Visibility.ALWAYS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (npc instanceof ServerPlayer npcPlayer) {
|
|
||||||
team.setPlayerPrefix(vanillaComponent);
|
|
||||||
npcPlayer.listName = vanillaComponent;
|
|
||||||
|
|
||||||
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.noneOf(ClientboundPlayerInfoUpdatePacket.Action.class);
|
|
||||||
actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_DISPLAY_NAME);
|
|
||||||
if (data.isShowInTab()) {
|
|
||||||
actions.add(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LISTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientboundPlayerInfoUpdatePacket playerInfoPacket = new ClientboundPlayerInfoUpdatePacket(actions, List.of(npcPlayer));
|
|
||||||
if (data.isMirrorSkin()) {
|
|
||||||
handleMirroredSkin(playerInfoPacket, serverPlayer);
|
|
||||||
}
|
|
||||||
serverPlayer.connection.send(playerInfoPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isTeamCreatedForPlayer = this.isTeamCreated.getOrDefault(player.getUniqueId(), false);
|
|
||||||
serverPlayer.connection.send(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(team, !isTeamCreatedForPlayer));
|
|
||||||
isTeamCreated.put(player.getUniqueId(), true);
|
|
||||||
|
|
||||||
npc.setGlowingTag(data.isGlowing());
|
|
||||||
|
|
||||||
if (data.getEquipment() != null && data.getEquipment().size() > 0) {
|
|
||||||
List<Pair<EquipmentSlot, ItemStack>> equipmentList = new ArrayList<>();
|
|
||||||
|
|
||||||
for (NpcEquipmentSlot slot : data.getEquipment().keySet()) {
|
|
||||||
equipmentList.add(new Pair<>(EquipmentSlot.byName(slot.toNmsName()), CraftItemStack.asNMSCopy(data.getEquipment().get(slot))));
|
|
||||||
}
|
|
||||||
|
|
||||||
ClientboundSetEquipmentPacket setEquipmentPacket = new ClientboundSetEquipmentPacket(npc.getId(), equipmentList);
|
|
||||||
serverPlayer.connection.send(setEquipmentPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (npc instanceof ServerPlayer) {
|
|
||||||
// Enable second layer of skin (https://wiki.vg/Entity_metadata#Player)
|
|
||||||
npc.getEntityData().set(net.minecraft.world.entity.player.Player.DATA_PLAYER_MODE_CUSTOMISATION, (byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
|
||||||
}
|
|
||||||
|
|
||||||
data.applyAllAttributes(this);
|
|
||||||
|
|
||||||
refreshEntityData(player);
|
|
||||||
|
|
||||||
if (data.isSpawnEntity() && data.getLocation() != null) {
|
|
||||||
move(player, swingArm);
|
|
||||||
}
|
|
||||||
|
|
||||||
NpcAttribute playerPoseAttr = FancyNpcsPlugin.get().getAttributeManager().getAttributeByName(org.bukkit.entity.EntityType.PLAYER, "pose");
|
|
||||||
if (data.getAttributes().containsKey(playerPoseAttr)) {
|
|
||||||
String pose = data.getAttributes().get(playerPoseAttr);
|
|
||||||
|
|
||||||
if (pose.equals("sitting")) {
|
|
||||||
setSitting(serverPlayer);
|
|
||||||
} else {
|
|
||||||
if (sittingVehicle != null) {
|
|
||||||
ClientboundRemoveEntitiesPacket removeSittingVehiclePacket = new ClientboundRemoveEntitiesPacket(sittingVehicle.getId());
|
|
||||||
serverPlayer.connection.send(removeSittingVehiclePacket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void refreshEntityData(Player player) {
|
|
||||||
if (!isVisibleForPlayer.getOrDefault(player.getUniqueId(), false)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
|
|
||||||
Int2ObjectMap<SynchedEntityData.DataItem<?>> itemsById = (Int2ObjectMap<SynchedEntityData.DataItem<?>>) ReflectionUtils.getValue(npc.getEntityData(), MappingKeys1_19_4.SYNCHED_ENTITY_DATA__ITEMS_BY_ID.getMapping()); // itemsById
|
|
||||||
List<SynchedEntityData.DataValue<?>> entityData = new ArrayList<>();
|
|
||||||
for (SynchedEntityData.DataItem<?> dataItem : itemsById.values()) {
|
|
||||||
entityData.add(dataItem.value());
|
|
||||||
}
|
|
||||||
ClientboundSetEntityDataPacket setEntityDataPacket = new ClientboundSetEntityDataPacket(npc.getId(), entityData);
|
|
||||||
serverPlayer.connection.send(setEntityDataPacket);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void move(Player player, boolean swingArm) {
|
|
||||||
if (npc == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
|
|
||||||
npc.setPosRaw(data.getLocation().x(), data.getLocation().y(), data.getLocation().z());
|
|
||||||
npc.setRot(data.getLocation().getYaw(), data.getLocation().getPitch());
|
|
||||||
npc.setYHeadRot(data.getLocation().getYaw());
|
|
||||||
npc.setXRot(data.getLocation().getPitch());
|
|
||||||
npc.setYRot(data.getLocation().getYaw());
|
|
||||||
|
|
||||||
ClientboundTeleportEntityPacket teleportEntityPacket = new ClientboundTeleportEntityPacket(npc);
|
|
||||||
ReflectionUtils.setValue(teleportEntityPacket, MappingKeys1_19_4.CLIENTBOUND_TELEPORT_ENTITY_PACKET__X.getMapping(), data.getLocation().x()); // 'x'
|
|
||||||
ReflectionUtils.setValue(teleportEntityPacket, MappingKeys1_19_4.CLIENTBOUND_TELEPORT_ENTITY_PACKET__Y.getMapping(), data.getLocation().y()); // 'y'
|
|
||||||
ReflectionUtils.setValue(teleportEntityPacket, MappingKeys1_19_4.CLIENTBOUND_TELEPORT_ENTITY_PACKET__Z.getMapping(), data.getLocation().z()); // 'z'
|
|
||||||
serverPlayer.connection.send(teleportEntityPacket);
|
|
||||||
|
|
||||||
float angelMultiplier = 256f / 360f;
|
|
||||||
ClientboundRotateHeadPacket rotateHeadPacket = new ClientboundRotateHeadPacket(npc, (byte) (data.getLocation().getYaw() * angelMultiplier));
|
|
||||||
serverPlayer.connection.send(rotateHeadPacket);
|
|
||||||
|
|
||||||
if (swingArm && npc instanceof ServerPlayer) {
|
|
||||||
ClientboundAnimatePacket animatePacket = new ClientboundAnimatePacket(npc, 0);
|
|
||||||
serverPlayer.connection.send(animatePacket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSitting(ServerPlayer serverPlayer) {
|
|
||||||
if (npc == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sittingVehicle == null) {
|
|
||||||
sittingVehicle = new Display.TextDisplay(EntityType.TEXT_DISPLAY, ((CraftWorld) data.getLocation().getWorld()).getHandle());
|
|
||||||
}
|
|
||||||
|
|
||||||
sittingVehicle.setPos(data.getLocation().x(), data.getLocation().y(), data.getLocation().z());
|
|
||||||
|
|
||||||
ClientboundAddEntityPacket addEntityPacket = new ClientboundAddEntityPacket(sittingVehicle);
|
|
||||||
serverPlayer.connection.send(addEntityPacket);
|
|
||||||
|
|
||||||
sittingVehicle.passengers = ImmutableList.of(npc);
|
|
||||||
|
|
||||||
ClientboundSetPassengersPacket packet = new ClientboundSetPassengersPacket(sittingVehicle);
|
|
||||||
serverPlayer.connection.send(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleMirroredSkin(ClientboundPlayerInfoUpdatePacket playerInfoUpdatePacket, ServerPlayer viewer) {
|
|
||||||
if (!ServerLoginPacketListenerImpl.isValidUsername(viewer.getGameProfile().getName())) return;
|
|
||||||
ClientboundPlayerInfoUpdatePacket.Entry entry = playerInfoUpdatePacket.entries().get(0);
|
|
||||||
GameProfile profile = entry.profile();
|
|
||||||
GameProfile newProfile = new GameProfile(profile.getId(), profile.getName());
|
|
||||||
newProfile.getProperties().putAll(viewer.getGameProfile().getProperties());
|
|
||||||
ClientboundPlayerInfoUpdatePacket.Entry newEntry = new ClientboundPlayerInfoUpdatePacket.Entry(
|
|
||||||
entry.profileId(),
|
|
||||||
newProfile,
|
|
||||||
entry.listed(),
|
|
||||||
entry.latency(),
|
|
||||||
entry.gameMode(),
|
|
||||||
entry.displayName(),
|
|
||||||
entry.chatSession()
|
|
||||||
);
|
|
||||||
|
|
||||||
ReflectionUtils.setValue(playerInfoUpdatePacket, "b", List.of(newEntry)); // 'entries'
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getEyeHeight() {
|
|
||||||
return npc.getEyeHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getEntityId() {
|
|
||||||
return npc.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Entity getNpc() {
|
|
||||||
return npc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4;
|
|
||||||
|
|
||||||
import de.oliver.fancylib.FancyLib;
|
|
||||||
import de.oliver.fancylib.ReflectionUtils;
|
|
||||||
import de.oliver.fancynpcs.api.FancyNpcsPlugin;
|
|
||||||
import de.oliver.fancynpcs.api.Npc;
|
|
||||||
import de.oliver.fancynpcs.api.actions.ActionTrigger;
|
|
||||||
import de.oliver.fancynpcs.api.events.PacketReceivedEvent;
|
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import io.netty.handler.codec.MessageToMessageDecoder;
|
|
||||||
import net.minecraft.network.protocol.game.ServerboundInteractPacket;
|
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
|
||||||
import org.bukkit.craftbukkit.v1_19_R3.entity.CraftPlayer;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PacketReader_1_19_4 implements Listener {
|
|
||||||
|
|
||||||
public static boolean inject(Player player) {
|
|
||||||
ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
|
|
||||||
|
|
||||||
Channel channel = serverPlayer.connection.connection.channel;
|
|
||||||
|
|
||||||
if (channel.pipeline().get("PacketInjector") != null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
channel.pipeline().addAfter("decoder", "PacketInjector", new MessageToMessageDecoder<ServerboundInteractPacket>() {
|
|
||||||
@Override
|
|
||||||
protected void decode(ChannelHandlerContext ctx, ServerboundInteractPacket msg, List<Object> out) {
|
|
||||||
out.add(msg);
|
|
||||||
|
|
||||||
PacketReceivedEvent packetReceivedEvent = new PacketReceivedEvent(msg, player);
|
|
||||||
FancyLib.getInstance().getScheduler().runTaskLater(null, 1L, packetReceivedEvent::callEvent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
|
||||||
public void onPacketReceived(final PacketReceivedEvent event) {
|
|
||||||
// Skipping packets other than ServerboundInteractPacket...
|
|
||||||
if (!(event.getPacket() instanceof ServerboundInteractPacket interactPacket))
|
|
||||||
return;
|
|
||||||
// Getting NPC from entity identifier.
|
|
||||||
final Npc npc = FancyNpcsPlugin.get().getNpcManager().getNpc(interactPacket.getEntityId());
|
|
||||||
// Skipping entities that are not FancyNpcs' NPCs...
|
|
||||||
if (npc == null)
|
|
||||||
return;
|
|
||||||
// Getting interaction information.
|
|
||||||
final boolean isAttack = (interactPacket.getActionType() == ServerboundInteractPacket.ActionType.ATTACK);
|
|
||||||
final boolean isInteract = (interactPacket.getActionType() == ServerboundInteractPacket.ActionType.INTERACT_AT);
|
|
||||||
final EquipmentSlot hand = (interactPacket.getActionType() == ServerboundInteractPacket.ActionType.ATTACK)
|
|
||||||
? EquipmentSlot.HAND
|
|
||||||
: ReflectionUtils.getValue(ReflectionUtils.getValue(interactPacket, "b"), "a").toString().equals("MAIN_HAND") // ServerboundInteractPacket.InteractionAction.hand
|
|
||||||
? EquipmentSlot.HAND
|
|
||||||
: EquipmentSlot.OFF_HAND;
|
|
||||||
// This can optionally be ALSO called for OFF-HAND slot. Making sure to run logic only ONCE.
|
|
||||||
if (hand == EquipmentSlot.HAND) {
|
|
||||||
// This packet can be sent multiple times for interactions that are NOT attacks, making sure to run logic only ONCE.
|
|
||||||
if (isAttack || !isInteract || npc.getData().getType() == EntityType.ARMOR_STAND) {
|
|
||||||
npc.interact(event.getPlayer(), isAttack ? ActionTrigger.LEFT_CLICK : ActionTrigger.RIGHT_CLICK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4;
|
|
||||||
|
|
||||||
import de.oliver.fancylib.ReflectionUtils;
|
|
||||||
import de.oliver.fancynpcs.api.Npc;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
|
|
||||||
public class ReflectionHelper {
|
|
||||||
|
|
||||||
public static <T extends Entity> T getEntity(Npc npc) {
|
|
||||||
return (T) ReflectionUtils.getValue(npc, "npc");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4.attributes;
|
|
||||||
|
|
||||||
import de.oliver.fancynpcs.api.Npc;
|
|
||||||
import de.oliver.fancynpcs.api.NpcAttribute;
|
|
||||||
import de.oliver.fancynpcs.v1_19_4.ReflectionHelper;
|
|
||||||
import net.minecraft.world.entity.AgeableMob;
|
|
||||||
import org.bukkit.entity.Ageable;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AgeableMobAttributes {
|
|
||||||
|
|
||||||
public static List<NpcAttribute> getAllAttributes() {
|
|
||||||
List<NpcAttribute> attributes = new ArrayList<>();
|
|
||||||
|
|
||||||
attributes.add(new NpcAttribute(
|
|
||||||
"baby",
|
|
||||||
List.of("true", "false"),
|
|
||||||
Arrays.stream(EntityType.values())
|
|
||||||
.filter(type -> type.getEntityClass() != null && Ageable.class.isAssignableFrom(type.getEntityClass()))
|
|
||||||
.toList(),
|
|
||||||
AgeableMobAttributes::setBaby
|
|
||||||
));
|
|
||||||
|
|
||||||
return attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setBaby(Npc npc, String value) {
|
|
||||||
AgeableMob mob = ReflectionHelper.getEntity(npc);
|
|
||||||
|
|
||||||
boolean isBaby = Boolean.parseBoolean(value);
|
|
||||||
|
|
||||||
mob.setBaby(isBaby);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4.attributes;
|
|
||||||
|
|
||||||
import de.oliver.fancynpcs.api.Npc;
|
|
||||||
import de.oliver.fancynpcs.api.NpcAttribute;
|
|
||||||
import de.oliver.fancynpcs.v1_19_4.ReflectionHelper;
|
|
||||||
import net.minecraft.world.entity.animal.allay.Allay;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AllayAttributes {
|
|
||||||
|
|
||||||
public static List<NpcAttribute> getAllAttributes() {
|
|
||||||
List<NpcAttribute> attributes = new ArrayList<>();
|
|
||||||
|
|
||||||
attributes.add(new NpcAttribute(
|
|
||||||
"dancing",
|
|
||||||
List.of("true", "false"),
|
|
||||||
List.of(EntityType.ALLAY),
|
|
||||||
AllayAttributes::setDancing
|
|
||||||
));
|
|
||||||
|
|
||||||
return attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setDancing(Npc npc, String value) {
|
|
||||||
Allay allay = ReflectionHelper.getEntity(npc);
|
|
||||||
|
|
||||||
boolean dancing = Boolean.parseBoolean(value);
|
|
||||||
allay.setDancing(dancing);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4.attributes;
|
|
||||||
|
|
||||||
import de.oliver.fancynpcs.api.Npc;
|
|
||||||
import de.oliver.fancynpcs.api.NpcAttribute;
|
|
||||||
import de.oliver.fancynpcs.v1_19_4.ReflectionHelper;
|
|
||||||
import net.minecraft.world.entity.decoration.ArmorStand;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ArmorStandAttributes {
|
|
||||||
|
|
||||||
public static List<NpcAttribute> getAllAttributes() {
|
|
||||||
List<NpcAttribute> attributes = new ArrayList<>();
|
|
||||||
|
|
||||||
attributes.add(new NpcAttribute(
|
|
||||||
"show_arms",
|
|
||||||
List.of("true", "false"),
|
|
||||||
List.of(EntityType.ARMOR_STAND),
|
|
||||||
ArmorStandAttributes::setShowArms
|
|
||||||
));
|
|
||||||
|
|
||||||
return attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setShowArms(Npc npc, String value) {
|
|
||||||
ArmorStand armorStand = ReflectionHelper.getEntity(npc);
|
|
||||||
|
|
||||||
boolean showArms = Boolean.parseBoolean(value.toLowerCase());
|
|
||||||
|
|
||||||
armorStand.setShowArms(showArms);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4.attributes;
|
|
||||||
|
|
||||||
import de.oliver.fancynpcs.api.NpcAttribute;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Attributes_1_19_4 {
|
|
||||||
|
|
||||||
public static List<NpcAttribute> getAllAttributes() {
|
|
||||||
List<NpcAttribute> attributes = new ArrayList<>();
|
|
||||||
|
|
||||||
attributes.addAll(EntityAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(LivingEntityAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(AgeableMobAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(IllagerAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(SpellCasterAttributes.getAllAttributes());
|
|
||||||
|
|
||||||
attributes.addAll(PlayerAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(SheepAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(VillagerAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(FrogAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(HorseAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(ParrotAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(AxolotlAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(TropicalFishAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(FoxAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(PandaAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(GoatAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(AllayAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(CamelAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(RabbitAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(PiglinAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(CatAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(ShulkerAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(WolfAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(SlimeAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(PigAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(ArmorStandAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(BeeAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(VexAttributes.getAllAttributes());
|
|
||||||
|
|
||||||
attributes.addAll(DisplayAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(TextDisplayAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(BlockDisplayAttributes.getAllAttributes());
|
|
||||||
attributes.addAll(InteractionAttributes.getAllAttributes());
|
|
||||||
|
|
||||||
return attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package de.oliver.fancynpcs.v1_19_4.attributes;
|
|
||||||
|
|
||||||
import de.oliver.fancynpcs.api.Npc;
|
|
||||||
import de.oliver.fancynpcs.api.NpcAttribute;
|
|
||||||
import de.oliver.fancynpcs.v1_19_4.ReflectionHelper;
|
|
||||||
import net.minecraft.world.entity.animal.axolotl.Axolotl;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class AxolotlAttributes {
|
|
||||||
|
|
||||||
public static List<NpcAttribute> getAllAttributes() {
|
|
||||||
List<NpcAttribute> attributes = new ArrayList<>();
|
|
||||||
|
|
||||||
attributes.add(new NpcAttribute(
|
|
||||||
"variant",
|
|
||||||
Arrays.stream(Axolotl.Variant.values())
|
|
||||||
.map(Enum::name)
|
|
||||||
.toList(),
|
|
||||||
List.of(EntityType.AXOLOTL),
|
|
||||||
AxolotlAttributes::setVariant
|
|
||||||
));
|
|
||||||
|
|
||||||
attributes.add(new NpcAttribute(
|
|
||||||
"playing_dead",
|
|
||||||
List.of("true", "false"),
|
|
||||||
List.of(EntityType.AXOLOTL),
|
|
||||||
AxolotlAttributes::setPlayingDead
|
|
||||||
));
|
|
||||||
|
|
||||||
return attributes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setVariant(Npc npc, String value) {
|
|
||||||
Axolotl axolotl = ReflectionHelper.getEntity(npc);
|
|
||||||
|
|
||||||
Axolotl.Variant variant = Axolotl.Variant.valueOf(value.toUpperCase());
|
|
||||||
axolotl.setVariant(variant);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setPlayingDead(Npc npc, String value) {
|
|
||||||
Axolotl axolotl = ReflectionHelper.getEntity(npc);
|
|
||||||
|
|
||||||
boolean playingDead = Boolean.parseBoolean(value);
|
|
||||||
axolotl.setPlayingDead(playingDead);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user