package NET.worlds.core; import NET.worlds.console.Gamma; import NET.worlds.network.Cache; import NET.worlds.network.CacheFile; import NET.worlds.network.NetUpdate; import NET.worlds.network.ProgressDialog; import NET.worlds.network.URL; import NET.worlds.scape.BGLoaded; import NET.worlds.scape.BackgroundLoader; import NET.worlds.scape.Room; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; import java.io.StringReader; import java.util.StringTokenizer; import java.util.Vector; public class ServerTableManager implements BGLoaded { private Hashtable tables; private String tableFile; private int fileVersion = 0; public static ServerTableManager theTableManager = null; private static String tableStart = "private static String[] "; private static String version = "VERSION"; public int getFileVersion() { return this.fileVersion; } public static ServerTableManager instance() { if (theTableManager == null) { theTableManager = new ServerTableManager(); } return theTableManager; } public String[] getTable(String tableName) { Object table = this.tables.get(tableName); if (table == null) { System.out.println("Requested table " + tableName + " not found."); } return (String[])table; } private ServerTableManager() { this.tables = new Hashtable(); this.tableFile = IniFile.override().getIniString("ServerTableFile", "tables/tables.dat"); if (IniFile.gamma().getIniInt("encryptTables", 0) == 1) { this.encryptTablesFile(); } this.loadTableFile(); } private boolean loadTableFile() { URL tableURL = URL.make(NetUpdate.getUpgradeServerURL() + this.tableFile); boolean syncLoad = IniFile.gamma().getIniInt("synchronousTableLoad", 1) == 1; if (Gamma.loadProgress != null) { Gamma.loadProgress.setMessage("Downloading global server information..."); Gamma.loadProgress.advance(); } if (syncLoad) { CacheFile cf = Cache.getFile(tableURL); cf.waitUntilLoaded(); if (!cf.error()) { this.syncBackgroundLoad(cf.getLocalName(), null); } } boolean ok = this.parseFile(); if (!syncLoad) { BackgroundLoader.get(this, tableURL); } return ok; } @Override public synchronized Object asyncBackgroundLoad(String localName, URL remoteURL) { return localName; } @Override public boolean syncBackgroundLoad(Object obj, URL remoteURL) { String localName = (String)obj; if (localName != null && new File(localName).exists()) { ProgressDialog.copyFile(localName, this.tableFile); } return false; } @Override public Room getBackgroundLoadRoom() { return null; } private boolean parseFile() { BufferedReader buf = null; try { RandomAccessFile fIn = new RandomAccessFile(this.tableFile, "r"); byte[] encrypted = new byte[fIn.readInt()]; fIn.readFully(encrypted); fIn.close(); String decrypted = this.decrypt(encrypted); buf = new BufferedReader(new StringReader(decrypted)); String line; while ((line = buf.readLine()) != null) { line = line.trim(); if (!line.startsWith("//") && line.length() != 0) { if (line.startsWith(version)) { StringTokenizer tok = new StringTokenizer(line); String versionString = ""; while (tok.hasMoreTokens()) { versionString = tok.nextToken(); } if (versionString != "") { this.fileVersion = Double.valueOf(versionString).intValue(); } } if (line.startsWith(tableStart)) { String tableName = line.substring(tableStart.length()); StringTokenizer tok = new StringTokenizer(tableName); if (tok.hasMoreTokens()) { this.parseTable(buf, tok.nextToken().trim()); } } } } buf.close(); return true; } catch (FileNotFoundException var8) { System.out.println(var8); return false; } catch (IOException var9) { System.out.println(var9); return false; } } private String stripQuotes(String in) { String out = new String(in); if (out.charAt(0) == '"') { out = out.substring(1); } if (out.charAt(out.length() - 1) == '"') { out = out.substring(0, out.length() - 1); } int idx; while ((idx = out.indexOf(34)) != -1) { out = out.substring(0, idx) + out.substring(idx + 1); } return out; } private void parseTable(BufferedReader buf, String tableName) throws IOException { String lastEntry = null; Vector strings = new Vector(); String line; while ((line = buf.readLine()) != null) { line = line.trim(); if (line.length() != 0 && !line.startsWith("//")) { if (line.startsWith("};")) { break; } StringTokenizer tok = new StringTokenizer(line, ",\n\r"); while (tok.hasMoreTokens()) { String token = tok.nextToken().trim(); if (token.startsWith("+ \"")) { if (lastEntry != null) { token = token.substring(2); lastEntry = lastEntry + this.stripQuotes(token); strings.removeElement(strings.lastElement()); strings.addElement(lastEntry); } } else { String entry = this.stripQuotes(token); lastEntry = entry; strings.addElement(entry); } } } } int numStrings = strings.size(); String[] table = new String[numStrings]; for (int i = 0; i < numStrings; i++) { table[i] = strings.elementAt(i); } System.out.println("Adding table " + tableName); this.tables.put(tableName, table); } private byte[] encrypt(String in) { byte[] inBytes; try { inBytes = in.getBytes("UTF8"); } catch (Exception var6) { System.out.println("Error encoding to UTF8" + var6.toString()); return null; } byte[] outBytes = new byte[inBytes.length]; int len = inBytes.length; outBytes[0] = inBytes[0]; for (int idx = 1; idx < len; idx++) { outBytes[idx] = (byte)(inBytes[idx] ^ outBytes[idx - 1]); } return outBytes; } private String decrypt(byte[] in) { byte[] outBytes = new byte[in.length]; int len = in.length; outBytes[0] = in[0]; for (int idx = 1; idx < len; idx++) { outBytes[idx] = (byte)(in[idx] ^ in[idx - 1]); } try { return new String(outBytes, "UTF8"); } catch (Exception var6) { System.out.println("Error encoding UTF8 " + var6.toString()); return null; } } private void encryptTablesFile() { try { System.out.println("Encoding tables file..."); RandomAccessFile inFilth = new RandomAccessFile("..\\tables.txt", "r"); String inStr = new String(); while (inFilth.getFilePointer() < inFilth.length()) { String in = inFilth.readLine(); System.out.println(in); inStr = inStr + in + "\r\n"; } inFilth.close(); byte[] encrypted = this.encrypt(inStr); RandomAccessFile out = new RandomAccessFile(this.tableFile, "rw"); RandomAccessFile out2 = new RandomAccessFile("..\\tables.dat", "rw"); out.writeInt(encrypted.length); out2.writeInt(encrypted.length); out.write(encrypted); out2.write(encrypted); out.close(); out2.close(); System.out.println("Tables file " + this.tableFile + " successfully written."); } catch (Exception var6) { System.out.println("Error encoding tables file: " + var6.toString()); } } }