示例#1
0
        public static Replay Parse(string filePath)
        {
            var parsedReplay = new Replay();

            using (var fs = new FileStream(filePath, FileMode.Open))
                using (var br = new BinaryReader(fs))
                {
                    parsedReplay.ReplayVersion = br.ReadString();
                    parsedReplay.MapMd5        = br.ReadString();
                    br.ReadString();
                    parsedReplay.PlayerName = br.ReadString();
                    br.ReadString();
                    br.ReadInt64();

                    parsedReplay.Mode = (GameMode)br.ReadInt32();

                    if (parsedReplay.ReplayVersion == "0.0.1" || parsedReplay.ReplayVersion == "None")
                    {
                        parsedReplay.Mods = (Mods)br.ReadInt32();
                    }
                    else
                    {
                        parsedReplay.Mods = (Mods)br.ReadInt64();
                    }

                    br.ReadBytes(40);

                    if (parsedReplay.ReplayVersion != "None")
                    {
                        var replayVersion = new Version(parsedReplay.ReplayVersion);

                        if (replayVersion >= new Version("0.0.1"))
                        {
                            parsedReplay.RandomizeModifierSeed = br.ReadInt32();
                        }
                    }

                    parsedReplay.Frames = new List <ReplayFrame>();

                    var frames = new List <string>();

                    frames = Encoding.ASCII.GetString(LZMAHelper.Decompress(br.BaseStream).ToArray()).Split(',').ToList();

                    foreach (var frame in frames)
                    {
                        try
                        {
                            var frameSplit = frame.Split('|');

                            parsedReplay.Frames.Add(new ReplayFrame(int.Parse(frameSplit[0]), (ReplayKeyPressState)Enum.Parse(typeof(ReplayKeyPressState), frameSplit[1])));
                        }
                        catch
                        {
                            continue;
                        }
                    }
                }

            return(parsedReplay);
        }
示例#2
0
        /// <summary>
        /// Parses .osr file.
        /// </summary>
        /// <param name="stream">Stream containing replay data.</param>
        /// <returns>A usable <see cref="Replay"/>.</returns>
        public static Replay Decode(Stream stream)
        {
            Replay replay = new Replay();

            using (var r = new SerializationReader(stream))
            {
                replay.Ruleset        = (Ruleset)r.ReadByte();
                replay.OsuVersion     = r.ReadInt32();
                replay.BeatmapMD5Hash = r.ReadString();
                replay.PlayerName     = r.ReadString();
                replay.ReplayMD5Hash  = r.ReadString();
                replay.Count300       = r.ReadUInt16();
                replay.Count100       = r.ReadUInt16();
                replay.Count50        = r.ReadUInt16();
                replay.CountGeki      = r.ReadUInt16();
                replay.CountKatu      = r.ReadUInt16();
                replay.CountMiss      = r.ReadUInt16();
                replay.ReplayScore    = r.ReadInt32();
                replay.Combo          = r.ReadUInt16();
                replay.PerfectCombo   = r.ReadBoolean();
                replay.Mods           = (Mods)r.ReadInt32();

                string lifeData = r.ReadString();
                if (!string.IsNullOrEmpty(lifeData))
                {
                    foreach (string lifeBlock in lifeData.Split(','))
                    {
                        string[] split = lifeBlock.Split('|');
                        if (split.Length < 2)
                        {
                            continue;
                        }

                        replay.LifeFrames.Add(new LifeFrame()
                        {
                            Time       = Convert.ToInt32(split[0]),
                            Percentage = ParseHelper.ToFloat(split[1])
                        });
                    }
                }

                replay.ReplayTimestamp = r.ReadDateTime();
                replay.ReplayLength    = r.ReadInt32();

                if (replay.ReplayLength > 0)
                {
                    byte[] replayDataBytes    = r.ReadBytes(replay.ReplayLength);
                    byte[] decompressedBytes  = LZMAHelper.Decompress(replayDataBytes);
                    string decompressedString = Encoding.ASCII.GetString(decompressedBytes);
                    int    lastTime           = 0;

                    foreach (string frame in decompressedString.Split(','))
                    {
                        if (string.IsNullOrEmpty(frame))
                        {
                            continue;
                        }

                        string[] split = frame.Split('|');

                        if (split.Length < 4)
                        {
                            continue;
                        }

                        if (split[0] == "-12345")
                        {
                            replay.Seed = Convert.ToInt32(split[3]);
                            continue;
                        }

                        ReplayFrame replayFrame = new ReplayFrame();
                        replayFrame.TimeDiff = Convert.ToInt32(split[0]);
                        replayFrame.Time     = Convert.ToInt32(split[0]) + lastTime;
                        replayFrame.X        = ParseHelper.ToFloat(split[1]);
                        replayFrame.Y        = ParseHelper.ToFloat(split[2]);
                        switch (replay.Ruleset)
                        {
                        case Ruleset.Standard:
                            replayFrame.StandardKeys = (StandardKeys)Convert.ToInt32(split[3]);
                            break;

                        case Ruleset.Taiko:
                            replayFrame.TaikoKeys = (TaikoKeys)Convert.ToInt32(split[3]);
                            break;

                        case Ruleset.Fruits:
                            replayFrame.CatchKeys = (CatchKeys)Convert.ToInt32(split[3]);
                            break;

                        case Ruleset.Mania:
                            replayFrame.ManiaKeys = (ManiaKeys)replayFrame.X;
                            break;
                        }

                        replay.ReplayFrames.Add(replayFrame);

                        lastTime = replay.ReplayFrames.Last().Time;
                    }
                }

                if (r.BaseStream.Length - r.BaseStream.Position > 0)
                {
                    if (r.BaseStream.Length - r.BaseStream.Position == 4)
                    {
                        replay.OnlineId = r.ReadInt32();
                    }
                    else
                    {
                        replay.OnlineId = r.ReadInt64();
                    }
                }
            }

            return(replay);
        }