Restores drainRate

Single file read md5

pitch change synctime
This commit is contained in:
fd
2015-06-21 22:57:30 -04:00
parent df07c62609
commit 55628038fe
7 changed files with 151 additions and 19 deletions

View File

@@ -296,6 +296,10 @@ public class GameData {
/** The difficulty multiplier used in the score formula. */ /** The difficulty multiplier used in the score formula. */
private int difficultyMultiplier = 2; private int difficultyMultiplier = 2;
/** Beatmap HPDrainRate value. (0:easy ~ 10:hard) */
@SuppressWarnings("unused")
private float drainRate = 5f;
/** Default text symbol images. */ /** Default text symbol images. */
private Image[] defaultSymbols; private Image[] defaultSymbols;
@@ -371,6 +375,7 @@ public class GameData {
health = 100f; health = 100f;
healthDisplay = 100f; healthDisplay = 100f;
hitResultCount = new int[HIT_MAX]; hitResultCount = new int[HIT_MAX];
drainRate = 5f;
if (hitResultList != null) { if (hitResultList != null) {
for (HitObjectResult hitResult : hitResultList) { for (HitObjectResult hitResult : hitResultList) {
if (hitResult.curve != null) if (hitResult.curve != null)
@@ -461,6 +466,12 @@ public class GameData {
*/ */
public Image getScoreSymbolImage(char c) { return scoreSymbols.get(c); } public Image getScoreSymbolImage(char c) { return scoreSymbols.get(c); }
/**
* Sets the health drain rate.
* @param drainRate the new drain rate [0-10]
*/
public void setDrainRate(float drainRate) { this.drainRate = drainRate; }
/** /**
* Sets the array of hit result offsets. * Sets the array of hit result offsets.
*/ */
@@ -1423,7 +1434,7 @@ public class GameData {
replay = new Replay(); replay = new Replay();
replay.mode = Beatmap.MODE_OSU; replay.mode = Beatmap.MODE_OSU;
replay.version = Updater.get().getBuildDate(); 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.playerName = ""; // TODO
replay.replayHash = Long.toString(System.currentTimeMillis()); // TODO replay.replayHash = Long.toString(System.currentTimeMillis()); // TODO
replay.hit300 = (short) hitResultCount[HIT_300]; replay.hit300 = (short) hitResultCount[HIT_300];

View File

@@ -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();
}
}

View File

@@ -19,16 +19,20 @@
package itdelatrisu.opsu.beatmap; package itdelatrisu.opsu.beatmap;
import itdelatrisu.opsu.ErrorHandler; import itdelatrisu.opsu.ErrorHandler;
import itdelatrisu.opsu.MD5InputStreamWrapper;
import itdelatrisu.opsu.Utils; import itdelatrisu.opsu.Utils;
import itdelatrisu.opsu.db.BeatmapDB; import itdelatrisu.opsu.db.BeatmapDB;
import java.io.BufferedInputStream;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileReader; import java.io.FileReader;
import java.io.FilenameFilter; import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@@ -205,7 +209,15 @@ public class BeatmapParser {
Beatmap beatmap = new Beatmap(file); Beatmap beatmap = new Beatmap(file);
beatmap.timingPoints = new ArrayList<TimingPoint>(); 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 line = in.readLine();
String tokens[] = null; String tokens[] = null;
while (line != null) { while (line != null) {
@@ -578,6 +590,8 @@ public class BeatmapParser {
break; break;
} }
} }
if (md5stream != null)
beatmap.md5Hash = md5stream.getMD5();
} catch (IOException e) { } catch (IOException e) {
ErrorHandler.error(String.format("Failed to read file '%s'.", file.getAbsolutePath()), e, false); ErrorHandler.error(String.format("Failed to read file '%s'.", file.getAbsolutePath()), e, false);
} }
@@ -589,8 +603,6 @@ public class BeatmapParser {
// parse hit objects now? // parse hit objects now?
if (parseObjects) if (parseObjects)
parseHitObjects(beatmap); parseHitObjects(beatmap);
beatmap.md5Hash = Utils.getMD5(file);
return beatmap; return beatmap;
} }

View File

@@ -132,10 +132,8 @@ public class Circle implements GameObject {
result = GameData.HIT_100; result = GameData.HIT_100;
else if (timeDiff <= hitResultOffset[GameData.HIT_50]) else if (timeDiff <= hitResultOffset[GameData.HIT_50])
result = GameData.HIT_50; result = GameData.HIT_50;
else if (timeDiff <= hitResultOffset[GameData.HIT_MISS]){ else if (timeDiff <= hitResultOffset[GameData.HIT_MISS])
result = GameData.HIT_MISS; result = GameData.HIT_MISS;
System.out.println(timeDiff);
}
//else not a hit //else not a hit
return result; return result;

View File

@@ -227,6 +227,8 @@ public class Game extends BasicGameState {
private int height; private int height;
private boolean seeking;
public Game(int state) { public Game(int state) {
this.state = state; this.state = state;
} }
@@ -615,7 +617,7 @@ public class Game extends BasicGameState {
updateGame(replayX, replayY, delta, MusicController.getPosition(), lastKeysPressed); updateGame(replayX, replayY, delta, MusicController.getPosition(), lastKeysPressed);
//TODO probably should to disable sounds then reseek to the new position //TODO probably should to disable sounds then reseek to the new position
if(replayIndex-1 >= 1 && replayIndex < replay.frames.length && trackPosition < replay.frames[replayIndex-1].getTime()){ if(seeking && replayIndex-1 >= 1 && replayIndex < replay.frames.length && trackPosition < replay.frames[replayIndex-1].getTime()){
replayIndex = 0; replayIndex = 0;
while(objectIndex>=0){ while(objectIndex>=0){
gameObjects[objectIndex].reset(); gameObjects[objectIndex].reset();
@@ -633,6 +635,7 @@ public class Game extends BasicGameState {
timingPointIndex++; timingPointIndex++;
} }
} }
seeking = false;
} }
// update and run replay frames // update and run replay frames
@@ -925,6 +928,7 @@ public class Game extends BasicGameState {
if(!GameMod.AUTO.isActive() && y < 50){ if(!GameMod.AUTO.isActive() && y < 50){
float pos = (float)x / width * beatmap.endTime; float pos = (float)x / width * beatmap.endTime;
MusicController.setPosition((int)pos); MusicController.setPosition((int)pos);
seeking = true;
} }
return; return;
} }
@@ -1074,6 +1078,8 @@ public class Game extends BasicGameState {
retries = 0; retries = 0;
gameObjects = new GameObject[beatmap.objects.length]; gameObjects = new GameObject[beatmap.objects.length];
playbackSpeed = PlaybackSpeed.NORMAL;
// reset game data // reset game data
resetGameData(); resetGameData();
@@ -1332,8 +1338,7 @@ public class Game extends BasicGameState {
autoMouseY = 0; autoMouseY = 0;
autoMousePressed = false; autoMousePressed = false;
flashlightRadius = container.getHeight() * 2 / 3; flashlightRadius = container.getHeight() * 2 / 3;
playbackSpeed = PlaybackSpeed.NORMAL;
System.gc(); System.gc();
} }
@@ -1402,9 +1407,8 @@ public class Game extends BasicGameState {
float circleSize = Math.min(beatmap.circleSize * multiplier, 10f); float circleSize = Math.min(beatmap.circleSize * multiplier, 10f);
float approachRate = Math.min(beatmap.approachRate * multiplier, 10f); float approachRate = Math.min(beatmap.approachRate * multiplier, 10f);
float overallDifficulty = Math.min(beatmap.overallDifficulty * multiplier, 10f); float overallDifficulty = Math.min(beatmap.overallDifficulty * multiplier, 10f);
//TODO never actually used, everything seems to be using GameData.HP_DRAIN_MULTIPLIER float HPDrainRate = Math.min(beatmap.HPDrainRate * multiplier, 10f);
float HPDrainRate = Math.min(beatmap.HPDrainRate * multiplier, 10f);
// fixed difficulty overrides // fixed difficulty overrides
if (Options.getFixedCS() > 0f) if (Options.getFixedCS() > 0f)
circleSize = Options.getFixedCS(); circleSize = Options.getFixedCS();
@@ -1449,6 +1453,9 @@ public class Game extends BasicGameState {
data.setHitResultOffset(hitResultOffset); data.setHitResultOffset(hitResultOffset);
//*/ //*/
// HPDrainRate (health change)
data.setDrainRate(HPDrainRate);
// difficulty multiplier (scoring) // difficulty multiplier (scoring)
data.calculateDifficultyMultiplier(beatmap.HPDrainRate, beatmap.circleSize, beatmap.overallDifficulty); data.calculateDifficultyMultiplier(beatmap.HPDrainRate, beatmap.circleSize, beatmap.overallDifficulty);
} }

View File

@@ -41,6 +41,7 @@ import org.lwjgl.openal.OpenALException;
import org.newdawn.slick.util.Log; import org.newdawn.slick.util.Log;
import org.newdawn.slick.util.ResourceLoader; import org.newdawn.slick.util.ResourceLoader;
/** /**
* A generic tool to work on a supplied stream, pulling out PCM data and buffered it to OpenAL * A generic tool to work on a supplied stream, pulling out PCM data and buffered it to OpenAL
* as required. * as required.
@@ -224,6 +225,7 @@ public class OpenALStreamPlayer {
*/ */
public void setup(float pitch) { public void setup(float pitch) {
this.pitch = pitch; this.pitch = pitch;
syncPosition();
} }
/** /**
@@ -354,7 +356,7 @@ public class OpenALStreamPlayer {
} }
playedPos = streamPos; playedPos = streamPos;
syncStartTime = getTime() - playedPos * 1000 / sampleSize / sampleRate; syncStartTime = (long) (getTime() - (playedPos * 1000 / sampleSize / sampleRate)/pitch);
startPlayback(); startPlayback();
@@ -403,24 +405,34 @@ public class OpenALStreamPlayer {
float thisPosition = getALPosition(); float thisPosition = getALPosition();
long thisTime = getTime(); long thisTime = getTime();
float dxPosition = thisPosition - lastUpdatePosition; float dxPosition = thisPosition - lastUpdatePosition;
long dxTime = thisTime - syncStartTime; float dxTime = (thisTime - syncStartTime) * pitch;
// hard reset // hard reset
if (Math.abs(thisPosition - dxTime / 1000f) > 1 / 2f) { if (Math.abs(thisPosition - dxTime / 1000f) > 1 / 2f) {
syncStartTime = thisTime - ((long) (thisPosition * 1000)); //System.out.println("Time HARD Reset"+" "+thisPosition+" "+(dxTime / 1000f));
dxTime = thisTime - syncStartTime; syncPosition();
dxTime = (thisTime - syncStartTime) * pitch;
avgDiff = 0; avgDiff = 0;
} }
if ((int) (dxPosition * 1000) != 0) { // lastPosition != thisPosition if ((int) (dxPosition * 1000) != 0) { // lastPosition != thisPosition
float diff = thisPosition * 1000 - (dxTime); float diff = thisPosition * 1000 - (dxTime);
avgDiff = (diff + avgDiff * 9) / 10; avgDiff = (diff + avgDiff * 9) / 10;
syncStartTime -= (int) (avgDiff/2); if(Math.abs(avgDiff) >= 1){
dxTime = thisTime - syncStartTime; syncStartTime -= (int)(avgDiff);
avgDiff -= (int)(avgDiff);
dxTime = (thisTime - syncStartTime) * pitch;
}
lastUpdatePosition = thisPosition; lastUpdatePosition = thisPosition;
} }
return dxTime / 1000f; return dxTime / 1000f;
} }
private void syncPosition(){
syncStartTime = getTime() - (long) ( getALPosition() * 1000 / pitch);
avgDiff = 0;
}
/** /**
* Processes a track pause. * Processes a track pause.

View File

@@ -536,6 +536,7 @@ public class SoundStore {
*/ */
public void setMusicPitch(float pitch) { public void setMusicPitch(float pitch) {
if (soundWorks) { if (soundWorks) {
stream.setup(pitch);
AL10.alSourcef(sources.get(0), AL10.AL_PITCH, pitch); AL10.alSourcef(sources.get(0), AL10.AL_PITCH, pitch);
} }
} }