summaryrefslogtreecommitdiff
path: root/NET/worlds/core/Archive.java
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-12 22:33:32 -0800
committerFuwn <[email protected]>2026-02-12 22:33:32 -0800
commitc7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9 (patch)
treedf9f48bf128a6c0186a8e91857d6ff30fe0e9f18 /NET/worlds/core/Archive.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/core/Archive.java')
-rw-r--r--NET/worlds/core/Archive.java224
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;
+ }
+}