pushing beta to github

This commit is contained in:
xSquishyLiam
2025-09-09 23:41:26 +01:00
parent 8e36bf2829
commit ae3b67a733
31 changed files with 985 additions and 569 deletions

78
.idea/workspace.xml generated
View File

@@ -5,34 +5,31 @@
</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 afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/BetterModelListener.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/taskshandler/BetterModelTaskHandler.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/ModelEngineListener.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/taskshandler/ModelEngineTaskHandler.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/BetterModelEntityData.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/taskshandler/TaskHandler.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/EntityData.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/BetterModelModel.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/Model.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/ModelEngineModel.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/modelhandler/BetterModelHandler.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/modelhandler/ModelEngineHandler.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/modelhandler/ModelHandler.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/propertyhandler/BetterModelPropertyHandler.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/propertyhandler/ModelEnginePropertyHandler.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/propertyhandler/PropertyHandler.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_rebase_[Changes]/shelved.patch" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_rebase_[Changes]1/shelved.patch" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_rebase__Changes_.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_rebase__Changes_1.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle.kts" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/BetterModelListener.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/BetterModelListener.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/ModelEngineListener.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/ModelEngineListener.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/commands/CommandManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/commands/CommandManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/EntityTaskManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/EntityTaskManager.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/EntityTaskManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/EntityTaskManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/ModelManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/ModelManager.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/ModelManager.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/ModelManager.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/ModelEngineEntityData.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/BetterModelEntityData.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/BetterModelEntityData.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/EntityData.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/EntityData.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/ModelEngineEntityData.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/entity/ModelEngineEntityData.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/BetterModelModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/BetterModelModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/Model.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/Model.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/ModelEngineModel.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/model/ModelEngineModel.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/modelhandler/BetterModelHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/ModelHandler/BetterModelHandler.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/modelhandler/ModelEngineHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/ModelHandler/ModelEngineHandler.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/modelhandler/ModelHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/ModelHandler/ModelHandler.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/propertyhandler/BetterModelPropertyHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/PropertyHandler/BetterModelPropertyHandler.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/propertyhandler/ModelEnginePropertyHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/PropertyHandler/ModelEnginePropertyHandler.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/propertyhandler/PropertyHandler.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/managers/model/PropertyHandler/PropertyHandler.java" afterDir="false" />
<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" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/runnables/UpdateTaskRunnable.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/runnables/UpdateTaskRunnable.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/runnables/UpdateTaskRunnable.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/runnables/UpdateTaskRunnable.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/util/BooleanPacker.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/re/imc/geysermodelengine/util/BooleanPacker.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/main/resources/paper-plugin.yml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/paper-plugin.yml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/main/resources/paper-plugin.yml" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/resources/paper-plugin.yml" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
@@ -105,25 +102,26 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent">{
"keyToString": { &quot;keyToString&quot;: {
"Gradle.Download Sources.executor": "Run", &quot;Gradle.Build GeyserModelEngine.executor&quot;: &quot;Run&quot;,
"Gradle.GeyserModelEngine [build].executor": "Run", &quot;Gradle.Download Sources.executor&quot;: &quot;Run&quot;,
"Gradle.GeyserModelEngine [jar].executor": "Run", &quot;Gradle.GeyserModelEngine [build].executor&quot;: &quot;Run&quot;,
"Maven.GeyserModelEngine [install...].executor": "Run", &quot;Gradle.GeyserModelEngine [jar].executor&quot;: &quot;Run&quot;,
"Maven.GeyserModelEngine [install].executor": "Run", &quot;Maven.GeyserModelEngine [install...].executor&quot;: &quot;Run&quot;,
"ModuleVcsDetector.initialDetectionPerformed": "true", &quot;Maven.GeyserModelEngine [install].executor&quot;: &quot;Run&quot;,
"RunOnceActivity.ShowReadmeOnStart": "true", &quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;,
"RunOnceActivity.git.unshallow": "true", &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
"git-widget-placeholder": "bettermodel-support-dev", &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
"kotlin-language-version-configured": "true", &quot;git-widget-placeholder&quot;: &quot;bettermodel-support-dev&quot;,
"last_opened_file_path": "D:/Coding/Forks/Minecraft/GeyserModelEngine", &quot;kotlin-language-version-configured&quot;: &quot;true&quot;,
"project.structure.last.edited": "Project", &quot;last_opened_file_path&quot;: &quot;D:/Coding/Forks/Minecraft/GeyserModelEngine&quot;,
"project.structure.proportion": "0.0", &quot;project.structure.last.edited&quot;: &quot;Project&quot;,
"project.structure.side.proportion": "0.2", &quot;project.structure.proportion&quot;: &quot;0.0&quot;,
"settings.editor.selected.configurable": "reference.settings.project.maven.runner" &quot;project.structure.side.proportion&quot;: &quot;0.2&quot;,
&quot;settings.editor.selected.configurable&quot;: &quot;reference.settings.project.maven.runner&quot;
} }
}]]></component> }</component>
<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" />

