Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 33 additions & 6 deletions src/itdelatrisu/opsu/GameData.java
Original file line number Diff line number Diff line change
Expand Up @@ -1207,8 +1207,13 @@ public void sliderTickResult(int time, int result, float x, float y, HitObject h
}
fullObjectCount++;
}
public void sliderFinalResult(int time, int hitSlider30, float x, float y,
HitObject hitObject, int currentRepeats) {
score += 30;
}

/**
* https://osu.ppy.sh/wiki/Score
* Returns the score for a hit based on the following score formula:
* <p>
* Score = Hit Value + Hit Value * (Combo * Difficulty * Mod) / 25
Expand All @@ -1219,19 +1224,26 @@ public void sliderTickResult(int time, int result, float x, float y, HitObject h
* <li><strong>Mod:</strong> mod multipliers
* </ul>
* @param hitValue the hit value
* @param hitObject
* @return the score value
*/
private int getScoreForHit(int hitValue) {
return hitValue + (int) (hitValue * (Math.max(combo - 1, 0) * difficultyMultiplier * GameMod.getScoreMultiplier()) / 25);
private int getScoreForHit(int hitValue, HitObject hitObject) {
int comboMulti = Math.max(combo - 1, 0);
if(hitObject.isSlider()){
comboMulti += 1;
}
return (hitValue + (int)(hitValue * (comboMulti * difficultyMultiplier * GameMod.getScoreMultiplier()) / 25));
}

/**
* https://osu.ppy.sh/wiki/Score#How_to_calculate_the_Difficulty_multiplier
* Computes and stores the difficulty multiplier used in the score formula.
* @param drainRate the raw HP drain rate value
* @param circleSize the raw circle size value
* @param overallDifficulty the raw overall difficulty value
*/
public void calculateDifficultyMultiplier(float drainRate, float circleSize, float overallDifficulty) {
//TODO THE LIES ( difficultyMultiplier )
//*
float sum = drainRate + circleSize + overallDifficulty; // typically 2~27
if (sum <= 5f)
difficultyMultiplier = 2;
Expand All @@ -1243,8 +1255,21 @@ else if (sum <= 24f)
difficultyMultiplier = 5;
else //if (sum <= 30f)
difficultyMultiplier = 6;
//*/

/*
924 3x1/4 beat notes 0.14stars
924 3x1beat 0.28stars
912 3x1beat wth 1 extra note 10 sec away 0.29stars

seems to be based on hitobject density? (Total Objects/Time)
*/
/*
float mult = ((circleSize + overallDifficulty + drainRate) / 6) + 1.5f;
System.out.println("diffuculty Multiplier : "+ mult);
difficultyMultiplier = (int)mult;
*/
}

/**
* Handles a hit result and performs all associated calculations.
* @param time the object start time
Expand Down Expand Up @@ -1292,7 +1317,7 @@ private int handleHitResult(int time, int result, float x, float y, Color color,
hitObject.getAdditionSampleSet(repeat));

// calculate score and increment combo streak
changeScore(getScoreForHit(hitValue));
changeScore(getScoreForHit(hitValue, hitObject));
incrementComboStreak();
}
hitResultCount[result]++;
Expand Down Expand Up @@ -1357,6 +1382,7 @@ else if (hitResult == HIT_MISS && (GameMod.RELAX.isActive() || GameMod.AUTOPILOT
}
}


/**
* Returns a ScoreData object encapsulating all game data.
* If score data already exists, the existing object will be returned
Expand Down Expand Up @@ -1387,6 +1413,7 @@ public ScoreData getScoreData(Beatmap beatmap) {
scoreData.perfect = (comboMax == fullObjectCount);
scoreData.mods = GameMod.getModState();
scoreData.replayString = (replay == null) ? null : replay.getReplayFilename();
scoreData.playerName = "OpsuPlayer"; //TODO GameDataPlayerName?
return scoreData;
}

Expand All @@ -1407,7 +1434,7 @@ public Replay getReplay(ReplayFrame[] frames, Beatmap beatmap) {
replay = new Replay();
replay.mode = Beatmap.MODE_OSU;
replay.version = Updater.get().getBuildDate();
replay.beatmapHash = (beatmap == null) ? "" : Utils.getMD5(beatmap.getFile());
replay.beatmapHash = (beatmap == null) ? "" : beatmap.md5Hash;//Utils.getMD5(beatmap.getFile());
replay.playerName = ""; // TODO
replay.replayHash = Long.toString(System.currentTimeMillis()); // TODO
replay.hit300 = (short) hitResultCount[HIT_300];
Expand Down
91 changes: 91 additions & 0 deletions src/itdelatrisu/opsu/MD5InputStreamWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package itdelatrisu.opsu;

import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5InputStreamWrapper extends InputStream {

InputStream in;
private boolean eof; // End Of File
MessageDigest md;
public MD5InputStreamWrapper(InputStream in) throws NoSuchAlgorithmException {
this.in = in;
md = MessageDigest.getInstance("MD5");
}

@Override
public int read() throws IOException {
int readed = in.read();
if(readed>=0)
md.update((byte) readed);
else
eof=true;
return readed;
}

@Override
public int available() throws IOException {
return in.available();
}

@Override
public void close() throws IOException {
in.close();
}

@Override
public synchronized void mark(int readlimit) {
in.mark(readlimit);
}

@Override
public boolean markSupported() {
return in.markSupported();
}

@Override
public int read(byte[] b, int off, int len) throws IOException {
int readed = in.read(b, off, len);
if(readed>=0)
md.update(b, off, readed);
else
eof=true;

return readed;
}

@Override
public int read(byte[] b) throws IOException {
return read(b, 0 ,b.length);
}

@Override
public synchronized void reset() throws IOException {
throw new RuntimeException("MD5 stream not resetable");
}

@Override
public long skip(long n) throws IOException {
throw new RuntimeException("MD5 stream not skipable");
}

public String getMD5() throws IOException {
byte[] buf = null;
if(!eof)
buf = new byte[0x1000];
while(!eof){
read(buf);
}

byte[] md5byte = md.digest();
StringBuilder result = new StringBuilder();
for (byte b : md5byte)
result.append(String.format("%02x", b));
//System.out.println("MD5 stream md5 " + result.toString());
return result.toString();

}

}
17 changes: 17 additions & 0 deletions src/itdelatrisu/opsu/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ public class Options {
/** The replay directory (created when needed). */
private static File replayDir;

/** The replay import directory. */
private static File replayImportDir;

/** The root skin directory. */
private static File skinRootDir;

Expand Down Expand Up @@ -1067,7 +1070,21 @@ public static File getOSZDir() {
oszDir.mkdir();
return oszDir;
}

/**
* Returns the replay import directory.
* If invalid, this will create and return a "ReplayImport" directory.
* @return the replay import directory
*/
public static File getReplayImportDir() {
if (replayImportDir != null && replayImportDir.isDirectory())
return replayImportDir;

replayImportDir = new File(DATA_DIR, "ReplayImport/");
replayImportDir.mkdir();
return replayImportDir;
}

/**
* Returns the screenshot directory.
* If invalid, this will return a "Screenshot" directory.
Expand Down
11 changes: 10 additions & 1 deletion src/itdelatrisu/opsu/ScoreData.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public class ScoreData implements Comparable<ScoreData> {

/** The tooltip string. */
private String tooltip;

/** The players Name. */
public String playerName;

/** Drawing values. */
private static float baseX, baseY, buttonWidth, buttonHeight, buttonOffset;
Expand Down Expand Up @@ -164,6 +167,7 @@ public ScoreData(ResultSet rs) throws SQLException {
this.perfect = rs.getBoolean(16);
this.mods = rs.getInt(17);
this.replayString = rs.getString(18);
this.playerName = rs.getString(19);
}

/**
Expand Down Expand Up @@ -260,7 +264,7 @@ public void draw(Graphics g, int index, int rank, long prevScore, boolean focus)
// hit counts (custom: osu! shows user instead, above score)
Utils.FONT_SMALL.drawString(
textX, y + textOffset + Utils.FONT_MEDIUM.getLineHeight(),
String.format("300:%d 100:%d 50:%d Miss:%d", hit300, hit100, hit50, miss),
String.format("300:%d 100:%d 50:%d Miss:%d Name:%s", hit300, hit100, hit50, miss, getPlayerName()),
Color.white
);

Expand Down Expand Up @@ -331,6 +335,11 @@ public String toString() {
);
}

public String getPlayerName() {
if(playerName == null)
return "Null Name";
return playerName;
}
@Override
public int compareTo(ScoreData that) {
if (this.score != that.score)
Expand Down
5 changes: 4 additions & 1 deletion src/itdelatrisu/opsu/beatmap/Beatmap.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,10 @@ public class Beatmap implements Comparable<Beatmap> {

/** Slider border color. If null, the skin value is used. */
public Color sliderBorder;


/** md5 hash of this file */
public String md5Hash;

/**
* [HitObjects]
*/
Expand Down
16 changes: 15 additions & 1 deletion src/itdelatrisu/opsu/beatmap/BeatmapParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,20 @@
package itdelatrisu.opsu.beatmap;

import itdelatrisu.opsu.ErrorHandler;
import itdelatrisu.opsu.MD5InputStreamWrapper;
import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.db.BeatmapDB;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand Down Expand Up @@ -205,7 +209,15 @@ private static Beatmap parseFile(File file, File dir, ArrayList<Beatmap> beatmap
Beatmap beatmap = new Beatmap(file);
beatmap.timingPoints = new ArrayList<TimingPoint>();

try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
try (InputStream inFileStream = new BufferedInputStream(new FileInputStream(file));){
MD5InputStreamWrapper md5stream = null;
try {
md5stream = new MD5InputStreamWrapper(inFileStream);
} catch (NoSuchAlgorithmException e1) {
ErrorHandler.error("Failed to get MD5 hash stream.", e1, true);
}
BufferedReader in = new BufferedReader(new InputStreamReader(md5stream!=null?md5stream:inFileStream, "UTF-8"));

String line = in.readLine();
String tokens[] = null;
while (line != null) {
Expand Down Expand Up @@ -578,6 +590,8 @@ else if ((type & HitObject.TYPE_SLIDER) > 0)
break;
}
}
if (md5stream != null)
beatmap.md5Hash = md5stream.getMD5();
} catch (IOException e) {
ErrorHandler.error(String.format("Failed to read file '%s'.", file.getAbsolutePath()), e, false);
}
Expand Down
14 changes: 14 additions & 0 deletions src/itdelatrisu/opsu/beatmap/BeatmapSetList.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
Expand Down Expand Up @@ -57,6 +58,10 @@ public class BeatmapSetList {

/** Set of all beatmap set IDs for the parsed beatmaps. */
private HashSet<Integer> MSIDdb;

/** Map of all hash to Beatmap . */
public HashMap<String, Beatmap> beatmapHashesToFile;


/** Index of current expanded node (-1 if no node is expanded). */
private int expandedIndex;
Expand All @@ -83,6 +88,7 @@ public class BeatmapSetList {
private BeatmapSetList() {
parsedNodes = new ArrayList<BeatmapSetNode>();
MSIDdb = new HashSet<Integer>();
beatmapHashesToFile = new HashMap<String, Beatmap>();
reset();
}

Expand Down Expand Up @@ -117,6 +123,10 @@ public BeatmapSetNode addSongGroup(ArrayList<Beatmap> beatmaps) {
int msid = beatmaps.get(0).beatmapSetID;
if (msid > 0)
MSIDdb.add(msid);
for(Beatmap f : beatmaps) {
beatmapHashesToFile.put(f.md5Hash, f);
}


return node;
}
Expand Down Expand Up @@ -501,4 +511,8 @@ public boolean search(String query) {
* @return true if id is in the list
*/
public boolean containsBeatmapSetID(int id) { return MSIDdb.contains(id); }

public Beatmap getFileFromBeatmapHash(String beatmapHash) {
return beatmapHashesToFile.get(beatmapHash);
}
}
Loading