work in progress

This commit is contained in:
xSquishyLiam
2025-09-07 00:26:16 +01:00
parent 804d2aac04
commit 8e36bf2829
29 changed files with 574 additions and 2900 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +0,0 @@
<changelist name="Uncommitted_changes_before_rebase_[Changes]" date="1757196821391" recycled="false" toDelete="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_rebase_[Changes]/shelved.patch" />
<option name="DESCRIPTION" value="Uncommitted changes before rebase [Changes]" />
</changelist>

View File

@@ -1,4 +0,0 @@
<changelist name="Uncommitted_changes_before_rebase_[Changes]1" date="1757196822407" recycled="false" toDelete="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_rebase_[Changes]1/shelved.patch" />
<option name="DESCRIPTION" value="Uncommitted changes before rebase [Changes]" />
</changelist>

66
.idea/workspace.xml generated
View File

@@ -5,7 +5,35 @@
</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/Events/GeyserModelEngineModelSpawn.java" beforeDir="false" /> <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/listener/ModelEngineListener.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/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$/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/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/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/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/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" />
</list> </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" />
@@ -77,25 +105,25 @@
<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">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;Gradle.Download Sources.executor&quot;: &quot;Run&quot;, "Gradle.Download Sources.executor": "Run",
&quot;Gradle.GeyserModelEngine [build].executor&quot;: &quot;Run&quot;, "Gradle.GeyserModelEngine [build].executor": "Run",
&quot;Gradle.GeyserModelEngine [jar].executor&quot;: &quot;Run&quot;, "Gradle.GeyserModelEngine [jar].executor": "Run",
&quot;Maven.GeyserModelEngine [install...].executor&quot;: &quot;Run&quot;, "Maven.GeyserModelEngine [install...].executor": "Run",
&quot;Maven.GeyserModelEngine [install].executor&quot;: &quot;Run&quot;, "Maven.GeyserModelEngine [install].executor": "Run",
&quot;ModuleVcsDetector.initialDetectionPerformed&quot;: &quot;true&quot;, "ModuleVcsDetector.initialDetectionPerformed": "true",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;, "RunOnceActivity.git.unshallow": "true",
&quot;git-widget-placeholder&quot;: &quot;bettermodel-support-dev&quot;, "git-widget-placeholder": "bettermodel-support-dev",
&quot;kotlin-language-version-configured&quot;: &quot;true&quot;, "kotlin-language-version-configured": "true",
&quot;last_opened_file_path&quot;: &quot;D:/Coding/Forks/Minecraft/GeyserModelEngine&quot;, "last_opened_file_path": "D:/Coding/Forks/Minecraft/GeyserModelEngine",
&quot;project.structure.last.edited&quot;: &quot;Project&quot;, "project.structure.last.edited": "Project",
&quot;project.structure.proportion&quot;: &quot;0.0&quot;, "project.structure.proportion": "0.0",
&quot;project.structure.side.proportion&quot;: &quot;0.2&quot;, "project.structure.side.proportion": "0.2",
&quot;settings.editor.selected.configurable&quot;: &quot;reference.settings.project.maven.runner&quot; "settings.editor.selected.configurable": "reference.settings.project.maven.runner"
} }
}</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

@@ -24,6 +24,7 @@ dependencies {
implementation("dev.jorel:commandapi-bukkit-shade-mojang-mapped:10.1.2") implementation("dev.jorel:commandapi-bukkit-shade-mojang-mapped:10.1.2")
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.9") compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.9")
compileOnly("io.github.toxicity188:bettermodel:1.11.4")
compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar")) compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar"))
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT") compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")

View File

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

View File

@@ -0,0 +1,20 @@
package re.imc.geysermodelengine.listener;
import kr.toxicity.model.api.event.CreateTrackerEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import re.imc.geysermodelengine.GeyserModelEngine;
public class BetterModelListener implements Listener {
private final GeyserModelEngine plugin;
public BetterModelListener(GeyserModelEngine plugin) {
this.plugin = plugin;
}
@EventHandler
public void onModelSpawn(CreateTrackerEvent event) {
plugin.getLogger().info(event.getTracker().name());
}
}

View File

@@ -0,0 +1,60 @@
package re.imc.geysermodelengine.listener;
import com.ticxo.modelengine.api.events.*;
import com.ticxo.modelengine.api.model.ActiveModel;
import kr.toxicity.model.api.data.raw.ModelData;
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.entity.ModelEngineEntityData;
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(plugin, 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());
}
}
}