View File

@@ -53,10 +53,9 @@ public class GeyserModelEngine extends JavaPlugin {
@Override @Override
public void onDisable() { public void onDisable() {
this.modelManager.removeEntities();
PacketEvents.getAPI().terminate(); PacketEvents.getAPI().terminate();
this.modelManager.getModelHandler().removeEntities(this);
CommandAPI.onDisable(); CommandAPI.onDisable();
} }

View File

@@ -1,7 +1,9 @@
package re.imc.geysermodelengine.listener; package re.imc.geysermodelengine.listener;
import kr.toxicity.model.api.event.CreateTrackerEvent; import kr.toxicity.model.api.event.CreateEntityTrackerEvent;
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 re.imc.geysermodelengine.GeyserModelEngine; import re.imc.geysermodelengine.GeyserModelEngine;
@@ -13,8 +15,8 @@ public class BetterModelListener implements Listener {
this.plugin = plugin; this.plugin = plugin;
} }
@EventHandler @EventHandler(priority = EventPriority.MONITOR)
public void onModelSpawn(CreateTrackerEvent event) { public void onModelSpawn(CreateEntityTrackerEvent event) {
plugin.getLogger().info(event.getTracker().name()); plugin.getModelManager().getModelHandler().createModel(event.sourceEntity(), event.getTracker());
} }
} }

View File

@@ -26,7 +26,7 @@ public class ModelEngineListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onAddModel(AddModelEvent event) { public void onAddModel(AddModelEvent event) {
if (event.isCancelled()) return; if (event.isCancelled()) return;
plugin.getModelManager().getModelHandler().createModel(plugin, event.getTarget(), event.getModel()); plugin.getModelManager().getModelHandler().createModel(event.getTarget(), event.getModel());
} }
// Needs Testing // Needs Testing

View File

