diff --git a/README.md b/README.md index c48f9af..bc8f3f4 100644 --- a/README.md +++ b/README.md @@ -1,107 +1,72 @@ -# GeyserModelEngine 自定义实体分支 +# GeyserModelEngine Fork -> GitHub仓库:[https://github.com/zimzaza4/GeyserModelEngine/tree/custom-entity](https://github.com/zimzaza4/GeyserModelEngine/tree/custom-entity) +> GitHub:[https://github.com/zimzaza4/GeyserModelEngine/tree/custom-entity](https://github.com/OmeWillem/GeyserModelEngine/tree/custom-entity) -> [Discord](https://discord.gg/NNNaUdAbpP) ---- +# About -🌏 Language 🌏 +This is a fork of the GeyserModelEngine made by [zimzaza4](https://github.com/zimzaza4/GeyserModelEngine/tree/custom-entity). +This fork adds a bunch of stuff (alongside more recent bug fixes) like: +- Part Visibility +- Color support +- Scaling support +- & more -[[English](README_EN.md)] [[简体中文](README.md)] [欢迎贡献更多语言] +# How To Install ---- +Download the following plugins according to what server software you use. -# 这个跟主分支有什么区别? - -跟主分支不同的是,这个是真正的自定义实体!!!🎉🎉🎉 - -而主分支是给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: willem.dev) ---- +# FAQ -# 完结🤗 +### Where can I contact you? +You can contact me on discord under the name: willem.dev -恭喜你现在学会如何使用了😎有BUG或建议请发Issues - ---- - -# 当前限制💢 - -* 不支持多纹理 -* 头部旋转跟JE不太同步 -* 待挖掘 - ---- - -# 常见问题❓ - -### 召唤模型后召唤的并非模型而是史蒂夫? - -如果你确定你根据上面的教程一步一步做了,可能是这个模型的问题? 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/model/EntityTask.java b/src/main/java/re/imc/geysermodelengine/model/EntityTask.java index 452d54c..cf05be1 100644 --- a/src/main/java/re/imc/geysermodelengine/model/EntityTask.java +++ b/src/main/java/re/imc/geysermodelengine/model/EntityTask.java @@ -1,13 +1,18 @@ package re.imc.geysermodelengine.model; +import com.google.common.base.Joiner; 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.generator.blueprint.BlueprintBone; import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ModeledEntity; +import com.ticxo.modelengine.api.model.bone.BoneBehaviorTypes; +import com.ticxo.modelengine.api.model.bone.ModelBone; import lombok.Getter; import lombok.Setter; import me.zimzaza4.geyserutils.common.animation.Animation; +import me.zimzaza4.geyserutils.spigot.GeyserUtils; import me.zimzaza4.geyserutils.spigot.api.PlayerUtils; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; @@ -16,10 +21,12 @@ 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 java.util.Set; +import java.awt.*; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import static re.imc.geysermodelengine.model.ModelEntity.ENTITIES; @@ -41,6 +48,11 @@ public class EntityTask { boolean spawnAnimationPlayed = false; boolean removed = false; + float lastScale = -1.0f; + Color lastColor = null; + Map lastSet = new HashMap<>(); + + String lastAnimation = ""; boolean looping = true; @@ -175,7 +187,6 @@ public class EntityTask { } } - tick ++; if (tick > 400) { tick = 0; @@ -199,6 +210,15 @@ public class EntityTask { if (animationCooldown.get() > 0) { animationCooldown.decrementAndGet(); } + + Optional player = viewers.stream().findAny(); + if (player.isEmpty()) return; + + updateVisibility(player.get(), false); + + // do not actually use this, atleast bundle these up ;( + sendScale(player.get(), true); + sendColor(player.get(), true); } public void sendEntityData(Player player, int delay) { @@ -211,15 +231,67 @@ public class EntityTask { playBedrockAnimation(lastAnimation, Set.of(player), looping, 0f); } sendHitBox(player); - sendScale(player); + sendScale(player, true); Bukkit.getScheduler().runTaskLaterAsynchronously(GeyserModelEngine.getInstance(), () -> { sendHitBox(player); + sendScale(player, true); + updateVisibility(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 updateVisibility(Player player, boolean ignore) { + Entity entity = model.getEntity(); + + Map updates = new HashMap<>(); + model.getActiveModel().getBones().forEach((s,bone) -> { + if (!lastSet.containsKey(bone)) lastSet.put(bone, !bone.isVisible()); + + if (!lastSet.get(bone).equals(bone.isVisible()) || ignore) { + String name = unstripName(bone).toLowerCase(); + updates.put(model.getActiveModel().getBlueprint().getName() + ":" + name, bone.isVisible()); + lastSet.replace(bone, bone.isVisible()); + } + + }); + + 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() { @@ -300,14 +372,7 @@ public class EntityTask { 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 +393,7 @@ public class EntityTask { } - */ + public void playBedrockAnimation(String animationId, Set viewers, boolean loop, float blendTime) { // model.getViewers().forEach(viewer -> viewer.sendActionBar("CURRENT AN:" + animationId)); diff --git a/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java b/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java index 1025ddb..8e053e3 100644 --- a/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java +++ b/src/main/java/re/imc/geysermodelengine/model/ModelEntity.java @@ -6,7 +6,10 @@ import com.ticxo.modelengine.api.entity.BukkitEntity; import com.ticxo.modelengine.api.model.ActiveModel; import com.ticxo.modelengine.api.model.ModeledEntity; import lombok.Getter; +import me.zimzaza4.geyserutils.spigot.api.PlayerUtils; +import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.metadata.FixedMetadataValue; @@ -41,7 +44,6 @@ public class ModelEntity { this.activeModel = model; this.entity = spawnEntity(); runEntityTask(); - } public void teleportToModel() { 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