View File

@@ -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,45 +19,19 @@ public class ModelListener implements Listener {
this.plugin = plugin; this.plugin = plugin;
} }
@EventHandler(priority = EventPriority.MONITOR)
public void onAddModel(AddModelEvent event) {
if (event.isCancelled()) return;
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());
}
}
/* /*
/ xSquishyLiam: / xSquishyLiam:
/ I'm wondering if we could move this to more of a player loading chunks instead of checking all worlds via PlayerChunkLoadEvent? / May change this into a better system?
*/ */
@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(plugin, 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 make sures 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) {

View File

@@ -21,7 +21,7 @@ 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.name());
commandManagersCache.put(commandManager.name(), commandManager); commandManagersCache.put(commandManager.name(), 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());

View File

@@ -9,29 +9,35 @@ 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.packet.entity.PacketEntity; import re.imc.geysermodelengine.packet.entity.PacketEntity;
import re.imc.geysermodelengine.runnables.EntityTaskRunnable; 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();
} 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.getLogger().info("Using BetterModel property handler!");
} else {
plugin.getLogger().severe("No supported model engine found!");
plugin.getServer().getPluginManager().disablePlugin(plugin);
} }
} }
@@ -45,40 +51,7 @@ public class EntityTaskManager {
return name; return name;
} }
public void sendScale(ModelEntityData model, Collection<Player> players, float lastScale, boolean firstSend) { public void checkViewers(EntityData model, Set<Player> viewers) {
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,14 +69,14 @@ public class EntityTaskManager {
} }
} }
private void sendSpawnPacket(ModelEntityData model, Player onlinePlayer) { private void sendSpawnPacket(EntityData model, Player onlinePlayer) {
EntityTaskRunnable task = model.getEntityTask(); EntityTaskRunnable 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((ModelEngineEntityData) model, onlinePlayer, plugin.getConfigManager().getConfig().getInt("join-send-delay") / 50);
} else { } else {
task.sendEntityData(model, onlinePlayer, 5); task.sendEntityData((ModelEngineEntityData) model, onlinePlayer, 5);
} }
} }
@@ -122,13 +95,13 @@ public class EntityTaskManager {
return true; return true;
} }
public void sendHitBoxToAll(ModelEntityData model) { public void sendHitBoxToAll(ModelEngineEntityData 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) { public void sendHitBox(ModelEngineEntityData model, Player viewer) {
float w = 0; float w = 0;
if (model.getActiveModel().isShadowVisible()) { if (model.getActiveModel().isShadowVisible()) {
@@ -140,13 +113,13 @@ public class EntityTaskManager {
EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.02f, w); EntityUtils.sendCustomHitBox(viewer, model.getEntity().getEntityId(), 0.02f, w);
} }
public boolean hasAnimation(ModelEntityData 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);
return !(animationProperty == null); return !(animationProperty == null);
} }
public Method getScaleMethod() { public PropertyHandler getPropertyHandler() {
return scaleMethod; return propertyHandler;
} }
} }

View File

@@ -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,47 @@ 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();
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.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!");
return; plugin.getServer().getPluginManager().disablePlugin(plugin);
} return;
} }
map.put(model, modelEntity); modelHandler.loadListeners(plugin);
} }
public void processEntities(Entity entity) { public ModelHandler getModelHandler() {
if (entitiesCache.containsKey(entity.getEntityId())) return; return modelHandler;
ModeledEntity modeledEntity = ModelEngineAPI.getModeledEntity(entity);
if (modeledEntity == null) return;
Optional<ActiveModel> model = modeledEntity.getModels().values().stream().findFirst();
model.ifPresent(m -> create(modeledEntity, m));
}
public void removeEntities() {
for (Map<ActiveModel, ModelEntityData> entities : entitiesCache.values()) {
entities.forEach((model, modelEntity) -> modelEntity.getEntity().remove());
}
} }
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;
} }

View File

@@ -0,0 +1,4 @@
package re.imc.geysermodelengine.managers.model.entity;
public class BetterModelEntityData {
}

View File

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

View File

