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/scape/CDDBLookup.java | |
| download | worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.tar.xz worldsplayer-c7a9d4a6bd53ed7d61731770f2f10e8b9fd435f9.zip | |
Initial commit
Diffstat (limited to 'NET/worlds/scape/CDDBLookup.java')
| -rw-r--r-- | NET/worlds/scape/CDDBLookup.java | 363 |
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); + } + } +} |