Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ build/
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
.idea/workspace.xml
*.iws
*.iml
*.ipr
Expand Down Expand Up @@ -39,4 +40,4 @@ bin/
.vscode/

### Mac OS ###
.DS_Store
.DS_Store
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import re.imc.geysermodelengineextension.GeyserModelEngineExtension;
import re.imc.geysermodelengineextension.managers.resourcepack.generator.*;
import re.imc.geysermodelengineextension.managers.resourcepack.generator.data.TextureData;
import re.imc.geysermodelengineextension.util.ShortHashUtil;
import re.imc.geysermodelengineextension.util.ZipUtil;

import java.io.*;
Expand Down Expand Up @@ -61,6 +62,8 @@ public void loadPack() {
private void generateResourcePack(File inputFolder, File output) {
generateFromFolder("", inputFolder, true);

boolean hashEnabled = extension.getConfigManager().getConfig().getBoolean("options.resource-pack.hash-models-textures", true);

File animationsFolder = new File(output, "animations");
File entityFolder = new File(output, "entity");
File modelsFolder = new File(output, "models/entity");
Expand Down Expand Up @@ -130,10 +133,9 @@ private void generateResourcePack(File inputFolder, File output) {
}

for (Map.Entry<String, Geometry> entry : geometryCache.entrySet()) {
entry.getValue().modify();
Path path = modelsFolder.toPath().resolve(entry.getValue().getPath() + entry.getKey() + ".json");
entry.getValue().modify(hashEnabled);
Path path = modelsFolder.toPath().resolve(entry.getValue().getPath() + (hashEnabled ? ShortHashUtil.hashModelId(entry.getKey()) : entry.getKey()) + ".json");
path.toFile().getParentFile().mkdirs();
String id = entry.getValue().getGeometryId();

Entity entity = entityCache.get(entry.getKey());
if (entity != null) {
Expand All @@ -146,9 +148,13 @@ private void generateResourcePack(File inputFolder, File output) {
String suffix = size[0] + "_" + size[1];
entry.getValue().setTextureWidth(size[0]);
entry.getValue().setTextureHeight(size[1]);
path = modelsFolder.toPath().resolve(entry.getKey() + "_" + suffix + ".json");

entry.getValue().setId(id + "_" + suffix);
if (hashEnabled) {
path = modelsFolder.toPath().resolve(ShortHashUtil.hashModelId(entry.getKey() + "_" + suffix) + ".json");
entry.getValue().setId("geometry." + ShortHashUtil.hashModelId(entry.getKey() + "_" + suffix));
} else {
path = modelsFolder.toPath().resolve(entry.getKey() + "_" + suffix + ".json");
entry.getValue().setId("geometry.meg_" + entry.getKey() + "_" + suffix);
}

if (path.toFile().exists()) continue;

Expand All @@ -171,8 +177,10 @@ private void generateResourcePack(File inputFolder, File output) {
}

for (Map.Entry<String, Map<String, TextureData>> textures : textureCache.entrySet()) {
String modelId = textures.getKey();
for (Map.Entry<String, TextureData> entry : textures.getValue().entrySet()) {
Path path = texturesFolder.toPath().resolve(entry.getKey() + ".png");
String textureFileName = hashEnabled ? ShortHashUtil.hashTextureName(modelId, entry.getKey()) : entry.getKey();
Path path = texturesFolder.toPath().resolve(textureFileName + ".png");
path.toFile().getParentFile().mkdirs();

if (path.toFile().exists()) continue;
Expand All @@ -187,7 +195,7 @@ private void generateResourcePack(File inputFolder, File output) {

for (Map.Entry<String, Entity> entry : entityCache.entrySet()) {
Entity entity = entry.getValue();
entity.modify(extension.getConfigManager().getConfig().getString("models.namespace"));
entity.modify(extension.getConfigManager().getConfig().getString("models.namespace"), hashEnabled);

Path entityPath = entityFolder.toPath().resolve(entity.getPath() + entry.getKey() + ".json");
entityPath.toFile().getParentFile().mkdirs();
Expand All @@ -210,7 +218,7 @@ private void generateResourcePack(File inputFolder, File output) {
if (renderPath.toFile().exists()) continue;

try {
Files.writeString(renderPath, controller.generate(extension.getConfigManager().getConfig().getString("models.namespace")), StandardCharsets.UTF_8);
Files.writeString(renderPath, controller.generate(extension.getConfigManager().getConfig().getString("models.namespace"), hashEnabled), StandardCharsets.UTF_8);
} catch (IOException err) {
throw new RuntimeException(err);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.google.gson.JsonParser;
import me.zimzaza4.geyserutils.geyser.GeyserUtils;
import re.imc.geysermodelengineextension.managers.resourcepack.generator.data.TextureData;
import re.imc.geysermodelengineextension.util.ShortHashUtil;

import java.util.*;

Expand Down Expand Up @@ -56,11 +57,15 @@ public Entity(String modelId) {
this.modelId = modelId;
}

public void modify(String namespace) {
public void modify(String namespace, boolean hashEnabled) {
String modelShortName = hashEnabled ? ShortHashUtil.hashModelId(modelId) : modelId;
String geometryId = hashEnabled ? "geometry." + modelShortName : "geometry.meg_" + modelShortName;
String defaultTexturePath = hashEnabled ? "textures/entity/" + ShortHashUtil.hashTextureName(modelId, modelId) : "textures/entity/" + modelId;

this.json = JsonParser.parseString(TEMPLATE.replace("%namespace%", namespace)
.replace("%entity_id%", modelId)
.replace("%geometry%", "geometry.meg_" + modelId)
.replace("%texture%", "textures/entity/" + modelId)
.replace("%geometry%", geometryId)
.replace("%texture%", defaultTexturePath)
.replace("%look_at_target%", modelConfig.isEnableHeadRotation() ? "animation." + modelId + ".look_at_target" : "animation.none")
.replace("%material%", modelConfig.getMaterial())).getAsJsonObject();

Expand All @@ -76,8 +81,8 @@ public void modify(String namespace) {
materials.forEach(jsonMaterials::addProperty);

if (modelConfig.getPerTextureUvSize().isEmpty()) {
jsonGeometry.addProperty(modelId, "geometry.meg_" + modelId);
jsonTextures.addProperty("default", "textures/entity/" + modelId);
jsonGeometry.addProperty(modelShortName, geometryId);
jsonTextures.addProperty("default", defaultTexturePath);
}

for (String name : textureMap.keySet()) {
Expand All @@ -87,8 +92,15 @@ public void modify(String namespace) {
Integer[] size = modelConfig.getPerTextureUvSize().getOrDefault(name, new Integer[]{16, 16});
String suffix = size[0] + "_" + size[1];

jsonGeometry.addProperty(modelId + "_" + suffix, "geometry.meg_" + modelId + "_" + suffix);
jsonTextures.addProperty(name, "textures/entity/" + name);
if (hashEnabled) {
String hashedGeoName = ShortHashUtil.hashModelId(modelId + "_" + suffix);
jsonGeometry.addProperty(hashedGeoName, "geometry." + hashedGeoName);
jsonTextures.addProperty(ShortHashUtil.hashTextureName(modelId, name), "textures/entity/" + ShortHashUtil.hashTextureName(modelId, name));
} else {
String geoName = modelShortName + "_" + suffix;
jsonGeometry.addProperty(geoName, "geometry.meg_" + modelId + "_" + suffix);
jsonTextures.addProperty(name, "textures/entity/" + name);
}

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.gson.*;
import re.imc.geysermodelengineextension.GeyserModelEngineExtension;
import re.imc.geysermodelengineextension.managers.resourcepack.generator.data.BoneData;
import re.imc.geysermodelengineextension.util.ShortHashUtil;

import java.util.*;

Expand Down Expand Up @@ -36,7 +37,7 @@ public JsonObject getInternal() {
return json.get("minecraft:geometry").getAsJsonArray().get(0).getAsJsonObject();
}

public void modify() {
public void modify(boolean hashEnabled) {
JsonArray array = getInternal().get("bones").getAsJsonArray();
Iterator<JsonElement> iterator = array.iterator();
while(iterator.hasNext()) {
Expand Down Expand Up @@ -65,7 +66,11 @@ public void modify() {
}
}

setId("geometry.meg_" + modelId);
if (hashEnabled) {
setId("geometry." + ShortHashUtil.hashModelId(modelId));
} else {
setId("geometry.meg_" + modelId);
}
}

private void addAllChildren(BoneData p, BoneData c) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import re.imc.geysermodelengineextension.managers.resourcepack.generator.data.BoneData;
import re.imc.geysermodelengineextension.util.ShortHashUtil;

import java.util.*;

Expand All @@ -21,7 +22,7 @@ public RenderController(String modelId, Map<String, BoneData> bones, Entity enti
}

// look, I'm fine with your other code and stuff, but I ain't using templates for JSON lmao
public String generate(String namespace) {
public String generate(String namespace, boolean hashEnabled) {
List<String> se = new ArrayList<>(bones.keySet());
Collections.sort(se);
JsonObject root = new JsonObject();
Expand Down Expand Up @@ -56,9 +57,17 @@ public String generate(String namespace) {
if (!entity.getModelConfig().getPerTextureUvSize().isEmpty()) {
Integer[] size = entity.getModelConfig().getPerTextureUvSize().getOrDefault(key, new Integer[]{16, 16});
String suffix = size[0] + "_" + size[1];
controller.addProperty("geometry", "Geometry." + modelId + "_" + suffix);
if (hashEnabled) {
controller.addProperty("geometry", "Geometry." + ShortHashUtil.hashModelId(modelId + "_" + suffix));
} else {
controller.addProperty("geometry", "Geometry." + modelId + "_" + suffix);
}
} else {
controller.addProperty("geometry", "Geometry." + modelId);
if (hashEnabled) {
controller.addProperty("geometry", "Geometry." + ShortHashUtil.hashModelId(modelId));
} else {
controller.addProperty("geometry", "Geometry." + modelId);
}
}

JsonArray materials = new JsonArray();
Expand Down Expand Up @@ -91,7 +100,7 @@ public String generate(String namespace) {
if (singleTexture) {
textures.add("Texture.default");
} else {
textures.add("Texture." + key);
textures.add("Texture." + (hashEnabled ? ShortHashUtil.hashTextureName(modelId, key) : key));
}

controller.add("textures", textures);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ public boolean getBoolean(String path) {
return node.getBoolean();
}

public boolean getBoolean(String path, boolean def) {
CommentedConfigurationNode node = getInternal(path);
if (node == null) return def;
return node.getBoolean();
}

public boolean isBoolean(String path) {
CommentedConfigurationNode node = getInternal(path);
return node != null && node.raw() instanceof Boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package re.imc.geysermodelengineextension.util;

import java.math.BigInteger;
import java.security.MessageDigest;

public class ShortHashUtil {
private static final String CHARS = "0123456789abcdefghijklmnopqrstuvwxyz_";
private static final int SUFFIX_LEN = 6;
private static final long RADIX = 37;
private static final long SUFFIX_SPACE = (long) Math.pow(RADIX, SUFFIX_LEN);

public static String hashModelId(String modelId) {
return "gm_" + hash(modelId);
}

public static String hashTextureName(String modelId, String textureName) {
return "gm_" + hash(modelId + textureName);
}

public static String hash(String input) {
if (input == null) {
throw new IllegalArgumentException("Input cannot be null");
}
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes("UTF-8"));

BigInteger num = new BigInteger(1, digest);
BigInteger totalSpace = BigInteger.valueOf(26).multiply(BigInteger.valueOf(SUFFIX_SPACE));
BigInteger val = num.mod(totalSpace);

BigInteger[] divAndRem = val.divideAndRemainder(BigInteger.valueOf(SUFFIX_SPACE));
int firstIdx = divAndRem[0].intValue();
long remainder = divAndRem[1].longValue();
char[] suffix = new char[SUFFIX_LEN];
for (int i = SUFFIX_LEN - 1; i >= 0; i--) {
suffix[i] = CHARS.charAt((int) (remainder % RADIX));
remainder /= RADIX;
}
char firstChar = (char) ('a' + firstIdx);
return firstChar + new String(suffix);
} catch (Exception e) {
e.printStackTrace();
}
return input;
}
}
3 changes: 2 additions & 1 deletion geyser/src/main/resources/Extension/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ options:
debug:
geometry-bones: false
resource-pack:
auto-load: true
auto-load: true
hash-models-textures: true