/// <summary>
        /// Parses a KeyValueStruct from an expected position in a BinaryReader,
        /// returning the KeyValueStruct and advancing the reader past the object.
        /// </summary>
        /// <param name="reader"> BinaryReader advanced to a point expecting a KeyValueStruct </param>
        /// <returns> The KeyValueStruct found at the current reader position. </returns>
        public static KeyValueStruct Parse(BinaryReader reader)
        {
            var kv = new KeyValueStruct {
                Key = reader.ReadBytes(2), Value = ParseValueStruct(reader)
            };

            return(kv);
        }
示例#2
0
        /// <summary> Parses a single PlayerDetail structure from the current position of a BinaryReader object. </summary>
        /// <param name="reader"> The reader, at the position containing the start of the PlayerDetail structure. </param>
        /// <returns> Returns a Player filled with the parsed information. </returns>
        public static Player Parse(BinaryReader reader)
        {
            reader.ReadBytes(2); // playerHeader
            int shortNameLength = KeyValueStruct.Parse(reader).Value;

            byte[] nameBytes = reader.ReadBytes(shortNameLength);
            string shortName = Encoding.UTF8.GetString(nameBytes);

            reader.ReadBytes(3);
            KeyValueStruct.Parse(reader);
            reader.ReadBytes(6);

            var subIdKVS = KeyValueStruct.Parse(reader);

            var subId = subIdKVS.Value;

            var bnetIdKVS   = KeyValueStruct.Parse(reader);
            var battlenetId = bnetIdKVS.Value;

            var raceLengthKVS = KeyValueStruct.Parse(reader);
            int raceLength    = raceLengthKVS.Value;

            byte[] raceBytes = reader.ReadBytes(raceLength);
            var    race      = Encoding.UTF8.GetString(raceBytes);

            reader.ReadBytes(3); // unknown5

            var keys = new KeyValueStruct[9];

            // paramList - This contains the player's color and should eventually be parsed.
            for (int i = 0; i < 9; i++)
            {
                keys[i] = KeyValueStruct.Parse(reader);
            }

            return(new Player
            {
                Name = shortName,
                Race = race,
                Color =
                    string.Format(
                        "#{0}{1}{2}{3}",
                        keys[0].Value.ToString("X2"),
                        keys[1].Value.ToString("X2"),
                        keys[2].Value.ToString("X2"),
                        keys[3].Value.ToString("X2")),
                Handicap = keys[6].Value,
                Team = keys[7].Value,
                IsWinner = keys[8].Value == 1,     // 1 == winner, 2 == loser
                BattleNetId = battlenetId,
                BattleNetSubId = subId,
            });
        }
        /// <summary> Parses a single PlayerDetail structure from the current position of a BinaryReader object. </summary>
        /// <param name="reader"> The reader, at the position containing the start of the PlayerDetail structure. </param>
        /// <returns> Returns a Player filled with the parsed information. </returns>
        public static Player Parse(BinaryReader reader)
        {
            reader.ReadBytes(2); // playerHeader
            int shortNameLength = KeyValueStruct.Parse(reader).Value;

            byte[] nameBytes = reader.ReadBytes(shortNameLength);
            string shortName = Encoding.UTF8.GetString(nameBytes);

            reader.ReadBytes(3);
            KeyValueStruct.Parse(reader);
            reader.ReadBytes(6);

            var subIdKVS = KeyValueStruct.Parse(reader);

            var subId = subIdKVS.Value;

            var bnetIdKVS = KeyValueStruct.Parse(reader);
            var battlenetId = bnetIdKVS.Value;

            var raceLengthKVS = KeyValueStruct.Parse(reader);
            int raceLength = raceLengthKVS.Value;

            byte[] raceBytes = reader.ReadBytes(raceLength);
            var race = Encoding.UTF8.GetString(raceBytes);

            reader.ReadBytes(3); // unknown5

            var keys = new KeyValueStruct[9];

            // paramList - This contains the player's color and should eventually be parsed.
            for (int i = 0; i < 9; i++)
            {
                keys[i] = KeyValueStruct.Parse(reader);
            }

            return new Player
                {
                    Name = shortName,
                    Race = race,
                    Color =
                        string.Format(
                            "#{0}{1}{2}{3}",
                            keys[0].Value.ToString("X2"),
                            keys[1].Value.ToString("X2"),
                            keys[2].Value.ToString("X2"),
                            keys[3].Value.ToString("X2")),
                    Handicap = keys[6].Value,
                    Team = keys[7].Value,
                    IsWinner = keys[8].Value == 1, // 1 == winner, 2 == loser
                    BattleNetId = battlenetId,
                    BattleNetSubId = subId,
                };
        }