@@ -26,12 +26,12 @@ public class ModelListener implements Listener {
@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().getModelHandler().processEntities(plugin, entity)); world.getEntities().forEach(entity -> plugin.getModelManager().getModelHandler().processEntities(entity));
} }
/* /*
/ xSquishyLiam: / xSquishyLiam:
/ A runDelay make sures the client doesn't see pigs on login due to the client resyncing themselves back to normal / A runDelay makes sure the client doesn't see pigs on login due to the client resyncing themselves back to normal
*/ */
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {

View File

@@ -1,9 +1,7 @@
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;
@@ -11,12 +9,12 @@ import org.bukkit.entity.Player;
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.entity.EntityData; import re.imc.geysermodelengine.managers.model.entity.EntityData;
import re.imc.geysermodelengine.managers.model.propertyhandler.BetterModelPropertyHandler; import re.imc.geysermodelengine.managers.model.PropertyHandler.BetterModelPropertyHandler;
import re.imc.geysermodelengine.managers.model.propertyhandler.ModelEnginePropertyHandler; import re.imc.geysermodelengine.managers.model.PropertyHandler.ModelEnginePropertyHandler;
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler; import re.imc.geysermodelengine.managers.model.PropertyHandler.PropertyHandler;
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData; 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.util.*; import java.util.*;
@@ -30,10 +28,10 @@ public class EntityTaskManager {
this.plugin = plugin; this.plugin = plugin;
if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) { if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) {
this.propertyHandler = new ModelEnginePropertyHandler(); this.propertyHandler = new ModelEnginePropertyHandler(plugin);
plugin.getLogger().info("Using ModelEngine property handler!"); plugin.getLogger().info("Using ModelEngine property handler!");
} else if (Bukkit.getPluginManager().getPlugin("BetterModel") != null) { } else if (Bukkit.getPluginManager().getPlugin("BetterModel") != null) {
this.propertyHandler = new BetterModelPropertyHandler(); this.propertyHandler = new BetterModelPropertyHandler(plugin);
plugin.getLogger().info("Using BetterModel property handler!"); plugin.getLogger().info("Using BetterModel property handler!");
} else { } else {
plugin.getLogger().severe("No supported model engine found!"); plugin.getLogger().severe("No supported model engine found!");
@@ -41,16 +39,6 @@ public class EntityTaskManager {
} }
} }
public String unstripName(BlueprintBone bone) {
String name = bone.getName();
if (bone.getBehaviors().get("head") != null) {
if (!bone.getBehaviors().get("head").isEmpty()) return "hi_" + name;
return "h_" + name;
}
return name;
}
public void checkViewers(EntityData model, Set<Player> viewers) { public void checkViewers(EntityData 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;
@@ -70,13 +58,13 @@ public class EntityTaskManager {
} }
private void sendSpawnPacket(EntityData 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((ModelEngineEntityData) model, onlinePlayer, plugin.getConfigManager().getConfig().getInt("join-send-delay") / 50); task.sendEntityData(model, onlinePlayer, plugin.getConfigManager().getConfig().getInt("join-send-delay") / 50);
} else { } else {
task.sendEntityData((ModelEngineEntityData) model, onlinePlayer, 5); task.sendEntityData(model, onlinePlayer, 5);
} }
} }
@@ -95,24 +83,13 @@ public class EntityTaskManager {
return true; return true;
} }
public void sendHitBoxToAll(ModelEngineEntityData 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(ModelEngineEntityData model, Player viewer) { //TODO move this
float w = 0;
if (model.getActiveModel().isShadowVisible()) {
if (model.getActiveModel().getModelRenderer() instanceof DisplayRenderer displayRenderer) {
// w = displayRenderer.getHitbox().getShadowRadius().get();
}
}
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.02f, w);
}
public boolean hasAnimation(ModelEngineEntityData model, String animation) { public boolean hasAnimation(ModelEngineEntityData 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);

View File

@@ -0,0 +1,63 @@
package re.imc.geysermodelengine.managers.model.ModelHandler;
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;
}
// Why do you dupe smhhhh
@Override
public void createModel(Object... objects) {
Entity entitySource = (Entity) objects[0];
Tracker tracker = (Tracker) objects[1];
int entityID = entitySource.getEntityId();
PropertyHandler propertyHandler = plugin.getEntityTaskManager().getPropertyHandler();
EntityData entityData = new BetterModelEntityData(plugin, entitySource, tracker);
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);
}
}

View File

