Restores drainRate
Single file read md5 pitch change synctime
This commit is contained in:
parent
df07c62609
commit
55628038fe
|
@ -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];
|
||||
|
|
91
src/itdelatrisu/opsu/MD5InputStreamWrapper.java
Normal file
91
src/itdelatrisu/opsu/MD5InputStreamWrapper.java
Normal 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();
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user