diff --git a/src/main/java/li/cil/oc2/common/util/ResourceUtils.java b/src/main/java/li/cil/oc2/common/util/ResourceUtils.java new file mode 100644 index 00000000..419287d4 --- /dev/null +++ b/src/main/java/li/cil/oc2/common/util/ResourceUtils.java @@ -0,0 +1,41 @@ +package li.cil.oc2.common.util; + +import com.google.gson.JsonObject; +import net.minecraft.resources.IResource; +import net.minecraft.resources.IResourceManager; +import net.minecraft.resources.data.IMetadataSectionSerializer; +import net.minecraft.util.JSONUtils; +import net.minecraft.util.ResourceLocation; + +import javax.annotation.Nullable; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +public final class ResourceUtils { + @Nullable + public static T getMetadata(final IResourceManager manager, final ResourceLocation resourceLocation, final IMetadataSectionSerializer serializer) throws IOException { + final ResourceLocation metadataLocation = new ResourceLocation( + resourceLocation.getNamespace(), resourceLocation.getNamespace() + ".mcmeta"); + if (!manager.hasResource(metadataLocation)) { + return null; + } + + try (final IResource metadataResource = manager.getResource(metadataLocation)) { + final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(metadataResource.getInputStream(), StandardCharsets.UTF_8)); + final JsonObject metadataJson = JSONUtils.fromJson(bufferedReader); + if (metadataJson == null) { + return null; + } + + final String sectionName = serializer.getSectionName(); + if (!metadataJson.has(sectionName)) { + return null; + } + + final JsonObject section = JSONUtils.getJsonObject(metadataJson, sectionName); + return serializer.deserialize(section); + } + } +} diff --git a/src/main/java/li/cil/oc2/common/vm/fs/ResourceFileSystem.java b/src/main/java/li/cil/oc2/common/vm/fs/ResourceFileSystem.java index a6511eb7..1547b6b3 100644 --- a/src/main/java/li/cil/oc2/common/vm/fs/ResourceFileSystem.java +++ b/src/main/java/li/cil/oc2/common/vm/fs/ResourceFileSystem.java @@ -3,6 +3,7 @@ package li.cil.oc2.common.vm.fs; import com.google.gson.JsonObject; import it.unimi.dsi.fastutil.objects.Object2LongArrayMap; import li.cil.oc2.common.Constants; +import li.cil.oc2.common.util.ResourceUtils; import li.cil.sedna.fs.*; import net.minecraft.resources.IResource; import net.minecraft.resources.IResourceManager; @@ -298,9 +299,10 @@ public final class ResourceFileSystem implements FileSystem { boolean isDirectory; boolean isExecutable; if (location != null) { - try (final IResource resource = resourceManager.getResource(location)) { - // Successfully retrieved resource, meaning it's a file. - final FileAttributesMetadataSection metadata = resource.getMetadata(FileAttributesMetadataSection.SERIALIZER); + try { + // If we can successfully retrieved resource it's a file. Directories cause errors. + resourceManager.getResource(location); + final FileAttributesMetadataSection metadata = ResourceUtils.getMetadata(resourceManager, location, FileAttributesMetadataSection.SERIALIZER); isExecutable = metadata != null && metadata.isExecutable(); isDirectory = false; } catch (final IOException e) {