@@ -1,9 +1,8 @@
package re.imc.geysermodelengine.managers.model.modelhandler; package re.imc.geysermodelengine.managers.model.ModelHandler;
import com.ticxo.modelengine.api.ModelEngineAPI; 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.ModeledEntity;
import kr.toxicity.model.api.data.raw.ModelData;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import re.imc.geysermodelengine.GeyserModelEngine; import re.imc.geysermodelengine.GeyserModelEngine;
@@ -12,7 +11,7 @@ import re.imc.geysermodelengine.managers.model.entity.EntityData;
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData; import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
import re.imc.geysermodelengine.managers.model.model.Model; import re.imc.geysermodelengine.managers.model.model.Model;
import re.imc.geysermodelengine.managers.model.model.ModelEngineModel; import re.imc.geysermodelengine.managers.model.model.ModelEngineModel;
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler; import re.imc.geysermodelengine.managers.model.PropertyHandler.PropertyHandler;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@@ -20,10 +19,18 @@ import java.util.Optional;
public class ModelEngineHandler implements ModelHandler { public class ModelEngineHandler implements ModelHandler {
//TODO move driver hashmap here
private final GeyserModelEngine plugin;
public ModelEngineHandler(GeyserModelEngine plugin) {
this.plugin = plugin;
}
@Override @Override
public void createModel(GeyserModelEngine plugin, Object modeledEntity, Object activeModel) { public void createModel(Object... objects) {
ModeledEntity megEntity = (ModeledEntity) modeledEntity; ModeledEntity megEntity = (ModeledEntity) objects[0];
ActiveModel megActiveModel = (ActiveModel) activeModel; ActiveModel megActiveModel = (ActiveModel) objects[1];
int entityID = megEntity.getBase().getEntityId(); int entityID = megEntity.getBase().getEntityId();
@@ -35,7 +42,7 @@ public class ModelEngineHandler implements ModelHandler {
Map<Model, EntityData> entityDataCache = plugin.getModelManager().getEntitiesCache().computeIfAbsent(entityID, k -> new HashMap<>()); Map<Model, EntityData> entityDataCache = plugin.getModelManager().getEntitiesCache().computeIfAbsent(entityID, k -> new HashMap<>());
for (Map.Entry<Model, EntityData> entry : entityDataCache.entrySet()) { for (Map.Entry<Model, EntityData> entry : entityDataCache.entrySet()) {
if (entry.getKey() != model && entry.getKey().getName().equals(megActiveModel.getBlueprint().getName())) { if (entry.getKey() != model && entry.getKey().getName().equals(megActiveModel.getBlueprint().getName())) {
return; return;
} }
} }
@@ -45,25 +52,18 @@ public class ModelEngineHandler implements ModelHandler {
} }
@Override @Override
public void processEntities(GeyserModelEngine plugin, Entity entity) { public void processEntities(Entity entity) {
if (plugin.getModelManager().getEntitiesCache().containsKey(entity.getEntityId())) return; if (plugin.getModelManager().getEntitiesCache().containsKey(entity.getEntityId())) return;
ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity); ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity);
if (modeledEntity == null) return; if (modeledEntity == null) return;
Optional<ActiveModel> model = modeledEntity.getModels().values().stream().findFirst(); Optional<ActiveModel> model = modeledEntity.getModels().values().stream().findFirst();
model.ifPresent(m -> createModel(plugin, modeledEntity, m)); model.ifPresent(m -> createModel(modeledEntity, m));
} }
@Override @Override
public void removeEntities(GeyserModelEngine plugin) { public void loadListeners() {
for (Map<Model, EntityData> entities : plugin.getModelManager().getEntitiesCache().values()) {
entities.forEach((model, modelEntity) -> modelEntity.getEntity().remove());
}
}
@Override
public void loadListeners(GeyserModelEngine plugin) {
Bukkit.getPluginManager().registerEvents(new ModelEngineListener(plugin), plugin); Bukkit.getPluginManager().registerEvents(new ModelEngineListener(plugin), plugin);
} }
} }

View File

@@ -0,0 +1,12 @@
package re.imc.geysermodelengine.managers.model.ModelHandler;
import org.bukkit.entity.Entity;
public interface ModelHandler {
void createModel(Object... objects);
void processEntities(Entity entity);
void loadListeners();
}

View File

