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/network/URL.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/network/URL.java')
| -rw-r--r-- | NET/worlds/network/URL.java | 604 |
1 files changed, 604 insertions, 0 deletions
diff --git a/NET/worlds/network/URL.java b/NET/worlds/network/URL.java new file mode 100644 index 0000000..eb45616 --- /dev/null +++ b/NET/worlds/network/URL.java @@ -0,0 +1,604 @@ +package NET.worlds.network; + +import NET.worlds.console.Console; +import NET.worlds.console.Gamma; +import NET.worlds.core.IniFile; +import NET.worlds.scape.Restorer; +import NET.worlds.scape.Saver; +import NET.worlds.scape.SuperRoot; +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.net.MalformedURLException; +import java.util.Hashtable; +import java.util.StringTokenizer; + +public class URL implements Serializable { + static final long serialVersionUID = 1L; + private String _url; + private static Hashtable<String, Object> psConversion = new Hashtable<String, Object>(); + private static IniFile protocols = new IniFile("Protocol"); + private static String currentDir = System.getProperty("user.dir").replace('\\', '/'); + private static URL home; + private static URL file; + private static boolean useCachedFiles; + private static URL avatar; + + static { + assert currentDir.charAt(1) == ':' || currentDir.startsWith("//"); + + try { + currentDir = validateFile(currentDir); + } catch (MalformedURLException var2) { + var2.printStackTrace(System.out); + + assert false; + } + + if (!currentDir.endsWith("/")) { + currentDir = currentDir + "/"; + } + + home = make(Gamma.getHome()); + file = make("file:"); + psConversion.put("home", home); + useCachedFiles = true; + useCachedFiles = IniFile.gamma().getIniInt("useNetworkAvatars", 1) == 1; + int override = IniFile.override().getIniInt("useNetworkAvatars", -1); + if (override != -1) { + useCachedFiles = override == 1; + } + + String avatarDir = IniFile.gamma().getIniString("avatarDir", "avatar/"); + if (!avatarDir.endsWith("/")) { + avatarDir = avatarDir + "/"; + } + + if (useCachedFiles) { + setAvatarServer(NetUpdate.getUpgradeServerURL() + avatarDir); + } else { + setAvatarServer("home:avatars/"); + } + + avatar = make("avatar:"); + } + + public URL(SuperRoot reference, String urlstr) throws MalformedURLException { + this(getBestContainer(reference), urlstr); + } + + public URL(URL reference, String urlstr) throws MalformedURLException { + if (isAbsolute(urlstr)) { + this._url = normalize(urlstr); + } else { + this._url = "rel:" + reference.getAbsolute(urlstr); + } + } + + public URL(String urlstr) throws MalformedURLException { + this(null, urlstr); + } + + public static URL make(String s) { + return make(getCurDir(), s); + } + + public static URL make(URL url, String s) { + try { + return new URL(url, s); + } catch (MalformedURLException var3) { + var3.printStackTrace(System.out); + throw new Error("Can't make URL"); + } + } + + private String getAbsolute(String urlstr) throws MalformedURLException { + if (!isAbsolute(urlstr)) { + urlstr = this._url.substring(0, this.getBaseIndex()) + urlstr; + } + + if (urlstr.startsWith("rel:")) { + urlstr = urlstr.substring(4); + } + + return normalize(urlstr); + } + + private int getBaseIndex() { + int i = this.getPackageIndex(); + if (this._url.endsWith(".class")) { + int lastDot = this._url.lastIndexOf(46, this._url.length() - 7) + 1; + if (lastDot > i) { + i = lastDot; + } + } + + return i; + } + + public String getAbsolute() { + return this._url.startsWith("rel:") ? this._url.substring(4) : this._url; + } + + @Override + public String toString() { + return this.getInternal(); + } + + public String getInternal() { + return this._url; + } + + public String getBase() { + return this._url.substring(this.getBaseIndex()); + } + + public String getBaseWithoutExt() { + int start = this.getBaseIndex(); + int end = this._url.lastIndexOf(46); + if (end < start) { + end = this._url.length(); + } + + return this._url.substring(start, end); + } + + private static boolean isAbsolute(String urlstr) { + return urlstr != null && (urlstr.indexOf(58) >= 0 || urlstr.replace('\\', '/').startsWith("//")); + } + + private static int getRelpathIndex(String s) { + int i = s.indexOf(58) + 1; + if (s.regionMatches(i, "//", 0, 2)) { + i = s.indexOf(47, i + 2) + 1; + } else if (s.startsWith("file:") && s.regionMatches(i + 1, ":/", 0, 2)) { + i += 3; + } + + return i; + } + + private static String normalize(String url) throws MalformedURLException { + if (url == null) { + throw new MalformedURLException("null URL string"); + } else { + url = url.replace('\\', '/').trim(); + int pathi = url.indexOf(58) + 1; + if (pathi == 1) { + throw new MalformedURLException("Missing protocol specifier"); + } else { + boolean hasHost = url.regionMatches(pathi, "//", 0, 2); + if (pathi <= 2) { + if (pathi == 0 && !hasHost) { + throw new MalformedURLException("Missing protocol specifier"); + } + + url = "file:" + url; + pathi = 5; + } + + if (url.lastIndexOf(47, pathi - 1) >= 0) { + throw new MalformedURLException("/ in protocol specifier of " + url); + } else { + url = url.substring(0, pathi).toLowerCase() + url.substring(pathi); + if (hasHost) { + pathi = url.indexOf(47, pathi + 2) + 1; + if (pathi == 0) { + url = url + '/'; + pathi = url.length(); + } + } + + if (url.startsWith("rel:")) { + url = normalize(url.substring(4)); + return url.startsWith("rel:") ? url : "rel:" + url; + } else { + if (url.startsWith("file:")) { + url = "file:" + validateFile(url.substring(5)); + if (!hasHost) { + assert url.indexOf(58, 5) == 6; + + assert url.charAt(7) == '/'; + + pathi += 3; + } + } else if (url.startsWith("http") && !hasHost) { + throw new MalformedURLException("http must have //host/"); + } + + return url.substring(0, pathi) + removeDots(url.substring(pathi)); + } + } + } + } + } + + private static String validateFile(String p) throws MalformedURLException { + if (p.startsWith("//")) { + int slash = p.indexOf(47, 2); + if (slash < 0) { + p = p + "/"; + } + + return p; + } else { + p = p.toLowerCase(); + int colon = p.indexOf(58); + if (colon != 1) { + return p.indexOf(47) == 0 ? currentDir.substring(0, 2) + p : currentDir + p; + } else if (p.indexOf(47) != 2) { + throw new MalformedURLException("Slash must follow colon"); + } else { + char drive = Character.toLowerCase(p.charAt(0)); + if (!Character.isLowerCase(drive)) { + throw new MalformedURLException("Invalid drive letter"); + } else { + return drive + p.substring(1); + } + } + } + } + + public String getRelativeTo(URL reference) { + if (reference != null && this._url.startsWith("rel:")) { + String url = this.unalias(); + String ref = reference.unalias(); + int pathStart = ref.indexOf(58) + 1; + boolean isLocal = pathStart == 2; + if (!isLocal) { + String hasHost = null; + if (ref.regionMatches(pathStart, "//", 0, 2)) { + hasHost = ref; + } else if (url.regionMatches(pathStart, "//", 0, 2)) { + hasHost = url; + } + + if (hasHost != null) { + pathStart = hasHost.indexOf(47, pathStart + 2) + 1; + if (pathStart == 0) { + return this._url; + } + } + } + + if (!ref.regionMatches(isLocal, 0, url, 0, pathStart)) { + return this._url; + } else { + int noncommonStart = pathStart; + int len = Math.min(url.length(), ref.length()); + + for (int common = pathStart; common < len; common++) { + char c = url.charAt(common); + char d = ref.charAt(common); + if (c != d && (!isLocal || Character.toLowerCase(c) != Character.toLowerCase(d))) { + break; + } + + if (c == '/') { + noncommonStart = common + 1; + } + } + + url = url.substring(noncommonStart); + int pos = noncommonStart; + + while ((pos = ref.indexOf(47, pos) + 1) != 0) { + url = "../" + url; + if (this._url.startsWith("rel:home:")) { + return this._url; + } + } + + return url; + } + } else { + return this._url; + } + } + + public String getRelativeTo(SuperRoot r) { + return this.getRelativeTo(getBestContainer(r)); + } + + public static URL getBestContainer(SuperRoot sr) { + URL url = null; + if (sr != null) { + url = sr.getContainingSourceURL(); + } + + return url == null ? getCurDir() : url; + } + + public static String getRelativeTo(URL u, SuperRoot r) { + return u == null ? null : u.getRelativeTo(r); + } + + public static URL getHome() { + return home; + } + + public static String homeUnalias(String s) { + return make("home:" + s).unalias(); + } + + public static URL getContainingOrCurDir(SuperRoot t) { + URL dir = t.getContainingSourceURL(); + return dir == null ? getCurDir() : make(dir._url.substring(0, dir.getBaseIndex())); + } + + private static void setAvatarServer(String url) { + String avURL = protocols.getIniString("avatar", url); + + try { + psConversion.put("avatar", new URL(new URL(avURL).unalias())); + } catch (MalformedURLException var3) { + System.out.println("Avatar protocol is invalid."); + + assert false; + } + } + + public static boolean usingCachedAvatars() { + return useCachedFiles; + } + + public static void setHttpServer(String url) { + psConversion.put("worldshttp", make(url)); + } + + public static URL getCurDir() { + return file; + } + + public static URL getAvatar() { + return avatar; + } + + private int getPackageIndex() { + int i = this._url.lastIndexOf(47) + 1; + if (i == 0) { + i = this._url.indexOf(58) + 1; + if (i == 4 && this._url.startsWith("rel:")) { + i = this._url.indexOf(58, 4) + 1; + } + } + + return i; + } + + public String unalias() { + String url = this.getAbsolute(); + if (url.endsWith(".class")) { + int base = this.getPackageIndex(); + int len = url.length(); + url = url.substring(0, base) + url.substring(base, len - 6).replace('.', '/') + ".class"; + } + + int protLen = url.indexOf(58); + String prot = url.substring(0, protLen); + Object alias = psConversion.get(prot); + if (alias == null) { + psConversion.put(prot, psConversion); + String s = protocols.getIniString(prot, ""); + if (s != null && !s.equals("")) { + try { + alias = new URL(new URL(s).unalias()); + psConversion.put(prot, alias); + } catch (MalformedURLException var8) { + System.out.println("Invalid inifile entry for " + prot); + } + } + } else if (prot.equals("avatar") && url.endsWith(".rwg")) { + alias = null; + } + + if (alias instanceof URL) { + URL u = (URL)alias; + + assert !u._url.startsWith("rel:"); + + if (u._url.startsWith("file:") && url.length() > protLen + 1 && url.charAt(protLen + 1) == '/') { + protLen++; + } + + url = u._url.substring(0, u.getBaseIndex()) + url.substring(protLen + 1); + } + + if (!url.startsWith("file:")) { + return url; + } else { + url = url.substring(5); + + try { + url = normalize(validateFile(url)); + } catch (MalformedURLException var7) { + return url; + } + + assert url.startsWith("file:"); + + return url.substring(5); + } + } + + public static String searchPath(String name, String path) { + StringTokenizer e = new StringTokenizer(path, File.pathSeparator); + + while (e.hasMoreTokens()) { + String dir = e.nextToken(); + String expandedName = name; + if (!dir.equals(".")) { + expandedName = dir + File.separator + name; + } + + File f = new File(expandedName); + if (f.exists()) { + return expandedName; + } + } + + return null; + } + + public String getClassName() { + if (!this._url.endsWith(".class")) { + return null; + } else { + int base = this.getPackageIndex(); + int len = this._url.length(); + return this._url.substring(base, len - 6); + } + } + + public URL getClassDir() { + return !this._url.endsWith(".class") ? null : make(this._url.substring(0, this.getPackageIndex())); + } + + public boolean endsWith(String ext) { + return this._url.endsWith(ext); + } + + public String getExt() { + int i = this._url.lastIndexOf(46); + return i != -1 && this._url.indexOf(47, i) < 0 && this._url.indexOf(58, i) < 0 ? this._url.substring(i) : ""; + } + + public static String maybeAddExt(String url, String ext) { + int dot = url.lastIndexOf(46); + return dot >= 0 && url.indexOf(47, dot) < 0 && url.indexOf(92, dot) < 0 ? url : url + ext; + } + + public static URL restore(Restorer r, String defaultExt) throws IOException { + return restore(r, r.restoreString(), defaultExt); + } + + public static URL restore(Restorer r, String url, String defaultExt) throws IOException { + if (url == null) { + return null; + } else { + if (defaultExt != null) { + url = maybeAddExt(url, defaultExt); + } + + if (isAbsolute(url)) { + return new URL(url); + } else { + URL ref = r.getReferenceURL(); + if (r.version() >= 6) { + if (ref == null) { + throw new IOException("No absolute base for relative URL " + url); + } else { + return new URL(ref, url); + } + } else if (url.endsWith(".class")) { + return make((url.indexOf(47) < 0 ? "system:" : "file:") + url); + } else { + String s = searchPath(url, ".;.."); + if (s != null) { + if (ref == null) { + return new URL("file:" + s); + } else { + URL unaliasedRef = make(ref.unalias()); + String rel = new URL("rel:file:" + s).getRelativeTo(unaliasedRef); + return new URL(ref, rel); + } + } else { + System.out.println(url + " doesn't exist in RWSHAPEPATH"); + return make(ref, url); + } + } + } + } + } + + public static URL restore(Restorer r) throws IOException { + return restore(r, null); + } + + public void save(Saver s) throws IOException { + String r = this.getRelativeTo(s.getReferenceURL()); + if (r.startsWith("../") || r.startsWith("rel:file:") || r.startsWith("file:")) { + Console.println(Console.message("path-to-outside") + r); + } + + s.saveString(r); + } + + public static void save(Saver s, URL url) throws IOException { + if (url == null) { + s.saveString(null); + } else { + url.save(s); + } + } + + @Override + public boolean equals(Object o) { + if (o instanceof URL) { + URL other = (URL)o; + return this._url.equals(other.getInternal()) ? true : this.unalias().equals(other.unalias()); + } else { + return false; + } + } + + @Override + public int hashCode() { + return this.unalias().hashCode(); + } + + public boolean isRemote() { + String s = this.unalias(); + return s.startsWith("//") || s.indexOf(58) < 2 ? false : !s.startsWith("system:") && !s.startsWith("session:"); + } + + public static String removeDots(String url) { + url = "/" + url; + int firstSubdir = 1; + int nextSearch = firstSubdir - 1; + + int firstDot; + while ((firstDot = url.indexOf("/.", nextSearch) + 1) > 0) { + int endSlash = url.indexOf(47, firstDot); + if (endSlash < 0) { + break; + } + + int numDots = endSlash - firstDot; + int i = firstDot; + + while (i < endSlash && url.charAt(i) == '.') { + i++; + } + + if (i != endSlash) { + nextSearch = endSlash; + } else { + while (true) { + if (numDots == 1) { + endSlash++; + } else { + if (firstDot != firstSubdir) { + firstDot = url.lastIndexOf(47, firstDot - 2) + 1; + if (firstDot <= firstSubdir) { + firstDot = firstSubdir; + } + + numDots--; + continue; + } + + endSlash -= numDots; + firstSubdir += numDots + 1; + } + + url = url.substring(0, firstDot) + url.substring(endSlash); + nextSearch = firstSubdir - 1; + break; + } + } + } + + return url.substring(1); + } +} |