From c0294e15346bc62488a462417ec77a2733728b5a Mon Sep 17 00:00:00 2001 From: SquidDev Date: Fri, 14 Jul 2017 21:50:51 +0100 Subject: [PATCH] Adds the ability to load custom bios.lua files from resource packs Computer now delegates to IComputerEnvironment which, by default, looks in the following locations: - Resouce pack files - The "debug" folder - The original ComputerCraft jar --- .../dan200/computercraft/ComputerCraft.java | 88 ++++++++++++++++++- .../computercraft/core/computer/Computer.java | 2 +- .../core/computer/IComputerEnvironment.java | 3 + .../shared/computer/core/ServerComputer.java | 8 ++ 4 files changed, 98 insertions(+), 3 deletions(-) diff --git a/src/main/java/dan200/computercraft/ComputerCraft.java b/src/main/java/dan200/computercraft/ComputerCraft.java index f3418bcc2..1c5873c58 100644 --- a/src/main/java/dan200/computercraft/ComputerCraft.java +++ b/src/main/java/dan200/computercraft/ComputerCraft.java @@ -72,10 +72,10 @@ import net.minecraftforge.fml.common.network.FMLEventChannel; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; import net.minecraftforge.fml.relauncher.Side; +import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.Logger; -import java.io.File; -import java.io.IOException; +import java.io.*; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; @@ -83,6 +83,8 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; /////////////// // UNIVERSAL // @@ -875,6 +877,88 @@ public class ComputerCraft } } + public static InputStream getResourceFile( Class modClass, String domain, String subPath ) + { + // Start searching in possible locations + subPath = "assets/" + domain + "/" + subPath; + + // Look in resource packs + File resourcePackDir = getResourcePackDir(); + if( resourcePackDir.exists() && resourcePackDir.isDirectory() ) + { + String[] resourcePacks = resourcePackDir.list(); + for( String resourcePackPath : resourcePacks ) + { + File resourcePack = new File( resourcePackDir, resourcePackPath ); + if( resourcePack.isDirectory() ) + { + // Mount a resource pack from a folder + File subResource = new File( resourcePack, subPath ); + if( subResource.exists() && subResource.isFile() ) + { + try + { + return new FileInputStream( subResource ); + } + catch( FileNotFoundException ignored ) + { + } + } + } + else + { + ZipFile zipFile = null; + try + { + final ZipFile zip = zipFile = new ZipFile( resourcePack ); + ZipEntry entry = zipFile.getEntry( subPath ); + if( entry != null ) + { + // Return a custom InputStream which will close the original zip when finished. + return new FilterInputStream( zipFile.getInputStream( entry ) ) + { + @Override + public void close() throws IOException + { + super.close(); + zip.close(); + } + }; + } + else + { + IOUtils.closeQuietly( zipFile ); + } + } + catch( IOException e ) + { + if( zipFile != null ) IOUtils.closeQuietly( zipFile ); + } + } + } + } + + // Look in debug dir + File codeDir = getDebugCodeDir( modClass ); + if( codeDir != null ) + { + File subResource = new File( codeDir, subPath ); + if( subResource.exists() && subResource.isFile() ) + { + try + { + return new FileInputStream( subResource ); + } + catch( FileNotFoundException ignored ) + { + } + } + } + + // Look in class loader + return modClass.getClassLoader().getResourceAsStream( subPath ); + } + private static File getContainingJar( Class modClass ) { String path = modClass.getProtectionDomain().getCodeSource().getLocation().getPath(); diff --git a/src/main/java/dan200/computercraft/core/computer/Computer.java b/src/main/java/dan200/computercraft/core/computer/Computer.java index 885f85188..bb92b3837 100644 --- a/src/main/java/dan200/computercraft/core/computer/Computer.java +++ b/src/main/java/dan200/computercraft/core/computer/Computer.java @@ -635,7 +635,7 @@ public class Computer InputStream biosStream; try { - biosStream = Computer.class.getResourceAsStream( "/assets/computercraft/lua/bios.lua" ); + biosStream = m_environment.createResourceFile( "computercraft", "lua/bios.lua" ); } catch( Exception e ) { diff --git a/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java b/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java index 54760f539..14b9cefc8 100644 --- a/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java +++ b/src/main/java/dan200/computercraft/core/computer/IComputerEnvironment.java @@ -8,6 +8,8 @@ package dan200.computercraft.core.computer; import dan200.computercraft.api.filesystem.IMount; import dan200.computercraft.api.filesystem.IWritableMount; +import java.io.InputStream; + public interface IComputerEnvironment { int getDay(); @@ -19,4 +21,5 @@ public interface IComputerEnvironment int assignNewID(); IWritableMount createSaveDirMount( String subPath, long capacity ); IMount createResourceMount( String domain, String subPath ); + InputStream createResourceFile( String domain, String subPath ); } diff --git a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java index 60a2d9772..e9d5a55b8 100644 --- a/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java +++ b/src/main/java/dan200/computercraft/shared/computer/core/ServerComputer.java @@ -26,6 +26,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fml.common.Loader; +import java.io.InputStream; + public class ServerComputer extends ServerTerminal implements IComputer, IComputerEnvironment, INetworkedThing { @@ -309,6 +311,12 @@ public class ServerComputer extends ServerTerminal return ComputerCraftAPI.createResourceMount( ComputerCraft.class, domain, subPath ); } + @Override + public InputStream createResourceFile( String domain, String subPath ) + { + return ComputerCraft.getResourceFile( ComputerCraft.class, domain, subPath ); + } + @Override public long getComputerSpaceLimit() {