@@ -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,16 +7,17 @@ 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.packet.entity.PacketEntity; import re.imc.geysermodelengine.packet.entity.PacketEntity;
import re.imc.geysermodelengine.runnables.EntityTaskRunnable; 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();
@@ -26,38 +27,46 @@ public class ModelEntityData {
private EntityTaskRunnable entityTask; private EntityTaskRunnable 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 EntityTaskRunnable(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 void remove() {
}
@Override
public EntityTaskRunnable getEntityTask() {
return entityTask;
}
public ModeledEntity getModeledEntity() { public ModeledEntity getModeledEntity() {
return modeledEntity; return modeledEntity;
} }
@@ -65,8 +74,4 @@ public class ModelEntityData {
public ActiveModel getActiveModel() { public ActiveModel getActiveModel() {
return activeModel; return activeModel;
} }
public EntityTaskRunnable getEntityTask() {
return entityTask;
}
} }

View File

@@ -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 class BetterModelModel implements Model {
@Override
public String getName() {
return "";
}
@Override
public ModelHandler getModelHandler() {
return null;
}
@Override
public EntityData getEntityData() {
return null;
}
@Override
public PropertyHandler getPropertyHandler() {
return null;
}
}

View File

@@ -0,0 +1,14 @@
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 {
String getName();
ModelHandler getModelHandler();
EntityData getEntityData();
PropertyHandler getPropertyHandler();
}

View File

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

View File

@@ -0,0 +1,29 @@
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

@@ -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 kr.toxicity.model.api.data.raw.ModelData;
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 {
@Override
public void createModel(GeyserModelEngine plugin, Object modeledEntity, Object activeModel) {
ModeledEntity megEntity = (ModeledEntity) modeledEntity;
ActiveModel megActiveModel = (ActiveModel) activeModel;
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(GeyserModelEngine plugin, 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(plugin, modeledEntity, m));
}
@Override
public void removeEntities(GeyserModelEngine plugin) {
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);
}
}

View File

@@ -0,0 +1,16 @@
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

@@ -0,0 +1,25 @@
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

@@ -0,0 +1,71 @@
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

@@ -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 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

