package io.gitlab.jfronny.respackopts.mixin; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; 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; import java.util.HashMap; import java.util.Map; @Mixin(ResourcePackManager.class) public class ResourcePackManagerMixin { @Shadow private Map profiles; @Inject(at = @At("TAIL"), method = "scanPacks()V") private void scanPacks(CallbackInfo info) { profiles.forEach((s, v) -> { if (hasMetadata(v, "conf.json")) { try { Respackmeta conf = Respackopts.g.fromJson(readMetadata(v, "conf.json", Respackopts.g), Respackmeta.class); 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<>()); for (Map.Entry entry : conf.conf.entrySet()) { String n = entry.getKey(); if (n.contains(":") || n.contains(".")) { System.err.println(n + " contains invalid characters"); continue; } JsonElement e = entry.getValue(); if (e.isJsonPrimitive()) { JsonPrimitive p = e.getAsJsonPrimitive(); if (p.isBoolean()) { if (!Respackopts.boolVals.get(conf.id).containsKey(n)) Respackopts.boolVals.get(conf.id).put(n, p.getAsBoolean()); } else if (p.isNumber()) { if (!Respackopts.numVals.get(conf.id).containsKey(n)) Respackopts.numVals.get(conf.id).put(n, p.getAsDouble()); } else if (p.isString()) { if (!Respackopts.strVals.get(conf.id).containsKey(n)) Respackopts.strVals.get(conf.id).put(n, p.getAsString()); } } else { System.err.println("[respackopts] Unsupported non-primitive datatype"); } } if (Respackopts.metaVersion.equals(conf.version)) { Respackopts.resPackMetas.put(v.getDisplayName().asString(), conf); } else { System.err.println(s + " was not loaded as it specifies a different respackopts version than is installed"); } } catch (Throwable e) { e.printStackTrace(); } } }); Respackopts.load(); Respackopts.updateShaders(); Respackopts.save(); } private boolean hasMetadata(ResourcePackProfile v, String fname) { return v.createResourcePack().contains(ResourceType.CLIENT_RESOURCES, new Identifier(Respackopts.ID, fname)); } private JsonObject readMetadata(ResourcePackProfile v, String fname, Gson g) throws IOException { 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(); } }