diff --git a/res/values/options.xml b/res/values/options.xml
index 1e9df2fcf..00aa70dd5 100644
--- a/res/values/options.xml
+++ b/res/values/options.xml
@@ -68,6 +68,14 @@
- 1
- 2
+
+ - Score
+ - Performance Points
+
+
+ - 0
+ - 1
+
- placeholder
@@ -207,6 +215,9 @@
Load Avatar
Load avatar in online leaderboard
+ Global beatmap leaderboard scoring mode
+ Choose the scoring mode for global beatmap leaderboards
+
Hit error meter
Display hit error meter
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3ab21f2ff..aae3a7fc3 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -90,6 +90,7 @@
Manage Beatmap folder
Score: %s (%dx)
+ Performance: %spp (%dx)
Creator: %s
Back
Mod selection
diff --git a/res/xml/settings_general.xml b/res/xml/settings_general.xml
index ddad7aa7e..ad7a4ccf0 100644
--- a/res/xml/settings_general.xml
+++ b/res/xml/settings_general.xml
@@ -17,7 +17,16 @@
android:key="loadAvatar"
android:summary="@string/opt_loadavatar_summary"
android:title="@string/opt_loadavatar_title"
- app:layout="@layout/settings_preference_checkbox_bottom" />
+ app:layout="@layout/settings_preference_checkbox" />
+
+
diff --git a/src/ru/nsu/ccfit/zuev/osu/Config.java b/src/ru/nsu/ccfit/zuev/osu/Config.java
index 061a7c44c..c9632546d 100644
--- a/src/ru/nsu/ccfit/zuev/osu/Config.java
+++ b/src/ru/nsu/ccfit/zuev/osu/Config.java
@@ -23,6 +23,7 @@
import org.anddev.andengine.util.Debug;
import ru.nsu.ccfit.zuev.osu.helper.FileUtils;
+import ru.nsu.ccfit.zuev.osu.scoring.BeatmapLeaderboardScoringMode;
public class Config {
private static String corePath,
@@ -97,6 +98,8 @@ public class Config {
private static DifficultyAlgorithm difficultyAlgorithm;
+ private static BeatmapLeaderboardScoringMode beatmapLeaderboardScoringMode;
+
private static Map skins;
private static RGBColor[] comboColors;
@@ -251,6 +254,7 @@ public static void loadOnlineConfig(final Context context) {
onlinePassword = prefs.getString("onlinePassword", null);
stayOnline = prefs.getBoolean("stayOnline", false);
loadAvatar = prefs.getBoolean("loadAvatar",false);
+ beatmapLeaderboardScoringMode = BeatmapLeaderboardScoringMode.parse(Integer.parseInt(prefs.getString("beatmapLeaderboardScoringMode", "0")));
}
public static void setSize() {
@@ -520,6 +524,10 @@ public static void setStayOnline(boolean stayOnline) {
Config.stayOnline = stayOnline;
}
+ public static BeatmapLeaderboardScoringMode getBeatmapLeaderboardScoringMode() {
+ return beatmapLeaderboardScoringMode;
+ }
+
public static boolean getLoadAvatar() {
return loadAvatar;
}
diff --git a/src/ru/nsu/ccfit/zuev/osu/menu/ScoreBoard.java b/src/ru/nsu/ccfit/zuev/osu/menu/ScoreBoard.java
index 869f95a06..3d319d138 100644
--- a/src/ru/nsu/ccfit/zuev/osu/menu/ScoreBoard.java
+++ b/src/ru/nsu/ccfit/zuev/osu/menu/ScoreBoard.java
@@ -22,6 +22,7 @@
import ru.nsu.ccfit.zuev.osu.game.GameHelper;
import ru.nsu.ccfit.zuev.osu.helper.StringTable;
import ru.nsu.ccfit.zuev.osu.online.OnlineManager;
+import ru.nsu.ccfit.zuev.osu.scoring.BeatmapLeaderboardScoringMode;
import ru.nsu.ccfit.zuev.osuplus.R;
import java.io.File;
@@ -190,6 +191,12 @@ private String formatScore(StringBuilder sb, int score) {
return sb.toString();
}
+ private String formatPP(StringBuilder sb, int pp) {
+ sb.setLength(0);
+ sb.append(pp);
+ return sb.toString();
+ }
+
private void initFromOnline(BeatmapInfo beatmapInfo) {
loadingText.setText("Loading scores...");
@@ -218,62 +225,69 @@ public void run() {
loadingText.setText(OnlineManager.getInstance().getFailMessage());
+ boolean isPPScoringMode = Config.getBeatmapLeaderboardScoringMode() == BeatmapLeaderboardScoringMode.PP;
var username = OnlineManager.getInstance().getUsername();
var items = new ArrayList(scores.size());
var sb = new StringBuilder();
- int nextTotalScore = 0;
+ float nextTotal = 0;
for (int i = 0; i < scores.size() && isActive(); ++i) {
var data = scores.get(i).split("\\s+");
- if (data.length < 8 || data.length > 9) {
+ if (data.length < 9 || data.length > 10) {
continue;
}
- var isInLeaderboard = data.length == 8;
- var isPersonalBest = data.length == 9 || data[1].equals(username);
+ var isInLeaderboard = data.length == 9;
+ var isPersonalBest = data.length == 10 || data[1].equals(username);
var scoreID = Integer.parseInt(data[0]);
var playerName = isPersonalBest ? username : data[1];
- var currentTotalScore = Integer.parseInt(data[2]);
- var combo = Integer.parseInt(data[3]);
- var mark = data[4];
- var mods = data[5];
- var accuracy = GameHelper.Round(Float.parseFloat(data[6]) * 100, 2);
- var avatarURL = data[7];
- var beatmapRank = isPersonalBest && !isInLeaderboard ? Integer.parseInt(data[8]) : (i + 1);
+ var score = Integer.parseInt(data[2]);
+ var pp = Float.parseFloat(data[3]);
+ var combo = Integer.parseInt(data[4]);
+ var mark = data[5];
+ var mods = data[6];
+ var accuracy = Float.parseFloat(data[7]);
+ var avatarURL = data[8];
+ var beatmapRank = isPersonalBest && !isInLeaderboard ? Integer.parseInt(data[9]) : (i + 1);
sb.setLength(0);
- var totalScore = formatScore(sb, currentTotalScore);
+ var scoreStr = isPPScoringMode ?
+ // For display purposes, we round the pp.
+ formatPP(sb, Math.round(pp)) :
+ formatScore(sb, score);
sb.setLength(0);
var titleStr = sb.append('#').append(beatmapRank).append(' ').append(playerName)
.append('\n')
- .append(StringTable.format(R.string.menu_score, totalScore, combo))
+ .append(StringTable.format(
+ isPPScoringMode ? R.string.menu_performance : R.string.menu_score, scoreStr, combo))
.toString();
if (i < scores.size() - 1) {
String[] nextData = scores.get(i + 1).split("\\s+");
- if (nextData.length == 8 || nextData.length == 9) {
- nextTotalScore = Integer.parseInt(nextData[2]);
+ if (nextData.length == 9 || nextData.length == 10) {
+ nextTotal = isPPScoringMode ? Float.parseFloat(nextData[3]) : Integer.parseInt(nextData[2]);
}
} else {
- nextTotalScore = 0;
+ nextTotal = 0;
}
sb.setLength(0);
var modString = convertModString(sb, mods);
- var diffTotalScore = currentTotalScore - nextTotalScore;
+ var currentTotal = isPPScoringMode ? pp : score;
+ var diffTotal = Math.round(currentTotal) - Math.round(nextTotal);
sb.setLength(0);
var accStr = sb.append(modString)
.append('\n')
.append(StringTable.format("%.2f", GameHelper.Round(accuracy * 100, 2))).append('%')
.append('\n')
- .append(nextTotalScore == 0 ? "-" : ((diffTotalScore != 0 ? "+" : "") + diffTotalScore))
+ .append(nextTotal == 0 ? "-" : ((diffTotal != 0 ? "+" : "") + diffTotal))
.toString();
if (!isActive()) {
@@ -288,7 +302,7 @@ public void run() {
attachChild(new ScoreItem(avatarExecutor, titleStr, accStr, mark, true, scoreID, avatarURL, playerName, false));
var item = new ScoreBoardItem();
- item.set(beatmapRank, playerName, combo, currentTotalScore, scoreID);
+ item.set(beatmapRank, playerName, combo, score, scoreID);
items.add(item);
}
}
diff --git a/src/ru/nsu/ccfit/zuev/osu/online/OnlineManager.java b/src/ru/nsu/ccfit/zuev/osu/online/OnlineManager.java
index 0df2c39cf..0c6bc1937 100644
--- a/src/ru/nsu/ccfit/zuev/osu/online/OnlineManager.java
+++ b/src/ru/nsu/ccfit/zuev/osu/online/OnlineManager.java
@@ -28,6 +28,7 @@
import ru.nsu.ccfit.zuev.osu.*;
import ru.nsu.ccfit.zuev.osu.helper.MD5Calculator;
import ru.nsu.ccfit.zuev.osu.online.PostBuilder.RequestException;
+import ru.nsu.ccfit.zuev.osu.scoring.BeatmapLeaderboardScoringMode;
public class OnlineManager {
public static final String hostname = "osudroid.moe";
@@ -293,6 +294,12 @@ public ArrayList getTop(final File beatmapFile, final String hash) throw
post.addParam("hash", hash);
post.addParam("uid", String.valueOf(userId));
+ if (Config.getBeatmapLeaderboardScoringMode() == BeatmapLeaderboardScoringMode.PP) {
+ post.addParam("type", "pp");
+ } else {
+ post.addParam("type", "score");
+ }
+
ArrayList response = sendRequest(post, endpoint + "getrank.php");
if (response == null) {
diff --git a/src/ru/nsu/ccfit/zuev/osu/online/OnlineScoring.java b/src/ru/nsu/ccfit/zuev/osu/online/OnlineScoring.java
index cd00aaf00..a0fea9785 100644
--- a/src/ru/nsu/ccfit/zuev/osu/online/OnlineScoring.java
+++ b/src/ru/nsu/ccfit/zuev/osu/online/OnlineScoring.java
@@ -186,17 +186,6 @@ public void sendRecord(final StatisticV2 record, final SendingPanel panel, final
});
}
- public ArrayList getTop(final File beatmapFile, final String hash) {
- synchronized (onlineMutex) {
- try {
- return OnlineManager.getInstance().getTop(beatmapFile, hash);
- } catch (OnlineManager.OnlineManagerException e) {
- Debug.e("Cannot load scores " + e.getMessage());
- return new ArrayList<>();
- }
- }
- }
-
public void loadAvatar(final boolean both) {
if (!OnlineManager.getInstance().isStayOnline()) return;
final String avatarUrl = OnlineManager.getInstance().getAvatarURL();
diff --git a/src/ru/nsu/ccfit/zuev/osu/scoring/BeatmapLeaderboardScoringMode.java b/src/ru/nsu/ccfit/zuev/osu/scoring/BeatmapLeaderboardScoringMode.java
new file mode 100644
index 000000000..b3e8be0de
--- /dev/null
+++ b/src/ru/nsu/ccfit/zuev/osu/scoring/BeatmapLeaderboardScoringMode.java
@@ -0,0 +1,19 @@
+package ru.nsu.ccfit.zuev.osu.scoring;
+
+/**
+ * Represents the scoring mode used in online beatmap leaderboard.
+ */
+public enum BeatmapLeaderboardScoringMode {
+ SCORE,
+ PP;
+
+ /**
+ * Parses an integer value to a {@link BeatmapLeaderboardScoringMode}.
+ *
+ * @param value The integer value to parse.
+ * @return The parsed {@link BeatmapLeaderboardScoringMode}.
+ */
+ public static BeatmapLeaderboardScoringMode parse(int value) {
+ return value == 1 ? PP : SCORE;
+ }
+}