updated GeyserUtils

This commit is contained in:
xSquishyLiam
2025-10-16 10:40:44 +01:00
parent 2d6ebab498
commit e58c331800
21 changed files with 195 additions and 139 deletions

View File

@@ -13,7 +13,7 @@ repositories {
}
dependencies {
compileOnly("org.geysermc.geyser:api:2.8.3-SNAPSHOT")
compileOnly("org.geysermc.geyser:api:2.9.0-SNAPSHOT")
compileOnly(files("libs/geyserutils-geyser-1.0-SNAPSHOT.jar"))

View File

@@ -11,12 +11,15 @@ import org.geysermc.geyser.api.pack.PackCodec;
import org.geysermc.geyser.api.pack.ResourcePack;
import re.imc.geysermodelenginepackgenerator.managers.ConfigManager;
import re.imc.geysermodelenginepackgenerator.managers.resourcepack.ResourcePackManager;
import re.imc.geysermodelenginepackgenerator.managers.resourcepack.templates.TemplatesManager;
public class GeyserModelEnginePackGenerator implements Extension {
private static GeyserModelEnginePackGenerator extension;
private ConfigManager configManager;
private TemplatesManager templatesManager;
private ResourcePackManager resourcePackManager;
@Subscribe
@@ -35,17 +38,17 @@ public class GeyserModelEnginePackGenerator implements Extension {
.source(CommandSource.class)
.playerOnly(false)
.description("GeyserModelPackGenerator Reload Command")
.permission("geysermodelenginepackgenerator.admin")
.permission("geysermodelenginepackgenerator.commands.reload")
.executor((source, command, args) -> {
resourcePackManager.loadPack();
source.sendMessage("GeyserModelEnginePackGenerator reloaded!");
source.sendMessage(configManager.getLang().getString("commands.geysermodelenginepackgenerator.reload.successfully-reloaded"));
})
.build());
}
@Subscribe
public void onPackLoad(GeyserDefineResourcePacksEvent event) {
if (!extension.getConfigManager().getConfig().getBoolean("options.resource-pack.auto-load")) return;
if (!configManager.getConfig().getBoolean("options.resource-pack.auto-load")) return;
ResourcePack resourcePack = ResourcePack.create(PackCodec.path(resourcePackManager.getGeneratedPackZipPath()));
event.register(resourcePack);
@@ -53,6 +56,7 @@ public class GeyserModelEnginePackGenerator implements Extension {
private void loadManagers() {
this.configManager = new ConfigManager();
this.templatesManager = new TemplatesManager(this);
this.resourcePackManager = new ResourcePackManager(this);
}
@@ -64,6 +68,10 @@ public class GeyserModelEnginePackGenerator implements Extension {
return configManager;
}
public TemplatesManager getTemplatesManager() {
return templatesManager;
}
public ResourcePackManager getResourcePackManager() {
return resourcePackManager;
}

View File

@@ -1,39 +0,0 @@
package re.imc.geysermodelenginepackgenerator.generator;
public class Material {
public static final String TEMPLATE = """
{
"materials":{
"version":"1.0.0",
"entity_alphatest_anim_change_color:entity_alphatest_change_color":{
"+defines":[
"USE_UV_ANIM"
]
},
"entity_change_color_one_sided:entity": {
"+defines": [
"USE_OVERLAY",
"USE_COLOR_MASK"
]
},
"entity_alphatest_change_color_one_sided:entity_change_color_one_sided": {
"+defines": [ "ALPHA_TEST" ],
"+samplerStates": [
{
"samplerIndex": 1,
"textureWrap": "Repeat"
}
],
"msaaSupport": "Both"
},
"entity_alphatest_anim_change_color_one_sided:entity_alphatest_change_color_one_sided":{
"+defines":[
"USE_UV_ANIM"
]
}
}
}
""";
}

View File

@@ -1,32 +0,0 @@
package re.imc.geysermodelenginepackgenerator.generator;
import java.util.UUID;
public class PackManifest {
public static final String TEMPLATE = """
{
"format_version": 2,
"header": {
"name": "GeyserModelEngine",
"description": "GeyserModelEngine For Geyser",
"uuid": "%uuid-1%",
"version": [0, 0, 1],
"min_engine_version": [1, 21, 100]
},
"modules": [
{
"type": "resources",
"description": "GeyserModelEngine",
"uuid": "%uuid-2%",
"version": [0, 0, 1]
}
]
}
""";
public static String generate() {
return TEMPLATE.replace("%uuid-1%", UUID.randomUUID().toString())
.replace("%uuid-2%", UUID.randomUUID().toString());
}
}

View File

@@ -4,7 +4,7 @@ import re.imc.geysermodelenginepackgenerator.util.FileConfiguration;
public class ConfigManager {
private FileConfiguration config;
private FileConfiguration config, lang;
public ConfigManager() {
load();
@@ -12,9 +12,14 @@ public class ConfigManager {
public void load() {
this.config = new FileConfiguration("config.yml");
this.lang = new FileConfiguration("Lang/messages.yml");
}
public FileConfiguration getConfig() {
return config;
}
public FileConfiguration getLang() {
return lang;
}
}

View File

@@ -4,7 +4,8 @@ import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParser;
import re.imc.geysermodelenginepackgenerator.GeyserModelEnginePackGenerator;
import re.imc.geysermodelenginepackgenerator.generator.*;
import re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator.*;
import re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator.data.TextureData;
import re.imc.geysermodelenginepackgenerator.util.ZipUtil;
import java.io.*;
@@ -28,7 +29,7 @@ public class ResourcePackManager {
private final HashMap<String, Entity> entityCache = new HashMap<>();
private final HashMap<String, Animation> animationCache = new HashMap<>();
private final HashMap<String, Geometry> geometryCache = new HashMap<>();
private final HashMap<String, Map<String, Texture>> textureCache = new HashMap<>();
private final HashMap<String, Map<String, TextureData>> textureCache = new HashMap<>();
private final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
@@ -73,7 +74,9 @@ public class ResourcePackManager {
output.mkdirs();
if (!manifestFile.exists()) {
try {
Files.writeString(manifestFile.toPath(), PackManifest.generate(), StandardCharsets.UTF_8);
// PackManifest.generate()
Files.writeString(manifestFile.toPath(), extension.getTemplatesManager().getTemplatesCache().get("packmanifest").toString(), StandardCharsets.UTF_8);
} catch (IOException err) {
throw new RuntimeException(err);
}
@@ -91,7 +94,7 @@ public class ResourcePackManager {
if (!materialFile.exists()) {
try {
Files.writeString(materialFile.toPath(), Material.TEMPLATE, StandardCharsets.UTF_8);
Files.writeString(materialFile.toPath(), extension.getTemplatesManager().getTemplatesCache().get("material").toString(), StandardCharsets.UTF_8);
} catch (IOException err) {
throw new RuntimeException(err);
}
@@ -132,7 +135,7 @@ public class ResourcePackManager {
if (entity != null) {
ModelConfig modelConfig = entity.getModelConfig();
if (!modelConfig.getPerTextureUvSize().isEmpty()) {
for (Map.Entry<String, Texture> textureEntry : entity.getTextureMap().entrySet()) {
for (Map.Entry<String, TextureData> textureEntry : entity.getTextureMap().entrySet()) {
String name = textureEntry.getKey();
Integer[] size = modelConfig.getPerTextureUvSize().getOrDefault(name, new Integer[]{16, 16});
@@ -163,8 +166,8 @@ public class ResourcePackManager {
}
}
for (Map.Entry<String, Map<String, Texture>> textures : textureCache.entrySet()) {
for (Map.Entry<String, Texture> entry : textures.getValue().entrySet()) {
for (Map.Entry<String, Map<String, TextureData>> textures : textureCache.entrySet()) {
for (Map.Entry<String, TextureData> entry : textures.getValue().entrySet()) {
Path path = texturesFolder.toPath().resolve(entry.getValue().getPath() + textures.getKey() + "/" + entry.getKey() + ".png");
path.toFile().getParentFile().mkdirs();
@@ -248,9 +251,9 @@ public class ResourcePackManager {
bindingBones.add("*");
if (modelConfig.getBingingBones().containsKey(textureName)) bindingBones = modelConfig.getBingingBones().get(textureName);
Map<String, Texture> map = textureCache.computeIfAbsent(modelId, s -> new HashMap<>());
Map<String, TextureData> map = textureCache.computeIfAbsent(modelId, s -> new HashMap<>());
try {
map.put(textureName, new Texture(modelId, currentPath, bindingBones, Files.readAllBytes(file.toPath())));
map.put(textureName, new TextureData(modelId, currentPath, bindingBones, Files.readAllBytes(file.toPath())));
} catch (IOException err) {
throw new RuntimeException(err);
}
@@ -356,9 +359,9 @@ public class ResourcePackManager {
bindingBones = modelConfig.getBingingBones().get(textureName);
}
Map<String, Texture> map = textureCache.computeIfAbsent(modelId, s -> new HashMap<>());
Map<String, TextureData> map = textureCache.computeIfAbsent(modelId, s -> new HashMap<>());
try {
map.put(textureName, new Texture(modelId, currentPath, bindingBones, zip.getInputStream(e).readAllBytes()));
map.put(textureName, new TextureData(modelId, currentPath, bindingBones, zip.getInputStream(e).readAllBytes()));
} catch (IOException err) {
throw new RuntimeException(err);
}
@@ -439,7 +442,7 @@ public class ResourcePackManager {
return geometryCache;
}
public HashMap<String, Map<String, Texture>> getTextureCache() {
public HashMap<String, Map<String, TextureData>> getTextureCache() {
return textureCache;
}
}

View File

@@ -1,4 +1,4 @@
package re.imc.geysermodelenginepackgenerator.generator;
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;

View File

@@ -1,10 +1,8 @@
package re.imc.geysermodelenginepackgenerator.generator;
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.Getter;
import lombok.Setter;
import re.imc.geysermodelenginepackgenerator.GeyserModelEnginePackGenerator;
import java.util.ArrayList;
@@ -53,7 +51,6 @@ public class AnimationController {
id = id.replace(" ", "_");
int n = (int) Math.pow(2, (i % 24));
//TODO namespace
JsonObject controller = JsonParser.parseString(CONTROLLER_TEMPLATE.replace("%anim%", id).replace("%query%", "math.mod(math.floor(query.property('" + extension.getConfigManager().getConfig().getString("models.namespace") + ":anim" + i / 24 + "') / " + n + "), 2)")).getAsJsonObject();
animationControllers.add("controller.animation." + animation.getModelId() + "." + id, controller);
i++;

View File

@@ -1,13 +1,11 @@
package re.imc.geysermodelenginepackgenerator.generator;
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import me.zimzaza4.geyserutils.geyser.GeyserUtils;
import re.imc.geysermodelenginepackgenerator.GeyserModelEnginePackGenerator;
import re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator.data.TextureData;
import java.util.*;
@@ -22,7 +20,7 @@ public class Entity {
private Geometry geometry;
private RenderController renderController;
private String path;
private Map<String, Texture> textureMap = new HashMap<>();
private Map<String, TextureData> textureMap = new HashMap<>();
private ModelConfig modelConfig;
public static final String TEMPLATE = """
@@ -164,7 +162,7 @@ public class Entity {
this.path = path;
}
public void setTextureMap(Map<String, Texture> textureMap) {
public void setTextureMap(Map<String, TextureData> textureMap) {
this.textureMap = textureMap;
}
@@ -200,7 +198,7 @@ public class Entity {
return path;
}
public Map<String, Texture> getTextureMap() {
public Map<String, TextureData> getTextureMap() {
return textureMap;
}

View File

@@ -1,10 +1,7 @@
package re.imc.geysermodelenginepackgenerator.generator;
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator;
import com.google.gson.*;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator.data.BoneData;
import java.util.*;
@@ -13,7 +10,7 @@ public class Geometry {
private String modelId;
private String geometryId;
private JsonObject json;
private final Map<String, Bone> bones = new HashMap<>();
private final Map<String, BoneData> bones = new HashMap<>();
private String path;
@@ -53,13 +50,13 @@ public class Geometry {
if (name.equals("hitbox") || name.equals("shadow") || name.equals("mount") || name.startsWith("b_") || name.startsWith("ob_")) {
iterator.remove();
} else {
bones.put(name, new Bone(name, parent, new HashSet<>(), new HashSet<>()));
bones.put(name, new BoneData(name, parent, new HashSet<>(), new HashSet<>()));
}
}
for (Bone bone : bones.values()) {
for (BoneData bone : bones.values()) {
if (bone.getParent() != null) {
Bone parent = bones.get(bone.getParent());
BoneData parent = bones.get(bone.getParent());
if (parent != null) {
parent.getChildren().add(bone);
addAllChildren(parent, bone);
@@ -70,9 +67,9 @@ public class Geometry {
setId("geometry.meg_" + modelId);
}
public void addAllChildren(Bone p, Bone c) {
public void addAllChildren(BoneData p, BoneData c) {
p.getAllChildren().add(c);
Bone parent = bones.get(p.getParent());
BoneData parent = bones.get(p.getParent());
if (parent != null) {
addAllChildren(parent, c);
}
@@ -110,7 +107,7 @@ public class Geometry {
return path;
}
public Map<String, Bone> getBones() {
public Map<String, BoneData> getBones() {
return bones;
}
}

View File

@@ -1,4 +1,4 @@
package re.imc.geysermodelenginepackgenerator.generator;
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator;
import com.google.gson.annotations.SerializedName;
import lombok.*;

View File

@@ -1,7 +1,8 @@
package re.imc.geysermodelenginepackgenerator.generator;
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator.data.BoneData;
import java.util.*;
@@ -10,10 +11,10 @@ public class RenderController {
public static final Set<String> NEED_REMOVE_WHEN_SORT = Set.of("pbody_", "plarm_", "prarm_", "plleg_", "prleg_", "phead_", "p_");
private final String modelId;
private final Map<String, Bone> bones;
private final Map<String, BoneData> bones;
private final Entity entity;
public RenderController(String modelId, Map<String, Bone> bones, Entity entity) {
public RenderController(String modelId, Map<String, BoneData> bones, Entity entity) {
this.modelId = modelId;
this.bones = bones;
this.entity = entity;
@@ -29,7 +30,7 @@ public class RenderController {
JsonObject renderControllers = new JsonObject();
root.add("render_controllers", renderControllers);
Set<Bone> processedBones = new HashSet<>();
Set<BoneData> processedBones = new HashSet<>();
boolean singleTexture = entity.getTextureMap().size() == 1 && entity.getModelConfig().getPerTextureUvSize().isEmpty();
for (String key : entity.getTextureMap().keySet()) {
if (key.endsWith("_e")) continue;
@@ -126,10 +127,10 @@ public class RenderController {
for (String boneName : sorted) {
boneName = originalId.get(boneName);
JsonObject visibilityItem = new JsonObject();
Bone bone = bones.get(boneName);
BoneData bone = bones.get(boneName);
boolean uvParent = false;
for (Bone child : bone.getAllChildren()) {
for (BoneData child : bone.getAllChildren()) {
if (child.getName().startsWith("uv_")) {
if (uvAllBones.contains(child.getName())) {
uvParent = true;

View File

@@ -1,15 +1,15 @@
package re.imc.geysermodelenginepackgenerator.generator;
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator.data;
import java.util.Set;
public class Bone {
public class BoneData {
private final String name;
private final String parent;
private final Set<Bone> children;
private final Set<Bone> allChildren;
private final Set<BoneData> children;
private final Set<BoneData> allChildren;
public Bone(String name, String parent, Set<Bone> children, Set<Bone> allChildren) {
public BoneData(String name, String parent, Set<BoneData> children, Set<BoneData> allChildren) {
this.name = name;
this.parent = parent;
this.children = children;
@@ -24,11 +24,11 @@ public class Bone {
return parent;
}
public Set<Bone> getChildren() {
public Set<BoneData> getChildren() {
return children;
}
public Set<Bone> getAllChildren() {
public Set<BoneData> getAllChildren() {
return allChildren;
}
}

View File

@@ -1,15 +1,15 @@
package re.imc.geysermodelenginepackgenerator.generator;
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.generator.data;
import java.util.Set;
public class Texture {
public class TextureData {
private final String modelId;
private final String path;
private final Set<String> bindingBones;
private final byte[] image;
public Texture(String modelId, String path, Set<String> bindingBones, byte[] image) {
public TextureData(String modelId, String path, Set<String> bindingBones, byte[] image) {
this.modelId = modelId;
this.path = path;
this.bindingBones = bindingBones;

View File

@@ -0,0 +1,41 @@
package re.imc.geysermodelenginepackgenerator.managers.resourcepack.templates;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import re.imc.geysermodelenginepackgenerator.GeyserModelEnginePackGenerator;
import re.imc.geysermodelenginepackgenerator.util.FileUtils;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
public class TemplatesManager {
private final GeyserModelEnginePackGenerator extension;
private final HashMap<String, JsonObject> templatesCache = new HashMap<>();
public TemplatesManager(GeyserModelEnginePackGenerator extension) {
this.extension = extension;
loadTemplates();
}
private void loadTemplates() {
for (File file : FileUtils.getAllFiles(new File(extension.dataFolder().toFile(), "ResourcePack/Templates"), "json")) {
try (FileReader reader = new FileReader(file)) {
JsonObject templateObject = JsonParser.parseReader(reader).getAsJsonObject();
String templateName = file.getName().replace(".json", "");
templatesCache.put(templateName.toLowerCase(), templateObject);
} catch (IOException | JsonSyntaxException err) {
throw new RuntimeException(err);
}
}
}
public HashMap<String, JsonObject> getTemplatesCache() {
return templatesCache;
}
}

View File

@@ -4,17 +4,18 @@ import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
public class BooleanPacker {
public static final int MAX_BOOLEANS = 24;
public static int booleansToInt(List<Boolean> booleans) {
int result = 0;
int i = 1;
for (boolean b : booleans) {
if (b) {
result += i;
}
if (b) result += i;
i *= 2;
}
return result;
}
@@ -23,12 +24,12 @@ public class BooleanPacker {
int i = 1;
List<String> keys = new ArrayList<>(booleanMap.keySet());
Collections.sort(keys);
for (String key : keys) {
if (booleanMap.get(key)) {
result += i;
}
if (booleanMap.get(key)) result += i;
i *= 2;
}
return result;
}
@@ -58,12 +59,11 @@ public class BooleanPacker {
List<String> keys = new ArrayList<>(booleanMap.keySet());
List<Boolean> booleans = new ArrayList<>();
Collections.sort(keys);
for (String key : keys) {
booleans.add(booleanMap.get(key));
}
return booleansToInts(booleans);
}
}

View File

@@ -0,0 +1,23 @@
package re.imc.geysermodelenginepackgenerator.util;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class FileUtils {
public static List<File> getAllFiles(File folder, String fileType) {
List<File> files = new ArrayList<>();
if (folder == null || !folder.exists()) return files;
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
files.addAll(getAllFiles(file, fileType));
} else if (file.getName().endsWith(fileType)) {
files.add(file);
}
}
return files;
}
}

View File

@@ -0,0 +1,4 @@
commands:
geysermodelenginepackgenerator:
reload:
successfully-reloaded: "GeyserModelEnginePackGenerator reloaded!"

View File

@@ -0,0 +1,32 @@
{
"materials":{
"version":"1.0.0",
"entity_alphatest_anim_change_color:entity_alphatest_change_color":{
"+defines":[
"USE_UV_ANIM"
]
},
"entity_change_color_one_sided:entity": {
"+defines": [
"USE_OVERLAY",
"USE_COLOR_MASK"
]
},
"entity_alphatest_change_color_one_sided:entity_change_color_one_sided": {
"+defines": [ "ALPHA_TEST" ],
"+samplerStates": [
{
"samplerIndex": 1,
"textureWrap": "Repeat"
}
],
"msaaSupport": "Both"
},
"entity_alphatest_anim_change_color_one_sided:entity_alphatest_change_color_one_sided":{
"+defines":[
"USE_UV_ANIM"
]
}
}
}

View File

@@ -0,0 +1,18 @@
{
"format_version": 2,
"header": {
"name": "GeyserModelEngine",
"description": "GeyserModelEngine For Geyser",
"uuid": "782e97f0-5caf-473e-a47c-d7929859626b",
"version": [0, 0, 1],
"min_engine_version": [1, 21, 100]
},
"modules": [
{
"type": "resources",
"description": "GeyserModelEngine",
"uuid": "782e97f0-5caf-473e-a47c-d7929859626b",
"version": [0, 0, 1]
}
]
}