Replay importing
This commit is contained in:
parent
66bd97242f
commit
a49b5bc945
|
@ -1235,6 +1235,7 @@ public class GameData {
|
|||
scoreData.perfect = (comboMax == fullObjectCount);
|
||||
scoreData.mods = GameMod.getModState();
|
||||
scoreData.replayString = (replay == null) ? null : replay.getReplayFilename();
|
||||
scoreData.playerName = "OpsuPlayer"; //TODO?
|
||||
return scoreData;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,9 @@ public class Options {
|
|||
/** The replay directory (created when needed). */
|
||||
private static File replayDir;
|
||||
|
||||
/** The replay import directory. */
|
||||
private static File replayImportDir;
|
||||
|
||||
/** The current skin directory (for user skins). */
|
||||
private static File skinDir;
|
||||
|
||||
|
@ -824,7 +827,20 @@ public class Options {
|
|||
oszDir.mkdir();
|
||||
return oszDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the replay import directory.
|
||||
* If invalid, this will create and return a "SongPacks" directory.
|
||||
* @return the OSZ archive 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.
|
||||
|
|
|
@ -179,6 +179,8 @@ public class OsuFile implements Comparable<OsuFile> {
|
|||
|
||||
/** Combo colors (max 8). */
|
||||
public Color[] combo;
|
||||
|
||||
public String md5Hash;
|
||||
|
||||
/**
|
||||
* [HitObjects]
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.io.IOException;
|
|||
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;
|
||||
|
@ -55,6 +56,10 @@ public class OsuGroupList {
|
|||
|
||||
/** Set of all beatmap set IDs for the parsed beatmaps. */
|
||||
private HashSet<Integer> MSIDdb;
|
||||
|
||||
/** Set of all beatmap set IDs for the parsed beatmaps. */
|
||||
public HashMap<String, OsuFile> beatmapHashesToFile;
|
||||
|
||||
|
||||
/** Index of current expanded node (-1 if no node is expanded). */
|
||||
private int expandedIndex;
|
||||
|
@ -81,6 +86,7 @@ public class OsuGroupList {
|
|||
private OsuGroupList() {
|
||||
parsedNodes = new ArrayList<OsuGroupNode>();
|
||||
MSIDdb = new HashSet<Integer>();
|
||||
beatmapHashesToFile = new HashMap<String, OsuFile>();
|
||||
reset();
|
||||
}
|
||||
|
||||
|
@ -114,6 +120,9 @@ public class OsuGroupList {
|
|||
int msid = osuFiles.get(0).beatmapSetID;
|
||||
if (msid > 0)
|
||||
MSIDdb.add(msid);
|
||||
for(OsuFile f : osuFiles) {
|
||||
beatmapHashesToFile.put(f.md5Hash, f);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -498,4 +507,8 @@ public class OsuGroupList {
|
|||
* @return true if id is in the list
|
||||
*/
|
||||
public boolean containsBeatmapSetID(int id) { return MSIDdb.contains(id); }
|
||||
|
||||
public OsuFile getFileFromBeatmapHash(String beatmapHash) {
|
||||
return beatmapHashesToFile.get(beatmapHash);
|
||||
}
|
||||
}
|
|
@ -586,6 +586,8 @@ public class OsuParser {
|
|||
// parse hit objects now?
|
||||
if (parseObjects)
|
||||
parseHitObjects(osu);
|
||||
|
||||
osu.md5Hash = Utils.getMD5(file);
|
||||
|
||||
return osu;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,8 @@ public class ScoreData implements Comparable<ScoreData> {
|
|||
|
||||
/** The tooltip string. */
|
||||
private String tooltip;
|
||||
|
||||
public String playerName;
|
||||
|
||||
/** Drawing values. */
|
||||
private static float baseX, baseY, buttonWidth, buttonHeight, buttonOffset;
|
||||
|
@ -163,6 +165,7 @@ public class ScoreData implements Comparable<ScoreData> {
|
|||
this.perfect = rs.getBoolean(16);
|
||||
this.mods = rs.getInt(17);
|
||||
this.replayString = rs.getString(18);
|
||||
this.playerName = rs.getString(19);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -259,7 +262,7 @@ public class ScoreData implements Comparable<ScoreData> {
|
|||
// 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
|
||||
);
|
||||
|
||||
|
@ -330,6 +333,11 @@ public class ScoreData implements Comparable<ScoreData> {
|
|||
);
|
||||
}
|
||||
|
||||
public String getPlayerName() {
|
||||
if(playerName == null)
|
||||
return "Null Name";
|
||||
return playerName;
|
||||
}
|
||||
@Override
|
||||
public int compareTo(ScoreData that) {
|
||||
if (this.score != that.score)
|
||||
|
|
|
@ -43,7 +43,7 @@ public class OsuDB {
|
|||
* Current database version.
|
||||
* This value should be changed whenever the database format changes.
|
||||
*/
|
||||
private static final String DATABASE_VERSION = "2014-03-08";
|
||||
private static final String DATABASE_VERSION = "2015-03-30";
|
||||
|
||||
/** Minimum batch size ratio ({@code batchSize/cacheSize}) to invoke batch loading. */
|
||||
private static final float LOAD_BATCH_MIN_RATIO = 0.2f;
|
||||
|
@ -83,7 +83,7 @@ public class OsuDB {
|
|||
insertStmt = connection.prepareStatement(
|
||||
"INSERT INTO beatmaps VALUES (" +
|
||||
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, " +
|
||||
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
"?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
selectStmt = connection.prepareStatement("SELECT * FROM beatmaps WHERE dir = ? AND file = ?");
|
||||
deleteMapStmt = connection.prepareStatement("DELETE FROM beatmaps WHERE dir = ? AND file = ?");
|
||||
|
@ -116,7 +116,8 @@ public class OsuDB {
|
|||
"bpmMin INTEGER, bpmMax INTEGER, endTime INTEGER, " +
|
||||
"audioFile TEXT, audioLeadIn INTEGER, previewTime INTEGER, countdown INTEGER, sampleSet TEXT, stackLeniency REAL, " +
|
||||
"mode INTEGER, letterboxInBreaks BOOLEAN, widescreenStoryboard BOOLEAN, epilepsyWarning BOOLEAN, " +
|
||||
"bg TEXT, timingPoints TEXT, breaks TEXT, combo TEXT" +
|
||||
"bg TEXT, timingPoints TEXT, breaks TEXT, combo TEXT," +
|
||||
"md5hash TEXT" +
|
||||
"); " +
|
||||
"CREATE TABLE IF NOT EXISTS info (" +
|
||||
"key TEXT NOT NULL UNIQUE, value TEXT" +
|
||||
|
@ -333,7 +334,8 @@ public class OsuDB {
|
|||
stmt.setString(37, osu.timingPointsToString());
|
||||
stmt.setString(38, osu.breaksToString());
|
||||
stmt.setString(39, osu.comboToString());
|
||||
} catch (SQLException e) {
|
||||
stmt.setString(40, osu.md5Hash);
|
||||
} catch (SQLException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new SQLException(e);
|
||||
|
@ -470,6 +472,7 @@ public class OsuDB {
|
|||
osu.widescreenStoryboard = rs.getBoolean(34);
|
||||
osu.epilepsyWarning = rs.getBoolean(35);
|
||||
osu.bg = OsuParser.getDBString(rs.getString(36));
|
||||
osu.md5Hash = OsuParser.getDBString(rs.getString(40));
|
||||
} catch (SQLException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
|
|
|
@ -45,7 +45,7 @@ public class ScoreDB {
|
|||
* This value should be changed whenever the database format changes.
|
||||
* Add any update queries to the {@link #getUpdateQueries(int)} method.
|
||||
*/
|
||||
private static final int DATABASE_VERSION = 20140311;
|
||||
private static final int DATABASE_VERSION = 20150401;
|
||||
|
||||
/**
|
||||
* Returns a list of SQL queries to apply, in order, to update from
|
||||
|
@ -57,6 +57,8 @@ public class ScoreDB {
|
|||
List<String> list = new LinkedList<String>();
|
||||
if (version < 20140311)
|
||||
list.add("ALTER TABLE scores ADD COLUMN replay TEXT");
|
||||
if (version < 20150401)
|
||||
list.add("ALTER TABLE scores ADD COLUMN playerName TEXT");
|
||||
|
||||
/* add future updates here */
|
||||
|
||||
|
@ -96,7 +98,7 @@ public class ScoreDB {
|
|||
// prepare sql statements
|
||||
try {
|
||||
insertStmt = connection.prepareStatement(
|
||||
"INSERT INTO scores VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
"INSERT OR IGNORE INTO scores VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
selectMapStmt = connection.prepareStatement(
|
||||
"SELECT * FROM scores WHERE " +
|
||||
|
@ -137,7 +139,8 @@ public class ScoreDB {
|
|||
"combo INTEGER, " +
|
||||
"perfect BOOLEAN, " +
|
||||
"mods INTEGER, " +
|
||||
"replay TEXT" +
|
||||
"replay TEXT," +
|
||||
"playerName TEXT"+
|
||||
");" +
|
||||
"CREATE TABLE IF NOT EXISTS info (" +
|
||||
"key TEXT NOT NULL UNIQUE, value TEXT" +
|
||||
|
@ -283,6 +286,8 @@ public class ScoreDB {
|
|||
stmt.setInt(15, data.combo);
|
||||
stmt.setBoolean(16, data.perfect);
|
||||
stmt.setInt(17, data.mods);
|
||||
stmt.setString(19, data.playerName);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package itdelatrisu.opsu.io;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
|
@ -50,7 +51,7 @@ public class OsuReader {
|
|||
* @param source the input stream to read from
|
||||
*/
|
||||
public OsuReader(InputStream source) {
|
||||
this.reader = new DataInputStream(source);
|
||||
this.reader = new DataInputStream(new BufferedInputStream(source));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,15 +19,20 @@
|
|||
package itdelatrisu.opsu.replay;
|
||||
|
||||
import itdelatrisu.opsu.ErrorHandler;
|
||||
import itdelatrisu.opsu.GameMod;
|
||||
import itdelatrisu.opsu.Options;
|
||||
import itdelatrisu.opsu.OsuFile;
|
||||
import itdelatrisu.opsu.ScoreData;
|
||||
import itdelatrisu.opsu.Utils;
|
||||
import itdelatrisu.opsu.io.OsuReader;
|
||||
import itdelatrisu.opsu.io.OsuWriter;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.CharBuffer;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -100,6 +105,8 @@ public class Replay {
|
|||
/** Seed. (?) */
|
||||
public int seed;
|
||||
|
||||
private ScoreData scoreData;
|
||||
|
||||
/** Seed string. */
|
||||
private static final String SEED_STRING = "-12345";
|
||||
|
||||
|
@ -130,6 +137,41 @@ public class Replay {
|
|||
reader.close();
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a ScoreData object encapsulating all game data.
|
||||
* If score data already exists, the existing object will be returned
|
||||
* (i.e. this will not overwrite existing data).
|
||||
* @param osu the OsuFile
|
||||
* @return the ScoreData object
|
||||
*/
|
||||
public ScoreData getScoreData(OsuFile osu) {
|
||||
if (scoreData != null)
|
||||
return scoreData;
|
||||
|
||||
scoreData = new ScoreData();
|
||||
scoreData.timestamp = file.lastModified() / 1000L;
|
||||
scoreData.MID = osu.beatmapID;
|
||||
scoreData.MSID = osu.beatmapSetID;
|
||||
scoreData.title = osu.title;
|
||||
scoreData.artist = osu.artist;
|
||||
scoreData.creator = osu.creator;
|
||||
scoreData.version = osu.version;
|
||||
scoreData.hit300 = hit300;
|
||||
scoreData.hit100 = hit100;
|
||||
scoreData.hit50 = hit50;
|
||||
scoreData.geki = geki;
|
||||
scoreData.katu = katu;
|
||||
scoreData.miss = miss;
|
||||
scoreData.score = score;
|
||||
scoreData.combo = combo;
|
||||
scoreData.perfect = perfect;
|
||||
scoreData.mods = mods;
|
||||
scoreData.replayString = file!=null ? file.getName() : getReplayFilename();
|
||||
scoreData.playerName = playerName!=null ? playerName : "No Name";
|
||||
return scoreData;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads the replay header data.
|
||||
|
@ -139,6 +181,7 @@ public class Replay {
|
|||
private void loadHeader(OsuReader reader) throws IOException {
|
||||
this.mode = reader.readByte();
|
||||
this.version = reader.readInt();
|
||||
System.out.println("Header:"+file.getName()+" "+mode+" "+version);
|
||||
this.beatmapHash = reader.readString();
|
||||
this.playerName = reader.readString();
|
||||
this.replayHash = reader.readString();
|
||||
|
@ -232,7 +275,7 @@ public class Replay {
|
|||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try (FileOutputStream out = new FileOutputStream(file)) {
|
||||
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
|
||||
OsuWriter writer = new OsuWriter(out);
|
||||
|
||||
// header
|
||||
|
|
44
src/itdelatrisu/opsu/replay/ReplayImporter.java
Normal file
44
src/itdelatrisu/opsu/replay/ReplayImporter.java
Normal file
|
@ -0,0 +1,44 @@
|
|||
package itdelatrisu.opsu.replay;
|
||||
|
||||
import itdelatrisu.opsu.ErrorHandler;
|
||||
import itdelatrisu.opsu.Options;
|
||||
import itdelatrisu.opsu.OsuFile;
|
||||
import itdelatrisu.opsu.OsuGroupList;
|
||||
import itdelatrisu.opsu.ScoreData;
|
||||
import itdelatrisu.opsu.db.ScoreDB;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ReplayImporter {
|
||||
public static void importAllReplaysFromDir(File dir) {
|
||||
System.out.println(OsuGroupList.get().beatmapHashesToFile);
|
||||
for (File replayToImport : dir.listFiles()) {
|
||||
try {
|
||||
Replay r = new Replay(replayToImport);
|
||||
r.load();
|
||||
OsuFile oFile = OsuGroupList.get().getFileFromBeatmapHash(r.beatmapHash);
|
||||
if(oFile != null){
|
||||
//ErrorHandler.error("Importing"+replayToImport+" forBeatmap:"+oFile, null, false);
|
||||
ScoreData data = r.getScoreData(oFile);
|
||||
File moveToFile = new File(Options.getReplayDir(),replayToImport.getName());
|
||||
System.out.println("Moving "+replayToImport+" to "+moveToFile);
|
||||
if(
|
||||
!replayToImport.renameTo(moveToFile)
|
||||
){
|
||||
System.out.println("Rename Failed "+moveToFile);
|
||||
}
|
||||
data.replayString = replayToImport.getName().substring(0, replayToImport.getName().length()-4);
|
||||
ScoreDB.addScore(data);;
|
||||
} else {
|
||||
//ErrorHandler.error("Could not find beatmap for replay "+replayToImport, null, false);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
//e.printStackTrace();
|
||||
System.out.println(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,9 +18,11 @@
|
|||
|
||||
package itdelatrisu.opsu.states;
|
||||
|
||||
import itdelatrisu.opsu.ErrorHandler;
|
||||
import itdelatrisu.opsu.GameImage;
|
||||
import itdelatrisu.opsu.Opsu;
|
||||
import itdelatrisu.opsu.Options;
|
||||
import itdelatrisu.opsu.OsuFile;
|
||||
import itdelatrisu.opsu.OsuGroupList;
|
||||
import itdelatrisu.opsu.OsuParser;
|
||||
import itdelatrisu.opsu.OszUnpacker;
|
||||
|
@ -28,8 +30,11 @@ import itdelatrisu.opsu.UI;
|
|||
import itdelatrisu.opsu.Utils;
|
||||
import itdelatrisu.opsu.audio.MusicController;
|
||||
import itdelatrisu.opsu.audio.SoundController;
|
||||
import itdelatrisu.opsu.replay.Replay;
|
||||
import itdelatrisu.opsu.replay.ReplayImporter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.newdawn.slick.Color;
|
||||
import org.newdawn.slick.GameContainer;
|
||||
|
@ -39,6 +44,7 @@ import org.newdawn.slick.Input;
|
|||
import org.newdawn.slick.SlickException;
|
||||
import org.newdawn.slick.state.BasicGameState;
|
||||
import org.newdawn.slick.state.StateBasedGame;
|
||||
import org.newdawn.slick.util.Log;
|
||||
|
||||
/**
|
||||
* "Splash Screen" state.
|
||||
|
@ -104,6 +110,8 @@ public class Splash extends BasicGameState {
|
|||
|
||||
// parse song directory
|
||||
OsuParser.parseAllFiles(beatmapDir);
|
||||
|
||||
ReplayImporter.importAllReplaysFromDir(Options.getReplayImportDir());
|
||||
|
||||
// load sounds
|
||||
SoundController.init();
|
||||
|
|
Loading…
Reference in New Issue
Block a user