diff options
| author | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-12 22:33:32 -0800 |
| commit | c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch) | |
| tree | df9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/core/Archive.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/core/Archive.java')
| -rw-r--r-- | NET/worlds/core/Archive.java | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/NET/worlds/core/Archive.java b/NET/worlds/core/Archive.java new file mode 100644 index 0000000..e5e32d0 --- /dev/null +++ b/NET/worlds/core/Archive.java @@ -0,0 +1,224 @@ +package NET.worlds.core; + +import NET.worlds.network.URL; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +public class Archive { + public static final String archiveName = "content.zip"; + private static Object mutex = new Object(); + private static Object noArchive = new Object(); + private static java.util.Hashtable<String, Object> archives = new java.util.Hashtable<String, Object>(); + private static String homePrefix = URL.getHome().unalias(); + private ZipFile zip; + + public static boolean exists(String name) { + synchronized (mutex) { + String nname = name.toLowerCase().replace('\\', '/'); + if (nname.startsWith("./")) { + nname = homePrefix + nname.substring(2); + } + + if (nname.startsWith(homePrefix)) { + nname = nname.substring(homePrefix.length()); + Archive arch = getOrMake(""); + if (arch != null && arch.lookup(nname) != null) { + return true; + } + + int start = -1; + + int end; + while ((end = nname.indexOf(47, start + 1)) != -1) { + String path = nname.substring(0, end + 1); + arch = getOrMake(path); + if (arch != null) { + String file = nname.substring(end + 1); + if (arch.lookup(file) != null) { + return true; + } + } + + start = end; + } + } + + File f = new File(name); + int length = (int)f.length(); + return length != 0; + } + } + + private static void reallyRead(InputStream s, byte[] data) throws IOException { + int bytesRemaining = data.length; + int totalBytesRead = 0; + + while (bytesRemaining > 0) { + int bytesRead = s.read(data, totalBytesRead, bytesRemaining); + totalBytesRead += bytesRead; + if (bytesRead == -1) { + return; + } + + bytesRemaining -= bytesRead; + } + } + + public static byte[] readBinaryFile(String name) { + synchronized (mutex) { + try { + String nname = name.toLowerCase().replace('\\', '/'); + if (nname.startsWith("./")) { + nname = homePrefix + nname.substring(2); + } + + if (nname.startsWith(homePrefix)) { + nname = nname.substring(homePrefix.length()); + Archive arch = getOrMake(""); + ZipEntry entry; + if (arch != null && (entry = arch.lookup(nname)) != null) { + return arch.load(entry); + } + + int start = -1; + + int end; + while ((end = nname.indexOf(47, start + 1)) != -1) { + String path = nname.substring(0, end + 1); + arch = getOrMake(path); + if (arch != null) { + String file = nname.substring(end + 1); + if ((entry = arch.lookup(file)) != null) { + return arch.load(entry); + } + } + + start = end; + } + } + + File f = new File(name); + int length = (int)f.length(); + if (length != 0) { + FileInputStream fis = new FileInputStream(f); + byte[] data = new byte[length]; + reallyRead(fis, data); + fis.close(); + return data; + } + } catch (IOException var9) { + } + + return null; + } + } + + public static byte[] readTextFile(String name) { + byte[] data = readBinaryFile(name); + if (data != null) { + int count = 0; + + for (int i = 0; i < data.length; i++) { + if (data[i] == 13 && data[i + 1] == 10) { + i++; + count++; + } + } + + byte[] ret = new byte[data.length - count]; + int j = 0; + + for (int ix = 0; ix < data.length; ix++) { + if (data[ix] != 13 || data[ix + 1] != 10) { + ret[j++] = data[ix]; + } + } + + data = ret; + } + + return data; + } + + public static void flushAll() { + synchronized (mutex) { + Enumeration<Object> e = archives.elements(); + + while (e.hasMoreElements()) { + Object o = e.nextElement(); + if (o instanceof Archive) { + ((Archive)o).close(); + } + } + + archives.clear(); + } + } + + private static Archive getOrMake(String relPath) { + String archName = relPath + "content.zip"; + Object obj = archives.get(archName); + if (obj == null) { + try { + Archive arch = new Archive(archName); + archives.put(archName, arch); + return arch; + } catch (IOException var4) { + archives.put(archName, noArchive); + } + } else if (obj != noArchive) { + return (Archive)obj; + } + + return null; + } + + private Archive(String path) throws IOException { + this.zip = new ZipFile(homePrefix + path); + } + + private void close() { + try { + this.zip.close(); + } catch (IOException var2) { + } + } + + private ZipEntry lookup(String name) { + return this.zip.getEntry(name); + } + + private byte[] load(ZipEntry ent) throws IOException { + return load(this.zip, ent); + } + + static byte[] load(ZipFile zip, ZipEntry ent) throws IOException { + int size = (int)ent.getSize(); + byte[] data = new byte[size]; + InputStream is = zip.getInputStream(ent); + if (ent.getMethod() == 0) { + reallyRead(is, data); + } else { + BufferedInputStream bis = new BufferedInputStream(is, 4096); + int amt = 0; + + while (amt < size) { + amt += bis.read(data, amt, size - amt); + } + + bis.close(); + } + + return data; + } + + static Object getMutex() { + return mutex; + } +} |