summaryrefslogtreecommitdiff
path: root/NET/worlds/scape/CDDBLookup.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/scape/CDDBLookup.java
downloadworldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz
worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip
Initial commit
Diffstat (limited to 'NET/worlds/scape/CDDBLookup.java')
-rw-r--r--NET/worlds/scape/CDDBLookup.java363
1 files changed, 363 insertions, 0 deletions
diff --git a/NET/worlds/scape/CDDBLookup.java b/NET/worlds/scape/CDDBLookup.java
new file mode 100644
index 0000000..0deef54
--- /dev/null
+++ b/NET/worlds/scape/CDDBLookup.java
@@ -0,0 +1,363 @@
+package NET.worlds.scape;
+
+import NET.worlds.core.Hashtable;
+import NET.worlds.network.URL;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+public class CDDBLookup implements Runnable {
+ public static final int STATUS_SERVERERROR = -3;
+ public static final int STATUS_NOTUNIQUE = -2;
+ public static final int STATUS_NOTFOUND = -1;
+ public static final int STATUS_LOOKING = 0;
+ public static final int STATUS_EXACTMATCH = 1;
+ public static final int STATUS_CLOSEMATCH = 2;
+ private static final boolean debug = false;
+ private static final String lookupThreadName = "lookup";
+ private static final String siteThreadName = "site";
+ private static final String pkgName = "gamma";
+ private static final String pkgVersion = "1.0";
+ private static final int TIMEOUT = 3000;
+ private static final String dbName = "home:cdcache.db";
+ private static CDDBHost siteHost = new CDDBHost("cddb.cddb.com", 888);
+ private static Vector sites;
+ private static Object siteMutex = new Object();
+ private static Object knownDisksMutex = new Object();
+ private static int lastHostUsed = -1;
+ private static Hashtable threadActivity = new Hashtable();
+ private static Hashtable knownDisks;
+ private static String userName;
+ private static String hostName;
+ private CDTrackInfo tracks;
+ private String hash;
+ private CDDBStatus status;
+ private static final String discTitleKey = "DTITLE=";
+ private static final String trackTitleKey = "TTITLE";
+
+ public CDDBLookup(CDTrackInfo tracks) {
+ if (userName == null) {
+ userName = System.getProperty("user.name").replace(' ', '_');
+
+ try {
+ hostName = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException var3) {
+ hostName = "unknown";
+ }
+ }
+
+ this.tracks = tracks;
+ this.hash = CDDBHash.hashString(tracks);
+ if ((this.status = this.dbLookup()) == null) {
+ this.runThread("lookup");
+ }
+ }
+
+ public String getHash() {
+ return this.hash;
+ }
+
+ public CDDiskInfo getDiskInfo() {
+ return this.getDiskInfo(false);
+ }
+
+ public synchronized CDDiskInfo getDiskInfo(boolean wait) {
+ if (wait) {
+ while (this.status == null) {
+ try {
+ this.wait();
+ } catch (InterruptedException var3) {
+ }
+ }
+ }
+
+ return this.status != null ? this.status.getDiskInfo() : null;
+ }
+
+ public int getStatus() {
+ return this.status != null ? this.status.getStatus() : 0;
+ }
+
+ @Override
+ public void run() {
+ String name = Thread.currentThread().getName();
+ if (name.equals("lookup")) {
+ this.maybeRunSiteThread();
+
+ for (int i = 0; i < sites.size(); i++) {
+ synchronized (this) {
+ Thread t = this.runThread("" + i);
+
+ try {
+ do {
+ this.wait(3000L);
+ } while (this.status == null && this.recentlyActive(t));
+ } catch (InterruptedException var13) {
+ }
+
+ this.forgetThread(t);
+ if (this.status != null) {
+ break;
+ }
+
+ if (i == sites.size() - 1) {
+ this.status = new CDDBStatus(-3);
+ this.notifyAll();
+ }
+ }
+ }
+ } else if (name.equals("site")) {
+ Vector v = getSiteList();
+ synchronized (siteMutex) {
+ if (sites == null) {
+ sites = v;
+ }
+
+ siteMutex.notifyAll();
+ }
+ } else {
+ CDDBStatus newStatus = null;
+ int hostIndex = 0;
+
+ try {
+ hostIndex = Integer.parseInt(name);
+ } catch (NumberFormatException var11) {
+ }
+
+ CDDBHost host = null;
+ synchronized (siteMutex) {
+ host = (CDDBHost)sites.elementAt(hostIndex);
+ }
+
+ newStatus = this.findDiskInfo(host);
+ synchronized (this) {
+ if (this.status == null && newStatus != null) {
+ this.status = newStatus;
+ if (hostIndex != 0) {
+ synchronized (siteMutex) {
+ Object site = sites.elementAt(hostIndex);
+ sites.removeElementAt(hostIndex);
+ sites.insertElementAt(site, 0);
+ }
+ }
+
+ this.notifyAll();
+ }
+ }
+ }
+ }
+
+ private static void addSite(Vector v, String host, int port) {
+ v.addElement(new CDDBHost(host, port));
+ }
+
+ private static void defaultSites() {
+ sites = new Vector();
+ addSite(sites, "cddb.moonsoft.com", 888);
+ addSite(sites, "cddb.moonsoft.com", 8880);
+ addSite(sites, "cddb.celestial.com", 888);
+ addSite(sites, "cddb.sonic.net", 888);
+ addSite(sites, "sunsite.unc.edu", 888);
+ addSite(sites, "cddb.netads.com", 888);
+ addSite(sites, "cddb.mattdm.org", 888);
+ addSite(sites, "cddb.dartmouth.edu", 888);
+ }
+
+ private static Vector getSiteList() {
+ CDDBConnection con = null;
+
+ try {
+ con = new CDDBConnection(siteHost, false);
+ con.command("sites").startsWith("210 ");
+ Vector v = new Vector();
+
+ String line;
+ while ((line = con.readBody()) != null) {
+ StringTokenizer tok = new StringTokenizer(line, " ");
+ addSite(v, tok.nextToken(), Integer.parseInt(tok.nextToken()));
+ }
+
+ return v;
+ } catch (IOException var10) {
+ } catch (NumberFormatException var11) {
+ } catch (NoSuchElementException var12) {
+ } finally {
+ if (con != null) {
+ con.close();
+ }
+ }
+
+ return null;
+ }
+
+ private CDDBStatus findDiskInfo(CDDBHost host) {
+ CDDBConnection con = null;
+
+ CDDBStatus var9;
+ try {
+ con = new CDDBConnection(host, false);
+ if (!con.command("cddb hello " + userName + " " + hostName + " " + "gamma" + " " + "1.0").startsWith("200 ")) {
+ return null;
+ }
+
+ String resp = con.command("cddb query " + CDDBHash.lookupString(this.tracks));
+ StringTokenizer t = new StringTokenizer(resp, " ");
+ String code = t.nextToken();
+ if (code.equals("200")) {
+ return this.dbAdd(new CDDBStatus(1, this.getCDDBEntry(con, t)));
+ }
+
+ if (code.equals("211")) {
+ String line = con.readBody();
+ int extra = 0;
+
+ while (con.readBody() != null) {
+ extra++;
+ }
+
+ if (extra != 0) {
+ return this.dbAdd(new CDDBStatus(-2));
+ }
+
+ return this.dbAdd(new CDDBStatus(2, this.getCDDBEntry(con, new StringTokenizer(line, " "))));
+ }
+
+ if (!code.equals("202")) {
+ return null;
+ }
+
+ var9 = new CDDBStatus(-1);
+ } catch (IOException var13) {
+ return null;
+ } catch (NoSuchElementException var14) {
+ return null;
+ } finally {
+ if (con != null) {
+ con.close();
+ }
+ }
+
+ return var9;
+ }
+
+ private Thread runThread(String name) {
+ Thread t = new Thread(this, name);
+ t.setDaemon(true);
+ t.start();
+ return t;
+ }
+
+ private void maybeRunSiteThread() {
+ synchronized (siteMutex) {
+ if (sites == null) {
+ Thread t = this.runThread("site");
+
+ try {
+ do {
+ siteMutex.wait(3000L);
+ } while (sites == null && this.recentlyActive(t));
+ } catch (InterruptedException var4) {
+ }
+
+ this.forgetThread(t);
+ if (sites == null) {
+ defaultSites();
+ }
+ }
+ }
+ }
+
+ private CDDiskInfo getCDDBEntry(CDDBConnection con, StringTokenizer t) {
+ try {
+ String cat = t.nextToken();
+ String id = t.nextToken();
+ if (con.command("cddb read " + cat + " " + id).startsWith("210 ")) {
+ return this.parseCDDBEntry(cat, con);
+ }
+ } catch (IOException var5) {
+ } catch (NoSuchElementException var6) {
+ }
+
+ return null;
+ }
+
+ private CDDiskInfo parseCDDBEntry(String category, CDDBConnection con) throws IOException {
+ String artist = null;
+ String title = null;
+ String[] trackNames = new String[this.tracks.getNumTracks()];
+
+ for (int i = 0; i < trackNames.length; i++) {
+ trackNames[i] = "";
+ }
+
+ String line;
+ while ((line = con.readBody()) != null) {
+ if (line.startsWith("DTITLE=")) {
+ line = line.substring("DTITLE=".length());
+ int slashPos = line.indexOf(47);
+ if (slashPos == -1) {
+ artist = title = line.trim();
+ } else {
+ artist = line.substring(0, slashPos).trim();
+ title = line.substring(slashPos + 1).trim();
+ }
+ } else if (line.startsWith("TTITLE")) {
+ int eqIndex = line.indexOf(61);
+
+ try {
+ int trackNum = Integer.parseInt(line.substring("TTITLE".length(), eqIndex));
+ trackNames[trackNum] = trackNames[trackNum] + line.substring(eqIndex + 1);
+ } catch (NumberFormatException var9) {
+ } catch (IndexOutOfBoundsException var10) {
+ }
+ }
+ }
+
+ return new CDDiskInfo(artist, title, category, trackNames);
+ }
+
+ static void markActivity() {
+ threadActivity.put(Thread.currentThread(), new Long(System.currentTimeMillis()));
+ }
+
+ private boolean recentlyActive(Thread t) {
+ Long l = (Long)threadActivity.get(t);
+ return l != null ? System.currentTimeMillis() - l < 3000L : false;
+ }
+
+ private void forgetThread(Thread t) {
+ threadActivity.remove(t);
+ }
+
+ private CDDBStatus dbAdd(CDDBStatus status) {
+ synchronized (knownDisksMutex) {
+ if (knownDisks.get(this.hash) == null) {
+ knownDisks.put(this.hash, status);
+
+ try {
+ new Saver(new URL("home:cdcache.db")).save(knownDisks);
+ } catch (Exception var4) {
+ }
+ }
+
+ return status;
+ }
+ }
+
+ private CDDBStatus dbLookup() {
+ synchronized (knownDisksMutex) {
+ if (knownDisks == null) {
+ try {
+ knownDisks = (Hashtable)new Restorer(new URL("home:cdcache.db")).restore();
+ } catch (Exception var3) {
+ knownDisks = new Hashtable();
+ }
+ }
+
+ return (CDDBStatus)knownDisks.get(this.hash);
+ }
+ }
+}