mirror of
https://github.com/xSquishyLiam/mc-GeyserModelEngine-plugin.git
synced 2025-12-20 07:19:20 +00:00
Compare commits
54 Commits
1.0.1
...
bettermode
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c90fe4809 | ||
|
|
6892ffb519 | ||
|
|
f93559c822 | ||
|
|
468757762f | ||
|
|
e7114faf84 | ||
|
|
63bf26d7a9 | ||
|
|
a4fba7715d | ||
|
|
0176d86233 | ||
|
|
79f99ffebe | ||
|
|
ae3b67a733 | ||
|
|
8e36bf2829 | ||
|
|
804d2aac04 | ||
|
|
b6425ffa51 | ||
|
|
1c47fe83d2 | ||
|
|
7bbe66928c | ||
|
|
a26ea6e148 | ||
|
|
d1ef89088c | ||
|
|
c98e807827 | ||
|
|
35131c2d58 | ||
|
|
6651ae99f7 | ||
|
|
ca9a54ae71 | ||
|
|
865f5f567c | ||
|
|
b5d9d9b9ca | ||
|
|
31dac482bd | ||
|
|
b2bfa2977e | ||
|
|
84012a23b7 | ||
|
|
3943381b2c | ||
|
|
42d7ea506f | ||
|
|
e177c8af74 | ||
|
|
2c5dba8097 | ||
|
|
2a9fdec8b6 | ||
|
|
94df76b9a6 | ||
|
|
03f27514ef | ||
|
|
4679fa6f2b | ||
|
|
db99b2fe00 | ||
|
|
ffd72b0a56 | ||
|
|
e83caacd2f | ||
|
|
170e67e059 | ||
|
|
d150d7e324 | ||
|
|
db0367537e | ||
|
|
36ea0e5fa0 | ||
|
|
13c0b45d2a | ||
|
|
8f67ade51c | ||
|
|
d0fd719753 | ||
|
|
f4c5167ef5 | ||
|
|
dc4e39506d | ||
|
|
5fdf93db1e | ||
|
|
16e0dfcdfd | ||
|
|
b1969646e6 | ||
|
|
501eaaa37a | ||
|
|
f67ee6d9f8 | ||
|
|
3adb965697 | ||
|
|
4d75f0615c | ||
|
|
97e5bdefcd |
@@ -4,14 +4,15 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- bettermodel-support-dev
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
name: Build
|
name: Build
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
# Setup JDK
|
# Setup JDK
|
||||||
- name: Setup Java JDK
|
- name: Setup Java JDK
|
||||||
@@ -20,19 +21,13 @@ jobs:
|
|||||||
java-version: 17
|
java-version: 17
|
||||||
distribution: 'zulu'
|
distribution: 'zulu'
|
||||||
|
|
||||||
- name: Restore Maven cache
|
|
||||||
uses: skjolber/maven-cache-github-action@v1
|
|
||||||
with:
|
|
||||||
step: restore
|
|
||||||
|
|
||||||
# Build
|
# Build
|
||||||
- name: Build with Maven
|
- name: Make gradlew executable
|
||||||
run: mvn package
|
run: chmod +x gradlew
|
||||||
|
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: ./gradlew build
|
||||||
|
|
||||||
- name: Save Maven cache
|
|
||||||
uses: skjolber/maven-cache-github-action@v1
|
|
||||||
with:
|
|
||||||
step: save
|
|
||||||
- name: Auto release
|
- name: Auto release
|
||||||
uses: "marvinpinto/action-automatic-releases@latest"
|
uses: "marvinpinto/action-automatic-releases@latest"
|
||||||
with:
|
with:
|
||||||
@@ -40,4 +35,4 @@ jobs:
|
|||||||
automatic_release_tag: latest
|
automatic_release_tag: latest
|
||||||
prerelease: false
|
prerelease: false
|
||||||
files: |
|
files: |
|
||||||
target/GeyserModelEngine*.jar
|
build/libs/GeyserModelEngine*.jar
|
||||||
44
.gitignore
vendored
44
.gitignore
vendored
@@ -1,2 +1,42 @@
|
|||||||
# 项目排除路径
|
.gradle
|
||||||
/target/
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +0,0 @@
|
|||||||
#Tue May 27 16:38:57 BST 2025
|
|
||||||
gradle.version=8.12
|
|
||||||
Binary file not shown.
Binary file not shown.
120
.idea/workspace.xml
generated
120
.idea/workspace.xml
generated
@@ -4,15 +4,15 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="ff2e9770-ec88-4715-adeb-b9dbda130e1a" name="Changes" comment="">
|
<list default="true" id="ff2e9770-ec88-4715-adeb-b9dbda130e1a" name="Changes" comment="" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/commands/geysermodelenginecommands/GeyserModelEngineReloadCommand.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/commands/geysermodelenginecommands/GeyserModelEngineReloadCommand.java" afterDir="false" />
|
|
||||||
</list>
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="DarkyenusTimeTracker">
|
||||||
|
<option name="totalTimeSeconds" value="1293" />
|
||||||
|
</component>
|
||||||
<component name="ExternalProjectsData">
|
<component name="ExternalProjectsData">
|
||||||
<projectState path="$PROJECT_DIR$">
|
<projectState path="$PROJECT_DIR$">
|
||||||
<ProjectState />
|
<ProjectState />
|
||||||
@@ -60,9 +60,13 @@
|
|||||||
<component name="Git.Settings">
|
<component name="Git.Settings">
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="GradleScriptDefinitionsStorage" workingDir="$PROJECT_DIR$" gradleHome="C:\Users\Livid\.gradle\wrapper\dists\gradle-8.12-bin\cetblhg4pflnnks72fxwobvgv\gradle-8.12" javaHome="C:\Users\Livid\.jdks\openjdk-21.0.1" gradleVersion="8.12" />
|
||||||
<component name="MavenRunner">
|
<component name="MavenRunner">
|
||||||
<option name="delegateBuildToMaven" value="true" />
|
<option name="delegateBuildToMaven" value="true" />
|
||||||
</component>
|
</component>
|
||||||
|
<component name="ProblemsViewState">
|
||||||
|
<option name="selectedTabId" value="DEPENDENCY_CHECKER_PROBLEMS_TAB" />
|
||||||
|
</component>
|
||||||
<component name="ProjectColorInfo">{
|
<component name="ProjectColorInfo">{
|
||||||
"associatedIndex": 8
|
"associatedIndex": 8
|
||||||
}</component>
|
}</component>
|
||||||
@@ -76,13 +80,21 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
|
"Gradle.Build GeyserModelEngine.executor": "Run",
|
||||||
|
"Gradle.Download Sources.executor": "Run",
|
||||||
|
"Gradle.GeyserModelEngine [buildDependents].executor": "Run",
|
||||||
|
"Gradle.GeyserModelEngine [buildNeeded].executor": "Run",
|
||||||
|
"Gradle.GeyserModelEngine [build].executor": "Run",
|
||||||
|
"Gradle.GeyserModelEngine [clean].executor": "Run",
|
||||||
"Gradle.GeyserModelEngine [jar].executor": "Run",
|
"Gradle.GeyserModelEngine [jar].executor": "Run",
|
||||||
"Maven.GeyserModelEngine [install...].executor": "Run",
|
"Maven.GeyserModelEngine [install...].executor": "Run",
|
||||||
"Maven.GeyserModelEngine [install].executor": "Run",
|
"Maven.GeyserModelEngine [install].executor": "Run",
|
||||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"git-widget-placeholder": "main",
|
"git-widget-placeholder": "bettermodel-support-dev",
|
||||||
|
"kotlin-language-version-configured": "true",
|
||||||
"last_opened_file_path": "D:/Coding/Forks/Minecraft/GeyserModelEngine",
|
"last_opened_file_path": "D:/Coding/Forks/Minecraft/GeyserModelEngine",
|
||||||
"project.structure.last.edited": "Project",
|
"project.structure.last.edited": "Project",
|
||||||
"project.structure.proportion": "0.0",
|
"project.structure.proportion": "0.0",
|
||||||
@@ -94,8 +106,100 @@
|
|||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine" />
|
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine" />
|
||||||
</key>
|
</key>
|
||||||
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
|
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine\.github\workflows" />
|
||||||
|
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine\libs" />
|
||||||
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager">
|
<component name="RunManager" selected="Gradle.GeyserModelEngine [build]">
|
||||||
|
<configuration name="GeyserModelEngine [buildDependents]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="buildDependents" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>false</RunAsTest>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="GeyserModelEngine [buildNeeded]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="buildNeeded" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>false</RunAsTest>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="GeyserModelEngine [build]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="build" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>false</RunAsTest>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="GeyserModelEngine [clean]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="clean" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>false</RunAsTest>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
<configuration name="GeyserModelEngine [jar]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
<configuration name="GeyserModelEngine [jar]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
<ExternalSystemSettings>
|
<ExternalSystemSettings>
|
||||||
<option name="executionName" />
|
<option name="executionName" />
|
||||||
@@ -120,7 +224,11 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
<recent_temporary>
|
<recent_temporary>
|
||||||
<list>
|
<list>
|
||||||
|
<item itemvalue="Gradle.GeyserModelEngine [build]" />
|
||||||
|
<item itemvalue="Gradle.GeyserModelEngine [clean]" />
|
||||||
<item itemvalue="Gradle.GeyserModelEngine [jar]" />
|
<item itemvalue="Gradle.GeyserModelEngine [jar]" />
|
||||||
|
<item itemvalue="Gradle.GeyserModelEngine [buildDependents]" />
|
||||||
|
<item itemvalue="Gradle.GeyserModelEngine [buildNeeded]" />
|
||||||
</list>
|
</list>
|
||||||
</recent_temporary>
|
</recent_temporary>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
19
README.md
19
README.md
@@ -20,27 +20,22 @@ Download the following plugins according to what server software you use.
|
|||||||
- Put `GeyserModelEngine` in the plugins folder (only Spigot or forks of Spigot supported)
|
- Put `GeyserModelEngine` in the plugins folder (only Spigot or forks of Spigot supported)
|
||||||
- Put either `geyserutils-spigot` in your plugins folder aswell (`geyserutils-velocity`/`geyserutils-bungeecord` in your Velocity/Bungeecord plugins folder if you use it)
|
- Put either `geyserutils-spigot` in your plugins folder aswell (`geyserutils-velocity`/`geyserutils-bungeecord` in your Velocity/Bungeecord plugins folder if you use it)
|
||||||
- Put `GeyserModelEnginePackGenerator` and `geyserutils-geyser` into `plugins/[Geyser-Folder]/extensions`
|
- Put `GeyserModelEnginePackGenerator` and `geyserutils-geyser` into `plugins/[Geyser-Folder]/extensions`
|
||||||
|
- Inside `floodgate` set `send-floodgate-data` to `true` in your Velocity/Bungeecord folder and copy over the key.pem into your backend `floodgate` folders
|
||||||
|
|
||||||
Start the server to generate the relevant configuration files, and then shut down the server to convert any models.
|
Start the server to generate the relevant configuration files, and then shut down the server to convert any models.
|
||||||
|
|
||||||
# Convert Models
|
# Convert Models
|
||||||
This is old method to convert model:
|
|
||||||
|
|
||||||
`GeyserModelEnginePackGenerator` is capable of generating models all by itself. After generating it will also apply this pack automatically.
|
`GeyserModelEnginePackGenerator` is capable of generating models all by itself. After generating it will also apply this pack automatically.
|
||||||
|
|
||||||
- First go to `plugins/[Geyser-Folder]/extensions/geysermodelenginepackgenerator/input/`
|
- Firstly, install [packer plugin](https://github.com/GeyserExtensionists/GeyserModelEngineBlockbenchPacker) for your blockbench.
|
||||||
- Create a folder in this directory with the ID of the model. (this is the same name as your model within ModelEngine 4.)
|
|
||||||
|
- Then, open your bbmodel, go `File -> Export -> Export GeyserModelEngine Model`, you will get a zip, just unzip it to `input` folder.
|
||||||
|
|
||||||
<img src="docsimg/example.jpg" width="500">
|
<img src="docsimg/example.jpg" width="500">
|
||||||
|
|
||||||
> Each model should have a separate model folder
|
> Each model should have a separate model folder
|
||||||
> Subfolders are supported if you want to categorize them
|
> Subfolders are supported if you want to categorize them
|
||||||
|
|
||||||
- Now use BlockBench and convert your model to a Bedrock Entity, this will allow you to export the Bedrock Geometry and Animations.
|
|
||||||
- Put the geometry, animations and texture file in this folder you've made.
|
|
||||||
|
|
||||||
<img src="docsimg/example1.jpg" width="500">
|
|
||||||
|
|
||||||
- Restart the server or reload geyser to start generating the resource pack.
|
- Restart the server or reload geyser to start generating the resource pack.
|
||||||
- Go to `plugins/[Geyser-Folder]/extensions/geysermodelenginepackgenerator`, and you should see your pack generated!
|
- Go to `plugins/[Geyser-Folder]/extensions/geysermodelenginepackgenerator`, and you should see your pack generated!
|
||||||
|
|
||||||
@@ -49,12 +44,6 @@ This is old method to convert model:
|
|||||||
- Final step, reload Geyser or restart the server to load the resource pack.
|
- Final step, reload Geyser or restart the server to load the resource pack.
|
||||||
- Congratulations, you've completed this tutorial!
|
- Congratulations, you've completed this tutorial!
|
||||||
|
|
||||||
# Model Packer
|
|
||||||
|
|
||||||
This is new way to convert model
|
|
||||||
- Firstly, install [packer plugin](https://github.com/GeyserExtensionists/GeyserModelEngineBlockbenchPacker) for your blockbench.
|
|
||||||
- Then, open your bbmodel, go `File -> Export -> Export GeyserModelEngine Model`, you will get a zip, just unzip it to `input` folder.
|
|
||||||
|
|
||||||
# Tips
|
# Tips
|
||||||
|
|
||||||
* Pay attention! The pack only regenerates when the number of models changes, you can technically speaking remove the generated_pack folder to force a reload aswell.
|
* Pay attention! The pack only regenerates when the number of models changes, you can technically speaking remove the generated_pack folder to force a reload aswell.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("java")
|
id("java")
|
||||||
id("io.github.goooler.shadow") version "8.1.7"
|
id("io.github.goooler.shadow") version "8.1.8"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "re.imc"
|
group = "re.imc"
|
||||||
@@ -13,24 +13,24 @@ repositories {
|
|||||||
|
|
||||||
maven("https://mvn.lumine.io/repository/maven-public/")
|
maven("https://mvn.lumine.io/repository/maven-public/")
|
||||||
|
|
||||||
maven("https://repo.opencollab.dev/maven-releases/")
|
maven("https://repo.opencollab.dev/main/")
|
||||||
maven("https://repo.opencollab.dev/maven-snapshots/")
|
|
||||||
|
|
||||||
maven("https://repo.codemc.io/repository/maven-public/")
|
maven("https://repo.codemc.io/repository/maven-public/")
|
||||||
maven("https://repo.codemc.io/repository/maven-releases/")
|
maven("https://repo.codemc.io/repository/maven-releases/")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("io.papermc.paper:paper-api:1.21.7-R0.1-SNAPSHOT")
|
compileOnly("io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
|
||||||
|
implementation("dev.jorel:commandapi-paper-shade:11.0.0")
|
||||||
|
|
||||||
implementation("dev.jorel:commandapi-bukkit-shade-mojang-mapped:10.1.1")
|
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.9")
|
||||||
|
compileOnly("io.github.toxicity188:bettermodel:1.14.0")
|
||||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.4")
|
|
||||||
|
|
||||||
compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar"))
|
compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar"))
|
||||||
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
|
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
|
||||||
|
|
||||||
implementation("com.github.retrooper:packetevents-spigot:2.9.0-SNAPSHOT")
|
implementation("com.github.retrooper:packetevents-spigot:2.10.1")
|
||||||
|
implementation("org.bstats:bstats-bukkit:3.0.2")
|
||||||
|
|
||||||
implementation("org.reflections:reflections:0.10.2")
|
implementation("org.reflections:reflections:0.10.2")
|
||||||
}
|
}
|
||||||
@@ -44,14 +44,18 @@ tasks.compileJava {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.shadowJar {
|
tasks.shadowJar {
|
||||||
|
archiveFileName.set("${rootProject.name}-${version}.jar")
|
||||||
|
|
||||||
relocate("dev.jorel.commandapi", "re.imc.geysermodelengine.libs.commandapi")
|
relocate("dev.jorel.commandapi", "re.imc.geysermodelengine.libs.commandapi")
|
||||||
|
|
||||||
relocate("com.github.retrooper", "re.imc.geysermodelengine.libs.com.github.retrooper.packetevents")
|
relocate("com.github.retrooper", "re.imc.geysermodelengine.libs.com.github.retrooper.packetevents")
|
||||||
relocate("io.github.retrooper", "re.imc.geysermodelengine.libs.io.github.retrooper.packetevents")
|
relocate("io.github.retrooper", "re.imc.geysermodelengine.libs.io.github.retrooper.packetevents")
|
||||||
|
|
||||||
|
relocate("org.bstats", "re.imc.geysermodelengine.libs.bstats")
|
||||||
|
|
||||||
relocate("org.reflections", "re.imc.geysermodelengine.libs.reflections")
|
relocate("org.reflections", "re.imc.geysermodelengine.libs.reflections")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.jar {
|
tasks.build {
|
||||||
dependsOn(tasks.shadowJar)
|
dependsOn("shadowJar")
|
||||||
}
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
commands:
|
|
||||||
reload:
|
|
||||||
successfully-reloaded: "<#55FF55>GeyserModelEngine configuration reloaded!"
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
data-send-delay: 5
|
|
||||||
entity-view-distance: 50
|
|
||||||
join-send-delay: 20
|
|
||||||
entity-position-update-period: 35
|
|
||||||
model-entity-type: BAT # must be a living entity
|
|
||||||
enable-part-visibility-models:
|
|
||||||
- example
|
|
||||||
debug: false
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
main: re.imc.geysermodelengine.GeyserModelEngine
|
|
||||||
name: GeyserModelEngine
|
|
||||||
version: '1.0.0'
|
|
||||||
api-version: '1.21'
|
|
||||||
|
|
||||||
authors:
|
|
||||||
- zimzaza4
|
|
||||||
- willem.dev
|
|
||||||
- TheLividaProject
|
|
||||||
|
|
||||||
load: STARTUP
|
|
||||||
|
|
||||||
dependencies:
|
|
||||||
server:
|
|
||||||
GeyserUtils:
|
|
||||||
required: true
|
|
||||||
packetevents:
|
|
||||||
required: true
|
|
||||||
ModelEngine:
|
|
||||||
required: true
|
|
||||||
floodgate:
|
|
||||||
required: true
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +0,0 @@
|
|||||||
Manifest-Version: 1.0
|
|
||||||
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
Manifest-Version: 1.0
|
|
||||||
|
|
||||||
@@ -2,10 +2,11 @@ package re.imc.geysermodelengine;
|
|||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
|
||||||
import dev.jorel.commandapi.CommandAPI;
|
import dev.jorel.commandapi.CommandAPI;
|
||||||
import dev.jorel.commandapi.CommandAPIBukkitConfig;
|
import dev.jorel.commandapi.CommandAPIBukkitConfig;
|
||||||
|
import dev.jorel.commandapi.CommandAPIPaperConfig;
|
||||||
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||||
|
import org.bstats.bukkit.Metrics;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import re.imc.geysermodelengine.listener.ModelListener;
|
import re.imc.geysermodelengine.listener.ModelListener;
|
||||||
@@ -14,11 +15,9 @@ import re.imc.geysermodelengine.managers.ConfigManager;
|
|||||||
import re.imc.geysermodelengine.managers.commands.CommandManager;
|
import re.imc.geysermodelengine.managers.commands.CommandManager;
|
||||||
import re.imc.geysermodelengine.managers.model.EntityTaskManager;
|
import re.imc.geysermodelengine.managers.model.EntityTaskManager;
|
||||||
import re.imc.geysermodelengine.managers.model.ModelManager;
|
import re.imc.geysermodelengine.managers.model.ModelManager;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
|
||||||
import re.imc.geysermodelengine.runnables.BedrockMountControlRunnable;
|
import re.imc.geysermodelengine.runnables.BedrockMountControlRunnable;
|
||||||
import re.imc.geysermodelengine.runnables.UpdateTaskRunnable;
|
import re.imc.geysermodelengine.runnables.UpdateTaskRunnable;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
public class GeyserModelEngine extends JavaPlugin {
|
public class GeyserModelEngine extends JavaPlugin {
|
||||||
@@ -30,12 +29,14 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
private ModelManager modelManager;
|
private ModelManager modelManager;
|
||||||
private EntityTaskManager entityTaskManager;
|
private EntityTaskManager entityTaskManager;
|
||||||
|
|
||||||
|
private ScheduledExecutorService schedulerPool;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
||||||
PacketEvents.getAPI().load();
|
PacketEvents.getAPI().load();
|
||||||
|
|
||||||
CommandAPI.onLoad(new CommandAPIBukkitConfig(this));
|
CommandAPI.onLoad(new CommandAPIPaperConfig(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -44,6 +45,8 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
loadManagers();
|
loadManagers();
|
||||||
loadRunnables();
|
loadRunnables();
|
||||||
|
|
||||||
|
loadBStats();
|
||||||
|
|
||||||
PacketEvents.getAPI().getEventManager().registerListener(new MountPacketListener(this), PacketListenerPriority.NORMAL);
|
PacketEvents.getAPI().getEventManager().registerListener(new MountPacketListener(this), PacketListenerPriority.NORMAL);
|
||||||
|
|
||||||
Bukkit.getPluginManager().registerEvents(new ModelListener(this), this);
|
Bukkit.getPluginManager().registerEvents(new ModelListener(this), this);
|
||||||
@@ -51,14 +54,9 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
this.modelManager.removeEntities();
|
||||||
|
|
||||||
PacketEvents.getAPI().terminate();
|
PacketEvents.getAPI().terminate();
|
||||||
|
|
||||||
for (Map<ActiveModel, ModelEntityData> entities : modelManager.getEntitiesCache().values()) {
|
|
||||||
entities.forEach((model, modelEntity) -> {
|
|
||||||
modelEntity.getEntity().remove();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandAPI.onDisable();
|
CommandAPI.onDisable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,6 +65,10 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
CommandAPI.onEnable();
|
CommandAPI.onEnable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void loadBStats() {
|
||||||
|
if (configManager.getConfig().getBoolean("metrics.bstats", true)) new Metrics(this, 26981);
|
||||||
|
}
|
||||||
|
|
||||||
private void loadManagers() {
|
private void loadManagers() {
|
||||||
this.configManager = new ConfigManager(this);
|
this.configManager = new ConfigManager(this);
|
||||||
|
|
||||||
@@ -77,7 +79,9 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadRunnables() {
|
private void loadRunnables() {
|
||||||
Bukkit.getAsyncScheduler().runAtFixedRate(this, new UpdateTaskRunnable(this), 10, configManager.getConfig().getLong("entity-position-update-period", 35), TimeUnit.MILLISECONDS);
|
this.schedulerPool = Executors.newScheduledThreadPool(configManager.getConfig().getInt("models.thread-pool-size", 4));
|
||||||
|
|
||||||
|
Bukkit.getAsyncScheduler().runAtFixedRate(this, new UpdateTaskRunnable(this), 10, configManager.getConfig().getLong("models.entity-position-update-period", 35), TimeUnit.MILLISECONDS);
|
||||||
Bukkit.getAsyncScheduler().runAtFixedRate(this, new BedrockMountControlRunnable(this), 1, 1, TimeUnit.MILLISECONDS);
|
Bukkit.getAsyncScheduler().runAtFixedRate(this, new BedrockMountControlRunnable(this), 1, 1, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,4 +100,8 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
public EntityTaskManager getEntityTaskManager() {
|
public EntityTaskManager getEntityTaskManager() {
|
||||||
return entityTaskManager;
|
return entityTaskManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ScheduledExecutorService getSchedulerPool() {
|
||||||
|
return schedulerPool;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package re.imc.geysermodelengine.listener;
|
||||||
|
|
||||||
|
import kr.toxicity.model.api.event.CreateEntityTrackerEvent;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.BetterModelEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
|
||||||
|
public class BetterModelListener implements Listener {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public BetterModelListener(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onModelSpawn(CreateEntityTrackerEvent event) {
|
||||||
|
plugin.getModelManager().getModelHandler().createModel(event.sourceEntity(), event.getTracker(), event.tracker());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onModelDamage(EntityDamageByEntityEvent event) {
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
|
||||||
|
Model model = plugin.getModelManager().getModelEntitiesCache().get(entity.getEntityId());
|
||||||
|
if (model == null) return;
|
||||||
|
|
||||||
|
BetterModelEntityData entityData = (BetterModelEntityData) model.getEntityData();
|
||||||
|
|
||||||
|
entityData.setHurt(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package re.imc.geysermodelengine.listener;
|
||||||
|
|
||||||
|
import com.ticxo.modelengine.api.events.*;
|
||||||
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ModelEngineListener implements Listener {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public ModelEngineListener(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onAddModel(AddModelEvent event) {
|
||||||
|
if (event.isCancelled()) return;
|
||||||
|
plugin.getModelManager().getModelHandler().createModel(event.getTarget(), event.getModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needs Testing
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onModelMount(ModelMountEvent event) {
|
||||||
|
if (!event.isDriver()) return;
|
||||||
|
|
||||||
|
ActiveModel activeModel = event.getVehicle();
|
||||||
|
if (activeModel == null) return;
|
||||||
|
|
||||||
|
int entityID = activeModel.getModeledEntity().getBase().getEntityId();
|
||||||
|
|
||||||
|
Map<Model, EntityData> entityDataCache = plugin.getModelManager().getEntitiesCache().get(entityID);
|
||||||
|
if (entityDataCache == null) return;
|
||||||
|
|
||||||
|
Model model = plugin.getModelManager().getModelEntitiesCache().get(entityID);
|
||||||
|
|
||||||
|
EntityData entityData = entityDataCache.get(model);
|
||||||
|
|
||||||
|
if (entityData != null && event.getPassenger() instanceof Player player) {
|
||||||
|
plugin.getModelManager().getDriversCache().put(player.getUniqueId(), Pair.of(event.getVehicle(), event.getSeat()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onModelDismount(ModelDismountEvent event) {
|
||||||
|
if (event.getPassenger() instanceof Player player) {
|
||||||
|
plugin.getModelManager().getDriversCache().remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,15 @@
|
|||||||
package re.imc.geysermodelengine.listener;
|
package re.imc.geysermodelengine.listener;
|
||||||
|
|
||||||
import com.ticxo.modelengine.api.events.AddModelEvent;
|
|
||||||
import com.ticxo.modelengine.api.events.ModelDismountEvent;
|
|
||||||
import com.ticxo.modelengine.api.events.ModelMountEvent;
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.event.world.WorldInitEvent;
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
import org.bukkit.event.world.WorldLoadEvent;
|
import org.geysermc.floodgate.api.FloodgateApi;
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ModelListener implements Listener {
|
public class ModelListener implements Listener {
|
||||||
|
|
||||||
@@ -28,47 +19,31 @@ public class ModelListener implements Listener {
|
|||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
/*
|
||||||
public void onAddModel(AddModelEvent event) {
|
/ xSquishyLiam:
|
||||||
if (event.isCancelled()) return;
|
/ May change this into a better system?
|
||||||
|
*/
|
||||||
plugin.getModelManager().create(event.getTarget(), event.getModel());
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onModelMount(ModelMountEvent event) {
|
|
||||||
Map<ActiveModel, ModelEntityData> map = plugin.getModelManager().getEntitiesCache().get(event.getVehicle().getModeledEntity().getBase().getEntityId());
|
|
||||||
if (!event.isDriver()) return;
|
|
||||||
|
|
||||||
ModelEntityData model = map.get(event.getVehicle());
|
|
||||||
|
|
||||||
if (model != null && event.getPassenger() instanceof Player player) {
|
|
||||||
plugin.getModelManager().getDriversCache().put(player, Pair.of(event.getVehicle(), event.getSeat()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onModelDismount(ModelDismountEvent event) {
|
|
||||||
if (event.getPassenger() instanceof Player player) {
|
|
||||||
plugin.getModelManager().getDriversCache().remove(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onWorldInit(WorldInitEvent event) {
|
public void onWorldInit(WorldInitEvent event) {
|
||||||
World world = event.getWorld();
|
World world = event.getWorld();
|
||||||
world.getEntities().forEach(entity -> plugin.getModelManager().processEntities(entity));
|
world.getEntities().forEach(entity -> plugin.getModelManager().getModelHandler().processEntities(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
/ xSquishyLiam:
|
||||||
|
/ A runDelay makes sure the client doesn't see pigs on login due to the client resyncing themselves back to normal
|
||||||
|
*/
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
plugin.getModelManager().getPlayerJoinedCache().add(player.getUniqueId());
|
if (!FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) return;
|
||||||
|
Bukkit.getGlobalRegionScheduler().runDelayed(plugin, scheduledTask -> plugin.getModelManager().getPlayerJoinedCache().add(player.getUniqueId()), 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
if (!FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) return;
|
||||||
plugin.getModelManager().getPlayerJoinedCache().remove(player.getUniqueId());
|
plugin.getModelManager().getPlayerJoinedCache().remove(player.getUniqueId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,11 +28,11 @@ public class MountPacketListener implements PacketListener {
|
|||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
WrapperPlayClientEntityAction action = new WrapperPlayClientEntityAction(event);
|
WrapperPlayClientEntityAction action = new WrapperPlayClientEntityAction(event);
|
||||||
Pair<ActiveModel, Mount> seat = plugin.getModelManager().getDriversCache().get(player);
|
Pair<ActiveModel, Mount> seat = plugin.getModelManager().getDriversCache().get(player.getUniqueId());
|
||||||
|
|
||||||
if (seat == null) return;
|
if (seat == null) return;
|
||||||
if (action.getAction() != WrapperPlayClientEntityAction.Action.START_SNEAKING) return;
|
if (action.getAction() != WrapperPlayClientEntityAction.Action.START_SNEAKING) return;
|
||||||
|
|
||||||
ModelEngineAPI.getMountPairManager().tryDismount(event.getPlayer());
|
ModelEngineAPI.getMountPairManager().tryDismount(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ public class CommandManager {
|
|||||||
for (Class<?> clazz : new Reflections(path).getSubTypesOf(CommandManagers.class)) {
|
for (Class<?> clazz : new Reflections(path).getSubTypesOf(CommandManagers.class)) {
|
||||||
try {
|
try {
|
||||||
CommandManagers commandManager = (CommandManagers) clazz.getDeclaredConstructor(GeyserModelEngine.class).newInstance(plugin);
|
CommandManagers commandManager = (CommandManagers) clazz.getDeclaredConstructor(GeyserModelEngine.class).newInstance(plugin);
|
||||||
plugin.getLogger().warning("Loading Command Manager - " + commandManager.name());
|
plugin.getLogger().info("Loading Command Manager - " + commandManager.getName());
|
||||||
commandManagersCache.put(commandManager.name(), commandManager);
|
commandManagersCache.put(commandManager.getName(), commandManager);
|
||||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException err) {
|
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException err) {
|
||||||
plugin.getLogger().severe("Failed to load Command Manager " + clazz.getName());
|
plugin.getLogger().severe("Failed to load Command Manager " + clazz.getName());
|
||||||
throw new RuntimeException(err);
|
throw new RuntimeException(err);
|
||||||
|
|||||||
@@ -6,7 +6,13 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
public interface CommandManagers {
|
public interface CommandManagers {
|
||||||
|
|
||||||
String name();
|
/**
|
||||||
|
* Gets the name of the command manager
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the command manager subcommands
|
||||||
|
*/
|
||||||
ArrayList<SubCommands> getCommands();
|
ArrayList<SubCommands> getCommands();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class GeyserModelEngineCommandManager implements CommandManagers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void registerCommand() {
|
private void registerCommand() {
|
||||||
CommandAPICommand geyserModelEngineCommand = new CommandAPICommand(name());
|
CommandAPICommand geyserModelEngineCommand = new CommandAPICommand(getName());
|
||||||
|
|
||||||
commands.forEach(subCommands -> geyserModelEngineCommand.withSubcommand(subCommands.onCommand()));
|
commands.forEach(subCommands -> geyserModelEngineCommand.withSubcommand(subCommands.onCommand()));
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ public class GeyserModelEngineCommandManager implements CommandManagers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public String getName() {
|
||||||
return "geysermodelengine";
|
return "geysermodelengine";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,9 @@ package re.imc.geysermodelengine.managers.commands.subcommands;
|
|||||||
import dev.jorel.commandapi.CommandAPICommand;
|
import dev.jorel.commandapi.CommandAPICommand;
|
||||||
|
|
||||||
public interface SubCommands {
|
public interface SubCommands {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subcommand setup
|
||||||
|
*/
|
||||||
CommandAPICommand onCommand();
|
CommandAPICommand onCommand();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,91 +1,49 @@
|
|||||||
package re.imc.geysermodelengine.managers.model;
|
package re.imc.geysermodelengine.managers.model;
|
||||||
|
|
||||||
import com.ticxo.modelengine.api.animation.BlueprintAnimation;
|
import com.ticxo.modelengine.api.animation.BlueprintAnimation;
|
||||||
import com.ticxo.modelengine.api.generator.blueprint.BlueprintBone;
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
import com.ticxo.modelengine.api.model.render.DisplayRenderer;
|
|
||||||
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.geysermc.floodgate.api.FloodgateApi;
|
import org.geysermc.floodgate.api.FloodgateApi;
|
||||||
import org.joml.Vector3fc;
|
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.BetterModelPropertyHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.ModelEnginePropertyHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.taskshandler.TaskHandler;
|
||||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
import re.imc.geysermodelengine.runnables.EntityTaskRunnable;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class EntityTaskManager {
|
public class EntityTaskManager {
|
||||||
|
|
||||||
private final GeyserModelEngine plugin;
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
private final Method scaleMethod;
|
private PropertyHandler propertyHandler;
|
||||||
|
|
||||||
public EntityTaskManager(GeyserModelEngine plugin) {
|
public EntityTaskManager(GeyserModelEngine plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
try {
|
if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) {
|
||||||
this.scaleMethod = ActiveModel.class.getMethod("getScale");
|
this.propertyHandler = new ModelEnginePropertyHandler(plugin);
|
||||||
} catch (NoSuchMethodException err) {
|
plugin.getLogger().info("Using ModelEngine property handler!");
|
||||||
throw new RuntimeException(err);
|
} else if (Bukkit.getPluginManager().getPlugin("BetterModel") != null) {
|
||||||
|
this.propertyHandler = new BetterModelPropertyHandler(plugin);
|
||||||
|
plugin.getLogger().info("Using BetterModel property handler!");
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().severe("No supported model engine found!");
|
||||||
|
plugin.getServer().getPluginManager().disablePlugin(plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String unstripName(BlueprintBone bone) {
|
public void checkViewers(EntityData model, Set<Player> viewers) {
|
||||||
String name = bone.getName();
|
|
||||||
if (bone.getBehaviors().get("head") != null) {
|
|
||||||
if (!bone.getBehaviors().get("head").isEmpty()) return "hi_" + name;
|
|
||||||
return "h_" + name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendScale(ModelEntityData model, Collection<Player> players, float lastScale, boolean firstSend) {
|
|
||||||
try {
|
|
||||||
if (players.isEmpty()) return;
|
|
||||||
|
|
||||||
Vector3fc scale = (Vector3fc) scaleMethod.invoke(model.getActiveModel());
|
|
||||||
|
|
||||||
float average = (scale.x() + scale.y() + scale.z()) / 3;
|
|
||||||
|
|
||||||
if (!firstSend) {
|
|
||||||
if (average == lastScale) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Player player : players) {
|
|
||||||
EntityUtils.sendCustomScale(player, model.getEntity().getEntityId(), average);
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendColor(ModelEntityData model, Collection<Player> players, Color lastColor, boolean firstSend) {
|
|
||||||
if (players.isEmpty()) return;
|
|
||||||
|
|
||||||
Color color = new Color(model.getActiveModel().getDefaultTint().asARGB());
|
|
||||||
if (model.getActiveModel().isMarkedHurt()) color = new Color(model.getActiveModel().getDamageTint().asARGB());
|
|
||||||
|
|
||||||
if (firstSend) {
|
|
||||||
if (color.equals(lastColor)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Player player : players) {
|
|
||||||
EntityUtils.sendCustomColor(player, model.getEntity().getEntityId(), color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkViewers(ModelEntityData model, Set<Player> viewers) {
|
|
||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||||
if (FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) {
|
if (!FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) continue;
|
||||||
|
|
||||||
if (canSee(onlinePlayer, model.getEntity())) {
|
if (canSee(onlinePlayer, model.getEntity())) {
|
||||||
|
|
||||||
if (!viewers.contains(onlinePlayer)) {
|
if (!viewers.contains(onlinePlayer)) {
|
||||||
sendSpawnPacket(model, onlinePlayer);
|
sendSpawnPacket(model, onlinePlayer);
|
||||||
viewers.add(onlinePlayer);
|
viewers.add(onlinePlayer);
|
||||||
@@ -98,14 +56,13 @@ public class EntityTaskManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void sendSpawnPacket(ModelEntityData model, Player onlinePlayer) {
|
private void sendSpawnPacket(EntityData model, Player onlinePlayer) {
|
||||||
EntityTaskRunnable task = model.getEntityTask();
|
TaskHandler task = model.getEntityTask();
|
||||||
boolean firstJoined = !plugin.getModelManager().getPlayerJoinedCache().contains(onlinePlayer.getUniqueId());
|
boolean firstJoined = !plugin.getModelManager().getPlayerJoinedCache().contains(onlinePlayer.getUniqueId());
|
||||||
|
|
||||||
if (firstJoined) {
|
if (firstJoined) {
|
||||||
task.sendEntityData(model, onlinePlayer, plugin.getConfigManager().getConfig().getInt("join-send-delay") / 50);
|
task.sendEntityData(model, onlinePlayer, plugin.getConfigManager().getConfig().getInt("models.join-send-delay") / 50);
|
||||||
} else {
|
} else {
|
||||||
task.sendEntityData(model, onlinePlayer, 5);
|
task.sendEntityData(model, onlinePlayer, 5);
|
||||||
}
|
}
|
||||||
@@ -126,31 +83,20 @@ public class EntityTaskManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendHitBoxToAll(ModelEntityData model) {
|
public void sendHitBoxToAll(EntityData model) {
|
||||||
for (Player viewer : model.getViewers()) {
|
for (Player viewer : model.getViewers()) {
|
||||||
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.01f, 0.01f);
|
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.01f, 0.01f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendHitBox(ModelEntityData model, Player viewer) {
|
//TODO move this
|
||||||
float w = 0;
|
public boolean hasAnimation(ModelEngineEntityData model, String animation) {
|
||||||
|
|
||||||
if (model.getActiveModel().isShadowVisible()) {
|
|
||||||
if (model.getActiveModel().getModelRenderer() instanceof DisplayRenderer displayRenderer) {
|
|
||||||
// w = displayRenderer.getHitbox().getShadowRadius().get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.02f, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAnimation(ModelEntityData model, String animation) {
|
|
||||||
ActiveModel activeModel = model.getActiveModel();
|
ActiveModel activeModel = model.getActiveModel();
|
||||||
BlueprintAnimation animationProperty = activeModel.getBlueprint().getAnimations().get(animation);
|
BlueprintAnimation animationProperty = activeModel.getBlueprint().getAnimations().get(animation);
|
||||||
return !(animationProperty == null);
|
return !(animationProperty == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Method getScaleMethod() {
|
public PropertyHandler getPropertyHandler() {
|
||||||
return scaleMethod;
|
return propertyHandler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
package re.imc.geysermodelengine.managers.model;
|
package re.imc.geysermodelengine.managers.model;
|
||||||
|
|
||||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
|
||||||
import com.ticxo.modelengine.api.model.bone.type.Mount;
|
import com.ticxo.modelengine.api.model.bone.type.Mount;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.BetterModelHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelEngineHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -17,55 +18,57 @@ public class ModelManager {
|
|||||||
|
|
||||||
private final GeyserModelEngine plugin;
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
private ModelHandler modelHandler;
|
||||||
|
|
||||||
private final HashSet<UUID> playerJoinedCache = new HashSet<>();
|
private final HashSet<UUID> playerJoinedCache = new HashSet<>();
|
||||||
|
|
||||||
private final ConcurrentHashMap<Integer, Map<ActiveModel, ModelEntityData>> entitiesCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Integer, Model> modelEntitiesCache = new ConcurrentHashMap<>();
|
||||||
private final ConcurrentHashMap<Integer, ModelEntityData> modelEntitiesCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Integer, Map<Model, EntityData>> entitiesCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private final ConcurrentHashMap<Player, Pair<ActiveModel, Mount>> driversCache = new ConcurrentHashMap<>();
|
// MEG ONLY
|
||||||
|
private final ConcurrentHashMap<UUID, Pair<ActiveModel, Mount>> driversCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public ModelManager(GeyserModelEngine plugin) {
|
public ModelManager(GeyserModelEngine plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
|
||||||
|
|
||||||
public void create(ModeledEntity entity, ActiveModel model) {
|
if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) {
|
||||||
ModelEntityData modelEntity = new ModelEntityData(plugin, entity, model);
|
this.modelHandler = new ModelEngineHandler(plugin);
|
||||||
int id = entity.getBase().getEntityId();
|
plugin.getLogger().info("Using ModelEngine handler!");
|
||||||
|
} else if (Bukkit.getPluginManager().getPlugin("BetterModel") != null) {
|
||||||
Map<ActiveModel, ModelEntityData> map = entitiesCache.computeIfAbsent(id, k -> new HashMap<>());
|
this.modelHandler = new BetterModelHandler(plugin);
|
||||||
|
plugin.getLogger().info("Using BetterModel handler!");
|
||||||
for (Map.Entry<ActiveModel, ModelEntityData> entry : map.entrySet()) {
|
} else {
|
||||||
if (entry.getKey() != model && entry.getKey().getBlueprint().getName().equals(model.getBlueprint().getName())) {
|
plugin.getLogger().severe("No supported model engine found!");
|
||||||
|
plugin.getServer().getPluginManager().disablePlugin(plugin);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
modelHandler.loadListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
map.put(model, modelEntity);
|
public void removeEntities() {
|
||||||
|
for (Map<Model, EntityData> entities : entitiesCache.values()) {
|
||||||
|
entities.forEach((model, modelEntity) -> modelEntity.getEntity().remove());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processEntities(Entity entity) {
|
public ModelHandler getModelHandler() {
|
||||||
if (entitiesCache.containsKey(entity.getEntityId())) return;
|
return modelHandler;
|
||||||
|
|
||||||
ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity);
|
|
||||||
if (modeledEntity == null) return;
|
|
||||||
|
|
||||||
Optional<ActiveModel> model = modeledEntity.getModels().values().stream().findFirst();
|
|
||||||
model.ifPresent(m -> create(modeledEntity, m));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashSet<UUID> getPlayerJoinedCache() {
|
public HashSet<UUID> getPlayerJoinedCache() {
|
||||||
return playerJoinedCache;
|
return playerJoinedCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConcurrentHashMap<Integer, Map<ActiveModel, ModelEntityData>> getEntitiesCache() {
|
public ConcurrentHashMap<Integer, Map<Model, EntityData>> getEntitiesCache() {
|
||||||
return entitiesCache;
|
return entitiesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConcurrentHashMap<Integer, ModelEntityData> getModelEntitiesCache() {
|
public ConcurrentHashMap<Integer, Model> getModelEntitiesCache() {
|
||||||
return modelEntitiesCache;
|
return modelEntitiesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConcurrentHashMap<Player, Pair<ActiveModel, Mount>> getDriversCache() {
|
public ConcurrentHashMap<UUID, Pair<ActiveModel, Mount>> getDriversCache() {
|
||||||
return driversCache;
|
return driversCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.entity;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import kr.toxicity.model.api.tracker.EntityTracker;
|
||||||
|
import kr.toxicity.model.api.tracker.Tracker;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.taskshandler.BetterModelTaskHandler;
|
||||||
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class BetterModelEntityData implements EntityData {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
private final PacketEntity entity;
|
||||||
|
private final Set<Player> viewers = Sets.newConcurrentHashSet();
|
||||||
|
|
||||||
|
private final Entity entitySource;
|
||||||
|
private final Tracker tracker;
|
||||||
|
private final EntityTracker entityTracker;
|
||||||
|
|
||||||
|
private BetterModelTaskHandler entityTask;
|
||||||
|
|
||||||
|
private boolean hurt;
|
||||||
|
|
||||||
|
public BetterModelEntityData(GeyserModelEngine plugin, Entity entitySource, Tracker tracker, EntityTracker entityTracker) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
this.entitySource = entitySource;
|
||||||
|
this.tracker = tracker;
|
||||||
|
this.entityTracker = entityTracker;
|
||||||
|
this.entity = new PacketEntity(EntityTypes.PIG, viewers, entitySource.getLocation());
|
||||||
|
|
||||||
|
runEntityTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void teleportToModel() {
|
||||||
|
Location location = entitySource.getLocation();
|
||||||
|
entity.teleport(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runEntityTask() {
|
||||||
|
entityTask = new BetterModelTaskHandler(plugin, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PacketEntity getEntity() {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Player> getViewers() {
|
||||||
|
return viewers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterModelTaskHandler getEntityTask() {
|
||||||
|
return entityTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHurt(boolean hurt) {
|
||||||
|
this.hurt = hurt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity getEntitySource() {
|
||||||
|
return entitySource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tracker getTracker() {
|
||||||
|
return tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityTracker getEntityTracker() {
|
||||||
|
return entityTracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHurt() {
|
||||||
|
return hurt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.entity;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.managers.model.taskshandler.TaskHandler;
|
||||||
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface EntityData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teleports the packet entity to the model
|
||||||
|
*/
|
||||||
|
void teleportToModel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the packet Entity
|
||||||
|
*/
|
||||||
|
PacketEntity getEntity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entity view of players
|
||||||
|
*/
|
||||||
|
Set<Player> getViewers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the entity task handler
|
||||||
|
*/
|
||||||
|
TaskHandler getEntityTask();
|
||||||
|
}
|
||||||
@@ -1,66 +1,64 @@
|
|||||||
package re.imc.geysermodelengine.managers.model.data;
|
package re.imc.geysermodelengine.managers.model.entity;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.taskshandler.ModelEngineTaskHandler;
|
||||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
import re.imc.geysermodelengine.runnables.EntityTaskRunnable;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class ModelEntityData {
|
public class ModelEngineEntityData implements EntityData {
|
||||||
|
|
||||||
private final GeyserModelEngine plugin;
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
private PacketEntity entity;
|
private final PacketEntity entity;
|
||||||
|
|
||||||
private final Set<Player> viewers = Sets.newConcurrentHashSet();
|
private final Set<Player> viewers = Sets.newConcurrentHashSet();
|
||||||
|
|
||||||
private final ModeledEntity modeledEntity;
|
private final ModeledEntity modeledEntity;
|
||||||
|
|
||||||
private final ActiveModel activeModel;
|
private final ActiveModel activeModel;
|
||||||
|
|
||||||
private EntityTaskRunnable entityTask;
|
private ModelEngineTaskHandler entityTask;
|
||||||
|
|
||||||
public ModelEntityData(GeyserModelEngine plugin, ModeledEntity modeledEntity, ActiveModel model) {
|
public ModelEngineEntityData(GeyserModelEngine plugin, ModeledEntity modeledEntity, ActiveModel activeModel) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
this.modeledEntity = modeledEntity;
|
this.modeledEntity = modeledEntity;
|
||||||
this.activeModel = model;
|
this.activeModel = activeModel;
|
||||||
this.entity = spawnEntity();
|
this.entity = new PacketEntity(EntityTypes.PIG, viewers, modeledEntity.getBase().getLocation());
|
||||||
|
|
||||||
runEntityTask();
|
runEntityTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void teleportToModel() {
|
public void teleportToModel() {
|
||||||
Location location = modeledEntity.getBase().getLocation();
|
Location location = modeledEntity.getBase().getLocation();
|
||||||
entity.teleport(location);
|
entity.teleport(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketEntity spawnEntity() {
|
|
||||||
entity = new PacketEntity(EntityTypes.PIG, viewers, modeledEntity.getBase().getLocation());
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runEntityTask() {
|
public void runEntityTask() {
|
||||||
entityTask = new EntityTaskRunnable(plugin, this);
|
entityTask = new ModelEngineTaskHandler(plugin, this);
|
||||||
Bukkit.getAsyncScheduler().runAtFixedRate(plugin, entityTask, 0, 20, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public PacketEntity getEntity() {
|
public PacketEntity getEntity() {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Set<Player> getViewers() {
|
public Set<Player> getViewers() {
|
||||||
return viewers;
|
return viewers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelEngineTaskHandler getEntityTask() {
|
||||||
|
return entityTask;
|
||||||
|
}
|
||||||
|
|
||||||
public ModeledEntity getModeledEntity() {
|
public ModeledEntity getModeledEntity() {
|
||||||
return modeledEntity;
|
return modeledEntity;
|
||||||
}
|
}
|
||||||
@@ -68,8 +66,4 @@ public class ModelEntityData {
|
|||||||
public ActiveModel getActiveModel() {
|
public ActiveModel getActiveModel() {
|
||||||
return activeModel;
|
return activeModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityTaskRunnable getEntityTask() {
|
|
||||||
return entityTask;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.model;
|
||||||
|
|
||||||
|
import kr.toxicity.model.api.tracker.Tracker;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
|
||||||
|
public class BetterModelModel implements Model {
|
||||||
|
|
||||||
|
private final Tracker tracker;
|
||||||
|
private final ModelHandler modelHandler;
|
||||||
|
private final EntityData entityData;
|
||||||
|
private final PropertyHandler propertyHandler;
|
||||||
|
|
||||||
|
public BetterModelModel(Tracker tracker, ModelHandler modelHandler, EntityData entityData, PropertyHandler propertyHandler) {
|
||||||
|
this.tracker = tracker;
|
||||||
|
this.modelHandler = modelHandler;
|
||||||
|
this.entityData = entityData;
|
||||||
|
this.propertyHandler = propertyHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return tracker.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelHandler getModelHandler() {
|
||||||
|
return modelHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityData getEntityData() {
|
||||||
|
return entityData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyHandler getPropertyHandler() {
|
||||||
|
return propertyHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.model;
|
||||||
|
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
|
||||||
|
public interface Model {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's name
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's entity data
|
||||||
|
*/
|
||||||
|
EntityData getEntityData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's model handler
|
||||||
|
*/
|
||||||
|
ModelHandler getModelHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's property handler
|
||||||
|
*/
|
||||||
|
PropertyHandler getPropertyHandler();
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.model;
|
||||||
|
|
||||||
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
|
||||||
|
public class ModelEngineModel implements Model {
|
||||||
|
|
||||||
|
private final ActiveModel activeModel;
|
||||||
|
private final ModelHandler modelHandler;
|
||||||
|
private final EntityData entityData;
|
||||||
|
private final PropertyHandler propertyHandler;
|
||||||
|
|
||||||
|
public ModelEngineModel(ActiveModel activeModel, ModelHandler modelHandler, EntityData entityData, PropertyHandler propertyHandler) {
|
||||||
|
this.activeModel = activeModel;
|
||||||
|
this.modelHandler = modelHandler;
|
||||||
|
this.entityData = entityData;
|
||||||
|
this.propertyHandler = propertyHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return activeModel.getBlueprint().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelHandler getModelHandler() {
|
||||||
|
return modelHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityData getEntityData() {
|
||||||
|
return entityData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyHandler getPropertyHandler() {
|
||||||
|
return propertyHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActiveModel getActiveModel() {
|
||||||
|
return activeModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.modelhandler;
|
||||||
|
|
||||||
|
import kr.toxicity.model.api.tracker.EntityTracker;
|
||||||
|
import kr.toxicity.model.api.tracker.Tracker;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.listener.BetterModelListener;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.BetterModelEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.BetterModelModel;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BetterModelHandler implements ModelHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public BetterModelHandler(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO fix dupe issue - dupe happens when server restart
|
||||||
|
@Override
|
||||||
|
public void createModel(Object... objects) {
|
||||||
|
Entity entitySource = (Entity) objects[0];
|
||||||
|
Tracker tracker = (Tracker) objects[1];
|
||||||
|
EntityTracker entityTracker = (EntityTracker) objects[2];
|
||||||
|
|
||||||
|
int entityID = entitySource.getEntityId();
|
||||||
|
|
||||||
|
PropertyHandler propertyHandler = plugin.getEntityTaskManager().getPropertyHandler();
|
||||||
|
EntityData entityData = new BetterModelEntityData(plugin, entitySource, tracker, entityTracker);
|
||||||
|
|
||||||
|
Model model = new BetterModelModel(tracker, this, entityData, propertyHandler);
|
||||||
|
|
||||||
|
Map<Model, EntityData> entityDataCache = plugin.getModelManager().getEntitiesCache().computeIfAbsent(entityID, k -> new HashMap<>());
|
||||||
|
|
||||||
|
for (Map.Entry<Model, EntityData> entry : entityDataCache.entrySet()) {
|
||||||
|
if (entry.getKey() != model && entry.getKey().getName().equals(tracker.name())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.getModelManager().getModelEntitiesCache().put(entityID, model);
|
||||||
|
entityDataCache.put(model, entityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processEntities(Entity entity) {
|
||||||
|
// if (plugin.getModelManager().getEntitiesCache().containsKey(entity.getEntityId())) return;
|
||||||
|
//
|
||||||
|
// @NotNull Optional<EntityTrackerRegistry> modeledEntity = BetterModel.registry(entity);
|
||||||
|
//
|
||||||
|
// modeledEntity.ifPresent(m -> createModel(modeledEntity.get().entity(), m.));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadListeners() {
|
||||||
|
Bukkit.getPluginManager().registerEvents(new BetterModelListener(plugin), plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.modelhandler;
|
||||||
|
|
||||||
|
import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||||
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
|
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.listener.ModelEngineListener;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.ModelEngineModel;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class ModelEngineHandler implements ModelHandler {
|
||||||
|
|
||||||
|
//TODO move driver hashmap here
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public ModelEngineHandler(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createModel(Object... objects) {
|
||||||
|
ModeledEntity megEntity = (ModeledEntity) objects[0];
|
||||||
|
ActiveModel megActiveModel = (ActiveModel) objects[1];
|
||||||
|
|
||||||
|
int entityID = megEntity.getBase().getEntityId();
|
||||||
|
|
||||||
|
PropertyHandler propertyHandler = plugin.getEntityTaskManager().getPropertyHandler();
|
||||||
|
EntityData entityData = new ModelEngineEntityData(plugin, megEntity, megActiveModel);
|
||||||
|
|
||||||
|
Model model = new ModelEngineModel(megActiveModel, this, entityData, propertyHandler);
|
||||||
|
|
||||||
|
Map<Model, EntityData> entityDataCache = plugin.getModelManager().getEntitiesCache().computeIfAbsent(entityID, k -> new HashMap<>());
|
||||||
|
|
||||||
|
for (Map.Entry<Model, EntityData> entry : entityDataCache.entrySet()) {
|
||||||
|
if (entry.getKey() != model && entry.getKey().getName().equals(megActiveModel.getBlueprint().getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.getModelManager().getModelEntitiesCache().put(entityID, model);
|
||||||
|
entityDataCache.put(model, entityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processEntities(Entity entity) {
|
||||||
|
if (plugin.getModelManager().getEntitiesCache().containsKey(entity.getEntityId())) return;
|
||||||
|
|
||||||
|
ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity);
|
||||||
|
if (modeledEntity == null) return;
|
||||||
|
|
||||||
|
Optional<ActiveModel> model = modeledEntity.getModels().values().stream().findFirst();
|
||||||
|
model.ifPresent(m -> createModel(modeledEntity, m));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadListeners() {
|
||||||
|
Bukkit.getPluginManager().registerEvents(new ModelEngineListener(plugin), plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.modelhandler;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
public interface ModelHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the model from the required Model Engine
|
||||||
|
* @param objects Processes the required objects
|
||||||
|
*/
|
||||||
|
void createModel(Object... objects);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes entities into createModel()
|
||||||
|
* @param entity Registers bukkit entities
|
||||||
|
*/
|
||||||
|
void processEntities(Entity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the required listeners
|
||||||
|
*/
|
||||||
|
void loadListeners();
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.propertyhandler;
|
||||||
|
|
||||||
|
import kr.toxicity.model.api.animation.AnimationIterator;
|
||||||
|
import kr.toxicity.model.api.bone.RenderedBone;
|
||||||
|
import kr.toxicity.model.api.data.blueprint.BlueprintAnimation;
|
||||||
|
import kr.toxicity.model.api.data.renderer.RenderPipeline;
|
||||||
|
import kr.toxicity.model.api.nms.ModelDisplay;
|
||||||
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.BetterModelEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.util.BooleanPacker;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BetterModelPropertyHandler implements PropertyHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public BetterModelPropertyHandler(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out on how to get the scale from BetterModel
|
||||||
|
@Override
|
||||||
|
public void sendScale(EntityData entityData, Collection<Player> players, float lastScale, boolean firstSend) {
|
||||||
|
BetterModelEntityData betterModelEntityData = (BetterModelEntityData) entityData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendColor(EntityData entityData, Collection<Player> players, Color lastColor, boolean firstSend) {
|
||||||
|
if (players.isEmpty()) return;
|
||||||
|
|
||||||
|
BetterModelEntityData betterModelEntityData = (BetterModelEntityData) entityData;
|
||||||
|
|
||||||
|
Color color = new Color(0xFFFFFF);
|
||||||
|
if (betterModelEntityData.isHurt()) color = new Color(betterModelEntityData.getEntityTracker().damageTintValue());
|
||||||
|
|
||||||
|
if (firstSend) {
|
||||||
|
if (color.equals(lastColor)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendCustomColor(player, betterModelEntityData.getEntity().getEntityId(), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
betterModelEntityData.setHurt(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendHitBox(EntityData entityData, Player player) {
|
||||||
|
BetterModelEntityData betterModelEntityData = (BetterModelEntityData) entityData;
|
||||||
|
|
||||||
|
float w = 0;
|
||||||
|
|
||||||
|
EntityUtils.sendCustomHitBox(player, betterModelEntityData.getEntity().getEntityId(), 0.02f, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateEntityProperties(EntityData entityData, Collection<Player> players, boolean firstSend, String... forceAnims) {
|
||||||
|
BetterModelEntityData model = (BetterModelEntityData) entityData;
|
||||||
|
|
||||||
|
int entity = model.getEntity().getEntityId();
|
||||||
|
Set<String> forceAnimSet = Set.of(forceAnims);
|
||||||
|
|
||||||
|
Map<String, Boolean> boneUpdates = new HashMap<>();
|
||||||
|
Map<String, Boolean> animUpdates = new HashMap<>();
|
||||||
|
Set<String> anims = new HashSet<>();
|
||||||
|
|
||||||
|
model.getTracker().bones().forEach(bone -> processBone(model, bone, boneUpdates));
|
||||||
|
|
||||||
|
RenderPipeline handler = model.getTracker().getPipeline();
|
||||||
|
|
||||||
|
for (RenderedBone renderedBone : handler.bones()) {
|
||||||
|
if (model.getTracker().bone(renderedBone.name()).runningAnimation() != null) {
|
||||||
|
BlueprintAnimation anim = model.getTracker().renderer().animations().get(renderedBone.runningAnimation().name());
|
||||||
|
|
||||||
|
anims.add(renderedBone.runningAnimation().name());
|
||||||
|
if (anim.override() && anim.loop() == AnimationIterator.Type.PLAY_ONCE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String id : handler.getParent().animations().keySet()) {
|
||||||
|
if (anims.contains(id)) {
|
||||||
|
animUpdates.put(id, true);
|
||||||
|
} else {
|
||||||
|
animUpdates.put(id, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> lastPlayed = new HashSet<>(model.getEntityTask().getLastPlayedAnim().asMap().keySet());
|
||||||
|
|
||||||
|
for (Map.Entry<String, Boolean> anim : animUpdates.entrySet()) {
|
||||||
|
if (anim.getValue()) {
|
||||||
|
model.getEntityTask().getLastPlayedAnim().put(anim.getKey(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String anim : lastPlayed) animUpdates.put(anim, true);
|
||||||
|
|
||||||
|
if (boneUpdates.isEmpty() && animUpdates.isEmpty()) return;
|
||||||
|
|
||||||
|
Map<String, Integer> intUpdates = new HashMap<>();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (Integer integer : BooleanPacker.mapBooleansToInts(boneUpdates)) {
|
||||||
|
intUpdates.put(plugin.getConfigManager().getConfig().getString("models.namespace") + ":bone" + i, integer);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (Integer integer : BooleanPacker.mapBooleansToInts(animUpdates)) {
|
||||||
|
intUpdates.put(plugin.getConfigManager().getConfig().getString("models.namespace") + ":anim" + i, integer);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!firstSend) {
|
||||||
|
if (intUpdates.equals(model.getEntityTask().getLastIntSet())) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
model.getEntityTask().getLastIntSet().clear();
|
||||||
|
model.getEntityTask().getLastIntSet().putAll(intUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.getConfigManager().getConfig().getBoolean("options.debug")) plugin.getLogger().info(animUpdates.toString());
|
||||||
|
|
||||||
|
List<String> list = new ArrayList<>(boneUpdates.keySet());
|
||||||
|
Collections.sort(list);
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendIntProperties(player, entity, intUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String unstripName(RenderedBone bone) {
|
||||||
|
@NotNull String name = bone.name().rawName();
|
||||||
|
|
||||||
|
if (name.equals("head")) {
|
||||||
|
if (!bone.getChildren().isEmpty()) return "hi_" + name;
|
||||||
|
return "h_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processBone(BetterModelEntityData entityData, RenderedBone bone, Map<String, Boolean> map) {
|
||||||
|
String name = unstripName(bone).toLowerCase();
|
||||||
|
if (name.equals("hitbox") || name.equals("shadow") || name.equals("mount") || name.startsWith("p_") || name.startsWith("b_") || name.startsWith("ob_")) return;
|
||||||
|
|
||||||
|
for (RenderedBone renderedBone : bone.getChildren().values()) {
|
||||||
|
processBone(entityData, renderedBone, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderedBone activeBone = entityData.getTracker().bone(bone.name());
|
||||||
|
|
||||||
|
ModelDisplay modelDisplay = activeBone.getDisplay();
|
||||||
|
if (modelDisplay == null) return;
|
||||||
|
boolean visible = activeBone.getDisplay().invisible();
|
||||||
|
|
||||||
|
map.put(name, visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.propertyhandler;
|
||||||
|
|
||||||
|
import com.ticxo.modelengine.api.animation.BlueprintAnimation;
|
||||||
|
import com.ticxo.modelengine.api.animation.handler.AnimationHandler;
|
||||||
|
import com.ticxo.modelengine.api.generator.blueprint.BlueprintBone;
|
||||||
|
import com.ticxo.modelengine.api.model.bone.ModelBone;
|
||||||
|
import com.ticxo.modelengine.api.model.render.DisplayRenderer;
|
||||||
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.joml.Vector3fc;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
|
||||||
|
import re.imc.geysermodelengine.util.BooleanPacker;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ModelEnginePropertyHandler implements PropertyHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public ModelEnginePropertyHandler(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendScale(EntityData modelData, Collection<Player> players, float lastScale, boolean firstSend) {
|
||||||
|
try {
|
||||||
|
if (players.isEmpty()) return;
|
||||||
|
|
||||||
|
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) modelData;
|
||||||
|
|
||||||
|
Vector3fc scale = modelEngineEntityData.getActiveModel().getScale();
|
||||||
|
|
||||||
|
float average = (scale.x() + scale.y() + scale.z()) / 3;
|
||||||
|
|
||||||
|
if (!firstSend) {
|
||||||
|
if (average == lastScale) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendCustomScale(player, modelEngineEntityData.getEntity().getEntityId(), average);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendColor(EntityData entityData, Collection<Player> players, Color lastColor, boolean firstSend) {
|
||||||
|
if (players.isEmpty()) return;
|
||||||
|
|
||||||
|
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) entityData;
|
||||||
|
|
||||||
|
Color color = new Color(modelEngineEntityData.getActiveModel().getDefaultTint().asARGB());
|
||||||
|
if (modelEngineEntityData.getActiveModel().isMarkedHurt()) color = new Color(modelEngineEntityData.getActiveModel().getDamageTint().asARGB());
|
||||||
|
|
||||||
|
if (firstSend) {
|
||||||
|
if (color.equals(lastColor)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendCustomColor(player, modelEngineEntityData.getEntity().getEntityId(), color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendHitBox(EntityData entityData, Player player) {
|
||||||
|
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) entityData;
|
||||||
|
|
||||||
|
float w = 0;
|
||||||
|
|
||||||
|
if (modelEngineEntityData.getActiveModel().isShadowVisible()) {
|
||||||
|
if (modelEngineEntityData.getActiveModel().getModelRenderer() instanceof DisplayRenderer displayRenderer) {
|
||||||
|
// w = displayRenderer.getHitbox().getShadowRadius().get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityUtils.sendCustomHitBox(player, modelEngineEntityData.getEntity().getEntityId(), 0.02f, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateEntityProperties(EntityData entityData, Collection<Player> players, boolean firstSend, String... forceAnims) {
|
||||||
|
ModelEngineEntityData model = (ModelEngineEntityData) entityData;
|
||||||
|
|
||||||
|
int entity = model.getEntity().getEntityId();
|
||||||
|
Set<String> forceAnimSet = Set.of(forceAnims);
|
||||||
|
|
||||||
|
Map<String, Boolean> boneUpdates = new HashMap<>();
|
||||||
|
Map<String, Boolean> animUpdates = new HashMap<>();
|
||||||
|
Set<String> anims = new HashSet<>();
|
||||||
|
|
||||||
|
model.getActiveModel().getBlueprint().getBones().forEach((s, bone) -> processBone(model, bone, boneUpdates));
|
||||||
|
|
||||||
|
AnimationHandler handler = model.getActiveModel().getAnimationHandler();
|
||||||
|
Set<String> priority = model.getActiveModel().getBlueprint().getAnimationDescendingPriority();
|
||||||
|
for (String animId : priority) {
|
||||||
|
if (handler.isPlayingAnimation(animId)) {
|
||||||
|
BlueprintAnimation anim = model.getActiveModel().getBlueprint().getAnimations().get(animId);
|
||||||
|
|
||||||
|
anims.add(animId);
|
||||||
|
if (anim.isOverride() && anim.getLoopMode() == BlueprintAnimation.LoopMode.ONCE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String id : priority) {
|
||||||
|
if (anims.contains(id)) {
|
||||||
|
animUpdates.put(id, true);
|
||||||
|
} else {
|
||||||
|
animUpdates.put(id, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> lastPlayed = new HashSet<>(model.getEntityTask().getLastPlayedAnim().asMap().keySet());
|
||||||
|
|
||||||
|
for (Map.Entry<String, Boolean> anim : animUpdates.entrySet()) {
|
||||||
|
if (anim.getValue()) {
|
||||||
|
model.getEntityTask().getLastPlayedAnim().put(anim.getKey(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String anim : lastPlayed) animUpdates.put(anim, true);
|
||||||
|
|
||||||
|
if (boneUpdates.isEmpty() && animUpdates.isEmpty()) return;
|
||||||
|
|
||||||
|
Map<String, Integer> intUpdates = new HashMap<>();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (Integer integer : BooleanPacker.mapBooleansToInts(boneUpdates)) {
|
||||||
|
intUpdates.put(plugin.getConfigManager().getConfig().getString("models.namespace") + ":bone" + i, integer);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (Integer integer : BooleanPacker.mapBooleansToInts(animUpdates)) {
|
||||||
|
intUpdates.put(plugin.getConfigManager().getConfig().getString("models.namespace") + ":anim" + i, integer);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!firstSend) {
|
||||||
|
if (intUpdates.equals(model.getEntityTask().getLastIntSet())) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
model.getEntityTask().getLastIntSet().clear();
|
||||||
|
model.getEntityTask().getLastIntSet().putAll(intUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.getConfigManager().getConfig().getBoolean("options.debug")) plugin.getLogger().info(animUpdates.toString());
|
||||||
|
|
||||||
|
List<String> list = new ArrayList<>(boneUpdates.keySet());
|
||||||
|
Collections.sort(list);
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendIntProperties(player, entity, intUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String unstripName(BlueprintBone bone) {
|
||||||
|
String name = bone.getName();
|
||||||
|
if (bone.getBehaviors().get("head") != null) {
|
||||||
|
if (!bone.getBehaviors().get("head").isEmpty()) return "hi_" + name;
|
||||||
|
return "h_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processBone(ModelEngineEntityData model, BlueprintBone bone, Map<String, Boolean> map) {
|
||||||
|
String name = unstripName(bone).toLowerCase();
|
||||||
|
if (name.equals("hitbox") || name.equals("shadow") || name.equals("mount") || name.startsWith("p_") || name.startsWith("b_") || name.startsWith("ob_")) return;
|
||||||
|
|
||||||
|
for (BlueprintBone blueprintBone : bone.getChildren().values()) {
|
||||||
|
processBone(model, blueprintBone, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelBone activeBone = model.getActiveModel().getBones().get(bone.getName());
|
||||||
|
|
||||||
|
boolean visible = false;
|
||||||
|
if (activeBone != null) visible = activeBone.isVisible();
|
||||||
|
|
||||||
|
map.put(name, visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.propertyhandler;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface PropertyHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends scale of the entity to the player
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param players Collection of players from the entity view
|
||||||
|
* @param lastScale Sends the last scale to the player
|
||||||
|
* @param firstSend Checks if it's the first time to send scale to the player
|
||||||
|
*/
|
||||||
|
void sendScale(EntityData entityData, Collection<Player> players, float lastScale, boolean firstSend);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a colour tint to the player
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param players Collection of players from the entity view
|
||||||
|
* @param lastColor Sends the last colour to the player
|
||||||
|
* @param firstSend Checks if it's the first time to send colour to the player
|
||||||
|
*/
|
||||||
|
void sendColor(EntityData entityData, Collection<Player> players, Color lastColor, boolean firstSend);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a hitbox to the player
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param player Sends the player the entity hitbox
|
||||||
|
*/
|
||||||
|
void sendHitBox(EntityData entityData, Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the entity to all viewable players
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param players Collection of players from the entity view
|
||||||
|
* @param firstSend Checks if it's the first time to send the entity to the player
|
||||||
|
* @param forceAnims Forces the entity to do an animation
|
||||||
|
*/
|
||||||
|
void updateEntityProperties(EntityData entityData, Collection<Player> players, boolean firstSend, String... forceAnims);
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.taskshandler;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import kr.toxicity.model.api.tracker.Tracker;
|
||||||
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.BetterModelEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class BetterModelTaskHandler implements TaskHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
private final BetterModelEntityData entityData;
|
||||||
|
|
||||||
|
private int tick = 0;
|
||||||
|
private int syncTick = 0;
|
||||||
|
|
||||||
|
private float lastScale = -1.0f;
|
||||||
|
private Color lastColor = null;
|
||||||
|
|
||||||
|
private boolean removed = false;
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, Integer> lastIntSet = new ConcurrentHashMap<>();
|
||||||
|
private final Cache<String, Boolean> lastPlayedAnim = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MILLISECONDS).build();
|
||||||
|
|
||||||
|
private ScheduledFuture scheduledFuture;
|
||||||
|
|
||||||
|
public BetterModelTaskHandler(GeyserModelEngine plugin, BetterModelEntityData entityData) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.entityData = entityData;
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().sendHitBoxToAll(entityData);
|
||||||
|
scheduledFuture = plugin.getSchedulerPool().scheduleAtFixedRate(this::runAsync, 0, 20, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runAsync() {
|
||||||
|
plugin.getEntityTaskManager().checkViewers(entityData, entityData.getViewers());
|
||||||
|
|
||||||
|
PacketEntity entity = entityData.getEntity();
|
||||||
|
if (entity.isDead()) return;
|
||||||
|
|
||||||
|
Set<Player> viewers = entityData.getViewers();
|
||||||
|
Entity entitySource = entityData.getEntitySource();
|
||||||
|
Tracker tracker = entityData.getTracker();
|
||||||
|
|
||||||
|
entityData.teleportToModel();
|
||||||
|
|
||||||
|
if (entitySource.isDead() || tracker.forRemoval()) {
|
||||||
|
removed = true;
|
||||||
|
entity.remove();
|
||||||
|
|
||||||
|
plugin.getModelManager().getEntitiesCache().remove(entitySource.getEntityId());
|
||||||
|
plugin.getModelManager().getModelEntitiesCache().remove(entitySource.getEntityId());
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tick % 5 == 0) {
|
||||||
|
if (tick % 40 == 0) {
|
||||||
|
for (Player viewer : Set.copyOf(viewers)) {
|
||||||
|
if (!plugin.getEntityTaskManager().canSee(viewer, entityData.getEntity())) {
|
||||||
|
viewers.remove(viewer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tick++;
|
||||||
|
if (tick > 400) {
|
||||||
|
tick = 0;
|
||||||
|
plugin.getEntityTaskManager().sendHitBoxToAll(entityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewers.isEmpty()) return;
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendScale(entityData, viewers, lastScale, false);
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendColor(entityData, viewers, lastColor, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEntityData(EntityData entityData, Player player, int delay) {
|
||||||
|
BetterModelEntityData betterModelEntityData = (BetterModelEntityData) entityData;
|
||||||
|
|
||||||
|
EntityUtils.setCustomEntity(player, betterModelEntityData.getEntity().getEntityId(), plugin.getConfigManager().getConfig().getString("models.namespace") + ":" + betterModelEntityData.getTracker().name().toLowerCase());
|
||||||
|
|
||||||
|
plugin.getSchedulerPool().schedule(() -> {
|
||||||
|
entityData.getEntity().sendSpawnPacket(Collections.singletonList(player));
|
||||||
|
|
||||||
|
plugin.getSchedulerPool().schedule(() -> {
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendHitBox(entityData, player);
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendScale(entityData, Collections.singleton(player), lastScale, true);
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendColor(entityData, Collections.singleton(player), lastColor, true);
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().updateEntityProperties(entityData, Collections.singleton(player), true);
|
||||||
|
}, 500, TimeUnit.MILLISECONDS);
|
||||||
|
}, delay * 50L, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
scheduledFuture.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTick(int tick) {
|
||||||
|
this.tick = tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSyncTick(int syncTick) {
|
||||||
|
this.syncTick = syncTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoved(boolean removed) {
|
||||||
|
this.removed = removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastScale(float lastScale) {
|
||||||
|
this.lastScale = lastScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTick() {
|
||||||
|
return tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSyncTick() {
|
||||||
|
return syncTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastColor(Color lastColor) {
|
||||||
|
this.lastColor = lastColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getLastScale() {
|
||||||
|
return lastScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getLastColor() {
|
||||||
|
return lastColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrentHashMap<String, Integer> getLastIntSet() {
|
||||||
|
return lastIntSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cache<String, Boolean> getLastPlayedAnim() {
|
||||||
|
return lastPlayedAnim;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduledFuture getScheduledFuture() {
|
||||||
|
return scheduledFuture;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.taskshandler;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
|
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||||
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
|
||||||
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class ModelEngineTaskHandler implements TaskHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
private final ModelEngineEntityData entityData;
|
||||||
|
|
||||||
|
private int tick = 0;
|
||||||
|
private int syncTick = 0;
|
||||||
|
|
||||||
|
private float lastScale = -1.0f;
|
||||||
|
private Color lastColor = null;
|
||||||
|
|
||||||
|
private boolean removed = false;
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, Integer> lastIntSet = new ConcurrentHashMap<>();
|
||||||
|
private final Cache<String, Boolean> lastPlayedAnim = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MILLISECONDS).build();
|
||||||
|
|
||||||
|
private ScheduledFuture scheduledFuture;
|
||||||
|
|
||||||
|
public ModelEngineTaskHandler(GeyserModelEngine plugin, ModelEngineEntityData entityData) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.entityData = entityData;
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().sendHitBoxToAll(entityData);
|
||||||
|
scheduledFuture = plugin.getSchedulerPool().scheduleAtFixedRate(this::runAsync, 0, 20, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runAsync() {
|
||||||
|
plugin.getEntityTaskManager().checkViewers(entityData, entityData.getViewers());
|
||||||
|
|
||||||
|
PacketEntity entity = entityData.getEntity();
|
||||||
|
if (entity.isDead()) return;
|
||||||
|
|
||||||
|
entityData.teleportToModel();
|
||||||
|
|
||||||
|
Set<Player> viewers = entityData.getViewers();
|
||||||
|
ActiveModel activeModel = entityData.getActiveModel();
|
||||||
|
ModeledEntity modeledEntity = entityData.getModeledEntity();
|
||||||
|
|
||||||
|
if (activeModel.isDestroyed() || activeModel.isRemoved()) {
|
||||||
|
removed = true;
|
||||||
|
entity.remove();
|
||||||
|
|
||||||
|
plugin.getModelManager().getEntitiesCache().remove(modeledEntity.getBase().getEntityId());
|
||||||
|
plugin.getModelManager().getModelEntitiesCache().remove(modeledEntity.getBase().getEntityId());
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tick % 5 == 0) {
|
||||||
|
if (tick % 40 == 0) {
|
||||||
|
for (Player viewer : Set.copyOf(viewers)) {
|
||||||
|
if (!plugin.getEntityTaskManager().canSee(viewer, entityData.getEntity())) {
|
||||||
|
viewers.remove(viewer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tick ++;
|
||||||
|
if (tick > 400) {
|
||||||
|
tick = 0;
|
||||||
|
plugin.getEntityTaskManager().sendHitBoxToAll(entityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewers.isEmpty()) return;
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendScale(entityData, viewers, lastScale, false);
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendColor(entityData, viewers, lastColor, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEntityData(EntityData entityData, Player player, int delay) {
|
||||||
|
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) entityData;
|
||||||
|
|
||||||
|
EntityUtils.setCustomEntity(player, modelEngineEntityData.getEntity().getEntityId(), plugin.getConfigManager().getConfig().getString("models.namespace") + ":" + modelEngineEntityData.getActiveModel().getBlueprint().getName().toLowerCase());
|
||||||
|
|
||||||
|
plugin.getSchedulerPool().schedule(() -> {
|
||||||
|
entityData.getEntity().sendSpawnPacket(Collections.singletonList(player));
|
||||||
|
|
||||||
|
plugin.getSchedulerPool().schedule(() -> {
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendHitBox(entityData, player);
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendScale(entityData, Collections.singleton(player), lastScale, true);
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendColor(entityData, Collections.singleton(player), lastColor, true);
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().updateEntityProperties(entityData, Collections.singleton(player), true);
|
||||||
|
}, 500, TimeUnit.MILLISECONDS);
|
||||||
|
}, delay * 50L, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
scheduledFuture.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTick(int tick) {
|
||||||
|
this.tick = tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSyncTick(int syncTick) {
|
||||||
|
this.syncTick = syncTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoved(boolean removed) {
|
||||||
|
this.removed = removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastScale(float lastScale) {
|
||||||
|
this.lastScale = lastScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTick() {
|
||||||
|
return tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSyncTick() {
|
||||||
|
return syncTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastColor(Color lastColor) {
|
||||||
|
this.lastColor = lastColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getLastScale() {
|
||||||
|
return lastScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getLastColor() {
|
||||||
|
return lastColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrentHashMap<String, Integer> getLastIntSet() {
|
||||||
|
return lastIntSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cache<String, Boolean> getLastPlayedAnim() {
|
||||||
|
return lastPlayedAnim;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduledFuture getScheduledFuture() {
|
||||||
|
return scheduledFuture;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.taskshandler;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
|
||||||
|
public interface TaskHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the entity scheduler
|
||||||
|
*/
|
||||||
|
void runAsync();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns the entity to the player
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param player Sends the entity to the player
|
||||||
|
* @param delay Delays sending the entity to the player
|
||||||
|
*/
|
||||||
|
void sendEntityData(EntityData entityData, Player player, int delay);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the entity scheduler
|
||||||
|
*/
|
||||||
|
void cancel();
|
||||||
|
}
|
||||||
@@ -58,7 +58,6 @@ public class PacketEntity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
removed = true;
|
removed = true;
|
||||||
sendEntityDestroyPacket(viewers);
|
sendEntityDestroyPacket(viewers);
|
||||||
@@ -78,7 +77,6 @@ public class PacketEntity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void sendLocationPacket(Collection<Player> players) {
|
public void sendLocationPacket(Collection<Player> players) {
|
||||||
|
|
||||||
PacketWrapper<?> packet;
|
PacketWrapper<?> packet;
|
||||||
EntityPositionData data = new EntityPositionData(SpigotConversionUtil.fromBukkitLocation(location).getPosition(), Vector3d.zero(), location.getYaw(), location.getPitch());
|
EntityPositionData data = new EntityPositionData(SpigotConversionUtil.fromBukkitLocation(location).getPosition(), Vector3d.zero(), location.getYaw(), location.getPitch());
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
|||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.geysermc.floodgate.api.FloodgateApi;
|
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class BedrockMountControlRunnable implements Consumer<ScheduledTask> {
|
public class BedrockMountControlRunnable implements Consumer<ScheduledTask> {
|
||||||
@@ -24,11 +24,11 @@ public class BedrockMountControlRunnable implements Consumer<ScheduledTask> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ScheduledTask scheduledTask) {
|
public void accept(ScheduledTask scheduledTask) {
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (UUID playerUUID : plugin.getModelManager().getPlayerJoinedCache()) {
|
||||||
if (!FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) continue;
|
Player player = Bukkit.getPlayer(playerUUID);
|
||||||
|
|
||||||
float pitch = player.getLocation().getPitch();
|
float pitch = player.getLocation().getPitch();
|
||||||
Pair<ActiveModel, Mount> seat = plugin.getModelManager().getDriversCache().get(player);
|
Pair<ActiveModel, Mount> seat = plugin.getModelManager().getDriversCache().get(player.getUniqueId());
|
||||||
|
|
||||||
if (seat == null) continue;
|
if (seat == null) continue;
|
||||||
|
|
||||||
|
|||||||
@@ -1,258 +0,0 @@
|
|||||||
package re.imc.geysermodelengine.runnables;
|
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.ticxo.modelengine.api.animation.BlueprintAnimation;
|
|
||||||
import com.ticxo.modelengine.api.animation.handler.AnimationHandler;
|
|
||||||
import com.ticxo.modelengine.api.generator.blueprint.BlueprintBone;
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
|
||||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
|
||||||
import com.ticxo.modelengine.api.model.bone.ModelBone;
|
|
||||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
|
||||||
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
|
||||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
|
||||||
import re.imc.geysermodelengine.util.BooleanPacker;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class EntityTaskRunnable implements Consumer<ScheduledTask> {
|
|
||||||
|
|
||||||
private final GeyserModelEngine plugin;
|
|
||||||
|
|
||||||
private final ModelEntityData model;
|
|
||||||
|
|
||||||
private int tick = 0;
|
|
||||||
private int syncTick = 0;
|
|
||||||
|
|
||||||
private float lastScale = -1.0f;
|
|
||||||
private Color lastColor = null;
|
|
||||||
|
|
||||||
private boolean removed = false;
|
|
||||||
|
|
||||||
private final ConcurrentHashMap<String, Integer> lastIntSet = new ConcurrentHashMap<>();
|
|
||||||
private final Cache<String, Boolean> lastPlayedAnim = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MILLISECONDS).build();
|
|
||||||
|
|
||||||
private final BooleanPacker booleanPacker = new BooleanPacker();
|
|
||||||
|
|
||||||
public EntityTaskRunnable(GeyserModelEngine plugin, ModelEntityData model) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
|
|
||||||
this.model = model;
|
|
||||||
|
|
||||||
plugin.getEntityTaskManager().sendHitBoxToAll(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(ScheduledTask scheduledTask) {
|
|
||||||
plugin.getEntityTaskManager().checkViewers(model, model.getViewers());
|
|
||||||
|
|
||||||
PacketEntity entity = model.getEntity();
|
|
||||||
if (entity.isDead()) return;
|
|
||||||
|
|
||||||
model.teleportToModel();
|
|
||||||
|
|
||||||
Set<Player> viewers = model.getViewers();
|
|
||||||
ActiveModel activeModel = model.getActiveModel();
|
|
||||||
ModeledEntity modeledEntity = model.getModeledEntity();
|
|
||||||
|
|
||||||
if (activeModel.isDestroyed() || activeModel.isRemoved()) {
|
|
||||||
removed = true;
|
|
||||||
entity.remove();
|
|
||||||
|
|
||||||
plugin.getModelManager().getEntitiesCache().remove(modeledEntity.getBase().getEntityId());
|
|
||||||
plugin.getModelManager().getModelEntitiesCache().remove(entity.getEntityId());
|
|
||||||
scheduledTask.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tick % 5 == 0) {
|
|
||||||
if (tick % 40 == 0) {
|
|
||||||
for (Player viewer : Set.copyOf(viewers)) {
|
|
||||||
if (!plugin.getEntityTaskManager().canSee(viewer, model.getEntity())) {
|
|
||||||
viewers.remove(viewer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tick ++;
|
|
||||||
if (tick > 400) {
|
|
||||||
tick = 0;
|
|
||||||
plugin.getEntityTaskManager().sendHitBoxToAll(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (viewers.isEmpty()) return;
|
|
||||||
|
|
||||||
plugin.getEntityTaskManager().sendScale(model, viewers, lastScale, false);
|
|
||||||
plugin.getEntityTaskManager().sendColor(model, viewers, lastColor, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendEntityData(ModelEntityData model, Player player, int delay) {
|
|
||||||
EntityUtils.setCustomEntity(player, model.getEntity().getEntityId(), "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase());
|
|
||||||
|
|
||||||
Bukkit.getAsyncScheduler().runDelayed(plugin, scheduledTask -> {
|
|
||||||
model.getEntity().sendSpawnPacket(Collections.singletonList(player));
|
|
||||||
|
|
||||||
Bukkit.getAsyncScheduler().runDelayed(plugin, scheduledTask1 -> {
|
|
||||||
plugin.getEntityTaskManager().sendHitBox(model, player);
|
|
||||||
plugin.getEntityTaskManager().sendScale(model, Collections.singleton(player), lastScale, true);
|
|
||||||
plugin.getEntityTaskManager().sendColor(model, Collections.singleton(player), lastColor, true);
|
|
||||||
|
|
||||||
updateEntityProperties(model, Collections.singleton(player), true);
|
|
||||||
}, 500, TimeUnit.MILLISECONDS);
|
|
||||||
}, delay * 50L, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateEntityProperties(ModelEntityData model, Collection<Player> players, boolean firstSend, String... forceAnims) {
|
|
||||||
int entity = model.getEntity().getEntityId();
|
|
||||||
Set<String> forceAnimSet = Set.of(forceAnims);
|
|
||||||
|
|
||||||
Map<String, Boolean> boneUpdates = new HashMap<>();
|
|
||||||
Map<String, Boolean> animUpdates = new HashMap<>();
|
|
||||||
Set<String> anims = new HashSet<>();
|
|
||||||
|
|
||||||
model.getActiveModel().getBlueprint().getBones().forEach((s, bone) -> processBone(model, bone, boneUpdates));
|
|
||||||
|
|
||||||
AnimationHandler handler = model.getActiveModel().getAnimationHandler();
|
|
||||||
Set<String> priority = model.getActiveModel().getBlueprint().getAnimationDescendingPriority();
|
|
||||||
for (String animId : priority) {
|
|
||||||
if (handler.isPlayingAnimation(animId)) {
|
|
||||||
BlueprintAnimation anim = model.getActiveModel().getBlueprint().getAnimations().get(animId);
|
|
||||||
|
|
||||||
anims.add(animId);
|
|
||||||
if (anim.isOverride() && anim.getLoopMode() == BlueprintAnimation.LoopMode.ONCE) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String id : priority) {
|
|
||||||
if (anims.contains(id)) {
|
|
||||||
animUpdates.put(id, true);
|
|
||||||
} else {
|
|
||||||
animUpdates.put(id, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> lastPlayed = new HashSet<>(lastPlayedAnim.asMap().keySet());
|
|
||||||
|
|
||||||
for (Map.Entry<String, Boolean> anim : animUpdates.entrySet()) {
|
|
||||||
if (anim.getValue()) {
|
|
||||||
lastPlayedAnim.put(anim.getKey(), true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (String anim : lastPlayed) animUpdates.put(anim, true);
|
|
||||||
|
|
||||||
if (boneUpdates.isEmpty() && animUpdates.isEmpty()) return;
|
|
||||||
|
|
||||||
Map<String, Integer> intUpdates = new HashMap<>();
|
|
||||||
int i = 0;
|
|
||||||
for (Integer integer : booleanPacker.mapBooleansToInts(boneUpdates)) {
|
|
||||||
intUpdates.put("modelengine:bone" + i, integer);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
for (Integer integer : booleanPacker.mapBooleansToInts(animUpdates)) {
|
|
||||||
intUpdates.put("modelengine:anim" + i, integer);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!firstSend) {
|
|
||||||
if (intUpdates.equals(lastIntSet)) {
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
lastIntSet.clear();
|
|
||||||
lastIntSet.putAll(intUpdates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (plugin.getConfigManager().getConfig().getBoolean("debug")) plugin.getLogger().info(animUpdates.toString());
|
|
||||||
|
|
||||||
List<String> list = new ArrayList<>(boneUpdates.keySet());
|
|
||||||
Collections.sort(list);
|
|
||||||
|
|
||||||
for (Player player : players) {
|
|
||||||
EntityUtils.sendIntProperties(player, entity, intUpdates);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processBone(ModelEntityData model, BlueprintBone bone, Map<String, Boolean> map) {
|
|
||||||
String name = plugin.getEntityTaskManager().unstripName(bone).toLowerCase();
|
|
||||||
if (name.equals("hitbox") ||
|
|
||||||
name.equals("shadow") ||
|
|
||||||
name.equals("mount") ||
|
|
||||||
name.startsWith("p_") ||
|
|
||||||
name.startsWith("b_") ||
|
|
||||||
name.startsWith("ob_")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (BlueprintBone blueprintBone : bone.getChildren().values()) processBone(model, blueprintBone, map);
|
|
||||||
|
|
||||||
ModelBone activeBone = model.getActiveModel().getBones().get(bone.getName());
|
|
||||||
|
|
||||||
boolean visible = false;
|
|
||||||
if (activeBone != null) visible = activeBone.isVisible();
|
|
||||||
|
|
||||||
map.put(name, visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTick(int tick) {
|
|
||||||
this.tick = tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSyncTick(int syncTick) {
|
|
||||||
this.syncTick = syncTick;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRemoved(boolean removed) {
|
|
||||||
this.removed = removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastScale(float lastScale) {
|
|
||||||
this.lastScale = lastScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTick() {
|
|
||||||
return tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSyncTick() {
|
|
||||||
return syncTick;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLastColor(Color lastColor) {
|
|
||||||
this.lastColor = lastColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getLastScale() {
|
|
||||||
return lastScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Color getLastColor() {
|
|
||||||
return lastColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRemoved() {
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConcurrentHashMap<String, Integer> getLastIntSet() {
|
|
||||||
return lastIntSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Cache<String, Boolean> getLastPlayedAnim() {
|
|
||||||
return lastPlayedAnim;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package re.imc.geysermodelengine.runnables;
|
package re.imc.geysermodelengine.runnables;
|
||||||
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
|
||||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -19,8 +19,8 @@ public class UpdateTaskRunnable implements Consumer<ScheduledTask> {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(ScheduledTask scheduledTask) {
|
public void accept(ScheduledTask scheduledTask) {
|
||||||
try {
|
try {
|
||||||
for (Map<ActiveModel, ModelEntityData> models : plugin.getModelManager().getEntitiesCache().values()) {
|
for (Map<Model, EntityData> models : plugin.getModelManager().getEntitiesCache().values()) {
|
||||||
models.values().forEach(model -> model.getEntityTask().updateEntityProperties(model, model.getViewers(), false));
|
models.values().forEach(entityData -> plugin.getEntityTaskManager().getPropertyHandler().updateEntityProperties(entityData, entityData.getViewers(), false));
|
||||||
}
|
}
|
||||||
} catch (Throwable err) {
|
} catch (Throwable err) {
|
||||||
throw new RuntimeException(err);
|
throw new RuntimeException(err);
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class BooleanPacker {
|
public class BooleanPacker {
|
||||||
|
|
||||||
private final int MAX_BOOLEANS = 24;
|
private static final int MAX_BOOLEANS = 24;
|
||||||
|
|
||||||
public int booleansToInt(List<Boolean> booleans) {
|
public static int booleansToInt(List<Boolean> booleans) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ public class BooleanPacker {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int mapBooleansToInt(Map<String, Boolean> booleanMap) {
|
public static int mapBooleansToInt(Map<String, Boolean> booleanMap) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public class BooleanPacker {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> booleansToInts(List<Boolean> booleans) {
|
public static List<Integer> booleansToInts(List<Boolean> booleans) {
|
||||||
List<Integer> results = new ArrayList<>();
|
List<Integer> results = new ArrayList<>();
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
@@ -62,7 +62,7 @@ public class BooleanPacker {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> mapBooleansToInts(Map<String, Boolean> booleanMap) {
|
public static List<Integer> mapBooleansToInts(Map<String, Boolean> booleanMap) {
|
||||||
List<String> keys = new ArrayList<>(booleanMap.keySet());
|
List<String> keys = new ArrayList<>(booleanMap.keySet());
|
||||||
List<Boolean> booleans = new ArrayList<>();
|
List<Boolean> booleans = new ArrayList<>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
|
metrics:
|
||||||
|
bstats: true
|
||||||
|
|
||||||
|
models:
|
||||||
|
namespace: "modelengine"
|
||||||
data-send-delay: 5
|
data-send-delay: 5
|
||||||
entity-view-distance: 50
|
entity-view-distance: 50
|
||||||
join-send-delay: 20
|
join-send-delay: 20
|
||||||
entity-position-update-period: 35
|
entity-position-update-period: 35
|
||||||
model-entity-type: BAT # must be a living entity
|
thread-pool-size: 4
|
||||||
enable-part-visibility-models:
|
|
||||||
- example
|
options:
|
||||||
debug: false
|
debug: false
|
||||||
@@ -6,7 +6,7 @@ api-version: '1.21'
|
|||||||
authors:
|
authors:
|
||||||
- zimzaza4
|
- zimzaza4
|
||||||
- willem.dev
|
- willem.dev
|
||||||
- TheLividaProject
|
- xSquishyLiam
|
||||||
|
|
||||||
load: STARTUP
|
load: STARTUP
|
||||||
|
|
||||||
@@ -16,7 +16,9 @@ dependencies:
|
|||||||
required: true
|
required: true
|
||||||
packetevents:
|
packetevents:
|
||||||
required: true
|
required: true
|
||||||
ModelEngine:
|
|
||||||
required: true
|
|
||||||
floodgate:
|
floodgate:
|
||||||
required: true
|
required: true
|
||||||
|
ModelEngine:
|
||||||
|
required: false
|
||||||
|
BetterModel:
|
||||||
|
required: false
|
||||||
Reference in New Issue
Block a user