mirror of
https://github.com/xSquishyLiam/mc-GeyserModelEngine-plugin.git
synced 2025-12-19 06:49:24 +00:00
Major Overhaul (needs testing)
This commit is contained in:
BIN
.gradle/8.12/checksums/checksums.lock
Normal file
BIN
.gradle/8.12/checksums/checksums.lock
Normal file
Binary file not shown.
BIN
.gradle/8.12/checksums/md5-checksums.bin
Normal file
BIN
.gradle/8.12/checksums/md5-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/8.12/checksums/sha1-checksums.bin
Normal file
BIN
.gradle/8.12/checksums/sha1-checksums.bin
Normal file
Binary file not shown.
BIN
.gradle/8.12/executionHistory/executionHistory.bin
Normal file
BIN
.gradle/8.12/executionHistory/executionHistory.bin
Normal file
Binary file not shown.
BIN
.gradle/8.12/executionHistory/executionHistory.lock
Normal file
BIN
.gradle/8.12/executionHistory/executionHistory.lock
Normal file
Binary file not shown.
BIN
.gradle/8.12/fileChanges/last-build.bin
Normal file
BIN
.gradle/8.12/fileChanges/last-build.bin
Normal file
Binary file not shown.
BIN
.gradle/8.12/fileHashes/fileHashes.bin
Normal file
BIN
.gradle/8.12/fileHashes/fileHashes.bin
Normal file
Binary file not shown.
BIN
.gradle/8.12/fileHashes/fileHashes.lock
Normal file
BIN
.gradle/8.12/fileHashes/fileHashes.lock
Normal file
Binary file not shown.
BIN
.gradle/8.12/fileHashes/resourceHashesCache.bin
Normal file
BIN
.gradle/8.12/fileHashes/resourceHashesCache.bin
Normal file
Binary file not shown.
0
.gradle/8.12/gc.properties
Normal file
0
.gradle/8.12/gc.properties
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
BIN
.gradle/buildOutputCleanup/buildOutputCleanup.lock
Normal file
Binary file not shown.
2
.gradle/buildOutputCleanup/cache.properties
Normal file
2
.gradle/buildOutputCleanup/cache.properties
Normal file
@@ -0,0 +1,2 @@
|
||||
#Tue May 27 16:38:57 BST 2025
|
||||
gradle.version=8.12
|
||||
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
BIN
.gradle/buildOutputCleanup/outputFiles.bin
Normal file
Binary file not shown.
BIN
.gradle/file-system.probe
Normal file
BIN
.gradle/file-system.probe
Normal file
Binary file not shown.
0
.gradle/vcs-1/gc.properties
Normal file
0
.gradle/vcs-1/gc.properties
Normal file
18
.idea/compiler.xml
generated
Normal file
18
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="GeyserModelEngine" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
<component name="JavacSettings">
|
||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
||||
<module name="GeyserModelEngine" options="" />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
7
.idea/encodings.xml
generated
Normal file
7
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
65
.idea/jarRepositories.xml
generated
Normal file
65
.idea/jarRepositories.xml
generated
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="codemc-snapshots" />
|
||||
<option name="name" value="codemc-snapshots" />
|
||||
<option name="url" value="https://repo.codemc.io/repository/maven-snapshots/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="opencollab-snapshot-repo" />
|
||||
<option name="name" value="opencollab-snapshot-repo" />
|
||||
<option name="url" value="https://repo.opencollab.dev/maven-snapshots/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="sonatype" />
|
||||
<option name="name" value="sonatype" />
|
||||
<option name="url" value="https://oss.sonatype.org/content/groups/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="opencollab-release-repo" />
|
||||
<option name="name" value="opencollab-release-repo" />
|
||||
<option name="url" value="https://repo.opencollab.dev/maven-releases/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="codemc-releases" />
|
||||
<option name="name" value="codemc-releases" />
|
||||
<option name="url" value="https://repo.codemc.io/repository/maven-releases/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="dmulloy2-repo" />
|
||||
<option name="name" value="dmulloy2-repo" />
|
||||
<option name="url" value="https://repo.dmulloy2.net/repository/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="papermc-repo" />
|
||||
<option name="name" value="papermc-repo" />
|
||||
<option name="url" value="https://repo.papermc.io/repository/maven-public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="nexus" />
|
||||
<option name="name" value="Lumine Public" />
|
||||
<option name="url" value="https://mvn.lumine.io/repository/maven-public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="md_5-public" />
|
||||
<option name="name" value="md_5-public" />
|
||||
<option name="url" value="https://repo.md-5.net/content/groups/public/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
12
.idea/misc.xml
generated
Normal file
12
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK" />
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
49
.idea/workspace.xml
generated
Normal file
49
.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,49 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="ff2e9770-ec88-4715-adeb-b9dbda130e1a" name="Changes" comment="" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="MavenRunner">
|
||||
<option name="delegateBuildToMaven" value="true" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo"><![CDATA[{
|
||||
"associatedIndex": 8
|
||||
}]]></component>
|
||||
<component name="ProjectId" id="2xedme8VKz03tyMoE1OuGEibnGo" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"Maven.GeyserModelEngine [install...].executor": "Run",
|
||||
"Maven.GeyserModelEngine [install].executor": "Run",
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"git-widget-placeholder": "main",
|
||||
"last_opened_file_path": "D:/Coding/Forks/Minecraft/GeyserModelEngine",
|
||||
"settings.editor.selected.configurable": "reference.settings.project.maven.runner"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="ff2e9770-ec88-4715-adeb-b9dbda130e1a" name="Changes" comment="" />
|
||||
<created>1748302633990</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1748302633990</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="minecraft" name="Minecraft">
|
||||
<configuration>
|
||||
<autoDetectTypes>
|
||||
<platformType>PAPER</platformType>
|
||||
<platformType>ADVENTURE</platformType>
|
||||
</autoDetectTypes>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="McpModuleSettings">
|
||||
<option name="srgType" value="SRG" />
|
||||
</component>
|
||||
</module>
|
||||
60
build.gradle.kts
Normal file
60
build.gradle.kts
Normal file
@@ -0,0 +1,60 @@
|
||||
plugins {
|
||||
id("java")
|
||||
id("io.github.goooler.shadow") version "8.1.7"
|
||||
}
|
||||
|
||||
group = "re.imc"
|
||||
version = "1.0.0"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||
|
||||
maven("https://mvn.lumine.io/repository/maven-public/")
|
||||
|
||||
maven("https://repo.opencollab.dev/maven-releases/") {
|
||||
isAllowInsecureProtocol = true
|
||||
}
|
||||
maven("https://repo.opencollab.dev/maven-snapshots/") {
|
||||
isAllowInsecureProtocol = true
|
||||
}
|
||||
|
||||
maven("https://repo.codemc.io/repository/maven-public/")
|
||||
maven("https://repo.codemc.io/repository/maven-releases/")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.5-R0.1-SNAPSHOT")
|
||||
|
||||
implementation("dev.jorel:commandapi-bukkit-shade-mojang-mapped:10.0.1")
|
||||
|
||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.4")
|
||||
compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar"))
|
||||
compileOnly("org.geysermc.floodgate:api:2.2.2-SNAPSHOT")
|
||||
|
||||
implementation("com.github.retrooper:packetevents-spigot:2.8.0")
|
||||
|
||||
implementation("org.reflections:reflections:0.10.2")
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
|
||||
tasks.compileJava {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
tasks.shadowJar {
|
||||
relocate("dev.jorel.commandapi", "re.imc.geysermodelengine.libs.commandapi")
|
||||
|
||||
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("org.reflections", "re.imc.geysermodelengine.libs.reflections")
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
dependsOn(tasks.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.
Binary file not shown.
Binary file not shown.
BIN
build/libs/GeyserModelEngine-1.0.0-all.jar
Normal file
BIN
build/libs/GeyserModelEngine-1.0.0-all.jar
Normal file
Binary file not shown.
BIN
build/libs/GeyserModelEngine-1.0.0.jar
Normal file
BIN
build/libs/GeyserModelEngine-1.0.0.jar
Normal file
Binary file not shown.
663
build/reports/problems/problems-report.html
Normal file
663
build/reports/problems/problems-report.html
Normal file
File diff suppressed because one or more lines are too long
4
build/resources/main/Lang/messages.yml
Normal file
4
build/resources/main/Lang/messages.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
commands:
|
||||
reload:
|
||||
successfully-reloaded: "<#55FF55>GeyserModelEngine configuration reloaded!"
|
||||
8
build/resources/main/config.yml
Normal file
8
build/resources/main/config.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
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
|
||||
18
build/resources/main/paper-plugin.yml
Normal file
18
build/resources/main/paper-plugin.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
main: re.imc.geysermodelengine.GeyserModelEngine
|
||||
name: GeyserModelEngine
|
||||
version: '1.0.0'
|
||||
api-version: '1.21'
|
||||
|
||||
authors:
|
||||
- zimzaza4
|
||||
- willem.dev
|
||||
- TheLividaProject
|
||||
|
||||
dependencies:
|
||||
server:
|
||||
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.
BIN
build/tmp/compileJava/previous-compilation-data.bin
Normal file
BIN
build/tmp/compileJava/previous-compilation-data.bin
Normal file
Binary file not shown.
2
build/tmp/jar/MANIFEST.MF
Normal file
2
build/tmp/jar/MANIFEST.MF
Normal file
@@ -0,0 +1,2 @@
|
||||
Manifest-Version: 1.0
|
||||
|
||||
2
build/tmp/shadowJar/MANIFEST.MF
Normal file
2
build/tmp/shadowJar/MANIFEST.MF
Normal file
@@ -0,0 +1,2 @@
|
||||
Manifest-Version: 1.0
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
251
gradlew
vendored
Normal file
251
gradlew
vendored
Normal file
@@ -0,0 +1,251 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC2039,SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command:
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||
# and any embedded shellness will be escaped.
|
||||
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||
# treated as '${Hostname}' itself on the command line.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
94
gradlew.bat
vendored
Normal file
94
gradlew.bat
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo. 1>&2
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||
echo. 1>&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||
echo location of your Java installation. 1>&2
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
152
pom.xml
152
pom.xml
@@ -1,152 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>re.imc</groupId>
|
||||
<artifactId>GeyserModelEngine</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>GeyserModelEngine</name>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>16</source>
|
||||
<target>16</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>com.github.retrooper.packetevents</pattern>
|
||||
<shadedPattern>re.imc.geysermodelengine.libs.com.github.retrooper.packetevents</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>io.github.retrooper.packetevents</pattern>
|
||||
<shadedPattern>re.imc.geysermodelengine.libs.io.github.retrooper.packetevents</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc-repo</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>nexus</id>
|
||||
<name>Lumine Public</name>
|
||||
<url>https://mvn.lumine.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>md_5-public</id>
|
||||
<url>https://repo.md-5.net/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>opencollab-release-repo</id>
|
||||
<url>https://repo.opencollab.dev/maven-releases/</url>
|
||||
<releases>
|
||||
<enabled>true</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>opencollab-snapshot-repo</id>
|
||||
<url>https://repo.opencollab.dev/maven-snapshots/</url>
|
||||
<releases>
|
||||
<enabled>false</enabled>
|
||||
</releases>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>dmulloy2-repo</id>
|
||||
<url>https://repo.dmulloy2.net/repository/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>codemc-releases</id>
|
||||
<url>https://repo.codemc.io/repository/maven-releases/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>codemc-snapshots</id>
|
||||
<url>https://repo.codemc.io/repository/maven-snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>1.21.5-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.ticxo.modelengine</groupId>
|
||||
<artifactId>ModelEngine</artifactId>
|
||||
<version>R4.0.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.geyserextensionists</groupId>
|
||||
<artifactId>geyserutils-spigot</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<scope>system</scope>
|
||||
<systemPath>${project.basedir}/libs/geyserutils-spigot-1.0-SNAPSHOT.jar</systemPath>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.geysermc.floodgate</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>2.2.2-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.retrooper</groupId>
|
||||
<artifactId>packetevents-spigot</artifactId>
|
||||
<version>2.8.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
2
settings.gradle.kts
Normal file
2
settings.gradle.kts
Normal file
@@ -0,0 +1,2 @@
|
||||
rootProject.name = "GeyserModelEngine"
|
||||
|
||||
@@ -2,149 +2,143 @@ package re.imc.geysermodelengine;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||
import com.ticxo.modelengine.api.model.bone.type.Mount;
|
||||
import dev.jorel.commandapi.CommandAPI;
|
||||
import dev.jorel.commandapi.CommandAPIBukkitConfig;
|
||||
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import re.imc.geysermodelengine.commands.ReloadCommand;
|
||||
import re.imc.geysermodelengine.listener.ModelListener;
|
||||
import re.imc.geysermodelengine.listener.MountPacketListener;
|
||||
import re.imc.geysermodelengine.model.BedrockMountControl;
|
||||
import re.imc.geysermodelengine.model.ModelEntity;
|
||||
import re.imc.geysermodelengine.managers.ConfigManager;
|
||||
import re.imc.geysermodelengine.managers.bedrock.BedrockMountControlManager;
|
||||
import re.imc.geysermodelengine.managers.commands.CommandManager;
|
||||
import re.imc.geysermodelengine.managers.model.EntityTaskManager;
|
||||
import re.imc.geysermodelengine.managers.model.ModelManager;
|
||||
import re.imc.geysermodelengine.managers.player.PlayerManager;
|
||||
import re.imc.geysermodelengine.managers.server.ServerManager;
|
||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
||||
import re.imc.geysermodelengine.runnables.BedrockMountControlRunnable;
|
||||
import re.imc.geysermodelengine.runnables.UpdateTaskRunnable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public final class GeyserModelEngine extends JavaPlugin {
|
||||
public class GeyserModelEngine extends JavaPlugin {
|
||||
|
||||
@Getter
|
||||
private static GeyserModelEngine instance;
|
||||
private ConfigManager configManager;
|
||||
private ServerManager serverManager;
|
||||
|
||||
@Getter
|
||||
private static boolean alwaysSendSkin;
|
||||
private CommandManager commandManager;
|
||||
|
||||
@Getter
|
||||
private int sendDelay;
|
||||
private ModelManager modelManager;
|
||||
private EntityTaskManager entityTaskManager;
|
||||
private BedrockMountControlManager bedrockMountControlManager;
|
||||
|
||||
@Getter
|
||||
private int viewDistance;
|
||||
|
||||
@Getter
|
||||
private Set<Player> joinedPlayers = new HashSet<>();
|
||||
|
||||
@Getter
|
||||
private int joinSendDelay;
|
||||
|
||||
@Getter
|
||||
private long entityPositionUpdatePeriod;
|
||||
|
||||
@Getter
|
||||
private boolean debug;
|
||||
|
||||
@Getter
|
||||
private Map<Player, Pair<ActiveModel, Mount>> drivers = new ConcurrentHashMap<>();
|
||||
|
||||
@Getter
|
||||
private boolean initialized = false;
|
||||
|
||||
@Getter
|
||||
private List<String> enablePartVisibilityModels = new ArrayList<>();
|
||||
|
||||
@Getter
|
||||
private ScheduledExecutorService scheduler;
|
||||
private ScheduledFuture<?> updateTask;
|
||||
private PlayerManager playerManager;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
||||
PacketEvents.getAPI().load();
|
||||
|
||||
CommandAPI.onLoad(new CommandAPIBukkitConfig(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
PacketEvents.getAPI().init();
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new MountPacketListener(), PacketListenerPriority.NORMAL);
|
||||
/*
|
||||
scheduler.scheduleAtFixedRate(() -> {
|
||||
try {
|
||||
for (Map<ActiveModel, ModelEntity> models : ModelEntity.ENTITIES.values()) {
|
||||
models.values().forEach(ModelEntity::teleportToModel);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}, 10, entityPositionUpdatePeriod, TimeUnit.MILLISECONDS);
|
||||
loadHooks();
|
||||
loadManagers();
|
||||
loadRunnables();
|
||||
|
||||
*/
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new MountPacketListener(this), PacketListenerPriority.NORMAL);
|
||||
|
||||
reload();
|
||||
getCommand("geysermodelengine").setExecutor(new ReloadCommand(this));
|
||||
Bukkit.getPluginManager().registerEvents(new ModelListener(), this);
|
||||
Bukkit.getScheduler()
|
||||
.runTaskLater(GeyserModelEngine.getInstance(), () -> {
|
||||
Bukkit.getPluginManager().registerEvents(new ModelListener(this), this);
|
||||
|
||||
Bukkit.getScheduler().runTaskLater(this, () -> {
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
|
||||
for (Entity entity : world.getEntities()) {
|
||||
if (!ModelEntity.ENTITIES.containsKey(entity.getEntityId())) {
|
||||
|
||||
if (!modelManager.getEntitiesCache().containsKey(entity.getEntityId())) {
|
||||
|
||||
ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity);
|
||||
|
||||
if (modeledEntity != null) {
|
||||
Optional<ActiveModel> model = modeledEntity.getModels().values().stream().findFirst();
|
||||
model.ifPresent(m -> ModelEntity.create(modeledEntity, m));
|
||||
model.ifPresent(m -> modelManager.create(modeledEntity, m));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
initialized = true;
|
||||
|
||||
}, 100);
|
||||
|
||||
|
||||
BedrockMountControl.startTask();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
saveDefaultConfig();
|
||||
// alwaysSendSkin = getConfig().getBoolean("always-send-skin");
|
||||
sendDelay = getConfig().getInt("data-send-delay", 5);
|
||||
scheduler = Executors.newScheduledThreadPool(getConfig().getInt("thread-pool-size", 4));
|
||||
viewDistance = getConfig().getInt("entity-view-distance", 60);
|
||||
debug = getConfig().getBoolean("debug", false);
|
||||
joinSendDelay = getConfig().getInt("join-send-delay", 20);
|
||||
entityPositionUpdatePeriod = getConfig().getLong("entity-position-update-period", 35);
|
||||
enablePartVisibilityModels.addAll(getConfig().getStringList("enable-part-visibility-models"));
|
||||
|
||||
instance = this;
|
||||
if (updateTask != null) updateTask.cancel(true);
|
||||
|
||||
updateTask = scheduler.scheduleWithFixedDelay(() -> {
|
||||
try {
|
||||
for (Map<ActiveModel, ModelEntity> models : ModelEntity.ENTITIES.values()) {
|
||||
models.values().forEach(model -> model.getTask().updateEntityProperties(model.getViewers(), false));
|
||||
}
|
||||
} catch (Throwable err) {
|
||||
throw new RuntimeException(err);
|
||||
}
|
||||
}, 10, entityPositionUpdatePeriod, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
PacketEvents.getAPI().terminate();
|
||||
for (Map<ActiveModel, ModelEntity> entities : ModelEntity.ENTITIES.values()) {
|
||||
|
||||
for (Map<ActiveModel, ModelEntityData> entities : modelManager.getEntitiesCache().values()) {
|
||||
entities.forEach((model, modelEntity) -> {
|
||||
modelEntity.getEntity().remove();
|
||||
});
|
||||
}
|
||||
// Plugin shutdown logic
|
||||
|
||||
CommandAPI.onDisable();
|
||||
}
|
||||
|
||||
private void loadHooks() {
|
||||
PacketEvents.getAPI().init();
|
||||
CommandAPI.onEnable();
|
||||
}
|
||||
|
||||
private void loadManagers() {
|
||||
this.configManager = new ConfigManager(this);
|
||||
this.serverManager = new ServerManager();
|
||||
|
||||
this.commandManager = new CommandManager(this);
|
||||
|
||||
this.modelManager = new ModelManager(this);
|
||||
this.entityTaskManager = new EntityTaskManager(this);
|
||||
this.bedrockMountControlManager = new BedrockMountControlManager();
|
||||
|
||||
this.playerManager = new PlayerManager();
|
||||
}
|
||||
|
||||
private void loadRunnables() {
|
||||
Bukkit.getAsyncScheduler().runAtFixedRate(this, new UpdateTaskRunnable(this), 10, configManager.getConfig().getLong("entity-position-update-period"), TimeUnit.MILLISECONDS);
|
||||
Bukkit.getAsyncScheduler().runAtFixedRate(this, new BedrockMountControlRunnable(this), 1, 1, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public ConfigManager getConfigManager() {
|
||||
return configManager;
|
||||
}
|
||||
|
||||
public ServerManager getServerManager() {
|
||||
return serverManager;
|
||||
}
|
||||
|
||||
public CommandManager getCommandManager() {
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
public ModelManager getModelManager() {
|
||||
return modelManager;
|
||||
}
|
||||
|
||||
public EntityTaskManager getEntityTaskManager() {
|
||||
return entityTaskManager;
|
||||
}
|
||||
|
||||
public BedrockMountControlManager getBedrockMountControlManager() {
|
||||
return bedrockMountControlManager;
|
||||
}
|
||||
|
||||
public PlayerManager getPlayerManager() {
|
||||
return playerManager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package re.imc.geysermodelengine.commands;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
|
||||
public class ReloadCommand implements CommandExecutor {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
public ReloadCommand(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
|
||||
if (sender instanceof Player && !sender.hasPermission("geysermodelengine.reload")) {
|
||||
sender.sendMessage("§cYou don't have permission to use this command.");
|
||||
return true;
|
||||
}
|
||||
|
||||
plugin.reloadConfig();
|
||||
plugin.reload();
|
||||
|
||||
sender.sendMessage("§aGeyserModelEngine configuration reloaded!");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package re.imc.geysermodelengine.commands.geysermodelenginecommands;
|
||||
|
||||
import dev.jorel.commandapi.CommandAPICommand;
|
||||
import org.bukkit.Bukkit;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.managers.commands.subcommands.SubCommands;
|
||||
import re.imc.geysermodelengine.util.ColourUtils;
|
||||
|
||||
public class GeyserModelEngineReloadCommand implements SubCommands {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
private final ColourUtils colourUtils = new ColourUtils();
|
||||
|
||||
public GeyserModelEngineReloadCommand(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandAPICommand onCommand() {
|
||||
return new CommandAPICommand("reload")
|
||||
.withPermission("geysermodelengine.commands.reload")
|
||||
.executes((sender, args) -> {
|
||||
Bukkit.getAsyncScheduler().runNow(plugin, scheduledTask -> {
|
||||
plugin.getConfigManager().load();
|
||||
});
|
||||
|
||||
sender.sendMessage(colourUtils.miniFormat(plugin.getConfigManager().getLang().getString("commands.reload.successfully-reloaded")));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ 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.events.RemoveModelEvent;
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -12,117 +11,54 @@ import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.model.ModelEntity;
|
||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ModelListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onAddModel(AddModelEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
if (!GeyserModelEngine.getInstance().isInitialized()) {
|
||||
return;
|
||||
}
|
||||
ModelEntity.create(event.getTarget(), event.getModel());
|
||||
public ModelListener(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onAddModel(AddModelEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
|
||||
@EventHandler
|
||||
public void onRemoveModel(RemoveModelEvent event) {
|
||||
plugin.getModelManager().create(event.getTarget(), event.getModel());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onModelMount(ModelMountEvent event) {
|
||||
Map<ActiveModel, ModelEntity> map = ModelEntity.ENTITIES.get(event.getVehicle().getModeledEntity().getBase().getEntityId());
|
||||
if (map == null) {
|
||||
}
|
||||
if (!event.isDriver()) {
|
||||
return;
|
||||
}
|
||||
ModelEntity model = map.get(event.getVehicle());
|
||||
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) {
|
||||
GeyserModelEngine.getInstance().getDrivers().put(player, Pair.of(event.getVehicle(), event.getSeat()));
|
||||
plugin.getBedrockMountControlManager().getDriversCache().put(player, Pair.of(event.getVehicle(), event.getSeat()));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onModelDismount(ModelDismountEvent event) {
|
||||
if (event.getPassenger() instanceof Player player) {
|
||||
GeyserModelEngine.getInstance().getDrivers().remove(player);
|
||||
plugin.getBedrockMountControlManager().getDriversCache().remove(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@EventHandler(priority = EventPriority.MONITOR)
|
||||
public void onModelEntityHurt(EntityDamageEvent event) {
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Map<ActiveModel, ModelEntity> model = ModelEntity.ENTITIES.get(event.getEntity().getEntityId());
|
||||
if (model != null) {
|
||||
for (Map.Entry<ActiveModel, ModelEntity> entry : model.entrySet()) {
|
||||
if (!entry.getValue().getEntity().isDead()) {
|
||||
//entry.getValue().getEntity().sendHurtPacket(entry.getValue().getViewers());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@EventHandler
|
||||
public void onModelAttack(EntityDamageByEntityEvent event) {
|
||||
ModelEntity model = ModelEntity.ENTITIES.get(event.getDamager().getEntityId());
|
||||
if (model != null) {
|
||||
EntityTask task = model.getTask();
|
||||
|
||||
task.playAnimation("attack", 55);
|
||||
}
|
||||
}|
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onAnimationPlay(AnimationPlayEvent event) {
|
||||
Map<ActiveModel, ModelEntity> map = ModelEntity.ENTITIES.get(event.getModel().getModeledEntity().getBase().getEntityId());
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModelEntity model = map.get(event.getModel());
|
||||
model.getTask().updateEntityProperties(model.getViewers(), false, event.getProperty().getName());
|
||||
}
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
|
||||
public void onAnimationEnd(AnimationEndEvent event) {
|
||||
Map<ActiveModel, ModelEntity> map = ModelEntity.ENTITIES.get(event.getModel().getModeledEntity().getBase().getEntityId());
|
||||
if (map == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModelEntity model = map.get(event.getModel());
|
||||
model.getTask().updateEntityProperties(model.getViewers(), false, event.getProperty().);
|
||||
}
|
||||
*/
|
||||
//TODO Find out why we need this bc uh what?
|
||||
@EventHandler
|
||||
public void onPlayerLogin(PlayerJoinEvent event) {
|
||||
Bukkit.getScheduler().runTaskLater(GeyserModelEngine.getInstance(), () -> GeyserModelEngine.getInstance().getJoinedPlayers().add(event.getPlayer()), 10);
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(plugin, scheduledTask -> plugin.getPlayerManager().getPlayerJoinedCache().add(event.getPlayer()), 10);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
Bukkit.getScheduler().runTaskLater(GeyserModelEngine.getInstance(), () -> GeyserModelEngine.getInstance().getJoinedPlayers().remove(event.getPlayer()), 10);
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(plugin, scheduledTask -> plugin.getPlayerManager().getPlayerJoinedCache().remove(event.getPlayer()), 10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@ import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
|
||||
public class MountPacketListener implements PacketListener {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
public MountPacketListener(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() != PacketType.Play.Client.ENTITY_ACTION) return;
|
||||
@@ -22,7 +28,7 @@ public class MountPacketListener implements PacketListener {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
WrapperPlayClientEntityAction action = new WrapperPlayClientEntityAction(event);
|
||||
Pair<ActiveModel, Mount> seat = GeyserModelEngine.getInstance().getDrivers().get(player);
|
||||
Pair<ActiveModel, Mount> seat = plugin.getBedrockMountControlManager().getDriversCache().get(player);
|
||||
|
||||
if (seat == null) return;
|
||||
if (action.getAction() != WrapperPlayClientEntityAction.Action.START_SNEAKING) return;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package re.imc.geysermodelengine.managers;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
private FileConfiguration config, lang;
|
||||
|
||||
public ConfigManager(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
load();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
this.config = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder(), "config.yml"));
|
||||
this.lang = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder(), "Lang/messages.yml"));
|
||||
}
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public FileConfiguration getLang() {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package re.imc.geysermodelengine.managers.bedrock;
|
||||
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.bone.type.Mount;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class BedrockMountControlManager {
|
||||
|
||||
private final ConcurrentHashMap<Player, Pair<ActiveModel, Mount>> driversCache = new ConcurrentHashMap<>();
|
||||
|
||||
public ConcurrentHashMap<Player, Pair<ActiveModel, Mount>> getDriversCache() {
|
||||
return driversCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package re.imc.geysermodelengine.managers.commands;
|
||||
|
||||
import org.reflections.Reflections;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class CommandManager {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
private final HashMap<String, CommandManagers> commandManagersCache = new HashMap<>();
|
||||
|
||||
public CommandManager(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
load("re.imc.geysermodelengine.managers.commands.managers");
|
||||
}
|
||||
|
||||
private void load(String path) {
|
||||
for (Class<?> clazz : new Reflections(path).getSubTypesOf(CommandManagers.class)) {
|
||||
try {
|
||||
CommandManagers commandManager = (CommandManagers) clazz.getDeclaredConstructor(GeyserModelEngine.class).newInstance(plugin);
|
||||
plugin.getLogger().warning("Loading Command Manager - " + commandManager.name());
|
||||
commandManagersCache.put(commandManager.name(), commandManager);
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException err) {
|
||||
plugin.getLogger().severe("Failed to load Command Manager " + clazz.getName());
|
||||
throw new RuntimeException(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<String, CommandManagers> getCommandManagersCache() {
|
||||
return commandManagersCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package re.imc.geysermodelengine.managers.commands;
|
||||
|
||||
import re.imc.geysermodelengine.managers.commands.subcommands.SubCommands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface CommandManagers {
|
||||
|
||||
String name();
|
||||
|
||||
ArrayList<SubCommands> getCommands();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package re.imc.geysermodelengine.managers.commands.managers.geysermodelengine;
|
||||
|
||||
import dev.jorel.commandapi.CommandAPICommand;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.commands.geysermodelenginecommands.GeyserModelEngineReloadCommand;
|
||||
import re.imc.geysermodelengine.managers.commands.CommandManagers;
|
||||
import re.imc.geysermodelengine.managers.commands.subcommands.SubCommands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GeyserModelEngineCommandManager implements CommandManagers {
|
||||
|
||||
private final ArrayList<SubCommands> commands = new ArrayList<>();
|
||||
|
||||
public GeyserModelEngineCommandManager(GeyserModelEngine plugin) {
|
||||
commands.add(new GeyserModelEngineReloadCommand(plugin));
|
||||
|
||||
registerCommand();
|
||||
}
|
||||
|
||||
private void registerCommand() {
|
||||
CommandAPICommand geyserModelEngineCommand = new CommandAPICommand(name());
|
||||
|
||||
commands.forEach(subCommands -> geyserModelEngineCommand.withSubcommand(subCommands.onCommand()));
|
||||
|
||||
geyserModelEngineCommand.register();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "geysermodelengine";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayList<SubCommands> getCommands() {
|
||||
return commands;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package re.imc.geysermodelengine.managers.commands.subcommands;
|
||||
|
||||
import dev.jorel.commandapi.CommandAPICommand;
|
||||
|
||||
public interface SubCommands {
|
||||
CommandAPICommand onCommand();
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package re.imc.geysermodelengine.managers.model;
|
||||
|
||||
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.render.DisplayRenderer;
|
||||
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.joml.Vector3fc;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||
import re.imc.geysermodelengine.runnables.EntityTaskRunnable;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
public class EntityTaskManager {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
private final Method scaleMethod;
|
||||
|
||||
public EntityTaskManager(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
try {
|
||||
this.scaleMethod = ActiveModel.class.getMethod("getScale");
|
||||
} catch (NoSuchMethodException err) {
|
||||
throw new RuntimeException(err);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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()) {
|
||||
if (FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) {
|
||||
|
||||
if (canSee(onlinePlayer, model.getEntity())) {
|
||||
|
||||
if (!viewers.contains(onlinePlayer)) {
|
||||
sendSpawnPacket(model, onlinePlayer);
|
||||
viewers.add(onlinePlayer);
|
||||
}
|
||||
} else {
|
||||
if (viewers.contains(onlinePlayer)) {
|
||||
model.getEntity().sendEntityDestroyPacket(Collections.singletonList(onlinePlayer));
|
||||
viewers.remove(onlinePlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendSpawnPacket(ModelEntityData model, Player onlinePlayer) {
|
||||
EntityTaskRunnable task = model.getEntityTask();
|
||||
boolean firstJoined = !plugin.getPlayerManager().getPlayerJoinedCache().contains(onlinePlayer);
|
||||
|
||||
if (firstJoined) {
|
||||
task.sendEntityData(model, onlinePlayer, plugin.getConfigManager().getConfig().getInt("join-send-delay") / 50);
|
||||
} else {
|
||||
task.sendEntityData(model, onlinePlayer, 5);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canSee(Player player, PacketEntity entity) {
|
||||
if (!player.isOnline()) return false;
|
||||
if (!plugin.getPlayerManager().getPlayerJoinedCache().contains(player)) return false;
|
||||
|
||||
Location playerLocation = player.getLocation().clone();
|
||||
Location entityLocation = entity.getLocation().clone();
|
||||
playerLocation.setY(0);
|
||||
entityLocation.setY(0);
|
||||
|
||||
if (playerLocation.getWorld() != entityLocation.getWorld()) return false;
|
||||
if (playerLocation.distanceSquared(entityLocation) > player.getSendViewDistance() * player.getSendViewDistance() * 48) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void sendHitBoxToAll(ModelEntityData model) {
|
||||
for (Player viewer : model.getViewers()) {
|
||||
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.01f, 0.01f);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendHitBox(ModelEntityData model, Player viewer) {
|
||||
float w = 0;
|
||||
|
||||
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();
|
||||
BlueprintAnimation animationProperty = activeModel.getBlueprint().getAnimations().get(animation);
|
||||
return !(animationProperty == null);
|
||||
}
|
||||
|
||||
public Method getScaleMethod() {
|
||||
return scaleMethod;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package re.imc.geysermodelengine.managers.model;
|
||||
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
||||
import re.imc.geysermodelengine.runnables.EntityTaskRunnable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ModelManager {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
private final ConcurrentHashMap<Integer, Map<ActiveModel, ModelEntityData>> entitiesCache = new ConcurrentHashMap<>();
|
||||
private final Map<Integer, ModelEntityData> modelEntitiesCache = new ConcurrentHashMap<>();
|
||||
|
||||
public ModelManager(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void create(ModeledEntity entity, ActiveModel model) {
|
||||
ModelEntityData modelEntity = new ModelEntityData(plugin, entity, model);
|
||||
int id = entity.getBase().getEntityId();
|
||||
|
||||
Map<ActiveModel, ModelEntityData> map = entitiesCache.computeIfAbsent(id, k -> new HashMap<>());
|
||||
|
||||
for (Map.Entry<ActiveModel, ModelEntityData> entry : map.entrySet()) {
|
||||
if (entry.getKey() != model && entry.getKey().getBlueprint().getName().equals(model.getBlueprint().getName())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
map.put(model, modelEntity);
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<Integer, Map<ActiveModel, ModelEntityData>> getEntitiesCache() {
|
||||
return entitiesCache;
|
||||
}
|
||||
|
||||
public Map<Integer, ModelEntityData> getModelEntitiesCache() {
|
||||
return modelEntitiesCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package re.imc.geysermodelengine.managers.model.data;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||
import re.imc.geysermodelengine.runnables.EntityTaskRunnable;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ModelEntityData {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
private PacketEntity entity;
|
||||
|
||||
private final Set<Player> viewers = Sets.newConcurrentHashSet();
|
||||
|
||||
private final ModeledEntity modeledEntity;
|
||||
|
||||
private final ActiveModel activeModel;
|
||||
|
||||
private EntityTaskRunnable entityTask;
|
||||
|
||||
public ModelEntityData(GeyserModelEngine plugin, ModeledEntity modeledEntity, ActiveModel model) {
|
||||
this.plugin = plugin;
|
||||
|
||||
this.modeledEntity = modeledEntity;
|
||||
this.activeModel = model;
|
||||
this.entity = spawnEntity();
|
||||
|
||||
runEntityTask();
|
||||
}
|
||||
|
||||
public void teleportToModel() {
|
||||
Location location = modeledEntity.getBase().getLocation();
|
||||
entity.teleport(location);
|
||||
}
|
||||
|
||||
public PacketEntity spawnEntity() {
|
||||
entity = new PacketEntity(EntityTypes.PIG, viewers, modeledEntity.getBase().getLocation());
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void runEntityTask() {
|
||||
entityTask = new EntityTaskRunnable(plugin, this);
|
||||
Bukkit.getAsyncScheduler().runAtFixedRate(plugin, entityTask, 0, 20, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public PacketEntity getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public Set<Player> getViewers() {
|
||||
return viewers;
|
||||
}
|
||||
|
||||
public ModeledEntity getModeledEntity() {
|
||||
return modeledEntity;
|
||||
}
|
||||
|
||||
public ActiveModel getActiveModel() {
|
||||
return activeModel;
|
||||
}
|
||||
|
||||
public EntityTaskRunnable getEntityTask() {
|
||||
return entityTask;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package re.imc.geysermodelengine.managers.player;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
public class PlayerManager {
|
||||
|
||||
private final HashSet<Player> playerJoinedCache = new HashSet<>();
|
||||
|
||||
public HashSet<Player> getPlayerJoinedCache() {
|
||||
return playerJoinedCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package re.imc.geysermodelengine.managers.server;
|
||||
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ServerData {
|
||||
|
||||
private final ConcurrentHashMap<String, ScheduledTask> activeRunnablesCache = new ConcurrentHashMap<>();
|
||||
|
||||
public ConcurrentHashMap<String, ScheduledTask> getActiveRunnablesCache() {
|
||||
return activeRunnablesCache;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package re.imc.geysermodelengine.managers.server;
|
||||
|
||||
public class ServerManager {
|
||||
|
||||
private final ServerData serverData;
|
||||
|
||||
public ServerManager() {
|
||||
this.serverData = new ServerData();
|
||||
}
|
||||
|
||||
public ServerData getServerData() {
|
||||
return serverData;
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package re.imc.geysermodelengine.model;
|
||||
|
||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||
import com.ticxo.modelengine.api.entity.BukkitEntity;
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.bone.type.Mount;
|
||||
import com.ticxo.modelengine.api.mount.controller.MountController;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
|
||||
public class BedrockMountControl {
|
||||
|
||||
public static void startTask() {
|
||||
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (!FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float pitch = player.getLocation().getPitch();
|
||||
Pair<ActiveModel, Mount> seat = GeyserModelEngine.getInstance().getDrivers().get(player);
|
||||
if (seat != null) {
|
||||
if (pitch < -30) {
|
||||
MountController controller = ModelEngineAPI.getMountPairManager()
|
||||
.getController(player.getUniqueId());
|
||||
if (controller != null) {
|
||||
MountController.MountInput input = controller.getInput();
|
||||
if (input != null) {
|
||||
input.setJump(true);
|
||||
controller.setInput(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pitch > 80) {
|
||||
if (seat.getKey().getModeledEntity().getBase() instanceof BukkitEntity bukkitEntity) {
|
||||
if (bukkitEntity.getOriginal().isOnGround()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
MountController controller = ModelEngineAPI.getMountPairManager()
|
||||
.getController(player.getUniqueId());
|
||||
|
||||
if (controller != null) {
|
||||
MountController.MountInput input = controller.getInput();
|
||||
if (input != null) {
|
||||
input.setSneak(true);
|
||||
controller.setInput(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}.runTaskTimerAsynchronously(GeyserModelEngine.getInstance(), 1, 1);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,406 +0,0 @@
|
||||
package re.imc.geysermodelengine.model;
|
||||
|
||||
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 com.ticxo.modelengine.api.model.render.DisplayRenderer;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3fc;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||
import re.imc.geysermodelengine.util.BooleanPacker;
|
||||
|
||||
import java.awt.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static re.imc.geysermodelengine.model.ModelEntity.ENTITIES;
|
||||
import static re.imc.geysermodelengine.model.ModelEntity.MODEL_ENTITIES;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class EntityTask {
|
||||
public static final Method GET_SCALE;
|
||||
|
||||
static {
|
||||
try {
|
||||
GET_SCALE = ActiveModel.class.getMethod("getScale");
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
ModelEntity model;
|
||||
|
||||
int tick = 0;
|
||||
int syncTick = 0;
|
||||
|
||||
boolean removed = false;
|
||||
|
||||
float lastScale = -1.0f;
|
||||
Color lastColor = null;
|
||||
Map<String, Integer> lastIntSet = new ConcurrentHashMap<>();
|
||||
Cache<String, Boolean> lastPlayedAnim = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(30, TimeUnit.MILLISECONDS).build();
|
||||
|
||||
private ScheduledFuture scheduledFuture;
|
||||
|
||||
public EntityTask(ModelEntity model) {
|
||||
this.model = model;
|
||||
}
|
||||
public void runAsync() {
|
||||
PacketEntity entity = model.getEntity();
|
||||
if (entity.isDead()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PacketEntity packetEntity = model.getEntity();
|
||||
// packetEntity.setHeadYaw((float) Math.toDegrees(model.getModeledEntity().getYHeadRot()));
|
||||
// packetEntity.setHeadPitch((float) Math.toDegrees(model.getModeledEntity().getXHeadRot()));
|
||||
model.teleportToModel();
|
||||
|
||||
Set<Player> viewers = model.getViewers();
|
||||
ActiveModel activeModel = model.getActiveModel();
|
||||
ModeledEntity modeledEntity = model.getModeledEntity();
|
||||
if (activeModel.isDestroyed() || activeModel.isRemoved()) {
|
||||
removed = true;
|
||||
entity.remove();
|
||||
|
||||
ENTITIES.remove(modeledEntity.getBase().getEntityId());
|
||||
MODEL_ENTITIES.remove(entity.getEntityId());
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (tick % 5 == 0) {
|
||||
if (tick % 40 == 0) {
|
||||
for (Player viewer : Set.copyOf(viewers)) {
|
||||
if (!canSee(viewer, model.getEntity())) {
|
||||
viewers.remove(viewer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tick ++;
|
||||
if (tick > 400) {
|
||||
tick = 0;
|
||||
sendHitBoxToAll();
|
||||
}
|
||||
|
||||
// Optional<Player> player = viewers.stream().findAny();
|
||||
// if (player.isEmpty()) return
|
||||
|
||||
if (viewers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// updateEntityProperties(viewers, false);
|
||||
|
||||
// do not actually use this, atleast bundle these up ;(
|
||||
sendScale(viewers, false);
|
||||
sendColor(viewers, false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void checkViewers(Set<Player> viewers) {
|
||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||
if (FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) {
|
||||
|
||||
if (canSee(onlinePlayer, model.getEntity())) {
|
||||
|
||||
if (!viewers.contains(onlinePlayer)) {
|
||||
sendSpawnPacket(onlinePlayer);
|
||||
viewers.add(onlinePlayer);
|
||||
}
|
||||
} else {
|
||||
if (viewers.contains(onlinePlayer)) {
|
||||
model.getEntity().sendEntityDestroyPacket(Collections.singletonList(onlinePlayer));
|
||||
viewers.remove(onlinePlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void sendSpawnPacket(Player onlinePlayer) {
|
||||
EntityTask task = model.getTask();
|
||||
boolean firstJoined = !GeyserModelEngine.getInstance().getJoinedPlayers().contains(onlinePlayer);
|
||||
|
||||
if (firstJoined) {
|
||||
task.sendEntityData(onlinePlayer, GeyserModelEngine.getInstance().getJoinSendDelay() / 50);
|
||||
} else {
|
||||
task.sendEntityData(onlinePlayer, 5);
|
||||
}
|
||||
}
|
||||
|
||||
public void sendEntityData(Player player, int delay) {
|
||||
EntityUtils.setCustomEntity(player, model.getEntity().getEntityId(), "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase());
|
||||
GeyserModelEngine.getInstance().getScheduler().schedule(() -> {
|
||||
model.getEntity().sendSpawnPacket(Collections.singletonList(player));
|
||||
GeyserModelEngine.getInstance().getScheduler().schedule(() -> {
|
||||
sendHitBox(player);
|
||||
sendScale(Collections.singleton(player), true);
|
||||
sendColor(Collections.singleton(player), true);
|
||||
updateEntityProperties(Collections.singleton(player), true);
|
||||
}, 500, TimeUnit.MILLISECONDS);
|
||||
}, delay * 50L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
public void sendScale(Collection<Player> players, boolean firstSend) {
|
||||
try {
|
||||
if (players.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Vector3fc scale = (Vector3fc) GET_SCALE.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);
|
||||
}
|
||||
lastScale = average;
|
||||
} catch (Throwable t) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
public void sendColor(Collection<Player> players, 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);
|
||||
}
|
||||
lastColor = color;
|
||||
}
|
||||
|
||||
|
||||
public void updateEntityProperties(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<>();
|
||||
// if (GeyserModelEngine.getInstance().getEnablePartVisibilityModels().contains(model.getActiveModel().getBlueprint().getName())) {
|
||||
|
||||
model.getActiveModel().getBlueprint().getBones().forEach((s, bone) -> {
|
||||
processBone(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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// System.out.println("AN: " + animUpdates.size() + ", BO:" + boneUpdates.size());
|
||||
if (GeyserModelEngine.getInstance().isDebug()) {
|
||||
GeyserModelEngine.getInstance().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(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(blueprintBone, map);
|
||||
}
|
||||
ModelBone activeBone = model.getActiveModel().getBones().get(bone.getName());
|
||||
|
||||
boolean visible = false;
|
||||
if (activeBone != null) {
|
||||
visible = activeBone.isVisible();
|
||||
}
|
||||
map.put(name, visible);
|
||||
}
|
||||
private 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;
|
||||
}
|
||||
|
||||
public void sendHitBoxToAll() {
|
||||
for (Player viewer : model.getViewers()) {
|
||||
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.01f, 0.01f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void sendHitBox(Player viewer) {
|
||||
float w = 0;
|
||||
|
||||
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(String animation) {
|
||||
ActiveModel activeModel = model.getActiveModel();
|
||||
BlueprintAnimation animationProperty = activeModel.getBlueprint().getAnimations().get(animation);
|
||||
return !(animationProperty == null);
|
||||
}
|
||||
|
||||
|
||||
private boolean canSee(Player player, PacketEntity entity) {
|
||||
if (!player.isOnline()) {
|
||||
return false;
|
||||
}
|
||||
if (!GeyserModelEngine.getInstance().getJoinedPlayers().contains(player)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Location playerLocation = player.getLocation().clone();
|
||||
Location entityLocation = entity.getLocation().clone();
|
||||
playerLocation.setY(0);
|
||||
entityLocation.setY(0);
|
||||
if (playerLocation.getWorld() != entityLocation.getWorld()) {
|
||||
return false;
|
||||
}
|
||||
if (playerLocation.distanceSquared(entityLocation) > player.getSendViewDistance() * player.getSendViewDistance() * 48) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
/*
|
||||
if (entity.getLocation().getChunk() == player.getChunk()) {
|
||||
return true;
|
||||
}
|
||||
if (entity.getLocation().getWorld() != player.getWorld()) {
|
||||
return false;
|
||||
}
|
||||
if (player.getLocation().distanceSquared(entity.getLocation()) > player.getSimulationDistance() * player.getSimulationDistance() * 256) {
|
||||
return false;
|
||||
}
|
||||
if (player.getLocation().distance(entity.getLocation()) > model.getActiveModel().getModeledEntity().getBase().getRenderRadius()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
// syncTask.cancel();
|
||||
scheduledFuture.cancel(true);
|
||||
}
|
||||
|
||||
public void run(GeyserModelEngine instance) {
|
||||
|
||||
sendHitBoxToAll();
|
||||
|
||||
Runnable asyncTask = () -> {
|
||||
try {
|
||||
checkViewers(model.getViewers());
|
||||
runAsync();
|
||||
} catch (Throwable t) {
|
||||
|
||||
}
|
||||
};
|
||||
scheduledFuture = GeyserModelEngine.getInstance().getScheduler().scheduleAtFixedRate(asyncTask, 0, 20, TimeUnit.MILLISECONDS);
|
||||
|
||||
//asyncTask.runTaskTimerAsynchronously(instance, 0, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
package re.imc.geysermodelengine.model;
|
||||
|
||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Getter
|
||||
public class ModelEntity {
|
||||
|
||||
public static Map<Integer, Map<ActiveModel, ModelEntity>> ENTITIES = new ConcurrentHashMap<>();
|
||||
|
||||
public static Map<Integer, ModelEntity> MODEL_ENTITIES = new ConcurrentHashMap<>();
|
||||
|
||||
private PacketEntity entity;
|
||||
|
||||
private final Set<Player> viewers = Sets.newConcurrentHashSet();
|
||||
|
||||
private final ModeledEntity modeledEntity;
|
||||
|
||||
private final ActiveModel activeModel;
|
||||
|
||||
private EntityTask task;
|
||||
|
||||
private ModelEntity(ModeledEntity modeledEntity, ActiveModel model) {
|
||||
this.modeledEntity = modeledEntity;
|
||||
this.activeModel = model;
|
||||
this.entity = spawnEntity();
|
||||
runEntityTask();
|
||||
}
|
||||
|
||||
public void teleportToModel() {
|
||||
Location location = modeledEntity.getBase().getLocation();
|
||||
entity.teleport(location);
|
||||
}
|
||||
public static ModelEntity create(ModeledEntity entity, ActiveModel model) {
|
||||
ModelEntity modelEntity = new ModelEntity(entity, model);
|
||||
int id = entity.getBase().getEntityId();
|
||||
Map<ActiveModel, ModelEntity> map = ENTITIES.computeIfAbsent(id, k -> new HashMap<>());
|
||||
for (Map.Entry<ActiveModel, ModelEntity> entry : map.entrySet()) {
|
||||
if (entry.getKey() != model && entry.getKey().getBlueprint().getName().equals(model.getBlueprint().getName())) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
map.put(model, modelEntity);
|
||||
return modelEntity;
|
||||
}
|
||||
|
||||
public PacketEntity spawnEntity() {
|
||||
entity = new PacketEntity(EntityTypes.PIG, viewers, modeledEntity.getBase().getLocation());
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void runEntityTask() {
|
||||
task = new EntityTask(this);
|
||||
task.run(GeyserModelEngine.getInstance());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -27,14 +27,6 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
@Setter
|
||||
public class PacketEntity {
|
||||
|
||||
public PacketEntity(EntityType type, Set<Player> viewers, Location location) {
|
||||
this.id = ThreadLocalRandom.current().nextInt(300000000, 400000000);
|
||||
this.uuid = UUID.randomUUID();
|
||||
this.type = type;
|
||||
this.viewers = viewers;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
private int id;
|
||||
private UUID uuid;
|
||||
private EntityType type;
|
||||
@@ -44,6 +36,15 @@ public class PacketEntity {
|
||||
private float headPitch;
|
||||
|
||||
private boolean removed = false;
|
||||
|
||||
public PacketEntity(EntityType type, Set<Player> viewers, Location location) {
|
||||
this.id = ThreadLocalRandom.current().nextInt(300000000, 400000000);
|
||||
this.uuid = UUID.randomUUID();
|
||||
this.type = type;
|
||||
this.viewers = viewers;
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public @NotNull Location getLocation() {
|
||||
return location;
|
||||
}
|
||||
@@ -51,10 +52,9 @@ public class PacketEntity {
|
||||
public boolean teleport(@NotNull Location location) {
|
||||
boolean sent = this.location.getWorld() != location.getWorld() || this.location.distanceSquared(location) > 0.000001;
|
||||
this.location = location.clone();
|
||||
if (sent) {
|
||||
sendLocationPacket(viewers);
|
||||
// sendHeadRotation(viewers); // TODO
|
||||
}
|
||||
|
||||
if (sent) sendLocationPacket(viewers);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -73,8 +73,6 @@ public class PacketEntity {
|
||||
}
|
||||
|
||||
public void sendSpawnPacket(Collection<Player> players) {
|
||||
// EntitySpawnPacket packet = new EntitySpawnPacket(id, uuid, type, location);
|
||||
// EntityMetadataPacket metadataPacket = new EntityMetadataPacket(id);
|
||||
WrapperPlayServerSpawnEntity spawnEntity = new WrapperPlayServerSpawnEntity(id, uuid, type, SpigotConversionUtil.fromBukkitLocation(location), location.getYaw(), 0, null);
|
||||
players.forEach(player -> PacketEvents.getAPI().getPlayerManager().sendPacket(player, spawnEntity));
|
||||
}
|
||||
@@ -83,13 +81,14 @@ public class PacketEntity {
|
||||
|
||||
PacketWrapper<?> packet;
|
||||
EntityPositionData data = new EntityPositionData(SpigotConversionUtil.fromBukkitLocation(location).getPosition(), Vector3d.zero(), location.getYaw(), location.getPitch());
|
||||
|
||||
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_21_2)) {
|
||||
packet = new WrapperPlayServerEntityPositionSync(id, data, false);
|
||||
} else {
|
||||
packet = new WrapperPlayServerEntityTeleport(id, data, RelativeFlag.NONE,false);
|
||||
}
|
||||
players.forEach(player -> PacketEvents.getAPI().getPlayerManager().sendPacket(player, packet));
|
||||
|
||||
players.forEach(player -> PacketEvents.getAPI().getPlayerManager().sendPacket(player, packet));
|
||||
}
|
||||
|
||||
public void sendHeadRotation(Collection<Player> players) {
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package re.imc.geysermodelengine.runnables;
|
||||
|
||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||
import com.ticxo.modelengine.api.entity.BukkitEntity;
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import com.ticxo.modelengine.api.model.bone.type.Mount;
|
||||
import com.ticxo.modelengine.api.mount.controller.MountController;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BedrockMountControlRunnable implements Consumer<ScheduledTask> {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
public BedrockMountControlRunnable(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ScheduledTask scheduledTask) {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
if (!FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) continue;
|
||||
|
||||
float pitch = player.getLocation().getPitch();
|
||||
Pair<ActiveModel, Mount> seat = plugin.getBedrockMountControlManager().getDriversCache().get(player);
|
||||
|
||||
if (seat == null) continue;
|
||||
|
||||
if (pitch < -30) {
|
||||
MountController controller = ModelEngineAPI.getMountPairManager()
|
||||
.getController(player.getUniqueId());
|
||||
if (controller != null) {
|
||||
MountController.MountInput input = controller.getInput();
|
||||
if (input != null) {
|
||||
input.setJump(true);
|
||||
controller.setInput(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pitch > 80) {
|
||||
if (seat.getKey().getModeledEntity().getBase() instanceof BukkitEntity bukkitEntity) {
|
||||
if (bukkitEntity.getOriginal().isOnGround()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MountController controller = ModelEngineAPI.getMountPairManager().getController(player.getUniqueId());
|
||||
|
||||
if (controller != null) {
|
||||
MountController.MountInput input = controller.getInput();
|
||||
if (input != null) {
|
||||
input.setSneak(true);
|
||||
controller.setInput(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,258 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package re.imc.geysermodelengine.runnables;
|
||||
|
||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class UpdateTaskRunnable implements Consumer<ScheduledTask> {
|
||||
|
||||
private final GeyserModelEngine plugin;
|
||||
|
||||
public UpdateTaskRunnable(GeyserModelEngine plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ScheduledTask scheduledTask) {
|
||||
try {
|
||||
for (Map<ActiveModel, ModelEntityData> models : plugin.getModelManager().getEntitiesCache().values()) {
|
||||
models.values().forEach(model -> model.getEntityTask().updateEntityProperties(model, model.getViewers(), false));
|
||||
}
|
||||
} catch (Throwable err) {
|
||||
throw new RuntimeException(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,30 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BooleanPacker {
|
||||
public static final int MAX_BOOLEANS = 24;
|
||||
|
||||
public static int booleansToInt(List<Boolean> booleans) {
|
||||
private final int MAX_BOOLEANS = 24;
|
||||
|
||||
public int booleansToInt(List<Boolean> booleans) {
|
||||
int result = 0;
|
||||
int i = 1;
|
||||
|
||||
for (boolean b : booleans) {
|
||||
if (b) {
|
||||
result += i;
|
||||
}
|
||||
i *= 2;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int mapBooleansToInt(Map<String, Boolean> booleanMap) {
|
||||
public int mapBooleansToInt(Map<String, Boolean> booleanMap) {
|
||||
int result = 0;
|
||||
int i = 1;
|
||||
|
||||
List<String> keys = new ArrayList<>(booleanMap.keySet());
|
||||
Collections.sort(keys);
|
||||
|
||||
for (String key : keys) {
|
||||
if (booleanMap.get(key)) {
|
||||
result += i;
|
||||
@@ -34,11 +39,12 @@ public class BooleanPacker {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<Integer> booleansToInts(List<Boolean> booleans) {
|
||||
public List<Integer> booleansToInts(List<Boolean> booleans) {
|
||||
List<Integer> results = new ArrayList<>();
|
||||
int result = 0;
|
||||
int i = 1;
|
||||
int i1 = 1;
|
||||
|
||||
for (boolean b : booleans) {
|
||||
if (b) {
|
||||
result += i;
|
||||
@@ -56,15 +62,15 @@ public class BooleanPacker {
|
||||
return results;
|
||||
}
|
||||
|
||||
public static List<Integer> mapBooleansToInts(Map<String, Boolean> booleanMap) {
|
||||
public List<Integer> mapBooleansToInts(Map<String, Boolean> booleanMap) {
|
||||
List<String> keys = new ArrayList<>(booleanMap.keySet());
|
||||
List<Boolean> booleans = new ArrayList<>();
|
||||
|
||||
Collections.sort(keys);
|
||||
|
||||
for (String key : keys) {
|
||||
booleans.add(booleanMap.get(key));
|
||||
}
|
||||
return booleansToInts(booleans);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
29
src/main/java/re/imc/geysermodelengine/util/ColourUtils.java
Normal file
29
src/main/java/re/imc/geysermodelengine/util/ColourUtils.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package re.imc.geysermodelengine.util;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ColourUtils {
|
||||
|
||||
private final MiniMessage miniMessage = MiniMessage.miniMessage();
|
||||
|
||||
public @NotNull Component miniFormat(String message) {
|
||||
return miniMessage.deserialize(message).decoration(TextDecoration.ITALIC, false);
|
||||
}
|
||||
|
||||
public @NotNull Component miniFormat(String message, TagResolver tagResolver) {
|
||||
return miniMessage.deserialize(message, tagResolver).decoration(TextDecoration.ITALIC, false);
|
||||
}
|
||||
|
||||
public String stripColour(Component component) {
|
||||
return PlainTextComponentSerializer.plainText().serialize(component);
|
||||
}
|
||||
|
||||
public MiniMessage getMiniMessage() {
|
||||
return miniMessage;
|
||||
}
|
||||
}
|
||||
4
src/main/resources/Lang/messages.yml
Normal file
4
src/main/resources/Lang/messages.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
commands:
|
||||
reload:
|
||||
successfully-reloaded: "<#55FF55>GeyserModelEngine configuration reloaded!"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user