public void Save(string file) { using (BinaryWriter bw = new BinaryWriter(new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.Read))) { //Header bw.Write((byte)GameMode); bw.Write(FileFormat); bw.WriteNullableString(MapHash); bw.WriteNullableString(PlayerName); bw.WriteNullableString(ReplayHash); bw.Write(Count300); bw.Write(Count100); bw.Write(Count50); bw.Write(CountGeki); bw.Write(CountKatu); bw.Write(CountMiss); bw.Write(TotalScore); bw.Write((UInt16)MaxCombo); bw.Write(IsPerfect); bw.Write((int)Mods); //Life StringBuilder sb = new StringBuilder(); for (int i = 0; i < LifeFrames.Count; i++) { sb.AppendFormat("{0}|{1},", LifeFrames[i].Time.ToString(culture), LifeFrames[i].Percentage.ToString(culture)); } bw.WriteNullableString(sb.ToString()); bw.Write(PlayTime.ToUniversalTime().Ticks); //Data if (ReplayFrames.Count == 0) { bw.Write(0); } else { sb.Clear(); for (int i = 0; i < ReplayFrames.Count; i++) { sb.AppendFormat("{0}|{1}|{2}|{3},", ReplayFrames[i].TimeDiff.ToString(culture), ReplayFrames[i].X.ToString(culture), ReplayFrames[i].Y.ToString(culture), (int)ReplayFrames[i].Keys); } sb.AppendFormat("{0}|{1}|{2}|{3},", -12345, 0, 0, Seed); byte[] rawBytes = Encoding.ASCII.GetBytes(sb.ToString()); using (MemoryStream ms = new MemoryStream()) { ms.Write(rawBytes, 0, rawBytes.Length); MemoryStream codedStream = LZMACoder.Compress(ms); byte[] rawBytesCompressed = new byte[codedStream.Length]; codedStream.Read(rawBytesCompressed, 0, rawBytesCompressed.Length); bw.Write(rawBytesCompressed.Length - 8); bw.Write(rawBytesCompressed); } } bw.Write(OnlineId); } }
/// <summary> /// Loads Metadata if not already loaded and loads Lifedata, Timestamp, Playtime and Clicks. /// </summary> public void Load() { if (!headerLoaded) { loadHeader(); } if (fullLoaded) { return; } //Life string lifeData = replayReader.ReadNullableString(); if (!string.IsNullOrEmpty(lifeData)) { foreach (string lifeBlock in lifeData.Split(',')) { string[] split = lifeBlock.Split('|'); if (split.Length < 2) { continue; } LifeFrames.Add(new LifeFrame() { Time = int.Parse(split[0], culture), Percentage = float.Parse(split[1], culture) }); } } Int64 ticks = replayReader.ReadInt64(); PlayTime = new DateTime(ticks, DateTimeKind.Utc); ReplayLength = replayReader.ReadInt32(); //Data if (ReplayLength > 0) { int lastTime = 0; using (MemoryStream codedStream = LZMACoder.Decompress(replayReader.BaseStream as FileStream)) using (StreamReader sr = new StreamReader(codedStream)) { foreach (string frame in sr.ReadToEnd().Split(',')) { if (string.IsNullOrEmpty(frame)) { continue; } string[] split = frame.Split('|'); if (split.Length < 4) { continue; } if (split[0] == "-12345") { Seed = int.Parse(split[3], culture); continue; } ReplayFrames.Add(new ReplayFrame() { TimeDiff = int.Parse(split[0], culture), Time = int.Parse(split[0], culture) + lastTime, X = float.Parse(split[1], culture), Y = float.Parse(split[2], culture), Keys = (Keys)Enum.Parse(typeof(Keys), split[3]) }); lastTime = ReplayFrames[ReplayFrames.Count - 1].Time; } } } //Todo: There are some extra bytes here fullLoaded = true; }