1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 14:47:26 +08:00
osu-lazer/osu.Game/Database/ScoreDatabase.cs

125 lines
4.5 KiB
C#
Raw Normal View History

2017-03-04 18:02:36 +08:00
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.IO;
using System.Linq;
2017-03-04 18:02:36 +08:00
using osu.Framework.Platform;
using osu.Game.IO.Legacy;
using osu.Game.IPC;
using osu.Game.Modes.Scoring;
2017-03-04 18:02:36 +08:00
using SharpCompress.Compressors.LZMA;
using SQLite.Net;
2017-03-04 18:02:36 +08:00
namespace osu.Game.Database
{
public class ScoreDatabase : Database
2017-03-04 18:02:36 +08:00
{
private readonly Storage storage;
2017-04-17 16:43:48 +08:00
2017-03-04 18:02:36 +08:00
private readonly BeatmapDatabase beatmaps;
2017-04-17 16:43:48 +08:00
private readonly RulesetDatabase rulesets;
2017-03-04 18:02:36 +08:00
private const string replay_folder = @"replays";
// ReSharper disable once NotAccessedField.Local (we should keep a reference to this so it is not finalised)
2017-03-04 18:02:36 +08:00
private ScoreIPCChannel ipc;
2017-04-17 16:43:48 +08:00
public ScoreDatabase(Storage storage, SQLiteConnection connection, IIpcHost importHost = null, BeatmapDatabase beatmaps = null, RulesetDatabase rulesets = null) : base(storage, connection)
2017-03-04 18:02:36 +08:00
{
this.storage = storage;
this.beatmaps = beatmaps;
2017-04-17 16:43:48 +08:00
this.rulesets = rulesets;
2017-03-04 18:02:36 +08:00
if (importHost != null)
ipc = new ScoreIPCChannel(importHost, this);
}
public Score ReadReplayFile(string replayFilename)
{
Score score;
using (Stream s = storage.GetStream(Path.Combine(replay_folder, replayFilename)))
using (SerializationReader sr = new SerializationReader(s))
{
2017-04-17 16:43:48 +08:00
var ruleset = rulesets.GetRuleset(sr.ReadByte()).CreateInstance();
2017-03-17 01:03:12 +08:00
score = ruleset.CreateScoreProcessor().CreateScore();
2017-03-04 18:02:36 +08:00
/* score.Pass = true;*/
var version = sr.ReadInt32();
/* score.FileChecksum = */
var beatmapHash = sr.ReadString();
score.Beatmap = beatmaps.Query<BeatmapInfo>().FirstOrDefault(b => b.Hash == beatmapHash);
2017-03-04 18:02:36 +08:00
/* score.PlayerName = */
sr.ReadString();
/* var localScoreChecksum = */
sr.ReadString();
/* score.Count300 = */
sr.ReadUInt16();
/* score.Count100 = */
sr.ReadUInt16();
/* score.Count50 = */
sr.ReadUInt16();
/* score.CountGeki = */
sr.ReadUInt16();
/* score.CountKatu = */
sr.ReadUInt16();
/* score.CountMiss = */
sr.ReadUInt16();
score.TotalScore = sr.ReadInt32();
score.MaxCombo = sr.ReadUInt16();
/* score.Perfect = */
sr.ReadBoolean();
/* score.EnabledMods = (Mods)*/
sr.ReadInt32();
/* score.HpGraphString = */
sr.ReadString();
/* score.Date = */
sr.ReadDateTime();
var compressedReplay = sr.ReadByteArray();
if (version >= 20140721)
/*OnlineId =*/
sr.ReadInt64();
else if (version >= 20121008)
/*OnlineId =*/
sr.ReadInt32();
using (var replayInStream = new MemoryStream(compressedReplay))
{
byte[] properties = new byte[5];
if (replayInStream.Read(properties, 0, 5) != 5)
2017-03-09 13:00:17 +08:00
throw new Exception("input .lzma is too short");
2017-03-04 18:02:36 +08:00
long outSize = 0;
for (int i = 0; i < 8; i++)
{
int v = replayInStream.ReadByte();
if (v < 0)
2017-03-09 13:00:17 +08:00
throw new Exception("Can't Read 1");
outSize |= (long)(byte)v << (8 * i);
2017-03-04 18:02:36 +08:00
}
long compressedSize = replayInStream.Length - replayInStream.Position;
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
using (var reader = new StreamReader(lzma))
score.Replay = score.CreateReplay(reader);
2017-03-04 18:02:36 +08:00
}
}
2017-03-04 18:02:36 +08:00
return score;
}
protected override void Prepare()
{
}
public override void Reset()
{
}
2017-04-17 16:43:48 +08:00
protected override Type[] ValidTypes => new[] { typeof(Score) };
2017-03-04 18:02:36 +08:00
}
}