@@ -11,7 +11,7 @@ import com.ticxo.modelengine.api.model.bone.ModelBone;
import me.zimzaza4.geyserutils.spigot.api.EntityUtils; import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
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.data.ModelEntityData; import re.imc.geysermodelengine.managers.model.entity.ModelEngineEntityData;
import re.imc.geysermodelengine.packet.entity.PacketEntity; import re.imc.geysermodelengine.packet.entity.PacketEntity;
import re.imc.geysermodelengine.util.BooleanPacker; import re.imc.geysermodelengine.util.BooleanPacker;
@@ -26,7 +26,7 @@ public class EntityTaskRunnable {
private final GeyserModelEngine plugin; private final GeyserModelEngine plugin;
private final ModelEntityData model; private final ModelEngineEntityData model;
private int tick = 0; private int tick = 0;
private int syncTick = 0; private int syncTick = 0;
@@ -39,11 +39,9 @@ public class EntityTaskRunnable {
private final ConcurrentHashMap<String, Integer> lastIntSet = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, Integer> lastIntSet = new ConcurrentHashMap<>();
private final Cache<String, Boolean> lastPlayedAnim = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MILLISECONDS).build(); private final Cache<String, Boolean> lastPlayedAnim = CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.MILLISECONDS).build();
private final BooleanPacker booleanPacker = new BooleanPacker();
private final ScheduledFuture scheduledFuture; private final ScheduledFuture scheduledFuture;
public EntityTaskRunnable(GeyserModelEngine plugin, ModelEntityData model) { public EntityTaskRunnable(GeyserModelEngine plugin, ModelEngineEntityData model) {
this.plugin = plugin; this.plugin = plugin;
this.model = model; this.model = model;
@@ -70,7 +68,8 @@ public class EntityTaskRunnable {
entity.remove(); entity.remove();
plugin.getModelManager().getEntitiesCache().remove(modeledEntity.getBase().getEntityId()); plugin.getModelManager().getEntitiesCache().remove(modeledEntity.getBase().getEntityId());
plugin.getModelManager().getModelEntitiesCache().remove(entity.getEntityId()); plugin.getModelManager().getModelEntitiesCache().remove(modeledEntity.getBase().getEntityId());
cancel(); cancel();
return; return;
} }
@@ -93,31 +92,32 @@ public class EntityTaskRunnable {
if (viewers.isEmpty()) return; if (viewers.isEmpty()) return;
plugin.getEntityTaskManager().sendScale(model, viewers, lastScale, false); plugin.getEntityTaskManager().getPropertyHandler().sendScale(model, viewers, lastScale, false);
plugin.getEntityTaskManager().sendColor(model, viewers, lastColor, false); plugin.getEntityTaskManager().getPropertyHandler().sendColor(model, viewers, lastColor, false);
} }
public void cancel() { public void cancel() {
scheduledFuture.cancel(true); scheduledFuture.cancel(true);
} }
public void sendEntityData(ModelEntityData model, Player player, int delay) { 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()); EntityUtils.setCustomEntity(player, model.getEntity().getEntityId(), plugin.getConfigManager().getConfig().getString("namespace") + ":" + model.getActiveModel().getBlueprint().getName().toLowerCase());
plugin.getSchedulerPool().schedule(() -> { plugin.getSchedulerPool().schedule(() -> {
model.getEntity().sendSpawnPacket(Collections.singletonList(player)); model.getEntity().sendSpawnPacket(Collections.singletonList(player));
plugin.getSchedulerPool().schedule(() -> { plugin.getSchedulerPool().schedule(() -> {
plugin.getEntityTaskManager().sendHitBox(model, player); plugin.getEntityTaskManager().getPropertyHandler().sendHitBox(model, player);
plugin.getEntityTaskManager().sendScale(model, Collections.singleton(player), lastScale, true);
plugin.getEntityTaskManager().sendColor(model, Collections.singleton(player), lastColor, true); 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); updateEntityProperties(model, Collections.singleton(player), true);
}, 500, TimeUnit.MILLISECONDS); }, 500, TimeUnit.MILLISECONDS);
}, delay * 50L, TimeUnit.MILLISECONDS); }, delay * 50L, TimeUnit.MILLISECONDS);
} }
public void updateEntityProperties(ModelEntityData model, Collection<Player> players, boolean firstSend, String... forceAnims) { public void updateEntityProperties(ModelEngineEntityData model, Collection<Player> players, boolean firstSend, String... forceAnims) {
int entity = model.getEntity().getEntityId(); int entity = model.getEntity().getEntityId();
Set<String> forceAnimSet = Set.of(forceAnims); Set<String> forceAnimSet = Set.of(forceAnims);
@@ -163,13 +163,13 @@ public class EntityTaskRunnable {
Map<String, Integer> intUpdates = new HashMap<>(); Map<String, Integer> intUpdates = new HashMap<>();
int i = 0; int i = 0;
for (Integer integer : booleanPacker.mapBooleansToInts(boneUpdates)) { for (Integer integer : BooleanPacker.mapBooleansToInts(boneUpdates)) {
intUpdates.put(plugin.getConfigManager().getConfig().getString("namespace") + ":bone" + i, integer); intUpdates.put(plugin.getConfigManager().getConfig().getString("namespace") + ":bone" + i, integer);
i++; i++;
} }
i = 0; i = 0;
for (Integer integer : booleanPacker.mapBooleansToInts(animUpdates)) { for (Integer integer : BooleanPacker.mapBooleansToInts(animUpdates)) {
intUpdates.put(plugin.getConfigManager().getConfig().getString("namespace") + ":anim" + i, integer); intUpdates.put(plugin.getConfigManager().getConfig().getString("namespace") + ":anim" + i, integer);
i++; i++;
} }
@@ -193,7 +193,7 @@ public class EntityTaskRunnable {
} }
} }
private void processBone(ModelEntityData model, BlueprintBone bone, Map<String, Boolean> map) { private void processBone(ModelEngineEntityData model, BlueprintBone bone, Map<String, Boolean> map) {
String name = plugin.getEntityTaskManager().unstripName(bone).toLowerCase(); String name = plugin.getEntityTaskManager().unstripName(bone).toLowerCase();
if (name.equals("hitbox") || if (name.equals("hitbox") ||
name.equals("shadow") || name.equals("shadow") ||

View File

@@ -1,9 +1,10 @@
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.entity.ModelEngineEntityData;
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 +20,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(model -> model.getEntityTask().updateEntityProperties((ModelEngineEntityData) model, model.getViewers(), false));
} }
} catch (Throwable err) { } catch (Throwable err) {
throw new RuntimeException(err); throw new RuntimeException(err);

View File

@@ -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<>();

View File

@@ -15,7 +15,11 @@ dependencies:
required: true required: true
packetevents: packetevents:
required: true required: true
ModelEngine:
required: true
floodgate: floodgate:
required: true required: true
ModelEngine:
required: false
join-classpath: true
BetterModel:
required: false
join-classpath: true