@@ -7,9 +7,9 @@ import org.bukkit.Bukkit;
import re.imc.geysermodelengine.GeyserModelEngine; import re.imc.geysermodelengine.GeyserModelEngine;
import re.imc.geysermodelengine.managers.model.entity.EntityData; import re.imc.geysermodelengine.managers.model.entity.EntityData;
import re.imc.geysermodelengine.managers.model.model.Model; import re.imc.geysermodelengine.managers.model.model.Model;
import re.imc.geysermodelengine.managers.model.modelhandler.BetterModelHandler; import re.imc.geysermodelengine.managers.model.ModelHandler.BetterModelHandler;
import re.imc.geysermodelengine.managers.model.modelhandler.ModelEngineHandler; import re.imc.geysermodelengine.managers.model.ModelHandler.ModelEngineHandler;
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler; import re.imc.geysermodelengine.managers.model.ModelHandler.ModelHandler;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -32,10 +32,10 @@ public class ModelManager {
this.plugin = plugin; this.plugin = plugin;
if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) { if (Bukkit.getPluginManager().getPlugin("ModelEngine") != null) {
this.modelHandler = new ModelEngineHandler(); this.modelHandler = new ModelEngineHandler(plugin);
plugin.getLogger().info("Using ModelEngine handler!"); plugin.getLogger().info("Using ModelEngine handler!");
} else if (Bukkit.getPluginManager().getPlugin("BetterModel") != null) { } else if (Bukkit.getPluginManager().getPlugin("BetterModel") != null) {
this.modelHandler = new BetterModelHandler(); this.modelHandler = new BetterModelHandler(plugin);
plugin.getLogger().info("Using BetterModel handler!"); plugin.getLogger().info("Using BetterModel handler!");
} else { } else {
plugin.getLogger().severe("No supported model engine found!"); plugin.getLogger().severe("No supported model engine found!");
@@ -43,7 +43,13 @@ public class ModelManager {
return; return;
} }
modelHandler.loadListeners(plugin); modelHandler.loadListeners();
}
public void removeEntities() {
for (Map<Model, EntityData> entities : entitiesCache.values()) {
entities.forEach((model, modelEntity) -> modelEntity.getEntity().remove());
}
} }
public ModelHandler getModelHandler() { public ModelHandler getModelHandler() {

View File

@@ -0,0 +1,155 @@
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;
}
// Other question is how am I meant to get the scale??
@Override
public void sendScale(EntityData entityData, Collection<Player> players, float lastScale, boolean firstSend) {
}
// Now real question how do I get the tint?
@Override
public void sendColor(EntityData entityData, Collection<Player> players, Color lastColor, boolean firstSend) {
}
@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().animationMap().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()) {
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("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(model.getEntityTask().getLastIntSet())) {
return;
} else {
model.getEntityTask().getLastIntSet().clear();
model.getEntityTask().getLastIntSet().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);
}
}
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);
}
}

View File

@@ -0,0 +1,196 @@
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.ActiveModel;
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.lang.reflect.Method;
import java.util.*;
import java.util.List;
public class ModelEnginePropertyHandler implements PropertyHandler {
private final GeyserModelEngine plugin;
private final Method scaleMethod;
public ModelEnginePropertyHandler(GeyserModelEngine plugin) {
this.plugin = plugin;
try {
this.scaleMethod = ActiveModel.class.getMethod("getScale");
} catch (NoSuchMethodException err) {
throw new RuntimeException(err);
}
}
@Override
public void sendScale(EntityData modelData, Collection<Player> players, float lastScale, boolean firstSend) {
try {
if (players.isEmpty()) return;
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) modelData;
Vector3fc scale = (Vector3fc) scaleMethod.invoke(modelEngineEntityData.getActiveModel());
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("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(model.getEntityTask().getLastIntSet())) {
return;
} else {
model.getEntityTask().getLastIntSet().clear();
model.getEntityTask().getLastIntSet().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);
}
}
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);
}
}

View File

@@ -0,0 +1,16 @@
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 {
void sendScale(EntityData entityData, Collection<Player> players, float lastScale, boolean firstSend);
void sendColor(EntityData entityData, Collection<Player> players, Color lastColor, boolean firstSend);
void sendHitBox(EntityData entityData, Player player);
void updateEntityProperties(EntityData entityData, Collection<Player> players, boolean firstSend, String... forceAnims);
}

