From 8173b9b4c2c0e522e5ac52819408924702bba263 Mon Sep 17 00:00:00 2001 From: Jeffrey Han Date: Sat, 8 Aug 2015 20:34:49 -0500 Subject: [PATCH] Added Mnetwork download mirror. URL: http://osu.uu.gl/ Note that there's no API available, so this just parses the HTML for beatmap data. It's pretty slow compared to the other servers. Signed-off-by: Jeffrey Han --- .../downloads/servers/MnetworkServer.java | 133 ++++++++++++++++++ .../opsu/states/DownloadsMenu.java | 5 +- 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 src/itdelatrisu/opsu/downloads/servers/MnetworkServer.java diff --git a/src/itdelatrisu/opsu/downloads/servers/MnetworkServer.java b/src/itdelatrisu/opsu/downloads/servers/MnetworkServer.java new file mode 100644 index 00000000..625f7015 --- /dev/null +++ b/src/itdelatrisu/opsu/downloads/servers/MnetworkServer.java @@ -0,0 +1,133 @@ +/* + * opsu! - an open-source osu! client + * Copyright (C) 2014, 2015 Jeffrey Han + * + * opsu! is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opsu! is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opsu!. If not, see . + */ + +package itdelatrisu.opsu.downloads.servers; + +import itdelatrisu.opsu.ErrorHandler; +import itdelatrisu.opsu.Utils; +import itdelatrisu.opsu.downloads.DownloadNode; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Download server: http://osu.uu.gl/ + */ +public class MnetworkServer extends DownloadServer { + /** Server name. */ + private static final String SERVER_NAME = "Mnetwork"; + + /** Formatted download URL: {@code beatmapSetID} */ + private static final String DOWNLOAD_URL = "http://osu.uu.gl/s/%d"; + + /** Formatted search URL: {@code query} */ + private static final String SEARCH_URL = "http://osu.uu.gl/d/%s"; + + /** Total result count from the last query. */ + private int totalResults = -1; + + /** Beatmap pattern. */ + private Pattern BEATMAP_PATTERN = Pattern.compile("^(\\d+) ([^-]+) - (.+)\\.osz$"); + + /** Constructor. */ + public MnetworkServer() {} + + @Override + public String getName() { return SERVER_NAME; } + + @Override + public String getDownloadURL(int beatmapSetID) { + return String.format(DOWNLOAD_URL, beatmapSetID); + } + + @Override + public DownloadNode[] resultList(String query, int page, boolean rankedOnly) throws IOException { + DownloadNode[] nodes = null; + try { + // read HTML + String queryString = (query.isEmpty()) ? "-" : query; + String search = String.format(SEARCH_URL, URLEncoder.encode(queryString, "UTF-8")); + String html = Utils.readDataFromUrl(new URL(search)); + if (html == null) { + this.totalResults = -1; + return null; + } + + // parse results + // NOTE: Not using a full HTML parser because this is a relatively simple operation. + // FORMAT: + //
+ // {{id}} {{artist}} - {{title}}.osz
+ // BPM: {{bpm}} | Total Time: {{m}}:{{s}}
+ // Genre: {{genre}} | Updated: {{MMM}} {{d}}, {{yyyy}}
+ List nodeList = new ArrayList(); + final String START_TAG = "
", HREF_TAG = " n) continue; + i = html.indexOf('>', i + HREF_TAG.length()); + if (i == -1 || i >= n) continue; + j = html.indexOf('<', i + 1); + if (j == -1 || j > n) continue; + String beatmap = html.substring(i + 1, j).trim(); + + // find date + i = html.indexOf(UPDATED, j); + if (i == -1 || i >= n) continue; + j = html.indexOf('<', i + UPDATED.length()); + if (j == -1 || j > n) continue; + String date = html.substring(i + UPDATED.length(), j).trim(); + + // parse id, title, and artist + Matcher m = BEATMAP_PATTERN.matcher(beatmap); + if (!m.matches()) + continue; + + nodeList.add(new DownloadNode(Integer.parseInt(m.group(1)), date, m.group(3), null, m.group(2), null, "")); + } + + nodes = nodeList.toArray(new DownloadNode[nodeList.size()]); + + // store total result count + this.totalResults = nodes.length; + } catch (MalformedURLException | UnsupportedEncodingException e) { + ErrorHandler.error(String.format("Problem loading result list for query '%s'.", query), e, true); + } + return nodes; + } + + @Override + public int minQueryLength() { return 0; } + + @Override + public int totalResults() { return totalResults; } +} diff --git a/src/itdelatrisu/opsu/states/DownloadsMenu.java b/src/itdelatrisu/opsu/states/DownloadsMenu.java index e4f261d8..09113e4c 100644 --- a/src/itdelatrisu/opsu/states/DownloadsMenu.java +++ b/src/itdelatrisu/opsu/states/DownloadsMenu.java @@ -35,6 +35,7 @@ import itdelatrisu.opsu.downloads.DownloadNode; import itdelatrisu.opsu.downloads.servers.BloodcatServer; import itdelatrisu.opsu.downloads.servers.DownloadServer; import itdelatrisu.opsu.downloads.servers.HexideServer; +import itdelatrisu.opsu.downloads.servers.MnetworkServer; import itdelatrisu.opsu.downloads.servers.YaSOnlineServer; import itdelatrisu.opsu.ui.MenuButton; import itdelatrisu.opsu.ui.UI; @@ -74,7 +75,9 @@ public class DownloadsMenu extends BasicGameState { private static final int MIN_REQUEST_INTERVAL = 300; /** Available beatmap download servers. */ - private static final DownloadServer[] SERVERS = { new BloodcatServer(), new HexideServer(), new YaSOnlineServer() }; + private static final DownloadServer[] SERVERS = { + new BloodcatServer(), new HexideServer(), new YaSOnlineServer(), new MnetworkServer() + }; /** The beatmap download server index. */ private int serverIndex = 0;