mirror of
https://github.com/xSquishyLiam/mc-GeyserModelEngine-plugin.git
synced 2025-12-19 14:59:19 +00:00
Merge branch 'bettermodel-support-dev'
This commit is contained in:
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@@ -4,6 +4,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- bettermodel-support-dev
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
|||||||
87
.idea/workspace.xml
generated
87
.idea/workspace.xml
generated
@@ -4,16 +4,14 @@
|
|||||||
<option name="autoReloadType" value="SELECTIVE" />
|
<option name="autoReloadType" value="SELECTIVE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="ff2e9770-ec88-4715-adeb-b9dbda130e1a" name="Changes" comment="">
|
<list default="true" id="ff2e9770-ec88-4715-adeb-b9dbda130e1a" name="Changes" comment="" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/packet/entity/PacketEntity.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/packet/entity/PacketEntity.java" afterDir="false" />
|
|
||||||
</list>
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="DarkyenusTimeTracker">
|
<component name="DarkyenusTimeTracker">
|
||||||
<option name="totalTimeSeconds" value="283" />
|
<option name="totalTimeSeconds" value="1293" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ExternalProjectsData">
|
<component name="ExternalProjectsData">
|
||||||
<projectState path="$PROJECT_DIR$">
|
<projectState path="$PROJECT_DIR$">
|
||||||
@@ -82,15 +80,20 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">{
|
<component name="PropertiesComponent">{
|
||||||
"keyToString": {
|
"keyToString": {
|
||||||
|
"Gradle.Build GeyserModelEngine.executor": "Run",
|
||||||
"Gradle.Download Sources.executor": "Run",
|
"Gradle.Download Sources.executor": "Run",
|
||||||
|
"Gradle.GeyserModelEngine [buildDependents].executor": "Run",
|
||||||
|
"Gradle.GeyserModelEngine [buildNeeded].executor": "Run",
|
||||||
"Gradle.GeyserModelEngine [build].executor": "Run",
|
"Gradle.GeyserModelEngine [build].executor": "Run",
|
||||||
|
"Gradle.GeyserModelEngine [clean].executor": "Run",
|
||||||
"Gradle.GeyserModelEngine [jar].executor": "Run",
|
"Gradle.GeyserModelEngine [jar].executor": "Run",
|
||||||
"Maven.GeyserModelEngine [install...].executor": "Run",
|
"Maven.GeyserModelEngine [install...].executor": "Run",
|
||||||
"Maven.GeyserModelEngine [install].executor": "Run",
|
"Maven.GeyserModelEngine [install].executor": "Run",
|
||||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||||
|
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
"RunOnceActivity.git.unshallow": "true",
|
||||||
"git-widget-placeholder": "main",
|
"git-widget-placeholder": "bettermodel-support-dev",
|
||||||
"kotlin-language-version-configured": "true",
|
"kotlin-language-version-configured": "true",
|
||||||
"last_opened_file_path": "D:/Coding/Forks/Minecraft/GeyserModelEngine",
|
"last_opened_file_path": "D:/Coding/Forks/Minecraft/GeyserModelEngine",
|
||||||
"project.structure.last.edited": "Project",
|
"project.structure.last.edited": "Project",
|
||||||
@@ -102,14 +105,57 @@
|
|||||||
<component name="RecentsManager">
|
<component name="RecentsManager">
|
||||||
<key name="CopyFile.RECENT_KEYS">
|
<key name="CopyFile.RECENT_KEYS">
|
||||||
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine" />
|
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine" />
|
||||||
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine\.github\workflows" />
|
|
||||||
</key>
|
</key>
|
||||||
<key name="MoveFile.RECENT_KEYS">
|
<key name="MoveFile.RECENT_KEYS">
|
||||||
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine\.github\workflows" />
|
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine\.github\workflows" />
|
||||||
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine\libs" />
|
<recent name="D:\Coding\Forks\Minecraft\GeyserModelEngine\libs" />
|
||||||
</key>
|
</key>
|
||||||
</component>
|
</component>
|
||||||
<component name="RunManager" selected="Gradle.GeyserModelEngine [jar]">
|
<component name="RunManager" selected="Gradle.GeyserModelEngine [build]">
|
||||||
|
<configuration name="GeyserModelEngine [buildDependents]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="buildDependents" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>false</RunAsTest>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
<configuration name="GeyserModelEngine [buildNeeded]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="buildNeeded" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>false</RunAsTest>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
<configuration name="GeyserModelEngine [build]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
<configuration name="GeyserModelEngine [build]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
<ExternalSystemSettings>
|
<ExternalSystemSettings>
|
||||||
<option name="executionName" />
|
<option name="executionName" />
|
||||||
@@ -132,6 +178,28 @@
|
|||||||
<RunAsTest>false</RunAsTest>
|
<RunAsTest>false</RunAsTest>
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
|
<configuration name="GeyserModelEngine [clean]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="executionName" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="externalSystemIdString" value="GRADLE" />
|
||||||
|
<option name="scriptParameters" />
|
||||||
|
<option name="taskDescriptions">
|
||||||
|
<list />
|
||||||
|
</option>
|
||||||
|
<option name="taskNames">
|
||||||
|
<list>
|
||||||
|
<option value="clean" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
<option name="vmOptions" />
|
||||||
|
</ExternalSystemSettings>
|
||||||
|
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||||
|
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||||
|
<DebugAllEnabled>false</DebugAllEnabled>
|
||||||
|
<RunAsTest>false</RunAsTest>
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
<configuration name="GeyserModelEngine [jar]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
<configuration name="GeyserModelEngine [jar]" type="GradleRunConfiguration" factoryName="Gradle" temporary="true">
|
||||||
<ExternalSystemSettings>
|
<ExternalSystemSettings>
|
||||||
<option name="executionName" />
|
<option name="executionName" />
|
||||||
@@ -156,8 +224,11 @@
|
|||||||
</configuration>
|
</configuration>
|
||||||
<recent_temporary>
|
<recent_temporary>
|
||||||
<list>
|
<list>
|
||||||
<item itemvalue="Gradle.GeyserModelEngine [jar]" />
|
|
||||||
<item itemvalue="Gradle.GeyserModelEngine [build]" />
|
<item itemvalue="Gradle.GeyserModelEngine [build]" />
|
||||||
|
<item itemvalue="Gradle.GeyserModelEngine [clean]" />
|
||||||
|
<item itemvalue="Gradle.GeyserModelEngine [jar]" />
|
||||||
|
<item itemvalue="Gradle.GeyserModelEngine [buildDependents]" />
|
||||||
|
<item itemvalue="Gradle.GeyserModelEngine [buildNeeded]" />
|
||||||
</list>
|
</list>
|
||||||
</recent_temporary>
|
</recent_temporary>
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -24,11 +24,12 @@ dependencies {
|
|||||||
implementation("dev.jorel:commandapi-paper-shade:11.0.0")
|
implementation("dev.jorel:commandapi-paper-shade:11.0.0")
|
||||||
|
|
||||||
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.9")
|
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.9")
|
||||||
|
compileOnly("io.github.toxicity188:bettermodel:1.14.0")
|
||||||
|
|
||||||
compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar"))
|
compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar"))
|
||||||
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
|
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
|
||||||
|
|
||||||
implementation("com.github.retrooper:packetevents-spigot:2.10.0")
|
implementation("com.github.retrooper:packetevents-spigot:2.10.1")
|
||||||
implementation("org.bstats:bstats-bukkit:3.0.2")
|
implementation("org.bstats:bstats-bukkit:3.0.2")
|
||||||
|
|
||||||
implementation("org.reflections:reflections:0.10.2")
|
implementation("org.reflections:reflections:0.10.2")
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
package re.imc.geysermodelengine.Events;
|
|
||||||
|
|
||||||
public class GeyserModelEngineModelSpawn {
|
|
||||||
|
|
||||||
//Spawn Event
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,7 @@ package re.imc.geysermodelengine;
|
|||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||||
import dev.jorel.commandapi.CommandAPI;
|
import dev.jorel.commandapi.CommandAPI;
|
||||||
|
import dev.jorel.commandapi.CommandAPIBukkitConfig;
|
||||||
import dev.jorel.commandapi.CommandAPIPaperConfig;
|
import dev.jorel.commandapi.CommandAPIPaperConfig;
|
||||||
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
@@ -53,10 +54,9 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
PacketEvents.getAPI().terminate();
|
|
||||||
|
|
||||||
this.modelManager.removeEntities();
|
this.modelManager.removeEntities();
|
||||||
|
|
||||||
|
PacketEvents.getAPI().terminate();
|
||||||
CommandAPI.onDisable();
|
CommandAPI.onDisable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadBStats() {
|
private void loadBStats() {
|
||||||
if (configManager.getConfig().getBoolean("bstats", true)) new Metrics(this, 26981);
|
if (configManager.getConfig().getBoolean("metrics.bstats", true)) new Metrics(this, 26981);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadManagers() {
|
private void loadManagers() {
|
||||||
@@ -79,9 +79,9 @@ public class GeyserModelEngine extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void loadRunnables() {
|
private void loadRunnables() {
|
||||||
this.schedulerPool = Executors.newScheduledThreadPool(configManager.getConfig().getInt("thread-pool-size", 4));
|
this.schedulerPool = Executors.newScheduledThreadPool(configManager.getConfig().getInt("models.thread-pool-size", 4));
|
||||||
|
|
||||||
Bukkit.getAsyncScheduler().runAtFixedRate(this, new UpdateTaskRunnable(this), 10, configManager.getConfig().getLong("entity-position-update-period", 35), TimeUnit.MILLISECONDS);
|
Bukkit.getAsyncScheduler().runAtFixedRate(this, new UpdateTaskRunnable(this), 10, configManager.getConfig().getLong("models.entity-position-update-period", 35), TimeUnit.MILLISECONDS);
|
||||||
Bukkit.getAsyncScheduler().runAtFixedRate(this, new BedrockMountControlRunnable(this), 1, 1, TimeUnit.MILLISECONDS);
|
Bukkit.getAsyncScheduler().runAtFixedRate(this, new BedrockMountControlRunnable(this), 1, 1, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package re.imc.geysermodelengine.listener;
|
||||||
|
|
||||||
|
import kr.toxicity.model.api.event.CreateEntityTrackerEvent;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.BetterModelEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
|
||||||
|
public class BetterModelListener implements Listener {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public BetterModelListener(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onModelSpawn(CreateEntityTrackerEvent event) {
|
||||||
|
plugin.getModelManager().getModelHandler().createModel(event.sourceEntity(), event.getTracker(), event.tracker());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onModelDamage(EntityDamageByEntityEvent event) {
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
|
||||||
|
Model model = plugin.getModelManager().getModelEntitiesCache().get(entity.getEntityId());
|
||||||
|
if (model == null) return;
|
||||||
|
|
||||||
|
BetterModelEntityData entityData = (BetterModelEntityData) model.getEntityData();
|
||||||
|
|
||||||
|
entityData.setHurt(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package re.imc.geysermodelengine.listener;
|
||||||
|
|
||||||
|
import com.ticxo.modelengine.api.events.*;
|
||||||
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ModelEngineListener implements Listener {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public ModelEngineListener(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onAddModel(AddModelEvent event) {
|
||||||
|
if (event.isCancelled()) return;
|
||||||
|
plugin.getModelManager().getModelHandler().createModel(event.getTarget(), event.getModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Needs Testing
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onModelMount(ModelMountEvent event) {
|
||||||
|
if (!event.isDriver()) return;
|
||||||
|
|
||||||
|
ActiveModel activeModel = event.getVehicle();
|
||||||
|
if (activeModel == null) return;
|
||||||
|
|
||||||
|
int entityID = activeModel.getModeledEntity().getBase().getEntityId();
|
||||||
|
|
||||||
|
Map<Model, EntityData> entityDataCache = plugin.getModelManager().getEntitiesCache().get(entityID);
|
||||||
|
if (entityDataCache == null) return;
|
||||||
|
|
||||||
|
Model model = plugin.getModelManager().getModelEntitiesCache().get(entityID);
|
||||||
|
|
||||||
|
EntityData entityData = entityDataCache.get(model);
|
||||||
|
|
||||||
|
if (entityData != null && event.getPassenger() instanceof Player player) {
|
||||||
|
plugin.getModelManager().getDriversCache().put(player.getUniqueId(), Pair.of(event.getVehicle(), event.getSeat()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onModelDismount(ModelDismountEvent event) {
|
||||||
|
if (event.getPassenger() instanceof Player player) {
|
||||||
|
plugin.getModelManager().getDriversCache().remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +1,15 @@
|
|||||||
package re.imc.geysermodelengine.listener;
|
package re.imc.geysermodelengine.listener;
|
||||||
|
|
||||||
import com.ticxo.modelengine.api.events.*;
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.event.world.WorldInitEvent;
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
import org.geysermc.floodgate.api.FloodgateApi;
|
import org.geysermc.floodgate.api.FloodgateApi;
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class ModelListener implements Listener {
|
public class ModelListener implements Listener {
|
||||||
|
|
||||||
@@ -26,41 +19,19 @@ public class ModelListener implements Listener {
|
|||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
/*
|
||||||
public void onAddModel(AddModelEvent event) {
|
/ xSquishyLiam:
|
||||||
if (event.isCancelled()) return;
|
/ May change this into a better system?
|
||||||
plugin.getModelManager().create(event.getTarget(), event.getModel());
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onModelMount(ModelMountEvent event) {
|
|
||||||
Map<ActiveModel, ModelEntityData> map = plugin.getModelManager().getEntitiesCache().get(event.getVehicle().getModeledEntity().getBase().getEntityId());
|
|
||||||
if (!event.isDriver()) return;
|
|
||||||
|
|
||||||
ModelEntityData model = map.get(event.getVehicle());
|
|
||||||
|
|
||||||
if (model != null && event.getPassenger() instanceof Player player) {
|
|
||||||
plugin.getModelManager().getDriversCache().put(player.getUniqueId(), Pair.of(event.getVehicle(), event.getSeat()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
|
||||||
public void onModelDismount(ModelDismountEvent event) {
|
|
||||||
if (event.getPassenger() instanceof Player player) {
|
|
||||||
plugin.getModelManager().getDriversCache().remove(player.getUniqueId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onWorldInit(WorldInitEvent event) {
|
public void onWorldInit(WorldInitEvent event) {
|
||||||
World world = event.getWorld();
|
World world = event.getWorld();
|
||||||
world.getEntities().forEach(entity -> plugin.getModelManager().processEntities(entity));
|
world.getEntities().forEach(entity -> plugin.getModelManager().getModelHandler().processEntities(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/ xSquishyLiam - conclusion:
|
/ xSquishyLiam:
|
||||||
/ I'm assuming when a player joins the server the packet for mob spawning is instant so the client resyncs itself
|
/ A runDelay makes sure the client doesn't see pigs on login due to the client resyncing themselves back to normal
|
||||||
/ hence why the pig is shown instead of going invisible and not displaying the texture of the modeled mob
|
|
||||||
*/
|
*/
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ public class CommandManager {
|
|||||||
for (Class<?> clazz : new Reflections(path).getSubTypesOf(CommandManagers.class)) {
|
for (Class<?> clazz : new Reflections(path).getSubTypesOf(CommandManagers.class)) {
|
||||||
try {
|
try {
|
||||||
CommandManagers commandManager = (CommandManagers) clazz.getDeclaredConstructor(GeyserModelEngine.class).newInstance(plugin);
|
CommandManagers commandManager = (CommandManagers) clazz.getDeclaredConstructor(GeyserModelEngine.class).newInstance(plugin);
|
||||||
plugin.getLogger().warning("Loading Command Manager - " + commandManager.name());
|
plugin.getLogger().info("Loading Command Manager - " + commandManager.getName());
|
||||||
commandManagersCache.put(commandManager.name(), commandManager);
|
commandManagersCache.put(commandManager.getName(), commandManager);
|
||||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException err) {
|
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException err) {
|
||||||
plugin.getLogger().severe("Failed to load Command Manager " + clazz.getName());
|
plugin.getLogger().severe("Failed to load Command Manager " + clazz.getName());
|
||||||
throw new RuntimeException(err);
|
throw new RuntimeException(err);
|
||||||
|
|||||||
@@ -6,7 +6,13 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
public interface CommandManagers {
|
public interface CommandManagers {
|
||||||
|
|
||||||
String name();
|
/**
|
||||||
|
* Gets the name of the command manager
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the command manager subcommands
|
||||||
|
*/
|
||||||
ArrayList<SubCommands> getCommands();
|
ArrayList<SubCommands> getCommands();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class GeyserModelEngineCommandManager implements CommandManagers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void registerCommand() {
|
private void registerCommand() {
|
||||||
CommandAPICommand geyserModelEngineCommand = new CommandAPICommand(name());
|
CommandAPICommand geyserModelEngineCommand = new CommandAPICommand(getName());
|
||||||
|
|
||||||
commands.forEach(subCommands -> geyserModelEngineCommand.withSubcommand(subCommands.onCommand()));
|
commands.forEach(subCommands -> geyserModelEngineCommand.withSubcommand(subCommands.onCommand()));
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ public class GeyserModelEngineCommandManager implements CommandManagers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String name() {
|
public String getName() {
|
||||||
return "geysermodelengine";
|
return "geysermodelengine";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,9 @@ package re.imc.geysermodelengine.managers.commands.subcommands;
|
|||||||
import dev.jorel.commandapi.CommandAPICommand;
|
import dev.jorel.commandapi.CommandAPICommand;
|
||||||
|
|
||||||
public interface SubCommands {
|
public interface SubCommands {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subcommand setup
|
||||||
|
*/
|
||||||
CommandAPICommand onCommand();
|
CommandAPICommand onCommand();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,84 +1,45 @@
|
|||||||
package re.imc.geysermodelengine.managers.model;
|
package re.imc.geysermodelengine.managers.model;
|
||||||
|
|
||||||
import com.ticxo.modelengine.api.animation.BlueprintAnimation;
|
import com.ticxo.modelengine.api.animation.BlueprintAnimation;
|
||||||
import com.ticxo.modelengine.api.generator.blueprint.BlueprintBone;
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
import com.ticxo.modelengine.api.model.render.DisplayRenderer;
|
|
||||||
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.geysermc.floodgate.api.FloodgateApi;
|
import org.geysermc.floodgate.api.FloodgateApi;
|
||||||
import org.joml.Vector3fc;
|
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.BetterModelPropertyHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.ModelEnginePropertyHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.taskshandler.TaskHandler;
|
||||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
import re.imc.geysermodelengine.runnables.EntityTaskRunnable;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class EntityTaskManager {
|
public class EntityTaskManager {
|
||||||
|
|
||||||
private final GeyserModelEngine plugin;
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
private final Method scaleMethod;
|
private PropertyHandler propertyHandler;
|
||||||
|
|
||||||
public EntityTaskManager(GeyserModelEngine plugin) {
|
public EntityTaskManager(GeyserModelEngine plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
try {
|
if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) {
|
||||||
this.scaleMethod = ActiveModel.class.getMethod("getScale");
|
this.propertyHandler = new ModelEnginePropertyHandler(plugin);
|
||||||
} catch (NoSuchMethodException err) {
|
plugin.getLogger().info("Using ModelEngine property handler!");
|
||||||
throw new RuntimeException(err);
|
} else if (Bukkit.getPluginManager().getPlugin("BetterModel") != null) {
|
||||||
|
this.propertyHandler = new BetterModelPropertyHandler(plugin);
|
||||||
|
plugin.getLogger().info("Using BetterModel property handler!");
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().severe("No supported model engine found!");
|
||||||
|
plugin.getServer().getPluginManager().disablePlugin(plugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String unstripName(BlueprintBone bone) {
|
public void checkViewers(EntityData model, Set<Player> viewers) {
|
||||||
String name = bone.getName();
|
|
||||||
if (bone.getBehaviors().get("head") != null) {
|
|
||||||
if (!bone.getBehaviors().get("head").isEmpty()) return "hi_" + name;
|
|
||||||
return "h_" + name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendScale(ModelEntityData model, Collection<Player> players, float lastScale, boolean firstSend) {
|
|
||||||
try {
|
|
||||||
if (players.isEmpty()) return;
|
|
||||||
|
|
||||||
Vector3fc scale = (Vector3fc) scaleMethod.invoke(model.getActiveModel());
|
|
||||||
|
|
||||||
float average = (scale.x() + scale.y() + scale.z()) / 3;
|
|
||||||
|
|
||||||
if (!firstSend) {
|
|
||||||
if (average == lastScale) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Player player : players) {
|
|
||||||
EntityUtils.sendCustomScale(player, model.getEntity().getEntityId(), average);
|
|
||||||
}
|
|
||||||
} catch (Throwable ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendColor(ModelEntityData model, Collection<Player> players, Color lastColor, boolean firstSend) {
|
|
||||||
if (players.isEmpty()) return;
|
|
||||||
|
|
||||||
Color color = new Color(model.getActiveModel().getDefaultTint().asARGB());
|
|
||||||
if (model.getActiveModel().isMarkedHurt()) color = new Color(model.getActiveModel().getDamageTint().asARGB());
|
|
||||||
|
|
||||||
if (firstSend) {
|
|
||||||
if (color.equals(lastColor)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Player player : players) {
|
|
||||||
EntityUtils.sendCustomColor(player, model.getEntity().getEntityId(), color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkViewers(ModelEntityData model, Set<Player> viewers) {
|
|
||||||
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
|
||||||
if (!FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) continue;
|
if (!FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) continue;
|
||||||
|
|
||||||
@@ -96,12 +57,12 @@ public class EntityTaskManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendSpawnPacket(ModelEntityData model, Player onlinePlayer) {
|
private void sendSpawnPacket(EntityData model, Player onlinePlayer) {
|
||||||
EntityTaskRunnable task = model.getEntityTask();
|
TaskHandler task = model.getEntityTask();
|
||||||
boolean firstJoined = !plugin.getModelManager().getPlayerJoinedCache().contains(onlinePlayer.getUniqueId());
|
boolean firstJoined = !plugin.getModelManager().getPlayerJoinedCache().contains(onlinePlayer.getUniqueId());
|
||||||
|
|
||||||
if (firstJoined) {
|
if (firstJoined) {
|
||||||
task.sendEntityData(model, onlinePlayer, plugin.getConfigManager().getConfig().getInt("join-send-delay") / 50);
|
task.sendEntityData(model, onlinePlayer, plugin.getConfigManager().getConfig().getInt("models.join-send-delay") / 50);
|
||||||
} else {
|
} else {
|
||||||
task.sendEntityData(model, onlinePlayer, 5);
|
task.sendEntityData(model, onlinePlayer, 5);
|
||||||
}
|
}
|
||||||
@@ -122,31 +83,20 @@ public class EntityTaskManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendHitBoxToAll(ModelEntityData model) {
|
public void sendHitBoxToAll(EntityData model) {
|
||||||
for (Player viewer : model.getViewers()) {
|
for (Player viewer : model.getViewers()) {
|
||||||
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.01f, 0.01f);
|
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.01f, 0.01f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendHitBox(ModelEntityData model, Player viewer) {
|
//TODO move this
|
||||||
float w = 0;
|
public boolean hasAnimation(ModelEngineEntityData model, String animation) {
|
||||||
|
|
||||||
if (model.getActiveModel().isShadowVisible()) {
|
|
||||||
if (model.getActiveModel().getModelRenderer() instanceof DisplayRenderer displayRenderer) {
|
|
||||||
// w = displayRenderer.getHitbox().getShadowRadius().get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.02f, w);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasAnimation(ModelEntityData model, String animation) {
|
|
||||||
ActiveModel activeModel = model.getActiveModel();
|
ActiveModel activeModel = model.getActiveModel();
|
||||||
BlueprintAnimation animationProperty = activeModel.getBlueprint().getAnimations().get(animation);
|
BlueprintAnimation animationProperty = activeModel.getBlueprint().getAnimations().get(animation);
|
||||||
return !(animationProperty == null);
|
return !(animationProperty == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Method getScaleMethod() {
|
public PropertyHandler getPropertyHandler() {
|
||||||
return scaleMethod;
|
return propertyHandler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
package re.imc.geysermodelengine.managers.model;
|
package re.imc.geysermodelengine.managers.model;
|
||||||
|
|
||||||
import com.ticxo.modelengine.api.ModelEngineAPI;
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
|
||||||
import com.ticxo.modelengine.api.model.bone.type.Mount;
|
import com.ticxo.modelengine.api.model.bone.type.Mount;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.Bukkit;
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.BetterModelHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelEngineHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
@@ -16,57 +18,53 @@ public class ModelManager {
|
|||||||
|
|
||||||
private final GeyserModelEngine plugin;
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
private ModelHandler modelHandler;
|
||||||
|
|
||||||
private final HashSet<UUID> playerJoinedCache = new HashSet<>();
|
private final HashSet<UUID> playerJoinedCache = new HashSet<>();
|
||||||
|
|
||||||
private final ConcurrentHashMap<Integer, Map<ActiveModel, ModelEntityData>> entitiesCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Integer, Model> modelEntitiesCache = new ConcurrentHashMap<>();
|
||||||
private final ConcurrentHashMap<Integer, ModelEntityData> modelEntitiesCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<Integer, Map<Model, EntityData>> entitiesCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// MEG ONLY
|
||||||
private final ConcurrentHashMap<UUID, Pair<ActiveModel, Mount>> driversCache = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<UUID, Pair<ActiveModel, Mount>> driversCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public ModelManager(GeyserModelEngine plugin) {
|
public ModelManager(GeyserModelEngine plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
|
||||||
|
|
||||||
public void create(ModeledEntity entity, ActiveModel model) {
|
if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) {
|
||||||
ModelEntityData modelEntity = new ModelEntityData(plugin, entity, model);
|
this.modelHandler = new ModelEngineHandler(plugin);
|
||||||
int id = entity.getBase().getEntityId();
|
plugin.getLogger().info("Using ModelEngine handler!");
|
||||||
|
} else if (Bukkit.getPluginManager().getPlugin("BetterModel") != null) {
|
||||||
Map<ActiveModel, ModelEntityData> map = entitiesCache.computeIfAbsent(id, k -> new HashMap<>());
|
this.modelHandler = new BetterModelHandler(plugin);
|
||||||
|
plugin.getLogger().info("Using BetterModel handler!");
|
||||||
for (Map.Entry<ActiveModel, ModelEntityData> entry : map.entrySet()) {
|
} else {
|
||||||
if (entry.getKey() != model && entry.getKey().getBlueprint().getName().equals(model.getBlueprint().getName())) {
|
plugin.getLogger().severe("No supported model engine found!");
|
||||||
|
plugin.getServer().getPluginManager().disablePlugin(plugin);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
map.put(model, modelEntity);
|
modelHandler.loadListeners();
|
||||||
}
|
|
||||||
|
|
||||||
public void processEntities(Entity entity) {
|
|
||||||
if (entitiesCache.containsKey(entity.getEntityId())) return;
|
|
||||||
|
|
||||||
ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity);
|
|
||||||
if (modeledEntity == null) return;
|
|
||||||
|
|
||||||
Optional<ActiveModel> model = modeledEntity.getModels().values().stream().findFirst();
|
|
||||||
model.ifPresent(m -> create(modeledEntity, m));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeEntities() {
|
public void removeEntities() {
|
||||||
for (Map<ActiveModel, ModelEntityData> entities : entitiesCache.values()) {
|
for (Map<Model, EntityData> entities : entitiesCache.values()) {
|
||||||
entities.forEach((model, modelEntity) -> modelEntity.getEntity().remove());
|
entities.forEach((model, modelEntity) -> modelEntity.getEntity().remove());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ModelHandler getModelHandler() {
|
||||||
|
return modelHandler;
|
||||||
|
}
|
||||||
|
|
||||||
public HashSet<UUID> getPlayerJoinedCache() {
|
public HashSet<UUID> getPlayerJoinedCache() {
|
||||||
return playerJoinedCache;
|
return playerJoinedCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConcurrentHashMap<Integer, Map<ActiveModel, ModelEntityData>> getEntitiesCache() {
|
public ConcurrentHashMap<Integer, Map<Model, EntityData>> getEntitiesCache() {
|
||||||
return entitiesCache;
|
return entitiesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConcurrentHashMap<Integer, ModelEntityData> getModelEntitiesCache() {
|
public ConcurrentHashMap<Integer, Model> getModelEntitiesCache() {
|
||||||
return modelEntitiesCache;
|
return modelEntitiesCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.entity;
|
||||||
|
|
||||||
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import kr.toxicity.model.api.tracker.EntityTracker;
|
||||||
|
import kr.toxicity.model.api.tracker.Tracker;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.taskshandler.BetterModelTaskHandler;
|
||||||
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class BetterModelEntityData implements EntityData {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
private final PacketEntity entity;
|
||||||
|
private final Set<Player> viewers = Sets.newConcurrentHashSet();
|
||||||
|
|
||||||
|
private final Entity entitySource;
|
||||||
|
private final Tracker tracker;
|
||||||
|
private final EntityTracker entityTracker;
|
||||||
|
|
||||||
|
private BetterModelTaskHandler entityTask;
|
||||||
|
|
||||||
|
private boolean hurt;
|
||||||
|
|
||||||
|
public BetterModelEntityData(GeyserModelEngine plugin, Entity entitySource, Tracker tracker, EntityTracker entityTracker) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
|
||||||
|
this.entitySource = entitySource;
|
||||||
|
this.tracker = tracker;
|
||||||
|
this.entityTracker = entityTracker;
|
||||||
|
this.entity = new PacketEntity(EntityTypes.PIG, viewers, entitySource.getLocation());
|
||||||
|
|
||||||
|
runEntityTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void teleportToModel() {
|
||||||
|
Location location = entitySource.getLocation();
|
||||||
|
entity.teleport(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runEntityTask() {
|
||||||
|
entityTask = new BetterModelTaskHandler(plugin, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PacketEntity getEntity() {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Player> getViewers() {
|
||||||
|
return viewers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BetterModelTaskHandler getEntityTask() {
|
||||||
|
return entityTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHurt(boolean hurt) {
|
||||||
|
this.hurt = hurt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Entity getEntitySource() {
|
||||||
|
return entitySource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tracker getTracker() {
|
||||||
|
return tracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityTracker getEntityTracker() {
|
||||||
|
return entityTracker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHurt() {
|
||||||
|
return hurt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.entity;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.managers.model.taskshandler.TaskHandler;
|
||||||
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public interface EntityData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Teleports the packet entity to the model
|
||||||
|
*/
|
||||||
|
void teleportToModel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the packet Entity
|
||||||
|
*/
|
||||||
|
PacketEntity getEntity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entity view of players
|
||||||
|
*/
|
||||||
|
Set<Player> getViewers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the entity task handler
|
||||||
|
*/
|
||||||
|
TaskHandler getEntityTask();
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package re.imc.geysermodelengine.managers.model.data;
|
package re.imc.geysermodelengine.managers.model.entity;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
@@ -7,57 +7,58 @@ import com.ticxo.modelengine.api.model.ModeledEntity;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.taskshandler.ModelEngineTaskHandler;
|
||||||
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
import re.imc.geysermodelengine.runnables.EntityTaskRunnable;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ModelEntityData {
|
public class ModelEngineEntityData implements EntityData {
|
||||||
|
|
||||||
private final GeyserModelEngine plugin;
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
private PacketEntity entity;
|
private final PacketEntity entity;
|
||||||
|
|
||||||
private final Set<Player> viewers = Sets.newConcurrentHashSet();
|
private final Set<Player> viewers = Sets.newConcurrentHashSet();
|
||||||
|
|
||||||
private final ModeledEntity modeledEntity;
|
private final ModeledEntity modeledEntity;
|
||||||
|
|
||||||
private final ActiveModel activeModel;
|
private final ActiveModel activeModel;
|
||||||
|
|
||||||
private EntityTaskRunnable entityTask;
|
private ModelEngineTaskHandler entityTask;
|
||||||
|
|
||||||
public ModelEntityData(GeyserModelEngine plugin, ModeledEntity modeledEntity, ActiveModel model) {
|
public ModelEngineEntityData(GeyserModelEngine plugin, ModeledEntity modeledEntity, ActiveModel activeModel) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
|
||||||
this.modeledEntity = modeledEntity;
|
this.modeledEntity = modeledEntity;
|
||||||
this.activeModel = model;
|
this.activeModel = activeModel;
|
||||||
this.entity = spawnEntity();
|
this.entity = new PacketEntity(EntityTypes.PIG, viewers, modeledEntity.getBase().getLocation());
|
||||||
|
|
||||||
runEntityTask();
|
runEntityTask();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void teleportToModel() {
|
public void teleportToModel() {
|
||||||
Location location = modeledEntity.getBase().getLocation();
|
Location location = modeledEntity.getBase().getLocation();
|
||||||
entity.teleport(location);
|
entity.teleport(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketEntity spawnEntity() {
|
|
||||||
entity = new PacketEntity(EntityTypes.PIG, viewers, modeledEntity.getBase().getLocation());
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runEntityTask() {
|
public void runEntityTask() {
|
||||||
entityTask = new EntityTaskRunnable(plugin, this);
|
entityTask = new ModelEngineTaskHandler(plugin, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public PacketEntity getEntity() {
|
public PacketEntity getEntity() {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Set<Player> getViewers() {
|
public Set<Player> getViewers() {
|
||||||
return viewers;
|
return viewers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelEngineTaskHandler getEntityTask() {
|
||||||
|
return entityTask;
|
||||||
|
}
|
||||||
|
|
||||||
public ModeledEntity getModeledEntity() {
|
public ModeledEntity getModeledEntity() {
|
||||||
return modeledEntity;
|
return modeledEntity;
|
||||||
}
|
}
|
||||||
@@ -65,8 +66,4 @@ public class ModelEntityData {
|
|||||||
public ActiveModel getActiveModel() {
|
public ActiveModel getActiveModel() {
|
||||||
return activeModel;
|
return activeModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityTaskRunnable getEntityTask() {
|
|
||||||
return entityTask;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.model;
|
||||||
|
|
||||||
|
import kr.toxicity.model.api.tracker.Tracker;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
|
||||||
|
public class BetterModelModel implements Model {
|
||||||
|
|
||||||
|
private final Tracker tracker;
|
||||||
|
private final ModelHandler modelHandler;
|
||||||
|
private final EntityData entityData;
|
||||||
|
private final PropertyHandler propertyHandler;
|
||||||
|
|
||||||
|
public BetterModelModel(Tracker tracker, ModelHandler modelHandler, EntityData entityData, PropertyHandler propertyHandler) {
|
||||||
|
this.tracker = tracker;
|
||||||
|
this.modelHandler = modelHandler;
|
||||||
|
this.entityData = entityData;
|
||||||
|
this.propertyHandler = propertyHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return tracker.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelHandler getModelHandler() {
|
||||||
|
return modelHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityData getEntityData() {
|
||||||
|
return entityData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyHandler getPropertyHandler() {
|
||||||
|
return propertyHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.model;
|
||||||
|
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
|
||||||
|
public interface Model {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's name
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's entity data
|
||||||
|
*/
|
||||||
|
EntityData getEntityData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's model handler
|
||||||
|
*/
|
||||||
|
ModelHandler getModelHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model's property handler
|
||||||
|
*/
|
||||||
|
PropertyHandler getPropertyHandler();
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.model;
|
||||||
|
|
||||||
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
|
||||||
|
public class ModelEngineModel implements Model {
|
||||||
|
|
||||||
|
private final ActiveModel activeModel;
|
||||||
|
private final ModelHandler modelHandler;
|
||||||
|
private final EntityData entityData;
|
||||||
|
private final PropertyHandler propertyHandler;
|
||||||
|
|
||||||
|
public ModelEngineModel(ActiveModel activeModel, ModelHandler modelHandler, EntityData entityData, PropertyHandler propertyHandler) {
|
||||||
|
this.activeModel = activeModel;
|
||||||
|
this.modelHandler = modelHandler;
|
||||||
|
this.entityData = entityData;
|
||||||
|
this.propertyHandler = propertyHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return activeModel.getBlueprint().getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelHandler getModelHandler() {
|
||||||
|
return modelHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EntityData getEntityData() {
|
||||||
|
return entityData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PropertyHandler getPropertyHandler() {
|
||||||
|
return propertyHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActiveModel getActiveModel() {
|
||||||
|
return activeModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.modelhandler;
|
||||||
|
|
||||||
|
import kr.toxicity.model.api.tracker.EntityTracker;
|
||||||
|
import kr.toxicity.model.api.tracker.Tracker;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.listener.BetterModelListener;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.BetterModelEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.BetterModelModel;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class BetterModelHandler implements ModelHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public BetterModelHandler(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO fix dupe issue - dupe happens when server restart
|
||||||
|
@Override
|
||||||
|
public void createModel(Object... objects) {
|
||||||
|
Entity entitySource = (Entity) objects[0];
|
||||||
|
Tracker tracker = (Tracker) objects[1];
|
||||||
|
EntityTracker entityTracker = (EntityTracker) objects[2];
|
||||||
|
|
||||||
|
int entityID = entitySource.getEntityId();
|
||||||
|
|
||||||
|
PropertyHandler propertyHandler = plugin.getEntityTaskManager().getPropertyHandler();
|
||||||
|
EntityData entityData = new BetterModelEntityData(plugin, entitySource, tracker, entityTracker);
|
||||||
|
|
||||||
|
Model model = new BetterModelModel(tracker, this, entityData, propertyHandler);
|
||||||
|
|
||||||
|
Map<Model, EntityData> entityDataCache = plugin.getModelManager().getEntitiesCache().computeIfAbsent(entityID, k -> new HashMap<>());
|
||||||
|
|
||||||
|
for (Map.Entry<Model, EntityData> entry : entityDataCache.entrySet()) {
|
||||||
|
if (entry.getKey() != model && entry.getKey().getName().equals(tracker.name())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.getModelManager().getModelEntitiesCache().put(entityID, model);
|
||||||
|
entityDataCache.put(model, entityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processEntities(Entity entity) {
|
||||||
|
// if (plugin.getModelManager().getEntitiesCache().containsKey(entity.getEntityId())) return;
|
||||||
|
//
|
||||||
|
// @NotNull Optional<EntityTrackerRegistry> modeledEntity = BetterModel.registry(entity);
|
||||||
|
//
|
||||||
|
// modeledEntity.ifPresent(m -> createModel(modeledEntity.get().entity(), m.));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadListeners() {
|
||||||
|
Bukkit.getPluginManager().registerEvents(new BetterModelListener(plugin), plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.modelhandler;
|
||||||
|
|
||||||
|
import com.ticxo.modelengine.api.ModelEngineAPI;
|
||||||
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
|
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.listener.ModelEngineListener;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.ModelEngineModel;
|
||||||
|
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class ModelEngineHandler implements ModelHandler {
|
||||||
|
|
||||||
|
//TODO move driver hashmap here
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public ModelEngineHandler(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createModel(Object... objects) {
|
||||||
|
ModeledEntity megEntity = (ModeledEntity) objects[0];
|
||||||
|
ActiveModel megActiveModel = (ActiveModel) objects[1];
|
||||||
|
|
||||||
|
int entityID = megEntity.getBase().getEntityId();
|
||||||
|
|
||||||
|
PropertyHandler propertyHandler = plugin.getEntityTaskManager().getPropertyHandler();
|
||||||
|
EntityData entityData = new ModelEngineEntityData(plugin, megEntity, megActiveModel);
|
||||||
|
|
||||||
|
Model model = new ModelEngineModel(megActiveModel, this, entityData, propertyHandler);
|
||||||
|
|
||||||
|
Map<Model, EntityData> entityDataCache = plugin.getModelManager().getEntitiesCache().computeIfAbsent(entityID, k -> new HashMap<>());
|
||||||
|
|
||||||
|
for (Map.Entry<Model, EntityData> entry : entityDataCache.entrySet()) {
|
||||||
|
if (entry.getKey() != model && entry.getKey().getName().equals(megActiveModel.getBlueprint().getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.getModelManager().getModelEntitiesCache().put(entityID, model);
|
||||||
|
entityDataCache.put(model, entityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processEntities(Entity entity) {
|
||||||
|
if (plugin.getModelManager().getEntitiesCache().containsKey(entity.getEntityId())) return;
|
||||||
|
|
||||||
|
ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity);
|
||||||
|
if (modeledEntity == null) return;
|
||||||
|
|
||||||
|
Optional<ActiveModel> model = modeledEntity.getModels().values().stream().findFirst();
|
||||||
|
model.ifPresent(m -> createModel(modeledEntity, m));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadListeners() {
|
||||||
|
Bukkit.getPluginManager().registerEvents(new ModelEngineListener(plugin), plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.modelhandler;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
|
||||||
|
public interface ModelHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the model from the required Model Engine
|
||||||
|
* @param objects Processes the required objects
|
||||||
|
*/
|
||||||
|
void createModel(Object... objects);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes entities into createModel()
|
||||||
|
* @param entity Registers bukkit entities
|
||||||
|
*/
|
||||||
|
void processEntities(Entity entity);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the required listeners
|
||||||
|
*/
|
||||||
|
void loadListeners();
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.propertyhandler;
|
||||||
|
|
||||||
|
import kr.toxicity.model.api.animation.AnimationIterator;
|
||||||
|
import kr.toxicity.model.api.bone.RenderedBone;
|
||||||
|
import kr.toxicity.model.api.data.blueprint.BlueprintAnimation;
|
||||||
|
import kr.toxicity.model.api.data.renderer.RenderPipeline;
|
||||||
|
import kr.toxicity.model.api.nms.ModelDisplay;
|
||||||
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.BetterModelEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.util.BooleanPacker;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BetterModelPropertyHandler implements PropertyHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public BetterModelPropertyHandler(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Figure out on how to get the scale from BetterModel
|
||||||
|
@Override
|
||||||
|
public void sendScale(EntityData entityData, Collection<Player> players, float lastScale, boolean firstSend) {
|
||||||
|
BetterModelEntityData betterModelEntityData = (BetterModelEntityData) entityData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendColor(EntityData entityData, Collection<Player> players, Color lastColor, boolean firstSend) {
|
||||||
|
if (players.isEmpty()) return;
|
||||||
|
|
||||||
|
BetterModelEntityData betterModelEntityData = (BetterModelEntityData) entityData;
|
||||||
|
|
||||||
|
Color color = new Color(0xFFFFFF);
|
||||||
|
if (betterModelEntityData.isHurt()) color = new Color(betterModelEntityData.getEntityTracker().damageTintValue());
|
||||||
|
|
||||||
|
if (firstSend) {
|
||||||
|
if (color.equals(lastColor)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendCustomColor(player, betterModelEntityData.getEntity().getEntityId(), color);
|
||||||
|
}
|
||||||
|
|
||||||
|
betterModelEntityData.setHurt(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendHitBox(EntityData entityData, Player player) {
|
||||||
|
BetterModelEntityData betterModelEntityData = (BetterModelEntityData) entityData;
|
||||||
|
|
||||||
|
float w = 0;
|
||||||
|
|
||||||
|
EntityUtils.sendCustomHitBox(player, betterModelEntityData.getEntity().getEntityId(), 0.02f, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateEntityProperties(EntityData entityData, Collection<Player> players, boolean firstSend, String... forceAnims) {
|
||||||
|
BetterModelEntityData model = (BetterModelEntityData) entityData;
|
||||||
|
|
||||||
|
int entity = model.getEntity().getEntityId();
|
||||||
|
Set<String> forceAnimSet = Set.of(forceAnims);
|
||||||
|
|
||||||
|
Map<String, Boolean> boneUpdates = new HashMap<>();
|
||||||
|
Map<String, Boolean> animUpdates = new HashMap<>();
|
||||||
|
Set<String> anims = new HashSet<>();
|
||||||
|
|
||||||
|
model.getTracker().bones().forEach(bone -> processBone(model, bone, boneUpdates));
|
||||||
|
|
||||||
|
RenderPipeline handler = model.getTracker().getPipeline();
|
||||||
|
|
||||||
|
for (RenderedBone renderedBone : handler.bones()) {
|
||||||
|
if (model.getTracker().bone(renderedBone.name()).runningAnimation() != null) {
|
||||||
|
BlueprintAnimation anim = model.getTracker().renderer().animations().get(renderedBone.runningAnimation().name());
|
||||||
|
|
||||||
|
anims.add(renderedBone.runningAnimation().name());
|
||||||
|
if (anim.override() && anim.loop() == AnimationIterator.Type.PLAY_ONCE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String id : handler.getParent().animations().keySet()) {
|
||||||
|
if (anims.contains(id)) {
|
||||||
|
animUpdates.put(id, true);
|
||||||
|
} else {
|
||||||
|
animUpdates.put(id, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> lastPlayed = new HashSet<>(model.getEntityTask().getLastPlayedAnim().asMap().keySet());
|
||||||
|
|
||||||
|
for (Map.Entry<String, Boolean> anim : animUpdates.entrySet()) {
|
||||||
|
if (anim.getValue()) {
|
||||||
|
model.getEntityTask().getLastPlayedAnim().put(anim.getKey(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String anim : lastPlayed) animUpdates.put(anim, true);
|
||||||
|
|
||||||
|
if (boneUpdates.isEmpty() && animUpdates.isEmpty()) return;
|
||||||
|
|
||||||
|
Map<String, Integer> intUpdates = new HashMap<>();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (Integer integer : BooleanPacker.mapBooleansToInts(boneUpdates)) {
|
||||||
|
intUpdates.put(plugin.getConfigManager().getConfig().getString("models.namespace") + ":bone" + i, integer);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (Integer integer : BooleanPacker.mapBooleansToInts(animUpdates)) {
|
||||||
|
intUpdates.put(plugin.getConfigManager().getConfig().getString("models.namespace") + ":anim" + i, integer);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!firstSend) {
|
||||||
|
if (intUpdates.equals(model.getEntityTask().getLastIntSet())) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
model.getEntityTask().getLastIntSet().clear();
|
||||||
|
model.getEntityTask().getLastIntSet().putAll(intUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.getConfigManager().getConfig().getBoolean("options.debug")) plugin.getLogger().info(animUpdates.toString());
|
||||||
|
|
||||||
|
List<String> list = new ArrayList<>(boneUpdates.keySet());
|
||||||
|
Collections.sort(list);
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendIntProperties(player, entity, intUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String unstripName(RenderedBone bone) {
|
||||||
|
@NotNull String name = bone.name().rawName();
|
||||||
|
|
||||||
|
if (name.equals("head")) {
|
||||||
|
if (!bone.getChildren().isEmpty()) return "hi_" + name;
|
||||||
|
return "h_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processBone(BetterModelEntityData entityData, RenderedBone bone, Map<String, Boolean> map) {
|
||||||
|
String name = unstripName(bone).toLowerCase();
|
||||||
|
if (name.equals("hitbox") || name.equals("shadow") || name.equals("mount") || name.startsWith("p_") || name.startsWith("b_") || name.startsWith("ob_")) return;
|
||||||
|
|
||||||
|
for (RenderedBone renderedBone : bone.getChildren().values()) {
|
||||||
|
processBone(entityData, renderedBone, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderedBone activeBone = entityData.getTracker().bone(bone.name());
|
||||||
|
|
||||||
|
ModelDisplay modelDisplay = activeBone.getDisplay();
|
||||||
|
if (modelDisplay == null) return;
|
||||||
|
boolean visible = activeBone.getDisplay().invisible();
|
||||||
|
|
||||||
|
map.put(name, visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.propertyhandler;
|
||||||
|
|
||||||
|
import com.ticxo.modelengine.api.animation.BlueprintAnimation;
|
||||||
|
import com.ticxo.modelengine.api.animation.handler.AnimationHandler;
|
||||||
|
import com.ticxo.modelengine.api.generator.blueprint.BlueprintBone;
|
||||||
|
import com.ticxo.modelengine.api.model.bone.ModelBone;
|
||||||
|
import com.ticxo.modelengine.api.model.render.DisplayRenderer;
|
||||||
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.joml.Vector3fc;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
|
||||||
|
import re.imc.geysermodelengine.util.BooleanPacker;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ModelEnginePropertyHandler implements PropertyHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
public ModelEnginePropertyHandler(GeyserModelEngine plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendScale(EntityData modelData, Collection<Player> players, float lastScale, boolean firstSend) {
|
||||||
|
try {
|
||||||
|
if (players.isEmpty()) return;
|
||||||
|
|
||||||
|
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) modelData;
|
||||||
|
|
||||||
|
Vector3fc scale = modelEngineEntityData.getActiveModel().getScale();
|
||||||
|
|
||||||
|
float average = (scale.x() + scale.y() + scale.z()) / 3;
|
||||||
|
|
||||||
|
if (!firstSend) {
|
||||||
|
if (average == lastScale) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendCustomScale(player, modelEngineEntityData.getEntity().getEntityId(), average);
|
||||||
|
}
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendColor(EntityData entityData, Collection<Player> players, Color lastColor, boolean firstSend) {
|
||||||
|
if (players.isEmpty()) return;
|
||||||
|
|
||||||
|
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) entityData;
|
||||||
|
|
||||||
|
Color color = new Color(modelEngineEntityData.getActiveModel().getDefaultTint().asARGB());
|
||||||
|
if (modelEngineEntityData.getActiveModel().isMarkedHurt()) color = new Color(modelEngineEntityData.getActiveModel().getDamageTint().asARGB());
|
||||||
|
|
||||||
|
if (firstSend) {
|
||||||
|
if (color.equals(lastColor)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendCustomColor(player, modelEngineEntityData.getEntity().getEntityId(), color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendHitBox(EntityData entityData, Player player) {
|
||||||
|
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) entityData;
|
||||||
|
|
||||||
|
float w = 0;
|
||||||
|
|
||||||
|
if (modelEngineEntityData.getActiveModel().isShadowVisible()) {
|
||||||
|
if (modelEngineEntityData.getActiveModel().getModelRenderer() instanceof DisplayRenderer displayRenderer) {
|
||||||
|
// w = displayRenderer.getHitbox().getShadowRadius().get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EntityUtils.sendCustomHitBox(player, modelEngineEntityData.getEntity().getEntityId(), 0.02f, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateEntityProperties(EntityData entityData, Collection<Player> players, boolean firstSend, String... forceAnims) {
|
||||||
|
ModelEngineEntityData model = (ModelEngineEntityData) entityData;
|
||||||
|
|
||||||
|
int entity = model.getEntity().getEntityId();
|
||||||
|
Set<String> forceAnimSet = Set.of(forceAnims);
|
||||||
|
|
||||||
|
Map<String, Boolean> boneUpdates = new HashMap<>();
|
||||||
|
Map<String, Boolean> animUpdates = new HashMap<>();
|
||||||
|
Set<String> anims = new HashSet<>();
|
||||||
|
|
||||||
|
model.getActiveModel().getBlueprint().getBones().forEach((s, bone) -> processBone(model, bone, boneUpdates));
|
||||||
|
|
||||||
|
AnimationHandler handler = model.getActiveModel().getAnimationHandler();
|
||||||
|
Set<String> priority = model.getActiveModel().getBlueprint().getAnimationDescendingPriority();
|
||||||
|
for (String animId : priority) {
|
||||||
|
if (handler.isPlayingAnimation(animId)) {
|
||||||
|
BlueprintAnimation anim = model.getActiveModel().getBlueprint().getAnimations().get(animId);
|
||||||
|
|
||||||
|
anims.add(animId);
|
||||||
|
if (anim.isOverride() && anim.getLoopMode() == BlueprintAnimation.LoopMode.ONCE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String id : priority) {
|
||||||
|
if (anims.contains(id)) {
|
||||||
|
animUpdates.put(id, true);
|
||||||
|
} else {
|
||||||
|
animUpdates.put(id, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> lastPlayed = new HashSet<>(model.getEntityTask().getLastPlayedAnim().asMap().keySet());
|
||||||
|
|
||||||
|
for (Map.Entry<String, Boolean> anim : animUpdates.entrySet()) {
|
||||||
|
if (anim.getValue()) {
|
||||||
|
model.getEntityTask().getLastPlayedAnim().put(anim.getKey(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String anim : lastPlayed) animUpdates.put(anim, true);
|
||||||
|
|
||||||
|
if (boneUpdates.isEmpty() && animUpdates.isEmpty()) return;
|
||||||
|
|
||||||
|
Map<String, Integer> intUpdates = new HashMap<>();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (Integer integer : BooleanPacker.mapBooleansToInts(boneUpdates)) {
|
||||||
|
intUpdates.put(plugin.getConfigManager().getConfig().getString("models.namespace") + ":bone" + i, integer);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for (Integer integer : BooleanPacker.mapBooleansToInts(animUpdates)) {
|
||||||
|
intUpdates.put(plugin.getConfigManager().getConfig().getString("models.namespace") + ":anim" + i, integer);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!firstSend) {
|
||||||
|
if (intUpdates.equals(model.getEntityTask().getLastIntSet())) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
model.getEntityTask().getLastIntSet().clear();
|
||||||
|
model.getEntityTask().getLastIntSet().putAll(intUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.getConfigManager().getConfig().getBoolean("options.debug")) plugin.getLogger().info(animUpdates.toString());
|
||||||
|
|
||||||
|
List<String> list = new ArrayList<>(boneUpdates.keySet());
|
||||||
|
Collections.sort(list);
|
||||||
|
|
||||||
|
for (Player player : players) {
|
||||||
|
EntityUtils.sendIntProperties(player, entity, intUpdates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String unstripName(BlueprintBone bone) {
|
||||||
|
String name = bone.getName();
|
||||||
|
if (bone.getBehaviors().get("head") != null) {
|
||||||
|
if (!bone.getBehaviors().get("head").isEmpty()) return "hi_" + name;
|
||||||
|
return "h_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processBone(ModelEngineEntityData model, BlueprintBone bone, Map<String, Boolean> map) {
|
||||||
|
String name = unstripName(bone).toLowerCase();
|
||||||
|
if (name.equals("hitbox") || name.equals("shadow") || name.equals("mount") || name.startsWith("p_") || name.startsWith("b_") || name.startsWith("ob_")) return;
|
||||||
|
|
||||||
|
for (BlueprintBone blueprintBone : bone.getChildren().values()) {
|
||||||
|
processBone(model, blueprintBone, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelBone activeBone = model.getActiveModel().getBones().get(bone.getName());
|
||||||
|
|
||||||
|
boolean visible = false;
|
||||||
|
if (activeBone != null) visible = activeBone.isVisible();
|
||||||
|
|
||||||
|
map.put(name, visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.propertyhandler;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public interface PropertyHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends scale of the entity to the player
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param players Collection of players from the entity view
|
||||||
|
* @param lastScale Sends the last scale to the player
|
||||||
|
* @param firstSend Checks if it's the first time to send scale to the player
|
||||||
|
*/
|
||||||
|
void sendScale(EntityData entityData, Collection<Player> players, float lastScale, boolean firstSend);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a colour tint to the player
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param players Collection of players from the entity view
|
||||||
|
* @param lastColor Sends the last colour to the player
|
||||||
|
* @param firstSend Checks if it's the first time to send colour to the player
|
||||||
|
*/
|
||||||
|
void sendColor(EntityData entityData, Collection<Player> players, Color lastColor, boolean firstSend);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a hitbox to the player
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param player Sends the player the entity hitbox
|
||||||
|
*/
|
||||||
|
void sendHitBox(EntityData entityData, Player player);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the entity to all viewable players
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param players Collection of players from the entity view
|
||||||
|
* @param firstSend Checks if it's the first time to send the entity to the player
|
||||||
|
* @param forceAnims Forces the entity to do an animation
|
||||||
|
*/
|
||||||
|
void updateEntityProperties(EntityData entityData, Collection<Player> players, boolean firstSend, String... forceAnims);
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.taskshandler;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import kr.toxicity.model.api.tracker.Tracker;
|
||||||
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.BetterModelEntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class BetterModelTaskHandler implements TaskHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
private final BetterModelEntityData entityData;
|
||||||
|
|
||||||
|
private int tick = 0;
|
||||||
|
private int syncTick = 0;
|
||||||
|
|
||||||
|
private float lastScale = -1.0f;
|
||||||
|
private Color lastColor = null;
|
||||||
|
|
||||||
|
private boolean removed = false;
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, Integer> lastIntSet = new ConcurrentHashMap<>();
|
||||||
|
private final Cache<String, Boolean> lastPlayedAnim = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MILLISECONDS).build();
|
||||||
|
|
||||||
|
private ScheduledFuture scheduledFuture;
|
||||||
|
|
||||||
|
public BetterModelTaskHandler(GeyserModelEngine plugin, BetterModelEntityData entityData) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.entityData = entityData;
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().sendHitBoxToAll(entityData);
|
||||||
|
scheduledFuture = plugin.getSchedulerPool().scheduleAtFixedRate(this::runAsync, 0, 20, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runAsync() {
|
||||||
|
plugin.getEntityTaskManager().checkViewers(entityData, entityData.getViewers());
|
||||||
|
|
||||||
|
PacketEntity entity = entityData.getEntity();
|
||||||
|
if (entity.isDead()) return;
|
||||||
|
|
||||||
|
Set<Player> viewers = entityData.getViewers();
|
||||||
|
Entity entitySource = entityData.getEntitySource();
|
||||||
|
Tracker tracker = entityData.getTracker();
|
||||||
|
|
||||||
|
entityData.teleportToModel();
|
||||||
|
|
||||||
|
if (entitySource.isDead() || tracker.forRemoval()) {
|
||||||
|
removed = true;
|
||||||
|
entity.remove();
|
||||||
|
|
||||||
|
plugin.getModelManager().getEntitiesCache().remove(entitySource.getEntityId());
|
||||||
|
plugin.getModelManager().getModelEntitiesCache().remove(entitySource.getEntityId());
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tick % 5 == 0) {
|
||||||
|
if (tick % 40 == 0) {
|
||||||
|
for (Player viewer : Set.copyOf(viewers)) {
|
||||||
|
if (!plugin.getEntityTaskManager().canSee(viewer, entityData.getEntity())) {
|
||||||
|
viewers.remove(viewer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tick++;
|
||||||
|
if (tick > 400) {
|
||||||
|
tick = 0;
|
||||||
|
plugin.getEntityTaskManager().sendHitBoxToAll(entityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewers.isEmpty()) return;
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendScale(entityData, viewers, lastScale, false);
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendColor(entityData, viewers, lastColor, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEntityData(EntityData entityData, Player player, int delay) {
|
||||||
|
BetterModelEntityData betterModelEntityData = (BetterModelEntityData) entityData;
|
||||||
|
|
||||||
|
EntityUtils.setCustomEntity(player, betterModelEntityData.getEntity().getEntityId(), plugin.getConfigManager().getConfig().getString("models.namespace") + ":" + betterModelEntityData.getTracker().name().toLowerCase());
|
||||||
|
|
||||||
|
plugin.getSchedulerPool().schedule(() -> {
|
||||||
|
entityData.getEntity().sendSpawnPacket(Collections.singletonList(player));
|
||||||
|
|
||||||
|
plugin.getSchedulerPool().schedule(() -> {
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendHitBox(entityData, player);
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendScale(entityData, Collections.singleton(player), lastScale, true);
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendColor(entityData, Collections.singleton(player), lastColor, true);
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().updateEntityProperties(entityData, Collections.singleton(player), true);
|
||||||
|
}, 500, TimeUnit.MILLISECONDS);
|
||||||
|
}, delay * 50L, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
scheduledFuture.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTick(int tick) {
|
||||||
|
this.tick = tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSyncTick(int syncTick) {
|
||||||
|
this.syncTick = syncTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoved(boolean removed) {
|
||||||
|
this.removed = removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastScale(float lastScale) {
|
||||||
|
this.lastScale = lastScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTick() {
|
||||||
|
return tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSyncTick() {
|
||||||
|
return syncTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastColor(Color lastColor) {
|
||||||
|
this.lastColor = lastColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getLastScale() {
|
||||||
|
return lastScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getLastColor() {
|
||||||
|
return lastColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrentHashMap<String, Integer> getLastIntSet() {
|
||||||
|
return lastIntSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cache<String, Boolean> getLastPlayedAnim() {
|
||||||
|
return lastPlayedAnim;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduledFuture getScheduledFuture() {
|
||||||
|
return scheduledFuture;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.taskshandler;
|
||||||
|
|
||||||
|
import com.google.common.cache.Cache;
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.ticxo.modelengine.api.model.ActiveModel;
|
||||||
|
import com.ticxo.modelengine.api.model.ModeledEntity;
|
||||||
|
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
|
||||||
|
import re.imc.geysermodelengine.packet.entity.PacketEntity;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class ModelEngineTaskHandler implements TaskHandler {
|
||||||
|
|
||||||
|
private final GeyserModelEngine plugin;
|
||||||
|
|
||||||
|
private final ModelEngineEntityData entityData;
|
||||||
|
|
||||||
|
private int tick = 0;
|
||||||
|
private int syncTick = 0;
|
||||||
|
|
||||||
|
private float lastScale = -1.0f;
|
||||||
|
private Color lastColor = null;
|
||||||
|
|
||||||
|
private boolean removed = false;
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<String, Integer> lastIntSet = new ConcurrentHashMap<>();
|
||||||
|
private final Cache<String, Boolean> lastPlayedAnim = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MILLISECONDS).build();
|
||||||
|
|
||||||
|
private ScheduledFuture scheduledFuture;
|
||||||
|
|
||||||
|
public ModelEngineTaskHandler(GeyserModelEngine plugin, ModelEngineEntityData entityData) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
this.entityData = entityData;
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().sendHitBoxToAll(entityData);
|
||||||
|
scheduledFuture = plugin.getSchedulerPool().scheduleAtFixedRate(this::runAsync, 0, 20, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runAsync() {
|
||||||
|
plugin.getEntityTaskManager().checkViewers(entityData, entityData.getViewers());
|
||||||
|
|
||||||
|
PacketEntity entity = entityData.getEntity();
|
||||||
|
if (entity.isDead()) return;
|
||||||
|
|
||||||
|
entityData.teleportToModel();
|
||||||
|
|
||||||
|
Set<Player> viewers = entityData.getViewers();
|
||||||
|
ActiveModel activeModel = entityData.getActiveModel();
|
||||||
|
ModeledEntity modeledEntity = entityData.getModeledEntity();
|
||||||
|
|
||||||
|
if (activeModel.isDestroyed() || activeModel.isRemoved()) {
|
||||||
|
removed = true;
|
||||||
|
entity.remove();
|
||||||
|
|
||||||
|
plugin.getModelManager().getEntitiesCache().remove(modeledEntity.getBase().getEntityId());
|
||||||
|
plugin.getModelManager().getModelEntitiesCache().remove(modeledEntity.getBase().getEntityId());
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tick % 5 == 0) {
|
||||||
|
if (tick % 40 == 0) {
|
||||||
|
for (Player viewer : Set.copyOf(viewers)) {
|
||||||
|
if (!plugin.getEntityTaskManager().canSee(viewer, entityData.getEntity())) {
|
||||||
|
viewers.remove(viewer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tick ++;
|
||||||
|
if (tick > 400) {
|
||||||
|
tick = 0;
|
||||||
|
plugin.getEntityTaskManager().sendHitBoxToAll(entityData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewers.isEmpty()) return;
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendScale(entityData, viewers, lastScale, false);
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendColor(entityData, viewers, lastColor, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendEntityData(EntityData entityData, Player player, int delay) {
|
||||||
|
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) entityData;
|
||||||
|
|
||||||
|
EntityUtils.setCustomEntity(player, modelEngineEntityData.getEntity().getEntityId(), plugin.getConfigManager().getConfig().getString("models.namespace") + ":" + modelEngineEntityData.getActiveModel().getBlueprint().getName().toLowerCase());
|
||||||
|
|
||||||
|
plugin.getSchedulerPool().schedule(() -> {
|
||||||
|
entityData.getEntity().sendSpawnPacket(Collections.singletonList(player));
|
||||||
|
|
||||||
|
plugin.getSchedulerPool().schedule(() -> {
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendHitBox(entityData, player);
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendScale(entityData, Collections.singleton(player), lastScale, true);
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().sendColor(entityData, Collections.singleton(player), lastColor, true);
|
||||||
|
|
||||||
|
plugin.getEntityTaskManager().getPropertyHandler().updateEntityProperties(entityData, Collections.singleton(player), true);
|
||||||
|
}, 500, TimeUnit.MILLISECONDS);
|
||||||
|
}, delay * 50L, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
scheduledFuture.cancel(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTick(int tick) {
|
||||||
|
this.tick = tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSyncTick(int syncTick) {
|
||||||
|
this.syncTick = syncTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoved(boolean removed) {
|
||||||
|
this.removed = removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastScale(float lastScale) {
|
||||||
|
this.lastScale = lastScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTick() {
|
||||||
|
return tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSyncTick() {
|
||||||
|
return syncTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastColor(Color lastColor) {
|
||||||
|
this.lastColor = lastColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getLastScale() {
|
||||||
|
return lastScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getLastColor() {
|
||||||
|
return lastColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRemoved() {
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConcurrentHashMap<String, Integer> getLastIntSet() {
|
||||||
|
return lastIntSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cache<String, Boolean> getLastPlayedAnim() {
|
||||||
|
return lastPlayedAnim;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScheduledFuture getScheduledFuture() {
|
||||||
|
return scheduledFuture;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package re.imc.geysermodelengine.managers.model.taskshandler;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
|
||||||
|
public interface TaskHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs the entity scheduler
|
||||||
|
*/
|
||||||
|
void runAsync();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns the entity to the player
|
||||||
|
* @param entityData The data of the entity
|
||||||
|
* @param player Sends the entity to the player
|
||||||
|
* @param delay Delays sending the entity to the player
|
||||||
|
*/
|
||||||
|
void sendEntityData(EntityData entityData, Player player, int delay);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the entity scheduler
|
||||||
|
*/
|
||||||
|
void cancel();
|
||||||
|
}
|
||||||
@@ -58,7 +58,6 @@ public class PacketEntity {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
removed = true;
|
removed = true;
|
||||||
sendEntityDestroyPacket(viewers);
|
sendEntityDestroyPacket(viewers);
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
|||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.geysermc.floodgate.api.FloodgateApi;
|
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class BedrockMountControlRunnable implements Consumer<ScheduledTask> {
|
public class BedrockMountControlRunnable implements Consumer<ScheduledTask> {
|
||||||
@@ -24,8 +24,8 @@ public class BedrockMountControlRunnable implements Consumer<ScheduledTask> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(ScheduledTask scheduledTask) {
|
public void accept(ScheduledTask scheduledTask) {
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (UUID playerUUID : plugin.getModelManager().getPlayerJoinedCache()) {
|
||||||
if (!FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) continue;
|
Player player = Bukkit.getPlayer(playerUUID);
|
||||||
|
|
||||||
float pitch = player.getLocation().getPitch();
|
float pitch = player.getLocation().getPitch();
|
||||||
Pair<ActiveModel, Mount> seat = plugin.getModelManager().getDriversCache().get(player.getUniqueId());
|
Pair<ActiveModel, Mount> seat = plugin.getModelManager().getDriversCache().get(player.getUniqueId());
|
||||||
|
|||||||
@@ -1,268 +0,0 @@
|
|||||||
package re.imc.geysermodelengine.runnables;
|
|
||||||
|
|
||||||
import com.google.common.cache.Cache;
|
|
||||||
import com.google.common.cache.CacheBuilder;
|
|
||||||
import com.ticxo.modelengine.api.animation.BlueprintAnimation;
|
|
||||||
import com.ticxo.modelengine.api.animation.handler.AnimationHandler;
|
|
||||||
import com.ticxo.modelengine.api.generator.blueprint.BlueprintBone;
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
|
||||||
import com.ticxo.modelengine.api.model.ModeledEntity;
|
|
||||||
import com.ticxo.modelengine.api.model.bone.ModelBone;
|
|
||||||
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
|
|
||||||
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.ScheduledFuture;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class EntityTaskRunnable {
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
private final ScheduledFuture scheduledFuture;
|
|
||||||
|
|
||||||
public EntityTaskRunnable(GeyserModelEngine plugin, ModelEntityData model) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
|
|
||||||
this.model = model;
|
|
||||||
|
|
||||||
plugin.getEntityTaskManager().sendHitBoxToAll(model);
|
|
||||||
|
|
||||||
scheduledFuture = plugin.getSchedulerPool().scheduleAtFixedRate(this::runAsync, 0, 20, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void runAsync() {
|
|
||||||
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());
|
|
||||||
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 cancel() {
|
|
||||||
scheduledFuture.cancel(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendEntityData(ModelEntityData model, Player player, int delay) {
|
|
||||||
EntityUtils.setCustomEntity(player, model.getEntity().getEntityId(), plugin.getConfigManager().getConfig().getString("namespace") + ":" + model.getActiveModel().getBlueprint().getName().toLowerCase());
|
|
||||||
|
|
||||||
plugin.getSchedulerPool().schedule(() -> {
|
|
||||||
model.getEntity().sendSpawnPacket(Collections.singletonList(player));
|
|
||||||
|
|
||||||
plugin.getSchedulerPool().schedule(() -> {
|
|
||||||
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(plugin.getConfigManager().getConfig().getString("namespace") + ":bone" + i, integer);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
for (Integer integer : booleanPacker.mapBooleansToInts(animUpdates)) {
|
|
||||||
intUpdates.put(plugin.getConfigManager().getConfig().getString("namespace") + ":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;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ScheduledFuture getScheduledFuture() {
|
|
||||||
return scheduledFuture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package re.imc.geysermodelengine.runnables;
|
package re.imc.geysermodelengine.runnables;
|
||||||
|
|
||||||
import com.ticxo.modelengine.api.model.ActiveModel;
|
|
||||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||||
import re.imc.geysermodelengine.GeyserModelEngine;
|
import re.imc.geysermodelengine.GeyserModelEngine;
|
||||||
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
|
import re.imc.geysermodelengine.managers.model.entity.EntityData;
|
||||||
|
import re.imc.geysermodelengine.managers.model.model.Model;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
@@ -19,8 +19,8 @@ public class UpdateTaskRunnable implements Consumer<ScheduledTask> {
|
|||||||
@Override
|
@Override
|
||||||
public void accept(ScheduledTask scheduledTask) {
|
public void accept(ScheduledTask scheduledTask) {
|
||||||
try {
|
try {
|
||||||
for (Map<ActiveModel, ModelEntityData> models : plugin.getModelManager().getEntitiesCache().values()) {
|
for (Map<Model, EntityData> models : plugin.getModelManager().getEntitiesCache().values()) {
|
||||||
models.values().forEach(model -> model.getEntityTask().updateEntityProperties(model, model.getViewers(), false));
|
models.values().forEach(entityData -> plugin.getEntityTaskManager().getPropertyHandler().updateEntityProperties(entityData, entityData.getViewers(), false));
|
||||||
}
|
}
|
||||||
} catch (Throwable err) {
|
} catch (Throwable err) {
|
||||||
throw new RuntimeException(err);
|
throw new RuntimeException(err);
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class BooleanPacker {
|
public class BooleanPacker {
|
||||||
|
|
||||||
private final int MAX_BOOLEANS = 24;
|
private static final int MAX_BOOLEANS = 24;
|
||||||
|
|
||||||
public int booleansToInt(List<Boolean> booleans) {
|
public static int booleansToInt(List<Boolean> booleans) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ public class BooleanPacker {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int mapBooleansToInt(Map<String, Boolean> booleanMap) {
|
public static int mapBooleansToInt(Map<String, Boolean> booleanMap) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ public class BooleanPacker {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> booleansToInts(List<Boolean> booleans) {
|
public static List<Integer> booleansToInts(List<Boolean> booleans) {
|
||||||
List<Integer> results = new ArrayList<>();
|
List<Integer> results = new ArrayList<>();
|
||||||
int result = 0;
|
int result = 0;
|
||||||
int i = 1;
|
int i = 1;
|
||||||
@@ -62,7 +62,7 @@ public class BooleanPacker {
|
|||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Integer> mapBooleansToInts(Map<String, Boolean> booleanMap) {
|
public static List<Integer> mapBooleansToInts(Map<String, Boolean> booleanMap) {
|
||||||
List<String> keys = new ArrayList<>(booleanMap.keySet());
|
List<String> keys = new ArrayList<>(booleanMap.keySet());
|
||||||
List<Boolean> booleans = new ArrayList<>();
|
List<Boolean> booleans = new ArrayList<>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
|
metrics:
|
||||||
bstats: true
|
bstats: true
|
||||||
|
|
||||||
|
models:
|
||||||
namespace: "modelengine"
|
namespace: "modelengine"
|
||||||
data-send-delay: 5
|
data-send-delay: 5
|
||||||
entity-view-distance: 50
|
entity-view-distance: 50
|
||||||
join-send-delay: 20
|
join-send-delay: 20
|
||||||
entity-position-update-period: 35
|
entity-position-update-period: 35
|
||||||
thread-pool-size: 4
|
thread-pool-size: 4
|
||||||
model-entity-type: BAT # must be a living entity
|
|
||||||
enable-part-visibility-models:
|
|
||||||
- example
|
|
||||||
|
|
||||||
|
options:
|
||||||
debug: false
|
debug: false
|
||||||
@@ -16,7 +16,9 @@ dependencies:
|
|||||||
required: true
|
required: true
|
||||||
packetevents:
|
packetevents:
|
||||||
required: true
|
required: true
|
||||||
ModelEngine:
|
|
||||||
required: true
|
|
||||||
floodgate:
|
floodgate:
|
||||||
required: true
|
required: true
|
||||||
|
ModelEngine:
|
||||||
|
required: false
|
||||||
|
BetterModel:
|
||||||
|
required: false
|
||||||
Reference in New Issue
Block a user