View File

@@ -1,4 +1,69 @@
package re.imc.geysermodelengine.managers.model.entity; package re.imc.geysermodelengine.managers.model.entity;
public class BetterModelEntityData { import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.google.common.collect.Sets;
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 BetterModelTaskHandler entityTask;
public BetterModelEntityData(GeyserModelEngine plugin, Entity entitySource, Tracker tracker) {
this.plugin = plugin;
this.entitySource = entitySource;
this.tracker = tracker;
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 Entity getEntitySource() {
return entitySource;
}
public Tracker getTracker() {
return tracker;
}
} }

View File

@@ -1,20 +1,17 @@
package re.imc.geysermodelengine.managers.model.entity; package re.imc.geysermodelengine.managers.model.entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import re.imc.geysermodelengine.managers.model.model.Model; 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.util.Set; import java.util.Set;
public interface EntityData { public interface EntityData {
void teleportToModel();
PacketEntity getEntity(); PacketEntity getEntity();
Set<Player> getViewers(); Set<Player> getViewers();
void teleportToModel(); TaskHandler getEntityTask();
void remove();
EntityTaskRunnable getEntityTask();
} }

View File

@@ -7,9 +7,8 @@ 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.model.Model; 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;
@@ -18,14 +17,12 @@ public class ModelEngineEntityData implements EntityData {
private final GeyserModelEngine plugin; private final GeyserModelEngine plugin;
private final 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 ModelEngineEntityData(GeyserModelEngine plugin, ModeledEntity modeledEntity, ActiveModel activeModel) { public ModelEngineEntityData(GeyserModelEngine plugin, ModeledEntity modeledEntity, ActiveModel activeModel) {
this.plugin = plugin; this.plugin = plugin;
@@ -44,7 +41,7 @@ public class ModelEngineEntityData implements EntityData {
} }
public void runEntityTask() { public void runEntityTask() {
entityTask = new EntityTaskRunnable(plugin, this); entityTask = new ModelEngineTaskHandler(plugin, this);
} }
@Override @Override
@@ -58,12 +55,7 @@ public class ModelEngineEntityData implements EntityData {
} }
@Override @Override
public void remove() { public ModelEngineTaskHandler getEntityTask() {
}
@Override
public EntityTaskRunnable getEntityTask() {
return entityTask; return entityTask;
} }

View File

@@ -1,28 +1,41 @@
package re.imc.geysermodelengine.managers.model.model; 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.entity.EntityData;
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler; import re.imc.geysermodelengine.managers.model.ModelHandler.ModelHandler;
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler; import re.imc.geysermodelengine.managers.model.PropertyHandler.PropertyHandler;
public class BetterModelModel implements Model { 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 @Override
public String getName() { public String getName() {
return ""; return tracker.name();
} }
@Override @Override
public ModelHandler getModelHandler() { public ModelHandler getModelHandler() {
return null; return modelHandler;
} }
@Override @Override
public EntityData getEntityData() { public EntityData getEntityData() {
return null; return entityData;
} }
@Override @Override
public PropertyHandler getPropertyHandler() { public PropertyHandler getPropertyHandler() {
return null; return propertyHandler;
} }
} }

View File

@@ -1,14 +1,16 @@
package re.imc.geysermodelengine.managers.model.model; package re.imc.geysermodelengine.managers.model.model;
import re.imc.geysermodelengine.managers.model.entity.EntityData; import re.imc.geysermodelengine.managers.model.entity.EntityData;
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler; import re.imc.geysermodelengine.managers.model.ModelHandler.ModelHandler;
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler; import re.imc.geysermodelengine.managers.model.PropertyHandler.PropertyHandler;
public interface Model { public interface Model {
String getName(); String getName();
ModelHandler getModelHandler(); ModelHandler getModelHandler();
EntityData getEntityData(); EntityData getEntityData();
PropertyHandler getPropertyHandler(); PropertyHandler getPropertyHandler();
} }

