Respackopts/src/main/java/io/gitlab/jfronny/respackopts/mixin/ResourcePackManagerMixin.java

77 lines
3.5 KiB
Java

package io.gitlab.jfronny.respackopts.mixin;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.gitlab.jfronny.respackopts.Respackopts;
import io.gitlab.jfronny.respackopts.data.MetadataLocateResult;
import io.gitlab.jfronny.respackopts.data.Respackmeta;
import io.gitlab.jfronny.respackopts.data.entry.SyncMode;
import net.minecraft.resource.ResourcePack;
import net.minecraft.resource.ResourcePackManager;
import net.minecraft.resource.ResourcePackProfile;
import net.minecraft.resource.ResourceType;
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.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) {
Respackopts.NAME_LOOKUP.clear();
profiles.forEach((s, v) -> {
MetadataLocateResult scan = rpo$locateMetadata(v);
if (scan.hasMeta()) {
try {
Respackmeta conf = Respackopts.GSON.fromJson(rpo$readMetadata(scan), Respackmeta.class);
if (Respackopts.META_VERSION < conf.version) {
Respackopts.LOGGER.error(s + " was not loaded as it specifies a newer respackopts version than is installed");
return;
}
if (Respackopts.META_VERSION > conf.version) {
Respackopts.LOGGER.warn(s + " uses an outdated RPO format (" + conf.version + "). Although this is supported, using the latest version (" + Respackopts.META_VERSION + ") is recommended");
}
conf.conf.setVersion(conf.version);
if (!Respackopts.CONFIG_BRANCH.containsKey(conf.id))
Respackopts.CONFIG_BRANCH.put(conf.id, conf.conf);
else
Respackopts.CONFIG_BRANCH.get(conf.id).sync(conf.conf, SyncMode.RESPACK_LOAD);
Respackopts.NAME_LOOKUP.put(v.getDisplayName().asString(), conf.id);
Respackopts.load(conf.id);
} catch (Throwable e) {
Respackopts.LOGGER.error("Could not initialize pack meta for " + s, e);
}
}
});
}
private MetadataLocateResult rpo$locateMetadata(ResourcePackProfile v) {
ResourcePack pack = v.createResourcePack();
for (ResourceType type : ResourceType.values()) {
if (pack.contains(type, Respackopts.CONF_ID))
return new MetadataLocateResult(pack, true, type);
}
return new MetadataLocateResult(pack, false, null);
}
private JsonObject rpo$readMetadata(MetadataLocateResult pack) throws IOException {
InputStream is = pack.pack().open(pack.type(), Respackopts.CONF_ID);
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) != -1) {
os.write(buffer, 0, length);
}
return Respackopts.GSON.fromJson(os.toString(), JsonElement.class).getAsJsonObject();
}
}