From d0fd71975319c3e7db7659f14dd71a78c305137d Mon Sep 17 00:00:00 2001
From: TheLividaProject <56977759+TheLividaProject@users.noreply.github.com>
Date: Fri, 11 Jul 2025 10:50:05 +0100
Subject: [PATCH 1/4] updated PE to 2.9.1 and disabled the default jar and only
use shaded jar
---
.idea/workspace.xml | 4 +---
build.gradle.kts | 6 +++++-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 14c3e78..5a3e7b7 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,9 +4,7 @@
-
-
-
+
diff --git a/build.gradle.kts b/build.gradle.kts
index 1256c30..9d86998 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -29,7 +29,7 @@ dependencies {
compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar"))
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
- implementation("com.github.retrooper:packetevents-spigot:2.9.0-SNAPSHOT")
+ implementation("com.github.retrooper:packetevents-spigot:2.9.1")
implementation("org.reflections:reflections:0.10.2")
}
@@ -42,6 +42,10 @@ tasks.compileJava {
options.encoding = "UTF-8"
}
+tasks.jar {
+ enabled = false
+}
+
tasks.shadowJar {
relocate("dev.jorel.commandapi", "re.imc.geysermodelengine.libs.commandapi")
From 8f67ade51cc0641f9b4e1444f1bc1294ec4a3b25 Mon Sep 17 00:00:00 2001
From: TheLividaProject <56977759+TheLividaProject@users.noreply.github.com>
Date: Sun, 20 Jul 2025 16:51:45 +0100
Subject: [PATCH 2/4] Added some fixes and improved schedulers - still waiting
for 1.21.8 support
---
.idea/workspace.xml | 8 +++-
build.gradle.kts | 11 ++---
.../geysermodelengine/GeyserModelEngine.java | 8 ++++
.../listener/ModelListener.java | 7 ++-
.../managers/model/EntityTaskManager.java | 28 ++++++------
.../managers/model/data/ModelEntityData.java | 4 +-
.../runnables/EntityTaskRunnable.java | 44 +++++++++++++------
src/main/resources/config.yml | 1 +
8 files changed, 71 insertions(+), 40 deletions(-)
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 5a3e7b7..c49d851 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,7 +4,10 @@
-
+
+
+
+
@@ -60,6 +63,9 @@
+
+
+
{
"associatedIndex": 8
}
diff --git a/build.gradle.kts b/build.gradle.kts
index 9d86998..97b4556 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -21,15 +21,15 @@ repositories {
dependencies {
compileOnly("io.papermc.paper:paper-api:1.21.7-R0.1-SNAPSHOT")
-
implementation("dev.jorel:commandapi-bukkit-shade-mojang-mapped:10.1.1")
- compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.4")
+ compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.9")
compileOnly(files("libs/geyserutils-spigot-1.0-SNAPSHOT.jar"))
compileOnly("org.geysermc.floodgate:api:2.2.4-SNAPSHOT")
- implementation("com.github.retrooper:packetevents-spigot:2.9.1")
+
+ implementation("com.github.retrooper:packetevents-spigot:2.9.3")
implementation("org.reflections:reflections:0.10.2")
}
@@ -42,10 +42,6 @@ tasks.compileJava {
options.encoding = "UTF-8"
}
-tasks.jar {
- enabled = false
-}
-
tasks.shadowJar {
relocate("dev.jorel.commandapi", "re.imc.geysermodelengine.libs.commandapi")
@@ -56,5 +52,6 @@ tasks.shadowJar {
}
tasks.jar {
+ enabled = false
dependsOn(tasks.shadowJar)
}
\ No newline at end of file
diff --git a/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java b/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java
index 41f29b6..2041e17 100644
--- a/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java
+++ b/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java
@@ -30,6 +30,8 @@ public class GeyserModelEngine extends JavaPlugin {
private ModelManager modelManager;
private EntityTaskManager entityTaskManager;
+ private ScheduledExecutorService schedulerPool;
+
@Override
public void onLoad() {
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
@@ -77,6 +79,8 @@ public class GeyserModelEngine extends JavaPlugin {
}
private void loadRunnables() {
+ this.schedulerPool = Executors.newScheduledThreadPool(configManager.getConfig().getInt("thread-pool-size", 4));
+
Bukkit.getAsyncScheduler().runAtFixedRate(this, new UpdateTaskRunnable(this), 10, configManager.getConfig().getLong("entity-position-update-period", 35), TimeUnit.MILLISECONDS);
Bukkit.getAsyncScheduler().runAtFixedRate(this, new BedrockMountControlRunnable(this), 1, 1, TimeUnit.MILLISECONDS);
}
@@ -96,4 +100,8 @@ public class GeyserModelEngine extends JavaPlugin {
public EntityTaskManager getEntityTaskManager() {
return entityTaskManager;
}
+
+ public ScheduledExecutorService getSchedulerPool() {
+ return schedulerPool;
+ }
}
diff --git a/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java b/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java
index 5e12539..280d247 100644
--- a/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java
+++ b/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java
@@ -15,10 +15,12 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent;
+import org.geysermc.floodgate.api.FloodgateApi;
import re.imc.geysermodelengine.GeyserModelEngine;
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
public class ModelListener implements Listener {
@@ -63,12 +65,15 @@ public class ModelListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
- plugin.getModelManager().getPlayerJoinedCache().add(player.getUniqueId());
+ if (!FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) return;
+ //TODO temp fix bc like why? - the issue is when a player logs out and the mob is there, the player logs back in sometimes it can display as a pig only
+ Bukkit.getAsyncScheduler().runDelayed(plugin, scheduledTask -> plugin.getModelManager().getPlayerJoinedCache().add(player.getUniqueId()), 10, TimeUnit.MILLISECONDS);
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
Player player = event.getPlayer();
+ if (!FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) return;
plugin.getModelManager().getPlayerJoinedCache().remove(player.getUniqueId());
}
}
diff --git a/src/main/java/re/imc/geysermodelengine/managers/model/EntityTaskManager.java b/src/main/java/re/imc/geysermodelengine/managers/model/EntityTaskManager.java
index 7c9cd02..643f5a9 100644
--- a/src/main/java/re/imc/geysermodelengine/managers/model/EntityTaskManager.java
+++ b/src/main/java/re/imc/geysermodelengine/managers/model/EntityTaskManager.java
@@ -60,9 +60,7 @@ public class EntityTaskManager {
for (Player player : players) {
EntityUtils.sendCustomScale(player, model.getEntity().getEntityId(), average);
}
- } catch (Throwable t) {
- // ignore
- }
+ } catch (Throwable ignored) {}
}
public void sendColor(ModelEntityData model, Collection players, Color lastColor, boolean firstSend) {
@@ -82,24 +80,23 @@ public class EntityTaskManager {
public void checkViewers(ModelEntityData model, Set viewers) {
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
- if (FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) {
+ if (!FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) continue;
- if (canSee(onlinePlayer, model.getEntity())) {
-
- if (!viewers.contains(onlinePlayer)) {
- sendSpawnPacket(model, onlinePlayer);
- viewers.add(onlinePlayer);
- }
- } else {
- if (viewers.contains(onlinePlayer)) {
- model.getEntity().sendEntityDestroyPacket(Collections.singletonList(onlinePlayer));
- viewers.remove(onlinePlayer);
- }
+ if (canSee(onlinePlayer, model.getEntity())) {
+ if (!viewers.contains(onlinePlayer)) {
+ sendSpawnPacket(model, onlinePlayer);
+ viewers.add(onlinePlayer);
+ }
+ } else {
+ if (viewers.contains(onlinePlayer)) {
+ model.getEntity().sendEntityDestroyPacket(Collections.singletonList(onlinePlayer));
+ viewers.remove(onlinePlayer);
}
}
}
}
+ // Issue here - start: See ModelListener.class and look at function onPlayerJoin
private void sendSpawnPacket(ModelEntityData model, Player onlinePlayer) {
EntityTaskRunnable task = model.getEntityTask();
boolean firstJoined = !plugin.getModelManager().getPlayerJoinedCache().contains(onlinePlayer.getUniqueId());
@@ -125,6 +122,7 @@ public class EntityTaskManager {
return true;
}
+ // Issue here - end
public void sendHitBoxToAll(ModelEntityData model) {
for (Player viewer : model.getViewers()) {
diff --git a/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java b/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java
index 0dccec4..541a08b 100644
--- a/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java
+++ b/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java
@@ -4,7 +4,6 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.google.common.collect.Sets;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
-import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import re.imc.geysermodelengine.GeyserModelEngine;
@@ -12,7 +11,6 @@ import re.imc.geysermodelengine.packet.entity.PacketEntity;
import re.imc.geysermodelengine.runnables.EntityTaskRunnable;
import java.util.Set;
-import java.util.concurrent.TimeUnit;
public class ModelEntityData {
@@ -50,7 +48,7 @@ public class ModelEntityData {
public void runEntityTask() {
entityTask = new EntityTaskRunnable(plugin, this);
- Bukkit.getAsyncScheduler().runAtFixedRate(plugin, entityTask, 0, 20, TimeUnit.MILLISECONDS);
+ entityTask.run();
}
public PacketEntity getEntity() {
diff --git a/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java b/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java
index bb31aa2..40843a8 100644
--- a/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java
+++ b/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java
@@ -8,9 +8,7 @@ import com.ticxo.modelengine.api.generator.blueprint.BlueprintBone;
import com.ticxo.modelengine.api.model.ActiveModel;
import com.ticxo.modelengine.api.model.ModeledEntity;
import com.ticxo.modelengine.api.model.bone.ModelBone;
-import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
import me.zimzaza4.geyserutils.spigot.api.EntityUtils;
-import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import re.imc.geysermodelengine.GeyserModelEngine;
import re.imc.geysermodelengine.managers.model.data.ModelEntityData;
@@ -21,10 +19,10 @@ 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;
-import java.util.function.Consumer;
-public class EntityTaskRunnable implements Consumer {
+public class EntityTaskRunnable {
private final GeyserModelEngine plugin;
@@ -43,16 +41,27 @@ public class EntityTaskRunnable implements Consumer {
private final BooleanPacker booleanPacker = new BooleanPacker();
+ private ScheduledFuture scheduledFuture;
+
public EntityTaskRunnable(GeyserModelEngine plugin, ModelEntityData model) {
this.plugin = plugin;
this.model = model;
-
- plugin.getEntityTaskManager().sendHitBoxToAll(model);
}
- @Override
- public void accept(ScheduledTask scheduledTask) {
+ public void run() {
+ plugin.getEntityTaskManager().sendHitBoxToAll(model);
+
+ Runnable asyncTask = () -> {
+ try {
+ runAsync();
+ } catch (Throwable ignored) {}
+ };
+
+ scheduledFuture = plugin.getSchedulerPool().scheduleAtFixedRate(asyncTask, 0, 20, TimeUnit.MILLISECONDS);
+ }
+
+ public void runAsync() {
plugin.getEntityTaskManager().checkViewers(model, model.getViewers());
PacketEntity entity = model.getEntity();
@@ -70,7 +79,7 @@ public class EntityTaskRunnable implements Consumer {
plugin.getModelManager().getEntitiesCache().remove(modeledEntity.getBase().getEntityId());
plugin.getModelManager().getModelEntitiesCache().remove(entity.getEntityId());
- scheduledTask.cancel();
+ cancel();
return;
}
@@ -96,20 +105,25 @@ public class EntityTaskRunnable implements Consumer {
plugin.getEntityTaskManager().sendColor(model, viewers, lastColor, false);
}
+ public void cancel() {
+ scheduledFuture.cancel(true);
+ }
+
public void sendEntityData(ModelEntityData model, Player player, int delay) {
+ //TODO with ModelEngine, you can define the namespace inside the config, make an option to change it here as well? if i'm right about this
EntityUtils.setCustomEntity(player, model.getEntity().getEntityId(), "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase());
- Bukkit.getAsyncScheduler().runDelayed(plugin, scheduledTask -> {
+ plugin.getSchedulerPool().schedule(() -> {
model.getEntity().sendSpawnPacket(Collections.singletonList(player));
- Bukkit.getAsyncScheduler().runDelayed(plugin, scheduledTask1 -> {
+ plugin.getSchedulerPool().schedule(() -> {
plugin.getEntityTaskManager().sendHitBox(model, player);
plugin.getEntityTaskManager().sendScale(model, Collections.singleton(player), lastScale, true);
plugin.getEntityTaskManager().sendColor(model, Collections.singleton(player), lastColor, true);
updateEntityProperties(model, Collections.singleton(player), true);
- }, 500, TimeUnit.MILLISECONDS);
- }, delay * 50L, TimeUnit.MILLISECONDS);
+ }, delay * 50L, TimeUnit.MILLISECONDS);
+ }, 500, TimeUnit.MILLISECONDS);
}
public void updateEntityProperties(ModelEntityData model, Collection players, boolean firstSend, String... forceAnims) {
@@ -255,4 +269,8 @@ public class EntityTaskRunnable implements Consumer {
public Cache getLastPlayedAnim() {
return lastPlayedAnim;
}
+
+ public ScheduledFuture getScheduledFuture() {
+ return scheduledFuture;
+ }
}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index ba9fd1e..a632a74 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -2,6 +2,7 @@ data-send-delay: 5
entity-view-distance: 50
join-send-delay: 20
entity-position-update-period: 35
+thread-pool-size: 4
model-entity-type: BAT # must be a living entity
enable-part-visibility-models:
- example
From 13c0b45d2a21bd358b9c66908912efef5b3af9d6 Mon Sep 17 00:00:00 2001
From: TheLividaProject <56977759+TheLividaProject@users.noreply.github.com>
Date: Mon, 21 Jul 2025 21:57:06 +0100
Subject: [PATCH 3/4] 1.21.8 support
---
.idea/workspace.xml | 4 ++--
build.gradle.kts | 9 ++++-----
.../managers/model/data/ModelEntityData.java | 1 -
.../runnables/EntityTaskRunnable.java | 12 ++----------
4 files changed, 8 insertions(+), 18 deletions(-)
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index c49d851..9238fa3 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,8 +5,8 @@
-
-
+
+
diff --git a/build.gradle.kts b/build.gradle.kts
index 97b4556..e607db7 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -20,8 +20,8 @@ repositories {
}
dependencies {
- compileOnly("io.papermc.paper:paper-api:1.21.7-R0.1-SNAPSHOT")
- implementation("dev.jorel:commandapi-bukkit-shade-mojang-mapped:10.1.1")
+ compileOnly("io.papermc.paper:paper-api:1.21.8-R0.1-SNAPSHOT")
+ implementation("dev.jorel:commandapi-bukkit-shade-mojang-mapped:10.1.2")
compileOnly("com.ticxo.modelengine:ModelEngine:R4.0.9")
@@ -51,7 +51,6 @@ tasks.shadowJar {
relocate("org.reflections", "re.imc.geysermodelengine.libs.reflections")
}
-tasks.jar {
- enabled = false
- dependsOn(tasks.shadowJar)
+tasks.build {
+ dependsOn("shadowJar")
}
\ No newline at end of file
diff --git a/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java b/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java
index 541a08b..eadfd1b 100644
--- a/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java
+++ b/src/main/java/re/imc/geysermodelengine/managers/model/data/ModelEntityData.java
@@ -48,7 +48,6 @@ public class ModelEntityData {
public void runEntityTask() {
entityTask = new EntityTaskRunnable(plugin, this);
- entityTask.run();
}
public PacketEntity getEntity() {
diff --git a/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java b/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java
index 40843a8..c995060 100644
--- a/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java
+++ b/src/main/java/re/imc/geysermodelengine/runnables/EntityTaskRunnable.java
@@ -41,24 +41,16 @@ public class EntityTaskRunnable {
private final BooleanPacker booleanPacker = new BooleanPacker();
- private ScheduledFuture scheduledFuture;
+ private final ScheduledFuture scheduledFuture;
public EntityTaskRunnable(GeyserModelEngine plugin, ModelEntityData model) {
this.plugin = plugin;
this.model = model;
- }
- public void run() {
plugin.getEntityTaskManager().sendHitBoxToAll(model);
- Runnable asyncTask = () -> {
- try {
- runAsync();
- } catch (Throwable ignored) {}
- };
-
- scheduledFuture = plugin.getSchedulerPool().scheduleAtFixedRate(asyncTask, 0, 20, TimeUnit.MILLISECONDS);
+ scheduledFuture = plugin.getSchedulerPool().scheduleAtFixedRate(this::runAsync, 0, 20, TimeUnit.MILLISECONDS);
}
public void runAsync() {
From db0367537e686d83f4292f35d31b03873f44ae29 Mon Sep 17 00:00:00 2001
From: TheLividaProject <56977759+TheLividaProject@users.noreply.github.com>
Date: Mon, 21 Jul 2025 22:05:39 +0100
Subject: [PATCH 4/4] disables default jar hopefully
---
build.gradle.kts | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/build.gradle.kts b/build.gradle.kts
index e607db7..a776d87 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -51,6 +51,10 @@ tasks.shadowJar {
relocate("org.reflections", "re.imc.geysermodelengine.libs.reflections")
}
+tasks.jar {
+ enabled = false
+}
+
tasks.build {
dependsOn("shadowJar")
}
\ No newline at end of file