View File

@@ -2,8 +2,8 @@ package re.imc.geysermodelengine.managers.model.model;
import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ActiveModel;
import re.imc.geysermodelengine.managers.model.entity.EntityData; import re.imc.geysermodelengine.managers.model.entity.EntityData;
import re.imc.geysermodelengine.managers.model.modelhandler.ModelHandler; import re.imc.geysermodelengine.managers.model.ModelHandler.ModelHandler;
import re.imc.geysermodelengine.managers.model.propertyhandler.PropertyHandler; import re.imc.geysermodelengine.managers.model.PropertyHandler.PropertyHandler;
public class ModelEngineModel implements Model { public class ModelEngineModel implements Model {

View File

@@ -1,29 +0,0 @@
package re.imc.geysermodelengine.managers.model.modelhandler;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import re.imc.geysermodelengine.GeyserModelEngine;
import re.imc.geysermodelengine.listener.BetterModelListener;
public class BetterModelHandler implements ModelHandler {
@Override
public void createModel(GeyserModelEngine plugin, Object modeledEntity, Object activeModel) {
}
@Override
public void processEntities(GeyserModelEngine plugin, Entity entity) {
}
@Override
public void removeEntities(GeyserModelEngine plugin) {
}
@Override
public void loadListeners(GeyserModelEngine plugin) {
Bukkit.getPluginManager().registerEvents(new BetterModelListener(plugin), plugin);
}
}

View File

@@ -1,16 +0,0 @@
package re.imc.geysermodelengine.managers.model.modelhandler;
import org.bukkit.entity.Entity;
import re.imc.geysermodelengine.GeyserModelEngine;
public interface ModelHandler {
// Might do a hashmap way tbf
void createModel(GeyserModelEngine plugin, Object modeledEntity, Object activeModel);
void processEntities(GeyserModelEngine plugin, Entity entity);
void removeEntities(GeyserModelEngine plugin);
void loadListeners(GeyserModelEngine plugin);
}

View File

@@ -1,25 +0,0 @@
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 class BetterModelPropertyHandler implements PropertyHandler {
@Override
public void sendScale(EntityData modelData, Collection<Player> players, float lastScale, boolean firstSend) {
}
@Override
public void sendColor(EntityData modelData, Collection<Player> players, Color lastColor, boolean firstSend) {
}
@Override
public void sendHitBox(EntityData modelData, Player player) {
}
}

View File

@@ -1,71 +0,0 @@
package re.imc.geysermodelengine.managers.model.propertyhandler;
import com.ticxo.modelengine.api.model.ActiveModel;
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
import org.bukkit.entity.Player;
import org.joml.Vector3fc;
import re.imc.geysermodelengine.managers.model.entity.EntityData;
import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
import java.awt.*;
import java.lang.reflect.Method;
import java.util.Collection;
public class ModelEnginePropertyHandler implements PropertyHandler {
private final Method scaleMethod;
public ModelEnginePropertyHandler() {
try {
this.scaleMethod = ActiveModel.class.getMethod("getScale");
} catch (NoSuchMethodException err) {
throw new RuntimeException(err);
}
}
@Override
public void sendScale(EntityData modelData, Collection<Player> players, float lastScale, boolean firstSend) {
try {
if (players.isEmpty()) return;
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) modelData;
Vector3fc scale = (Vector3fc) scaleMethod.invoke(modelEngineEntityData.getActiveModel());
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 modelData, Collection<Player> players, Color lastColor, boolean firstSend) {
if (players.isEmpty()) return;
ModelEngineEntityData modelEngineEntityData = (ModelEngineEntityData) modelData;
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 modelData, Player player) {
for (Player viewer : modelData.getViewers()) {
EntityUtils.sendCustomHitBox(viewer, modelData.getEntity().getEntityId(), 0.01f, 0.01f);
}
}
}

View File

@@ -1,16 +0,0 @@
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 {
void sendScale(EntityData modelData, Collection<Player> players, float lastScale, boolean firstSend);
void sendColor(EntityData modelData, Collection<Player> players, Color lastColor, boolean firstSend);
void sendHitBox(EntityData modelData, Player player);
}

View File

@@ -0,0 +1,171 @@
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("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;
}
}

View File

@@ -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("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;
}
}

