diff --git a/README.md b/README.md index c48f9af..5ffc24e 100644 --- a/README.md +++ b/README.md @@ -1,107 +1,67 @@ -# GeyserModelEngine 自定义实体分支 +# GeyserModelEngine +# About -> GitHub仓库:[https://github.com/zimzaza4/GeyserModelEngine/tree/custom-entity](https://github.com/zimzaza4/GeyserModelEngine/tree/custom-entity) +Thanks to [Willem](https://github.com/OmeWillem/GeyserUtils) for adding the following features: +- Part Visibility +- Color support +- Scaling support +- & more -> [Discord](https://discord.gg/NNNaUdAbpP) ---- +# How To Install -🌏 Language 🌏 +Download the following plugins according to what server software you use. -[[English](README_EN.md)] [[简体中文](README.md)] [欢迎贡献更多语言] - ---- - -# 这个跟主分支有什么区别? - -跟主分支不同的是,这个是真正的自定义实体!!!🎉🎉🎉 - -而主分支是给BE生成个史蒂夫发送4d皮肤给be玩家,支持原版Geyser - -只需要往资源包里塞动画文件即可,可以有效防止那些进服下个资源包就跑白嫖你模型的贼,但同时限制也挺多😥 - -总之两者各有各优势,根据各服务器情况选择 - ---- - -# 如何安装 - -根据服务端版本下载以下插件 - -| 插件 | 链接 | 作用 | +| plugins | Link | effect | | :--- | :---- | :--- | -| GeyserUtils | [Github](https://github.com/zimzaza4/GeyserUtils) | 让你的Geyser支持调用一些BE的东西 | -| GeyserModelEngine | [Github](https://github.com/zimzaza4/GeyserModelEngine) | 你猜 | -| GeyserModelEnginePackGenerator | [Github](https://github.com/zimzaza4/GeyserModelEnginePackGenerator) | 帮你自动转换模型生成资源包 | +| GeyserUtils | [Github](https://github.com/OmeWillem/GeyserUtils) | Get your Geyser to support calling some BE stuff | +| GeyserModelEngine | [Github](https://github.com/OmeWillem/GeyserModelEngine) | Make your bedrock support MEG4 | +| GeyserModelEnginePackGenerator | [Github](https://github.com/OmeWillem/GeyserModelEnginePackGenerator) | Help you automatically transform the model to generate resource packs | -下载完后,将`GeyserModelEngine` `Geyser自定义实体分支`放入插件文件夹 +- Put `GeyserModelEngine` in the plugins folder (only Spigot or forks of Spigot supported) +- Put either `geyserutils-spigot` in your plugins folder aswell (`geyserutils-velocity` in your Velocity plugins folder if you use it) +- Put `GeyserModelEnginePackGenerator` and `geyserutils-geyser` into `plugins/[Geyser-Folder]/extensions` -根据服务端版本把`geyserutils-spigot`/`velocity`/`bungeecord`放入插件文件夹 +Start the server to generate the relevant configuration files, and then shut down the server to convert any models. -`GeyserModelEnginePackGenerator` `geyserutils-geyser`放入geyser的扩展文件夹 +# Convert Models -先启动服务器生成相关配置文件,之后关闭服务器就安装好了 +`GeyserModelEnginePackGenerator` is capable of generating models all by itself. After generating it will also apply this pack automatically. -当然,先别急着用,现在你还得接着读下去 - ---- - -# 转换模型📦 - -现在`GeyserModelEnginePackGenerator`长大了学会自己转换模型生成资源包了 - -我们来到以下路径 `plugins/Geyser-Spigot/extensions/geysermodelenginepackgenerator/input/` - -在此目录创建一个文件夹名为模型的ID,比如我有个模型id为`parry_knight`,那就命名为`parry_knight` +- First go to `plugins/[Geyser-Folder]/extensions/geysermodelenginepackgenerator/input/` +- Create a folder in this directory with the ID of the model. (this is the same name as your model within ModelEngine 4.) -> 每个模型都要有独立的模型文件夹 +> Each model should have a separate model folder -新版本BlockBench 导出的基岩版模型format_version 是1.21.0 -需要手动改成1.12.0 -否则你的客户端看不到模型 +- Now use BlockBench and convert your model to a Bedrock Entity, this will allow you to export the Bedrock Geometry and Animations. +- Put the geometry, animations and texture file in this folder you've made. -我们将模型、动画和纹理全部原封不动丢进这个文件夹 +> The new version of BlockBench exports the bedrock model format_version as `1.21.0`. +> You need to change it to `1.12.0` manually. +> Otherwise your client will NOT see the model. -重启服务器或者重载geyser让他开始生成资源包 - -来到`plugins/Geyser-Spigot/extensions/geysermodelenginepackgenerator`目录 - -这里你会看见多了个`generated_pack.zip`,那就说明打包好了 +- Restart the server or reload geyser to start generating the resource pack. +- Go to `plugins/[Geyser-Folder]/extensions/geysermodelenginepackgenerator`, and you should see your pack generated! -最后一步,重载Geyser或者重启服务器加载资源包 +- Final step, reload Geyser or restart the server to load the resource pack. +- Congratulations, you've completed this tutorial! -现在可以用基岩版进服下载资源包看看是否正常生效了 +# Tips ---- +* Pay attention! The pack only regenerates when the number of models changes, you can technically speaking remove the generated_pack folder to force a reload aswell. +* You do not have to manually put the pack into the packs folder of Geyser, the extension is capable of loading the pack itself. -# 注意事项❗ +# Current issues -* `geysermodelenginepackgenerator`是检测模型的数量有变更才会执行转换打包指令,想重新生成资源包建议先删掉`generated_pack.zip`然后重启服务器重新生成资源包。记得改uuid或版本号!!! -* 在新版本中不用把这个包丢进`geyser/packs`目录,他会自己加载上 +* Multi-textures are not supported +* Please report any bugs (discord: https://discord.gg/NNNaUdAbpP) ---- +# FAQ -# 完结🤗 - -恭喜你现在学会如何使用了😎有BUG或建议请发Issues - ---- - -# 当前限制💢 - -* 不支持多纹理 -* 头部旋转跟JE不太同步 -* 待挖掘 - ---- - -# 常见问题❓ - -### 召唤模型后召唤的并非模型而是史蒂夫? - -如果你确定你根据上面的教程一步一步做了,可能是这个模型的问题? +### Where can I contact you? +You can contact me on our Discord: https://discord.gg/NNNaUdAbpP diff --git a/README_EN.md b/README_EN.md deleted file mode 100644 index 8de0a7d..0000000 --- a/README_EN.md +++ /dev/null @@ -1,83 +0,0 @@ -# GeyserModelEngine CustomEntity Fork - -> GitHub:[https://github.com/zimzaza4/GeyserModelEngine/tree/custom-entity](https://github.com/zimzaza4/GeyserModelEngine/tree/custom-entity) - -🌏 [[English](README_EN.md)] [[简体中文](README.md)] [Welcome to contribute more languages] - -# About - -this is for [GeyserCustomEntityFork](https://github.com/zimzaza4/Geyser)'s version,no support vanilla Geyser - -Unlike the master, this one is truly a custom entity - -# how to install - -Download the following plugins according to the server core - -| plugins | Link | effect | -| :--- | :---- | :--- | -| GeyserUtils | [Github](https://github.com/zimzaza4/GeyserUtils) | Get your Geyser to support calling some BE stuff | -| GeyserModelEngine | [Github](https://github.com/zimzaza4/GeyserModelEngine) | Make your bedrock support MEG4 | -| GeyserModelEnginePackGenerator | [Github](https://github.com/zimzaza4/GeyserModelEnginePackGenerator) | Help you automatically transform the model to generate resource packs | - -replace your Geyser with that Geyser fork - -put `GeyserModelEngine` in the plugins folder (only spigot) - -and `geyserutils-spigot`/`velocity`/`bungeecord` - -`GeyserModelEnginePackGenerator` `geyserutils-geyser` put into `plugins/geyser/extensions` - -Start the server to generate the relevant configuration files, and then shut down the server to install - -# convert model - -`GeyserModelEnginePackGenerator` can generate resource packs himself - -We came to `plugins/Geyser-Spigot/extensions/geysermodelenginepackgenerator/input/` - -Create a folder in this directory called the ID of the model. - -For example, if I have a model with the id `parry_knight`, name it `parry_knight` - - - -> Each model should have a separate model folder - -Then drop the model, animations, and textures into this folder intact - -The new version of BlockBench exports the bedrock model format_version as `1.21.0` -You need to change it to `1.12.0` manually -Otherwise your client will not see the model - - - -Restart the server or reload geyser to start generating resource packs - -go to `plugins/Geyser-Spigot/extensions/geysermodelenginepackgenerator` - - - -final step, reload Geyser or restart the server to load the resource pack - -# tips - -* Pay attention! It is packaged by detecting the number of models and will not execute if the number does not change. -* To repackage it is recommended to delete `generated_pack.zip` and change the uuid or version -* instead of dropping the package into the `geyser/packs` directory, it will load pack itself - -# The end - -Congratulations you now learn how to use, any bugs please send Issues - -# limit - -* Multi-textures are not supported -* To be excavated - -# FAQ - -### Why does it turn into Steve after summoning a model? - -If you're sure you did it step by step according to the tutorial above, there may be a problem with this model? - diff --git a/libs/geyserutils-spigot-1.0-SNAPSHOT.jar b/libs/geyserutils-spigot-1.0-SNAPSHOT.jar index ec7de3a..b263621 100644 Binary files a/libs/geyserutils-spigot-1.0-SNAPSHOT.jar and b/libs/geyserutils-spigot-1.0-SNAPSHOT.jar differ diff --git a/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java b/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java index ef7814c..03778ff 100644 --- a/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java +++ b/src/main/java/re/imc/geysermodelengine/GeyserModelEngine.java @@ -16,7 +16,6 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; -import re.imc.geysermodelengine.listener.AddEntityPacketListener; import re.imc.geysermodelengine.listener.ModelListener; import re.imc.geysermodelengine.listener.MountPacketListener; import re.imc.geysermodelengine.model.ModelEntity; @@ -35,7 +34,7 @@ public final class GeyserModelEngine extends JavaPlugin { private static boolean alwaysSendSkin; @Getter - private int skinSendDelay; + private int sendDelay; @Getter private int viewDistance; @@ -46,16 +45,6 @@ public final class GeyserModelEngine extends JavaPlugin { @Getter private Cache joinedPlayer; - @Getter - @Setter - private boolean spawningModelEntity = false; - - - @Getter - @Setter - private ModelEntity currentModel = null; - - @Getter private int joinSendDelay; @@ -72,8 +61,8 @@ public final class GeyserModelEngine extends JavaPlugin { // Plugin startup logic saveDefaultConfig(); // alwaysSendSkin = getConfig().getBoolean("always-send-skin"); - skinSendDelay = getConfig().getInt("skin-send-delay", 0); - viewDistance = getConfig().getInt("skin-view-distance", 60); + sendDelay = getConfig().getInt("data-send-delay", 0); + viewDistance = getConfig().getInt("entity-view-distance", 60); debug = getConfig().getBoolean("debug", false); modelEntityType = EntityType.valueOf(getConfig().getString("model-entity-type", "BAT")); joinSendDelay = getConfig().getInt("join-send-delay", 20); @@ -82,7 +71,7 @@ public final class GeyserModelEngine extends JavaPlugin { .expireAfterWrite(joinSendDelay * 50L, TimeUnit.MILLISECONDS).build(); } instance = this; - ProtocolLibrary.getProtocolManager().addPacketListener(new AddEntityPacketListener()); + // ProtocolLibrary.getProtocolManager().addPacketListener(new AddEntityPacketListener()); ProtocolLibrary.getProtocolManager().addPacketListener(new MountPacketListener()); Bukkit.getPluginManager().registerEvents(new ModelListener(), this); diff --git a/src/main/java/re/imc/geysermodelengine/listener/AddEntityPacketListener.java b/src/main/java/re/imc/geysermodelengine/listener/AddEntityPacketListener.java deleted file mode 100644 index fb22064..0000000 --- a/src/main/java/re/imc/geysermodelengine/listener/AddEntityPacketListener.java +++ /dev/null @@ -1,82 +0,0 @@ -package re.imc.geysermodelengine.listener; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.*; -import com.comphenix.protocol.reflect.StructureModifier; -import com.comphenix.protocol.wrappers.WrappedWatchableObject; -import com.ticxo.modelengine.api.ModelEngineAPI; -import com.ticxo.modelengine.api.entity.BukkitEntity; -import com.ticxo.modelengine.api.entity.Hitbox; -import com.ticxo.modelengine.api.interaction.DynamicHitbox; -import com.ticxo.modelengine.api.interaction.InteractionTracker; -import com.ticxo.modelengine.api.model.bone.type.SubHitbox; -import com.ticxo.modelengine.api.nms.entity.HitboxEntity; -import org.bukkit.Bukkit; -import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; -import org.geysermc.floodgate.api.FloodgateApi; -import org.jetbrains.annotations.NotNull; -import re.imc.geysermodelengine.GeyserModelEngine; -import re.imc.geysermodelengine.model.EntityTask; -import re.imc.geysermodelengine.model.ModelEntity; - -import java.util.Set; -import java.util.UUID; - -public class AddEntityPacketListener extends PacketAdapter { - public AddEntityPacketListener() { - super(GeyserModelEngine.getInstance(), ListenerPriority.HIGHEST, Set.of(PacketType.Play.Server.SPAWN_ENTITY), ListenerOptions.SYNC); - } - - @Override - public void onPacketSending(PacketEvent event) { - - PacketContainer packet = event.getPacket(); - StructureModifier modifier = packet.getEntityModifier(event); - Entity entity = modifier.readSafely(0); - - if (entity == null) { - return; - } - boolean isBedrock = FloodgateApi.getInstance().isFloodgatePlayer(event.getPlayer().getUniqueId()); - ModelEntity model = ModelEntity.MODEL_ENTITIES.get(entity.getEntityId()); - - - if (model != null) { - if (isBedrock) { - if (packet.getMeta("delayed").isPresent()) { - if (model.getTask().isLooping()) { - - String lastAnimation = model.getTask().getLastAnimation(); - model.getTask().playBedrockAnimation(lastAnimation, Set.of(event.getPlayer()), true, 0f); - } - return; - } - - EntityTask task = model.getTask(); - int delay = 1; - boolean firstJoined = GeyserModelEngine.getInstance().getJoinedPlayer().getIfPresent(event.getPlayer()) != null; - if (firstJoined) { - delay = GeyserModelEngine.getInstance().getJoinSendDelay(); - } - if (task == null || firstJoined) { - Bukkit.getScheduler().runTaskLater(GeyserModelEngine.getInstance(), () -> { - model.getTask().sendEntityData(event.getPlayer(), GeyserModelEngine.getInstance().getSkinSendDelay()); - }, delay); - } else { - task.sendEntityData(event.getPlayer(), GeyserModelEngine.getInstance().getSkinSendDelay()); - } - - event.setCancelled(true); - - Bukkit.getScheduler().runTaskLater(GeyserModelEngine.getInstance(), () -> { - packet.setMeta("delayed", 1); - ProtocolLibrary.getProtocolManager().sendServerPacket(event.getPlayer(), packet); - }, delay + 2); - } else { - event.setCancelled(true); - } - } - } -} diff --git a/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java b/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java index 0706c72..c50e01a 100644 --- a/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java +++ b/src/main/java/re/imc/geysermodelengine/listener/ModelListener.java @@ -97,44 +97,7 @@ public class ModelListener implements Listener { } } - @EventHandler - public void onModelHurt(EntityDamageEvent event) { - ModelEntity model = ModelEntity.MODEL_ENTITIES.get(event.getEntity().getEntityId()); - if (model != null) { - if (!event.getEntity().hasMetadata("show_damage")) { - event.setCancelled(true); - } - event.getEntity().removeMetadata("show_damage", GeyserModelEngine.getInstance()); - if (!model.getEntity().isDead()) { - event.setDamage(0); - model.getEntity().setHealth(model.getEntity().getMaxHealth()); - } - } - } - - - @EventHandler(priority = EventPriority.HIGHEST) - public void onModelEntitySpawn(EntitySpawnEvent event) { - if (GeyserModelEngine.getInstance().isSpawningModelEntity() && event.getEntity() instanceof LivingEntity entity) { - if (event.isCancelled()) { - event.setCancelled(false); - } - ModelEntity model = GeyserModelEngine.getInstance().getCurrentModel(); - int id = entity.getEntityId(); - ActiveModel activeModel = model.getActiveModel(); - ModelEntity.MODEL_ENTITIES.put(id, model); - model.applyFeatures(entity, "model." + activeModel.getBlueprint().getName()); - GeyserModelEngine.getInstance().setCurrentModel(null); - GeyserModelEngine.getInstance().setSpawningModelEntity(false); - - for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { - if (FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) { - PlayerUtils.setCustomEntity(onlinePlayer, entity.getEntityId(), "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase()); - } - } - } - } @EventHandler public void onModelEntityHurt(EntityDamageEvent event) { @@ -142,8 +105,7 @@ public class ModelListener implements Listener { if (model != null) { for (Map.Entry entry : model.entrySet()) { if (!entry.getValue().getEntity().isDead()) { - entry.getValue().getEntity().setMetadata("show_damage", new FixedMetadataValue(GeyserModelEngine.getInstance(), true)); - entry.getValue().getEntity().damage(0); + entry.getValue().getEntity().sendHurtPacket(entry.getValue().getViewers()); } } @@ -164,20 +126,6 @@ public class ModelListener implements Listener { */ - @EventHandler - public void onModelHit(ProjectileHitEvent event) { - if (event.getHitEntity() == null) { - return; - } - ModelEntity model = ModelEntity.MODEL_ENTITIES.get(event.getHitEntity().getEntityId()); - if (model != null) { - - event.setCancelled(true); - model.getEntity().setHealth(model.getEntity().getMaxHealth()); - - } - } - @EventHandler public void onAnimationEnd(AnimationEndEvent event) { diff --git a/src/main/java/re/imc/geysermodelengine/listener/MountPacketListener.java b/src/main/java/re/imc/geysermodelengine/listener/MountPacketListener.java index 7d1dbb7..cfdab1a 100644 --- a/src/main/java/re/imc/geysermodelengine/listener/MountPacketListener.java +++ b/src/main/java/re/imc/geysermodelengine/listener/MountPacketListener.java @@ -41,15 +41,12 @@ public class MountPacketListener extends PacketAdapter { if (event.getPlayer().getInventory().getHeldItemSlot() == 0) { event.getPacket().getBooleans().writeSafely(0, true); event.getPlayer().getInventory().setHeldItemSlot(3); - event.getPlayer().sendActionBar("jump"); } if (pitch > 89 || event.getPlayer().getInventory().getHeldItemSlot() == 1) { event.getPacket().getBooleans().writeSafely(1, true); - event.getPlayer().sendActionBar("shift"); } if (event.getPlayer().getInventory().getHeldItemSlot() == 8) { event.getPacket().getBooleans().writeSafely(0, true); - event.getPlayer().sendActionBar("hold jump"); } } } diff --git a/src/main/java/re/imc/geysermodelengine/model/EntityTask.java b/src/main/java/re/imc/geysermodelengine/model/EntityTask.java index 452d54c..e33aba5 100644 --- a/src/main/java/re/imc/geysermodelengine/model/EntityTask.java +++ b/src/main/java/re/imc/geysermodelengine/model/EntityTask.java @@ -2,9 +2,9 @@ package re.imc.geysermodelengine.model; import com.ticxo.modelengine.api.animation.BlueprintAnimation; import com.ticxo.modelengine.api.entity.BaseEntity; -import com.ticxo.modelengine.api.entity.BukkitEntity; import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ModeledEntity; +import com.ticxo.modelengine.api.model.bone.ModelBone; import lombok.Getter; import lombok.Setter; import me.zimzaza4.geyserutils.common.animation.Animation; @@ -13,13 +13,13 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; -import org.bukkit.util.BoundingBox; import org.geysermc.floodgate.api.FloodgateApi; -import org.jetbrains.annotations.NotNull; +import org.joml.Vector3f; import re.imc.geysermodelengine.GeyserModelEngine; -import re.imc.geysermodelengine.listener.ModelListener; +import re.imc.geysermodelengine.packet.entity.PacketEntity; -import java.util.Set; +import java.awt.*; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import static re.imc.geysermodelengine.model.ModelEntity.ENTITIES; @@ -37,11 +37,18 @@ public class EntityTask { AtomicInteger animationCooldown = new AtomicInteger(0); AtomicInteger currentAnimationPriority = new AtomicInteger(0); - boolean firstAnimation = true; boolean spawnAnimationPlayed = false; boolean removed = false; + float lastScale = -1.0f; + Color lastColor = null; + Map lastModelBoneSet = new HashMap<>(); + + String lastAnimation = ""; + String currentAnimProperty = "anim_spawn"; + String lastAnimProperty = ""; + boolean looping = true; private BukkitRunnable syncTask; @@ -52,39 +59,17 @@ public class EntityTask { public EntityTask(ModelEntity model) { this.model = model; } - - public void runSync() { - - syncTick ++; - if (syncTick > 400) { - syncTick = 0; - } - - if (syncTick % 5 == 0) { - - for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { - if (!FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) { - onlinePlayer.hideEntity(GeyserModelEngine.getInstance(), model.getEntity()); - } - } - } - - if (!removed && model.getEntity().isDead() && model.getModeledEntity().getBase().isAlive() && !model.getActiveModel().isRemoved()) { - // model.spawnEntity(); - } - - model.getEntity().setVisualFire(false); - model.teleportToModel(); - } public void runAsync() { - Entity entity = model.getEntity(); + PacketEntity entity = model.getEntity(); if (entity.isDead()) { return; } + + model.teleportToModel(); Set viewers = model.getViewers(); ActiveModel activeModel = model.getActiveModel(); ModeledEntity modeledEntity = model.getModeledEntity(); - if (activeModel.isRemoved() || !modeledEntity.getBase().isAlive()) { + if (activeModel.isDestroyed() || activeModel.isRemoved() || !modeledEntity.getBase().isAlive()) { if (!activeModel.isRemoved() && hasAnimation("death")) { new BukkitRunnable() { @Override @@ -108,26 +93,12 @@ public class EntityTask { cancel(); return; } - /* - if (model.getEntity().isDead()) { - ENTITIES.remove(modeledEntity.getBase().getEntityId()); - MODEL_ENTITIES.remove(entity.getEntityId()); - cancel(); - return; - } - - */ - /* - if (waitingTick > 0) { - waitingTick--; - } - */ if (!spawnAnimationPlayed) { spawnAnimationPlayed = true; } - if (tick > 1 && tick % 5 == 0) { + if (tick % 5 == 0) { for (Player onlinePlayer : Bukkit.getOnlinePlayers()) { if (FloodgateApi.getInstance().isFloodgatePlayer(onlinePlayer.getUniqueId())) { @@ -135,22 +106,14 @@ public class EntityTask { if (canSee(onlinePlayer, model.getEntity())) { if (!viewers.contains(onlinePlayer)) { + sendSpawnPacket(onlinePlayer); viewers.add(onlinePlayer); - /* - if (GeyserModelEngine.getInstance().getSkinSendDelay() > 0) { - sendEntityData(onlinePlayer, GeyserModelEngine.getInstance().getSkinSendDelay()); - } else { - PlayerUtils.sendCustomSkin(onlinePlayer, model.getEntity(), activeModel.getBlueprint().getName()); - - Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> { - sendHitBox(onlinePlayer); - }, 2); - } - - */ } } else { - viewers.remove(onlinePlayer); + if (viewers.contains(onlinePlayer)) { + entity.sendEntityDestroyPacket(Collections.singletonList(onlinePlayer)); + viewers.remove(onlinePlayer); + } } } } @@ -162,20 +125,10 @@ public class EntityTask { if (!canSee(viewer, model.getEntity())) { viewers.remove(viewer); } - - /* - - if (GeyserModelEngine.isAlwaysSendSkin()) { - PlayerUtils.sendCustomSkin(viewer, model.getEntity(), activeModel.getBlueprint().getName()); - - } - - */ } } } - tick ++; if (tick > 400) { tick = 0; @@ -191,35 +144,123 @@ public class EntityTask { } else if (base.isJumping() && hasAnimation("jump")) { playAnimation("jump", 30); } else if (base.isWalking() && hasAnimation("walk")) { - playAnimation("walk", 20); + setAnimationProperty("modelengine:anim_walk"); + // playAnimation("walk", 20); } else if (hasAnimation("idle")) { - playAnimation("idle", 0); + // playAnimation("idle", 0); + setAnimationProperty("modelengine:anim_idle"); } if (animationCooldown.get() > 0) { animationCooldown.decrementAndGet(); } + + Optional player = viewers.stream().findAny(); + if (player.isEmpty()) return; + + // i think properties need send to all players + // because lastSet + viewers.forEach(viewer -> updateEntityProperties(player.get(), false)); + + // do not actually use this, atleast bundle these up ;( + sendScale(player.get(), true); + sendColor(player.get(), true); + } + + private void sendSpawnPacket(Player onlinePlayer) { + EntityTask task = model.getTask(); + int delay = 1; + boolean firstJoined = GeyserModelEngine.getInstance().getJoinedPlayer().getIfPresent(onlinePlayer) != null; + if (firstJoined) { + delay = GeyserModelEngine.getInstance().getJoinSendDelay(); + } + if (task == null || firstJoined) { + Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> { + model.getTask().sendEntityData(onlinePlayer, GeyserModelEngine.getInstance().getSendDelay()); + }, delay); + } else { + task.sendEntityData(onlinePlayer, GeyserModelEngine.getInstance().getSendDelay()); + } } public void sendEntityData(Player player, int delay) { - // System.out.println("TYPE: " + "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase()); PlayerUtils.setCustomEntity(player, model.getEntity().getEntityId(), "modelengine:" + model.getActiveModel().getBlueprint().getName().toLowerCase()); Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> { // PlayerUtils.sendCustomSkin(player, model.getEntity(), model.getActiveModel().getBlueprint().getName()); - if (looping) { - playBedrockAnimation(lastAnimation, Set.of(player), looping, 0f); - } - sendHitBox(player); - sendScale(player); + model.getEntity().sendSpawnPacket(Collections.singletonList(player)); + Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> { + if (looping) { + playBedrockAnimation(lastAnimation, Set.of(player), looping, 0f); + } sendHitBox(player); + sendScale(player, true); + updateEntityProperties(player, true); }, 8); }, delay); } - public void sendScale(Player player) { - // todo? + public void sendScale(Player player, boolean ignore) { + if (player == null) return; + + Vector3f scale = model.getActiveModel().getScale(); + float average = (scale.x + scale.y + scale.z) / 3; + if (average == lastScale) return; + + PlayerUtils.sendCustomScale(player, model.getEntity(), average); + + if (ignore) return; + lastScale = average; + } + + public void sendColor(Player player, boolean ignore) { + if (player == null) return; + + Color color = new Color(model.getActiveModel().getDefaultTint().asARGB()); + if (color.equals(lastColor)) return; + + PlayerUtils.sendCustomColor(player, model.getEntity(), color); + + if (ignore) return; + lastColor = color; + } + + public void setAnimationProperty(String currentAnimProperty) { + this.lastAnimProperty = currentAnimProperty; + this.currentAnimProperty = currentAnimProperty; + } + + public void updateEntityProperties(Player player, boolean ignore) { + Entity entity = model.getEntity(); + + Map updates = new HashMap<>(); + model.getActiveModel().getBones().forEach((s,bone) -> { + if (!lastModelBoneSet.containsKey(bone)) lastModelBoneSet.put(bone, !bone.isVisible()); + + if (!lastModelBoneSet.get(bone).equals(bone.isVisible()) || ignore) { + String name = unstripName(bone).toLowerCase(); + updates.put(model.getActiveModel().getBlueprint().getName() + ":" + name, bone.isVisible()); + lastModelBoneSet.replace(bone, bone.isVisible()); + } + + }); + if (ignore || !lastAnimProperty.equals(currentAnimProperty)) { + updates.put(lastAnimProperty, false); + updates.put(currentAnimProperty, true); + } + if (updates.isEmpty()) return; + PlayerUtils.sendBoolProperties(player, entity, updates); + } + + private String unstripName(ModelBone bone) { + String name = bone.getBoneId(); + if (bone.getBlueprintBone().getBehaviors().get("head") != null) { + if (!bone.getBlueprintBone().getBehaviors().get("head").isEmpty()) return "hi_" + name; + return "h_" + name; + } + + return name; } public void sendHitBoxToAll() { @@ -262,17 +303,10 @@ public class EntityTask { } else if (animationCooldown.get() == 0) { play = true; } - boolean delaySend = false; - if (firstAnimation) { - delaySend = true; - firstAnimation = false; - } - boolean lastLoopState = looping; looping = forceLoop || animationProperty.getLoopMode() == BlueprintAnimation.LoopMode.LOOP;; if (lastAnimation.equals(animation)) { if (looping) { - // play = waitingTick == 1; play = false; } } @@ -280,34 +314,20 @@ public class EntityTask { if (play) { + setAnimationProperty("modelengine:anim_stop"); + model.getViewers().forEach(viewer -> updateEntityProperties(viewer, false)); currentAnimationPriority.set(p); - if (lastLoopState && !lastAnimation.equals(animation)) { - // clearLoopAnimation(); - // delaySend = true; - } - String id = "animation." + activeModel.getBlueprint().getName().toLowerCase() + "." + animationProperty.getName().toLowerCase(); lastAnimation = id; animationCooldown.set((int) (animationProperty.getLength() * 20)); - if (delaySend) { - Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> playBedrockAnimation(id, model.getViewers(), looping, blendTime), 0); - } else { - playBedrockAnimation(id, model.getViewers(), looping, blendTime); - } + playBedrockAnimation(id, model.getViewers(), looping, blendTime); } return animationCooldown.get(); } - /* - private void clearLoopAnimation() { - playStopBedrockAnimation(lastAnimation); - - } - - - private void playStopBedrockAnimation(String animationId) { + public void playStopBedrockAnimation(String animationId) { Entity entity = model.getEntity(); Set viewers = model.getViewers(); @@ -328,7 +348,7 @@ public class EntityTask { } - */ + public void playBedrockAnimation(String animationId, Set viewers, boolean loop, float blendTime) { // model.getViewers().forEach(viewer -> viewer.sendActionBar("CURRENT AN:" + animationId)); @@ -355,9 +375,6 @@ public class EntityTask { if (player.isDead()) { return false; } - if (player.getWorld() != entity.getWorld()) { - return false; - } if (GeyserModelEngine.getInstance().getJoinedPlayer() != null && GeyserModelEngine.getInstance().getJoinedPlayer().getIfPresent(player) != null) { return false; } @@ -377,7 +394,7 @@ public class EntityTask { } public void cancel() { - syncTask.cancel(); + // syncTask.cancel(); asyncTask.cancel(); } @@ -393,13 +410,6 @@ public class EntityTask { lastAnimation = id; sendHitBoxToAll(); - syncTask = new BukkitRunnable() { - @Override - public void run() { - runSync(); - } - }; - syncTask.runTaskTimer(instance, i, 0); asyncTask = new BukkitRunnable() { @Override diff --git a/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java b/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java index 1025ddb..c175edd 100644 --- a/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java +++ b/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java @@ -1,8 +1,6 @@ package re.imc.geysermodelengine.model; import com.google.common.collect.Sets; -import com.ticxo.modelengine.api.ModelEngineAPI; -import com.ticxo.modelengine.api.entity.BukkitEntity; import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ModeledEntity; import lombok.Getter; @@ -10,8 +8,8 @@ import org.bukkit.Location; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.metadata.FixedMetadataValue; -import org.bukkit.util.Vector; import re.imc.geysermodelengine.GeyserModelEngine; +import re.imc.geysermodelengine.packet.entity.PacketEntity; import java.util.HashMap; import java.util.Map; @@ -25,8 +23,7 @@ public class ModelEntity { public static Map MODEL_ENTITIES = new ConcurrentHashMap<>(); - private LivingEntity entity; - private BukkitEntity controllerEntity; + private PacketEntity entity; private final Set viewers = Sets.newConcurrentHashSet(); @@ -41,29 +38,11 @@ public class ModelEntity { this.activeModel = model; this.entity = spawnEntity(); runEntityTask(); - } public void teleportToModel() { Location location = modeledEntity.getBase().getLocation(); - /* - location.setPitch(modeledEntity.getXHeadRot()); - location.setYaw(modeledEntity.getYHeadRot()); - for (Player viewer : viewers) { - viewer.sendActionBar("X:" + modeledEntity.getXHeadRot() + ", Y:" + modeledEntity.getYHeadRot()); - } - - */ - Vector vector = modeledEntity.getBase().getMoveController().getVelocity(); - ModelEngineAPI.getEntityHandler().setPosition(entity, location.getX(), location.getY(), location.getZ()); - // ModelEngineAPI.getEntityHandler().movePassenger(entity, location.getX(), location.getY(), location.getZ()); - controllerEntity.getMoveController().setVelocity(vector.getX(), vector.getY(), vector.getZ()); - if (modeledEntity.getBase() instanceof BukkitEntity bukkitEntity && bukkitEntity.getOriginal() instanceof LivingEntity livingEntity) { - controllerEntity.getLookController().setHeadYaw(livingEntity.getEyeLocation().getYaw()); - controllerEntity.getLookController().setPitch(livingEntity.getEyeLocation().getPitch()); - controllerEntity.getLookController().setBodyYaw(livingEntity.getBodyYaw()); - } - + entity.teleport(location); } public static ModelEntity create(ModeledEntity entity, ActiveModel model) { ModelEntity modelEntity = new ModelEntity(entity, model); @@ -79,14 +58,8 @@ public class ModelEntity { return modelEntity; } - public LivingEntity spawnEntity() { - ModelEntity model = this; - // int lastEntityId = ReflectionManager.getNewEntityId(); - // System.out.println("RID:" + entityId); - GeyserModelEngine.getInstance().setSpawningModelEntity(true); - GeyserModelEngine.getInstance().setCurrentModel(model); - entity = (LivingEntity) modeledEntity.getBase().getLocation().getWorld().spawnEntity(modeledEntity.getBase().getLocation(), GeyserModelEngine.getInstance().getModelEntityType()); - controllerEntity = new BukkitEntity(entity); + public PacketEntity spawnEntity() { + entity = new PacketEntity(GeyserModelEngine.getInstance().getModelEntityType(), viewers, modeledEntity.getBase().getLocation()); return entity; } @@ -96,30 +69,4 @@ public class ModelEntity { } - public void applyFeatures(LivingEntity display, String name) { - display.setGravity(false); - display.setMaxHealth(2048); - display.setHealth(2048); - display.setMetadata("model_entity", new FixedMetadataValue(GeyserModelEngine.getInstance(), true)); - - //display.setInvulnerable(true); - - display.setAI(false); - display.setSilent(true); - display.setPersistent(false); - - // armorStand.setVisible(false); - - /* - String uuid = UUID.randomUUID().toString(); - MobDisguise disguise = new MobDisguise(DisguiseType.getType(entity.getType())); - disguise.setDisguiseName(uuid); - - DisguiseAPI.disguiseEntity(display, disguise); - - */ - - } - - } diff --git a/src/main/java/re/imc/geysermodelengine/packet/EntityDestroyPacket.java b/src/main/java/re/imc/geysermodelengine/packet/EntityDestroyPacket.java new file mode 100644 index 0000000..de628ec --- /dev/null +++ b/src/main/java/re/imc/geysermodelengine/packet/EntityDestroyPacket.java @@ -0,0 +1,22 @@ +package re.imc.geysermodelengine.packet; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; + +import java.util.Collections; + +public class EntityDestroyPacket implements WrapperPacket { + + private final int id; + + public EntityDestroyPacket(int id) { + this.id = id; + } + + @Override + public PacketContainer encode() { + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); + packet.getIntLists().write(0, Collections.singletonList(this.id)); + return packet; + } +} diff --git a/src/main/java/re/imc/geysermodelengine/packet/EntityHurtAnimationPacket.java b/src/main/java/re/imc/geysermodelengine/packet/EntityHurtAnimationPacket.java new file mode 100644 index 0000000..975c445 --- /dev/null +++ b/src/main/java/re/imc/geysermodelengine/packet/EntityHurtAnimationPacket.java @@ -0,0 +1,21 @@ +package re.imc.geysermodelengine.packet; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; + +public class EntityHurtAnimationPacket implements WrapperPacket { + + private final int id; + + public EntityHurtAnimationPacket(int id) { + this.id = id; + } + + @Override + public PacketContainer encode() { + PacketContainer packet = new PacketContainer(PacketType.Play.Server.HURT_ANIMATION); + packet.getIntegers().write(0, id); + packet.getFloat().write(0, 1f); + return packet; + } +} diff --git a/src/main/java/re/imc/geysermodelengine/packet/EntityMetadataPacket.java b/src/main/java/re/imc/geysermodelengine/packet/EntityMetadataPacket.java new file mode 100644 index 0000000..edc32d6 --- /dev/null +++ b/src/main/java/re/imc/geysermodelengine/packet/EntityMetadataPacket.java @@ -0,0 +1,22 @@ +package re.imc.geysermodelengine.packet; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; + +public class EntityMetadataPacket implements WrapperPacket { + private final int id; + + public EntityMetadataPacket(int id) { + this.id = id; + } + + @Override + public PacketContainer encode() { + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); + packet.getIntegers().write(0, id); + WrappedDataWatcher watcher = new WrappedDataWatcher(); + packet.getWatchableCollectionModifier().writeSafely(0, watcher.getWatchableObjects()); + return packet; + } +} diff --git a/src/main/java/re/imc/geysermodelengine/packet/EntitySpawnPacket.java b/src/main/java/re/imc/geysermodelengine/packet/EntitySpawnPacket.java new file mode 100644 index 0000000..7dea6c5 --- /dev/null +++ b/src/main/java/re/imc/geysermodelengine/packet/EntitySpawnPacket.java @@ -0,0 +1,44 @@ +package re.imc.geysermodelengine.packet; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import org.bukkit.Location; +import org.bukkit.entity.EntityType; + +import java.util.UUID; + +public class EntitySpawnPacket implements WrapperPacket { + + private final int id; + private final UUID uuid; + private final EntityType type; + private final Location location; + public EntitySpawnPacket(int entityID, UUID uuid, EntityType type, Location location) { + this.id = entityID; + this.uuid = uuid; + this.type = type; + this.location = location; + } + + @Override + public PacketContainer encode() { + PacketContainer packet = ProtocolLibrary.getProtocolManager() + .createPacket(PacketType.Play.Server.SPAWN_ENTITY); + packet.getIntegers() + .write(0, this.id); + packet.getUUIDs() + .write(0, this.uuid); + packet.getDoubles() + .write(0, this.location.getX()) + .write(1, this.location.getY()) + .write(2, this.location.getZ()); + packet.getBytes() + .write(0, (byte) (this.location.getYaw() * 256.0F / 360.0F)) + .write(1, (byte) (this.location.getPitch() * 256.0F / 360.0F)); + packet.getEntityTypeModifier() + .writeSafely(0, type); + + return packet; + } +} diff --git a/src/main/java/re/imc/geysermodelengine/packet/EntityTeleportPacket.java b/src/main/java/re/imc/geysermodelengine/packet/EntityTeleportPacket.java new file mode 100644 index 0000000..9dbd221 --- /dev/null +++ b/src/main/java/re/imc/geysermodelengine/packet/EntityTeleportPacket.java @@ -0,0 +1,27 @@ +package re.imc.geysermodelengine.packet; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.PacketContainer; +import org.bukkit.Location; + +public class EntityTeleportPacket implements WrapperPacket { + + private final int id; + private final Location loc; + + public EntityTeleportPacket(int entityID, Location location) { + this.id = entityID; + this.loc = location; + } + @Override + public PacketContainer encode() { + PacketContainer packet = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); + packet.getIntegers().write(0, this.id); + packet.getDoubles().write(0, loc.getX()); + packet.getDoubles().write(1, loc.getY()); + packet.getDoubles().write(2, loc.getZ()); + packet.getBytes().write(1, (byte) (loc.getPitch() * 256.0F / 360.0F)); + packet.getBytes().write(0, (byte) (loc.getYaw() * 256.0F / 360.0F)); + return packet; + } +} diff --git a/src/main/java/re/imc/geysermodelengine/packet/WrapperPacket.java b/src/main/java/re/imc/geysermodelengine/packet/WrapperPacket.java new file mode 100644 index 0000000..1ccb3a1 --- /dev/null +++ b/src/main/java/re/imc/geysermodelengine/packet/WrapperPacket.java @@ -0,0 +1,9 @@ +package re.imc.geysermodelengine.packet; + +import com.comphenix.protocol.events.PacketContainer; + +public interface WrapperPacket { + + default WrapperPacket decode() { return null; }; + default PacketContainer encode() { return null; }; +} diff --git a/src/main/java/re/imc/geysermodelengine/packet/entity/PacketEntity.java b/src/main/java/re/imc/geysermodelengine/packet/entity/PacketEntity.java new file mode 100644 index 0000000..c355ecd --- /dev/null +++ b/src/main/java/re/imc/geysermodelengine/packet/entity/PacketEntity.java @@ -0,0 +1,803 @@ +package re.imc.geysermodelengine.packet.entity; + +import com.comphenix.protocol.ProtocolLibrary; +import io.papermc.paper.entity.TeleportFlag; +import io.papermc.paper.threadedregions.scheduler.EntityScheduler; +import net.kyori.adventure.text.Component; +import org.bukkit.*; +import org.bukkit.block.BlockFace; +import org.bukkit.block.PistonMoveReaction; +import org.bukkit.entity.*; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.metadata.MetadataValue; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.permissions.PermissionAttachmentInfo; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.plugin.Plugin; +import org.bukkit.util.BoundingBox; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import re.imc.geysermodelengine.packet.*; + +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ThreadLocalRandom; + +public class PacketEntity implements Entity { + public PacketEntity(EntityType type, Set viewers, Location location) { + this.id = ThreadLocalRandom.current().nextInt(20000, 100000000); + this.uuid = UUID.randomUUID(); + this.type = type; + this.viewers = viewers; + this.location = location; + } + + private int id; + private UUID uuid; + private EntityType type; + private Set viewers; + private Location location; + private boolean removed = false; + @Override + public @NotNull Location getLocation() { + return location; + } + + @Override + public boolean teleport(@NotNull Location location) { + this.location = location.clone(); + sendLocationPacket(viewers); + return true; + } + + + + @Override + public void remove() { + removed = true; + sendEntityDestroyPacket(viewers); + } + + @Override + public boolean isDead() { + return removed; + } + + @Override + public boolean isValid() { + return !removed; + } + + public void sendSpawnPacket(Collection players) { + EntitySpawnPacket packet = new EntitySpawnPacket(id, uuid, type, location); + EntityMetadataPacket metadataPacket = new EntityMetadataPacket(id); + players.forEach(player -> ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet.encode())); + players.forEach(player -> ProtocolLibrary.getProtocolManager().sendServerPacket(player, metadataPacket.encode())); + } + public void sendLocationPacket(Collection players) { + EntityTeleportPacket packet = new EntityTeleportPacket(id, location); + players.forEach(player -> ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet.encode())); + + } + + public void sendHurtPacket(Collection players) { + EntityHurtAnimationPacket packet = new EntityHurtAnimationPacket(id); + players.forEach(player -> ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet.encode())); + } + + public void sendEntityDestroyPacket(Collection players) { + EntityDestroyPacket packet = new EntityDestroyPacket(id); + players.forEach(player -> ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet.encode())); + } + + @Override + public int getEntityId() { + return id; + } + + // ---------------- + + @Override + public @Nullable Location getLocation(@Nullable Location location) { + return null; + } + + @Override + public void setVelocity(@NotNull Vector vector) { + + } + + @Override + public @NotNull Vector getVelocity() { + return null; + } + + @Override + public double getHeight() { + return 0; + } + + @Override + public double getWidth() { + return 0; + } + + @Override + public @NotNull BoundingBox getBoundingBox() { + return null; + } + + @Override + public boolean isOnGround() { + return false; + } + + @Override + public boolean isInWater() { + return false; + } + + @Override + public @NotNull World getWorld() { + return null; + } + + @Override + public void setRotation(float v, float v1) { + + } + + @Override + public boolean teleport(@NotNull Location location, PlayerTeleportEvent.@NotNull TeleportCause teleportCause, @NotNull TeleportFlag @NotNull ... teleportFlags) { + return false; + } + + + + @Override + public boolean teleport(@NotNull Location location, PlayerTeleportEvent.@NotNull TeleportCause teleportCause) { + return false; + } + + @Override + public boolean teleport(@NotNull Entity entity) { + return false; + } + + @Override + public boolean teleport(@NotNull Entity entity, PlayerTeleportEvent.@NotNull TeleportCause teleportCause) { + return false; + } + + @Override + public @NotNull CompletableFuture teleportAsync(@NotNull Location location, PlayerTeleportEvent.@NotNull TeleportCause teleportCause, @NotNull TeleportFlag @NotNull ... teleportFlags) { + return null; + } + + @Override + public @NotNull List getNearbyEntities(double v, double v1, double v2) { + return null; + } + + + + @Override + public int getFireTicks() { + return 0; + } + + @Override + public int getMaxFireTicks() { + return 0; + } + + @Override + public void setFireTicks(int i) { + + } + + @Override + public void setVisualFire(boolean b) { + + } + + @Override + public boolean isVisualFire() { + return false; + } + + @Override + public int getFreezeTicks() { + return 0; + } + + @Override + public int getMaxFreezeTicks() { + return 0; + } + + @Override + public void setFreezeTicks(int i) { + + } + + @Override + public boolean isFrozen() { + return false; + } + + @Override + public void setInvisible(boolean b) { + + } + + @Override + public boolean isInvisible() { + return false; + } + + @Override + public void setNoPhysics(boolean b) { + + } + + @Override + public boolean hasNoPhysics() { + return false; + } + + @Override + public boolean isFreezeTickingLocked() { + return false; + } + + @Override + public void lockFreezeTicks(boolean b) { + + } + + + @Override + public void sendMessage(@NotNull String s) { + + } + + @Override + public void sendMessage(@NotNull String... strings) { + + } + + @Override + public void sendMessage(@Nullable UUID uuid, @NotNull String s) { + + } + + @Override + public void sendMessage(@Nullable UUID uuid, @NotNull String... strings) { + + } + + @Override + public @NotNull Server getServer() { + return null; + } + + @Override + public @NotNull String getName() { + return null; + } + + @Override + public boolean isPersistent() { + return false; + } + + @Override + public void setPersistent(boolean b) { + + } + + @Override + public @Nullable Entity getPassenger() { + return null; + } + + @Override + public boolean setPassenger(@NotNull Entity entity) { + return false; + } + + @Override + public @NotNull List getPassengers() { + return null; + } + + @Override + public boolean addPassenger(@NotNull Entity entity) { + return false; + } + + @Override + public boolean removePassenger(@NotNull Entity entity) { + return false; + } + + @Override + public boolean isEmpty() { + return false; + } + + @Override + public boolean eject() { + return false; + } + + @Override + public float getFallDistance() { + return 0; + } + + @Override + public void setFallDistance(float v) { + + } + + @Override + public void setLastDamageCause(@Nullable EntityDamageEvent entityDamageEvent) { + + } + + @Override + public @Nullable EntityDamageEvent getLastDamageCause() { + return null; + } + + @Override + public @NotNull UUID getUniqueId() { + return null; + } + + @Override + public int getTicksLived() { + return 0; + } + + @Override + public void setTicksLived(int i) { + + } + + @Override + public void playEffect(@NotNull EntityEffect entityEffect) { + + } + + @Override + public @NotNull EntityType getType() { + return null; + } + + @Override + public @NotNull Sound getSwimSound() { + return null; + } + + @Override + public @NotNull Sound getSwimSplashSound() { + return null; + } + + @Override + public @NotNull Sound getSwimHighSpeedSplashSound() { + return null; + } + + @Override + public boolean isInsideVehicle() { + return false; + } + + @Override + public boolean leaveVehicle() { + return false; + } + + @Override + public @Nullable Entity getVehicle() { + return null; + } + + @Override + public void setCustomNameVisible(boolean b) { + + } + + @Override + public boolean isCustomNameVisible() { + return false; + } + + @Override + public void setVisibleByDefault(boolean b) { + + } + + @Override + public boolean isVisibleByDefault() { + return false; + } + + @Override + public @NotNull Set getTrackedBy() { + return null; + } + + @Override + public void setGlowing(boolean b) { + + } + + @Override + public boolean isGlowing() { + return false; + } + + @Override + public void setInvulnerable(boolean b) { + + } + + @Override + public boolean isInvulnerable() { + return false; + } + + @Override + public boolean isSilent() { + return false; + } + + @Override + public void setSilent(boolean b) { + + } + + @Override + public boolean hasGravity() { + return false; + } + + @Override + public void setGravity(boolean b) { + + } + + @Override + public int getPortalCooldown() { + return 0; + } + + @Override + public void setPortalCooldown(int i) { + + } + + @Override + public @NotNull Set getScoreboardTags() { + return null; + } + + @Override + public boolean addScoreboardTag(@NotNull String s) { + return false; + } + + @Override + public boolean removeScoreboardTag(@NotNull String s) { + return false; + } + + @Override + public @NotNull PistonMoveReaction getPistonMoveReaction() { + return null; + } + + @Override + public @NotNull BlockFace getFacing() { + return null; + } + + @Override + public @NotNull Pose getPose() { + return null; + } + + @Override + public boolean isSneaking() { + return false; + } + + @Override + public void setSneaking(boolean b) { + + } + + @Override + public void setPose(@NotNull Pose pose, boolean b) { + + } + + @Override + public boolean hasFixedPose() { + return false; + } + + @Override + public @NotNull SpawnCategory getSpawnCategory() { + return null; + } + + @Override + public boolean isInWorld() { + return false; + } + + @Override + public @Nullable EntitySnapshot createSnapshot() { + return null; + } + + @Override + public @NotNull Entity copy() { + return null; + } + + @Override + public @NotNull Entity copy(@NotNull Location location) { + return null; + } + + @Override + public @NotNull Spigot spigot() { + return null; + } + + @Override + public @NotNull Component name() { + return null; + } + + @Override + public @NotNull Component teamDisplayName() { + return null; + } + + @Override + public @Nullable Location getOrigin() { + return null; + } + + @Override + public boolean fromMobSpawner() { + return false; + } + + @Override + public CreatureSpawnEvent.@NotNull SpawnReason getEntitySpawnReason() { + return null; + } + + @Override + public boolean isUnderWater() { + return false; + } + + @Override + public boolean isInRain() { + return false; + } + + @Override + public boolean isInBubbleColumn() { + return false; + } + + @Override + public boolean isInWaterOrRain() { + return false; + } + + @Override + public boolean isInWaterOrBubbleColumn() { + return false; + } + + @Override + public boolean isInWaterOrRainOrBubbleColumn() { + return false; + } + + @Override + public boolean isInLava() { + return false; + } + + @Override + public boolean isTicking() { + return false; + } + + @Override + public @NotNull Set getTrackedPlayers() { + return null; + } + + @Override + public boolean spawnAt(@NotNull Location location, CreatureSpawnEvent.@NotNull SpawnReason spawnReason) { + return false; + } + + @Override + public boolean isInPowderedSnow() { + return false; + } + + @Override + public double getX() { + return 0; + } + + @Override + public double getY() { + return 0; + } + + @Override + public double getZ() { + return 0; + } + + @Override + public float getPitch() { + return 0; + } + + @Override + public float getYaw() { + return 0; + } + + @Override + public boolean collidesAt(@NotNull Location location) { + return false; + } + + @Override + public boolean wouldCollideUsing(@NotNull BoundingBox boundingBox) { + return false; + } + + @Override + public @NotNull EntityScheduler getScheduler() { + return null; + } + + @Override + public @NotNull String getScoreboardEntryName() { + return null; + } + + @Override + public @Nullable Component customName() { + return null; + } + + @Override + public void customName(@Nullable Component component) { + + } + + @Override + public @Nullable String getCustomName() { + return null; + } + + @Override + public void setCustomName(@Nullable String s) { + + } + + @Override + public void setMetadata(@NotNull String s, @NotNull MetadataValue metadataValue) { + + } + + @Override + public @NotNull List getMetadata(@NotNull String s) { + return null; + } + + @Override + public boolean hasMetadata(@NotNull String s) { + return false; + } + + @Override + public void removeMetadata(@NotNull String s, @NotNull Plugin plugin) { + + } + + @Override + public boolean isPermissionSet(@NotNull String s) { + return false; + } + + @Override + public boolean isPermissionSet(@NotNull Permission permission) { + return false; + } + + @Override + public boolean hasPermission(@NotNull String s) { + return false; + } + + @Override + public boolean hasPermission(@NotNull Permission permission) { + return false; + } + + @Override + public @NotNull PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String s, boolean b) { + return null; + } + + @Override + public @NotNull PermissionAttachment addAttachment(@NotNull Plugin plugin) { + return null; + } + + @Override + public @Nullable PermissionAttachment addAttachment(@NotNull Plugin plugin, @NotNull String s, boolean b, int i) { + return null; + } + + @Override + public @Nullable PermissionAttachment addAttachment(@NotNull Plugin plugin, int i) { + return null; + } + + @Override + public void removeAttachment(@NotNull PermissionAttachment permissionAttachment) { + + } + + @Override + public void recalculatePermissions() { + + } + + @Override + public @NotNull Set getEffectivePermissions() { + return null; + } + + @Override + public boolean isOp() { + return false; + } + + @Override + public void setOp(boolean b) { + + } + + @Override + public @NotNull PersistentDataContainer getPersistentDataContainer() { + return null; + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index eee40f1..bf38848 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,5 @@ -skin-send-delay: 0 -skin-view-distance: 50 +data-send-delay: 5 +entity-view-distance: 50 join-send-delay: 20 model-entity-type: BAT # must be a living entity debug: false \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index c7c9df6..5c607b9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,9 @@ name: GeyserModelEngine version: '${project.version}' main: re.imc.geysermodelengine.GeyserModelEngine +authors: + - zimzaza4 + - willem.dev api-version: '1.19' depend: - ModelEngine