2020-11-24 22:04:13 +01:00
|
|
|
package io.gitlab.jfronny.respackopts.mixin;
|
|
|
|
|
2020-11-26 20:11:38 +01:00
|
|
|
import com.google.gson.*;
|
2020-11-24 22:04:13 +01:00
|
|
|
import io.gitlab.jfronny.respackopts.Respackopts;
|
|
|
|
import io.gitlab.jfronny.respackopts.data.Respackmeta;
|
|
|
|
import net.minecraft.resource.ResourcePackManager;
|
|
|
|
import net.minecraft.resource.ResourcePackProfile;
|
|
|
|
import net.minecraft.resource.ResourceType;
|
|
|
|
import net.minecraft.util.Identifier;
|
|
|
|
import org.spongepowered.asm.mixin.Mixin;
|
|
|
|
import org.spongepowered.asm.mixin.Shadow;
|
|
|
|
import org.spongepowered.asm.mixin.injection.At;
|
|
|
|
import org.spongepowered.asm.mixin.injection.Inject;
|
|
|
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
|
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.InputStream;
|
2020-11-25 20:14:58 +01:00
|
|
|
import java.util.HashMap;
|
2020-12-28 09:41:02 +01:00
|
|
|
import java.util.LinkedHashSet;
|
2020-11-24 22:04:13 +01:00
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
@Mixin(ResourcePackManager.class)
|
|
|
|
public class ResourcePackManagerMixin {
|
|
|
|
@Shadow private Map<String, ResourcePackProfile> profiles;
|
|
|
|
|
|
|
|
@Inject(at = @At("TAIL"), method = "scanPacks()V")
|
|
|
|
private void scanPacks(CallbackInfo info) {
|
|
|
|
profiles.forEach((s, v) -> {
|
2020-12-21 13:18:13 +01:00
|
|
|
if (respackopts$hasMetadata(v, "conf.json")) {
|
2020-11-24 22:04:13 +01:00
|
|
|
try {
|
2020-12-21 13:18:13 +01:00
|
|
|
Respackmeta conf = Respackopts.g.fromJson(respackopts$readMetadata(v, "conf.json", Respackopts.g), Respackmeta.class);
|
2020-12-28 11:31:12 +01:00
|
|
|
if (!Respackopts.metaVersion.equals(conf.version)) {
|
|
|
|
System.err.println(s + " was not loaded as it specifies a different respackopts version than is installed");
|
|
|
|
return;
|
|
|
|
}
|
2020-11-25 20:14:58 +01:00
|
|
|
if (!Respackopts.boolVals.containsKey(conf.id))
|
|
|
|
Respackopts.boolVals.put(conf.id, new HashMap<>());
|
|
|
|
if (!Respackopts.numVals.containsKey(conf.id))
|
|
|
|
Respackopts.numVals.put(conf.id, new HashMap<>());
|
|
|
|
if (!Respackopts.strVals.containsKey(conf.id))
|
|
|
|
Respackopts.strVals.put(conf.id, new HashMap<>());
|
2020-11-26 20:11:38 +01:00
|
|
|
if (!Respackopts.enumKeys.containsKey(conf.id))
|
|
|
|
Respackopts.enumKeys.put(conf.id, new HashMap<>());
|
2020-12-28 11:31:12 +01:00
|
|
|
Respackopts.resPackMetas.put(v.getDisplayName().asString(), conf);
|
2020-12-21 13:18:13 +01:00
|
|
|
respackopts$registerFields(conf.conf, conf.id, "");
|
2020-12-28 11:31:12 +01:00
|
|
|
Respackopts.load(conf.id);
|
2020-11-25 20:14:58 +01:00
|
|
|
} catch (Throwable e) {
|
2020-11-24 22:04:13 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-12-21 13:18:13 +01:00
|
|
|
private void respackopts$registerFields(JsonObject data, String id, String keyPrefix) {
|
2020-12-28 11:31:12 +01:00
|
|
|
//Slider
|
|
|
|
if (data.entrySet().stream().allMatch(s -> "default".equals(s.getKey()) || "min".equals(s.getKey()) || "max".equals(s.getKey())))
|
|
|
|
{
|
|
|
|
JsonElement def = data.get("default");
|
|
|
|
JsonElement min = data.get("min");
|
|
|
|
JsonElement max = data.get("max");
|
|
|
|
if (def.isJsonPrimitive() && def.getAsJsonPrimitive().isNumber()
|
|
|
|
&& min.isJsonPrimitive() && min.getAsJsonPrimitive().isNumber()
|
|
|
|
&& max.isJsonPrimitive() && max.getAsJsonPrimitive().isNumber()) {
|
|
|
|
double defV = def.getAsNumber().doubleValue();
|
|
|
|
double minV = min.getAsNumber().doubleValue();
|
|
|
|
double maxV = max.getAsNumber().doubleValue();
|
|
|
|
if (defV < minV || defV > maxV) {
|
|
|
|
System.err.println("[respackopts] default value out of range at " + id);
|
|
|
|
}
|
|
|
|
else if (respackopts$isWhole(defV) && respackopts$isWhole(minV) && respackopts$isWhole(maxV)) {
|
|
|
|
Respackopts.numVals.get(id).put(keyPrefix, defV);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
System.err.println("[respackopts] expected whole number at " + id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
System.err.println("[respackopts] Expected numeric values at " + id);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
//Normal object
|
2020-12-21 13:18:13 +01:00
|
|
|
for (Map.Entry<String, JsonElement> entry : data.entrySet()) {
|
2020-12-28 11:31:12 +01:00
|
|
|
String n = ("".equals(keyPrefix) ? "" : keyPrefix + ".") + entry.getKey();
|
2020-12-21 13:18:13 +01:00
|
|
|
JsonElement e = entry.getValue();
|
|
|
|
if (e.isJsonPrimitive()) {
|
|
|
|
JsonPrimitive p = e.getAsJsonPrimitive();
|
|
|
|
if (p.isBoolean()) {
|
|
|
|
if (!Respackopts.boolVals.get(id).containsKey(n))
|
|
|
|
Respackopts.boolVals.get(id).put(n, p.getAsBoolean());
|
|
|
|
}
|
|
|
|
else if (p.isNumber()) {
|
|
|
|
if (!Respackopts.numVals.get(id).containsKey(n))
|
|
|
|
Respackopts.numVals.get(id).put(n, p.getAsDouble());
|
|
|
|
}
|
|
|
|
else if (p.isString()) {
|
|
|
|
if (!Respackopts.strVals.get(id).containsKey(n))
|
|
|
|
Respackopts.strVals.get(id).put(n, p.getAsString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (e.isJsonArray()) {
|
|
|
|
JsonArray a = e.getAsJsonArray();
|
|
|
|
for (JsonElement element : a) {
|
|
|
|
if (!element.isJsonPrimitive()) {
|
|
|
|
System.err.println("[respackopts] Unsupported non-primitive datatype");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!Respackopts.enumKeys.get(id).containsKey(n)) {
|
2020-12-28 09:41:02 +01:00
|
|
|
Respackopts.enumKeys.get(id).put(n, new LinkedHashSet<>());
|
2020-12-21 13:18:13 +01:00
|
|
|
}
|
|
|
|
JsonPrimitive p = element.getAsJsonPrimitive();
|
|
|
|
if (!p.isString()) {
|
|
|
|
System.err.println("[respackopts] Unsupported non-string enum key");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
String b = p.getAsString();
|
|
|
|
if (b.contains(":") || b.contains(".") || b.contains("_")) {
|
|
|
|
System.err.println(b + " contains invalid characters");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
Respackopts.enumKeys.get(id).get(n).add(b);
|
|
|
|
}
|
|
|
|
if (!Respackopts.numVals.get(id).containsKey(n)) {
|
|
|
|
Respackopts.numVals.get(id).put(n, 0d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (e.isJsonNull()) {
|
|
|
|
System.out.println("[respackopts] Config definition contains null, skipping that entry");
|
|
|
|
}
|
|
|
|
else if (e.isJsonObject()) {
|
2020-12-28 11:31:12 +01:00
|
|
|
respackopts$registerFields(e.getAsJsonObject(), id, n);
|
2020-12-21 13:18:13 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
System.err.println("[respackopts] Unsupported non-primitive datatype");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-28 11:31:12 +01:00
|
|
|
private boolean respackopts$isWhole(double v) {
|
|
|
|
return v == Math.floor(v) && !Double.isInfinite(v);
|
|
|
|
}
|
|
|
|
|
2020-12-21 13:18:13 +01:00
|
|
|
private boolean respackopts$hasMetadata(ResourcePackProfile v, String fname) {
|
2020-11-24 22:04:13 +01:00
|
|
|
return v.createResourcePack().contains(ResourceType.CLIENT_RESOURCES, new Identifier(Respackopts.ID, fname));
|
|
|
|
}
|
|
|
|
|
2020-12-21 13:18:13 +01:00
|
|
|
private JsonObject respackopts$readMetadata(ResourcePackProfile v, String fname, Gson g) throws IOException {
|
2020-11-24 22:04:13 +01:00
|
|
|
InputStream is = v.createResourcePack().open(ResourceType.CLIENT_RESOURCES, new Identifier(Respackopts.ID, fname));
|
|
|
|
ByteArrayOutputStream bais = new ByteArrayOutputStream();
|
|
|
|
byte[] buffer = new byte[1024];
|
|
|
|
int length;
|
|
|
|
while ((length = is.read(buffer)) != -1) {
|
|
|
|
bais.write(buffer, 0, length);
|
|
|
|
}
|
|
|
|
return g.fromJson(bais.toString(), JsonElement.class).getAsJsonObject();
|
|
|
|
}
|
|
|
|
}
|