View File

@@ -0,0 +1,11 @@
package re.imc.geysermodelengine.managers.model.taskshandler;
import org.bukkit.entity.Player;
import re.imc.geysermodelengine.managers.model.entity.EntityData;
public interface TaskHandler {
void runAsync();
void sendEntityData(EntityData entityData, Player player, int delay);
void cancel();
}

View File

@@ -58,7 +58,6 @@ public class PacketEntity {
return true; return true;
} }
public void remove() { public void remove() {
removed = true; removed = true;
sendEntityDestroyPacket(viewers); sendEntityDestroyPacket(viewers);
@@ -78,7 +77,6 @@ public class PacketEntity {
} }
public void sendLocationPacket(Collection<Player> players) { public void sendLocationPacket(Collection<Player> players) {
PacketWrapper<?> packet; PacketWrapper<?> packet;
EntityPositionData data = new EntityPositionData(SpigotConversionUtil.fromBukkitLocation(location).getPosition(), Vector3d.zero(), location.getYaw(), location.getPitch()); EntityPositionData data = new EntityPositionData(SpigotConversionUtil.fromBukkitLocation(location).getPosition(), Vector3d.zero(), location.getYaw(), location.getPitch());

View File

@@ -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.entity.ModelEngineEntityData;
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 ModelEngineEntityData 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 ScheduledFuture scheduledFuture;
public EntityTaskRunnable(GeyserModelEngine plugin, ModelEngineEntityData 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(modeledEntity.getBase().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().getPropertyHandler().sendScale(model, viewers, lastScale, false);
plugin.getEntityTaskManager().getPropertyHandler().sendColor(model, viewers, lastColor, false);
}
public void cancel() {
scheduledFuture.cancel(true);
}
public void sendEntityData(ModelEngineEntityData 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().getPropertyHandler().sendHitBox(model, player);
plugin.getEntityTaskManager().getPropertyHandler().sendScale(model, Collections.singleton(player), lastScale, true);
plugin.getEntityTaskManager().getPropertyHandler().sendColor(model, Collections.singleton(player), lastColor, true);
updateEntityProperties(model, Collections.singleton(player), true);
}, 500, TimeUnit.MILLISECONDS);
}, delay * 50L, TimeUnit.MILLISECONDS);
}
public void updateEntityProperties(ModelEngineEntityData 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(ModelEngineEntityData 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;
}
}

View File

@@ -3,7 +3,6 @@ package re.imc.geysermodelengine.runnables;
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.entity.EntityData; 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.Model;
import java.util.Map; import java.util.Map;
@@ -21,7 +20,7 @@ public class UpdateTaskRunnable implements Consumer<ScheduledTask> {
public void accept(ScheduledTask scheduledTask) { public void accept(ScheduledTask scheduledTask) {
try { try {
for (Map<Model, EntityData> models : plugin.getModelManager().getEntitiesCache().values()) { for (Map<Model, EntityData> models : plugin.getModelManager().getEntitiesCache().values()) {
models.values().forEach(model -> model.getEntityTask().updateEntityProperties((ModelEngineEntityData) 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);

View File

@@ -6,6 +6,7 @@ api-version: '1.21'
authors: authors:
- zimzaza4 - zimzaza4
- willem.dev - willem.dev
- xSquishyLiam
load: STARTUP load: STARTUP
@@ -19,7 +20,5 @@ dependencies:
required: true required: true
ModelEngine: ModelEngine:
required: false required: false
join-classpath: true
BetterModel: BetterModel:
required: false required: false
join-classpath: true