示例#4
0
        /// <summary> Parses the replay.details file, applying it to a Replay object. </summary>
        /// <param name="replay"> The replay object to apply the parsed information to. </param>
        /// <param name="stream"> The stream containing the replay.details file. </param>
        public static void Parse(Replay replay, Stream stream)
        {
            using (var reader = new BinaryReader(stream))
            {
                reader.ReadBytes(6);
                var playerCount = reader.ReadByte() >> 1;

                var players = new Player[playerCount];

                // Parsing Player Info
                for (int i = 0; i < playerCount; i++)
                {
                    var parsedPlayer = PlayerDetails.Parse(reader);

                    // The references between both of these classes are the same on purpose.
                    // We want updates to one to propogate to the other.
                    players[i] = parsedPlayer;
                    replay.ClientList[i + 1] = parsedPlayer;

                    if (replay.ReplayBuild >= 25180)
                    {
                        reader.ReadBytes(5);
                    }
                }

                replay.Players = players;

                var mapNameLength = KeyValueStruct.Parse(reader).Value;

                var mapBytes = reader.ReadBytes(mapNameLength);

                replay.Map = Encoding.UTF8.GetString(mapBytes);

                var stringLength = KeyValueStruct.Parse(reader).Value;

                // This is typically an empty string, no need to decode.
                var unknownString = reader.ReadBytes(stringLength);

                reader.ReadBytes(3);

                var mapPreviewNameLength = KeyValueStruct.Parse(reader).Value;
                var mapPreviewNameBytes  = reader.ReadBytes(mapPreviewNameLength);

                replay.MapPreviewName = Encoding.UTF8.GetString(mapPreviewNameBytes);

                reader.ReadBytes(3);

                var saveTime     = KeyValueLongStruct.Parse(reader).Value;
                var saveTimeZone = KeyValueLongStruct.Parse(reader).Value;
                var time         = DateTime.FromFileTime(saveTime);

                // Subtract the timezone to get the appropriate UTC time.
                time = time.Subtract(new TimeSpan(saveTimeZone));

                // We create a new timestamp so we can properly set this as UTC time.
                replay.Timestamp = new DateTime(time.Ticks, DateTimeKind.Utc);

                // don't know what the next 14 bytes are for, so we skip them
                reader.ReadBytes(14);

                var resources = new List <ResourceInfo>();
                reader.ReadBytes(2); // there are 2 bytes before each "s2ma" string
                var s2ma = Encoding.UTF8.GetString(reader.ReadBytes(4));

                while (s2ma == "s2ma")
                {
                    reader.ReadBytes(2); // 0x00, 0x00

                    resources.Add(
                        new ResourceInfo
                    {
                        Gateway = Encoding.UTF8.GetString(reader.ReadBytes(2)),
                        Hash    = reader.ReadBytes(32),
                    });

                    reader.ReadBytes(2);
                    s2ma = Encoding.UTF8.GetString(reader.ReadBytes(4));
                }

                var map = resources.Last();
                replay.MapGateway = map.Gateway;
                replay.MapHash    = map.Hash;

                reader.Close();
            }
        }
        /// <summary>
        /// Parses a KeyValueStruct from an expected position in a BinaryReader,
        /// returning the KeyValueStruct and advancing the reader past the object.
        /// </summary>
        /// <param name="reader"> BinaryReader advanced to a point expecting a KeyValueStruct </param>
        /// <returns> The KeyValueStruct found at the current reader position. </returns>
        public static KeyValueStruct Parse(BinaryReader reader)
        {
            var kv = new KeyValueStruct { Key = reader.ReadBytes(2), Value = ParseValueStruct(reader) };

            return kv;
        }