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. */
private int difficultyMultiplier = 2;
/** Beatmap HPDrainRate value. (0:easy ~ 10:hard) */
@SuppressWarnings("unused")
private float drainRate = 5f;
/** Default text symbol images. */
private Image[] defaultSymbols;
@ -371,6 +375,7 @@ public class GameData {
health = 100f;
healthDisplay = 100f;
hitResultCount = new int[HIT_MAX];
drainRate = 5f;
if (hitResultList != null) {
for (HitObjectResult hitResult : hitResultList) {
if (hitResult.curve != null)
@ -461,6 +466,12 @@ public class GameData {
*/
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.
*/
@ -1423,7 +1434,7 @@ public class GameData {
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];

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;
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;
@ -205,7 +209,15 @@ public class BeatmapParser {
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) {
@ -578,6 +590,8 @@ public class BeatmapParser {
break;
}
}
if (md5stream != null)
beatmap.md5Hash = md5stream.getMD5();
} catch (IOException e) {
ErrorHandler.error(String.format("Failed to read file '%s'.", file.getAbsolutePath()), e, false);
}
@ -589,8 +603,6 @@ public class BeatmapParser {
// parse hit objects now?
if (parseObjects)
parseHitObjects(beatmap);
beatmap.md5Hash = Utils.getMD5(file);
return beatmap;
}

View File

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

View File

@ -227,6 +227,8 @@ public class Game extends BasicGameState {
private int height;
private boolean seeking;
public Game(int state) {
this.state = state;
}
@ -615,7 +617,7 @@ public class Game extends BasicGameState {
updateGame(replayX, replayY, delta, MusicController.getPosition(), lastKeysPressed);
//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;
while(objectIndex>=0){
gameObjects[objectIndex].reset();
@ -633,6 +635,7 @@ public class Game extends BasicGameState {
timingPointIndex++;
}
}
seeking = false;
}
// update and run replay frames
@ -925,6 +928,7 @@ public class Game extends BasicGameState {
if(!GameMod.AUTO.isActive() && y < 50){
float pos = (float)x / width * beatmap.endTime;
MusicController.setPosition((int)pos);
seeking = true;
}
return;
}
@ -1074,6 +1078,8 @@ public class Game extends BasicGameState {
retries = 0;
gameObjects = new GameObject[beatmap.objects.length];
playbackSpeed = PlaybackSpeed.NORMAL;
// reset game data
resetGameData();
@ -1332,8 +1338,7 @@ public class Game extends BasicGameState {
autoMouseY = 0;
autoMousePressed = false;
flashlightRadius = container.getHeight() * 2 / 3;
playbackSpeed = PlaybackSpeed.NORMAL;
System.gc();
}
@ -1402,9 +1407,8 @@ public class Game extends BasicGameState {
float circleSize = Math.min(beatmap.circleSize * multiplier, 10f);
float approachRate = Math.min(beatmap.approachRate * 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
if (Options.getFixedCS() > 0f)
circleSize = Options.getFixedCS();
@ -1449,6 +1453,9 @@ public class Game extends BasicGameState {
data.setHitResultOffset(hitResultOffset);
//*/
// HPDrainRate (health change)
data.setDrainRate(HPDrainRate);
// difficulty multiplier (scoring)
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.ResourceLoader;
/**
* A generic tool to work on a supplied stream, pulling out PCM data and buffered it to OpenAL
* as required.
@ -224,6 +225,7 @@ public class OpenALStreamPlayer {
*/
public void setup(float pitch) {
this.pitch = pitch;
syncPosition();
}
/**
@ -354,7 +356,7 @@ public class OpenALStreamPlayer {
}
playedPos = streamPos;
syncStartTime = getTime() - playedPos * 1000 / sampleSize / sampleRate;
syncStartTime = (long) (getTime() - (playedPos * 1000 / sampleSize / sampleRate)/pitch);
startPlayback();
@ -403,24 +405,34 @@ public class OpenALStreamPlayer {
float thisPosition = getALPosition();
long thisTime = getTime();
float dxPosition = thisPosition - lastUpdatePosition;
long dxTime = thisTime - syncStartTime;
float dxTime = (thisTime - syncStartTime) * pitch;
// hard reset
if (Math.abs(thisPosition - dxTime / 1000f) > 1 / 2f) {
syncStartTime = thisTime - ((long) (thisPosition * 1000));
dxTime = thisTime - syncStartTime;
//System.out.println("Time HARD Reset"+" "+thisPosition+" "+(dxTime / 1000f));
syncPosition();
dxTime = (thisTime - syncStartTime) * pitch;
avgDiff = 0;
}
if ((int) (dxPosition * 1000) != 0) { // lastPosition != thisPosition
float diff = thisPosition * 1000 - (dxTime);
avgDiff = (diff + avgDiff * 9) / 10;
syncStartTime -= (int) (avgDiff/2);
dxTime = thisTime - syncStartTime;
if(Math.abs(avgDiff) >= 1){
syncStartTime -= (int)(avgDiff);
avgDiff -= (int)(avgDiff);
dxTime = (thisTime - syncStartTime) * pitch;
}
lastUpdatePosition = thisPosition;
}
return dxTime / 1000f;
}
private void syncPosition(){
syncStartTime = getTime() - (long) ( getALPosition() * 1000 / pitch);
avgDiff = 0;
}
/**
* Processes a track pause.

View File

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