public static Match FromBytes(byte[] bytes) { Match match = new Match() { Players = new List <Player>(), }; int curIdx = 9; curIdx = MatchSerializer.FindValue(8, bytes, curIdx).Value + 1; while (bytes[curIdx + 1] != 16) { curIdx = MatchSerializer.FindValue(8, bytes, curIdx).Value + 1; } match.Season = bytes[curIdx]; curIdx++; MatchSerializer.ValidateField(bytes, ref curIdx, 16); if (bytes[curIdx] == 1) { match.WinningTeam = TeamName.Radiant; } else { match.WinningTeam = TeamName.Dire; } curIdx++; MatchSerializer.ValidateField(bytes, ref curIdx, 24); byte[] valuesBefore = bytes.Take(curIdx).ToArray(); byte[] values = bytes.Take(curIdx).ToArray(); match.DurationSeconds = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); MatchSerializer.ValidateField(bytes, ref curIdx, 0x25); match.TimeDelta = MatchSerializer.ParseUInt32(bytes, ref curIdx); match.Time = MatchSerializer.BaseTime.AddSeconds(match.TimeDelta); MatchSerializer.ValidateField(bytes, ref curIdx, 0x2a); Player playerSummary = MatchSerializer.DecodePlayer(match, bytes, ref curIdx); match.Players.Add(playerSummary); while (bytes[curIdx] == 0x2a) { curIdx++; playerSummary = MatchSerializer.DecodePlayer(match, bytes, ref curIdx); match.Players.Add(playerSummary); } match.HasBots = match.Players.Exists(ps => ps.IsBot); values = bytes.Take(curIdx).ToArray(); MatchSerializer.ValidateField(bytes, ref curIdx, 0x30); match.Id = MatchSerializer.ParseVarInt(bytes, ref curIdx); MatchSerializer.ValidateField(bytes, ref curIdx, 64); match.TowerStatusRadiant = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); MatchSerializer.ValidateField(bytes, ref curIdx, 64); match.TowerStatusDire = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); MatchSerializer.ValidateField(bytes, ref curIdx, 72); match.BarracksStatusRadiant = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); MatchSerializer.ValidateField(bytes, ref curIdx, 72); match.BarracksStatusDire = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); MatchSerializer.ValidateField(bytes, ref curIdx, 80); match.Cluster = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); MatchSerializer.ValidateField(bytes, ref curIdx, 96); match.FirstBloodTimeSeconds = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); MatchSerializer.ValidateField(bytes, ref curIdx, 109); match.ReplaySalt = MatchSerializer.ParseUInt32(bytes, ref curIdx); MatchSerializer.ValidateField(bytes, ref curIdx, 128); MatchSerializer.ValidateField(bytes, ref curIdx, 1); match.LobbyType = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); MatchSerializer.ValidateField(bytes, ref curIdx, 136); MatchSerializer.ValidateField(bytes, ref curIdx, 1); match.HumanPlayerCount = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); // league id was added in later... figure out what code in the message tells me this? if (bytes.Length < curIdx) { MatchSerializer.ValidateField(bytes, ref curIdx, 176); MatchSerializer.ValidateField(bytes, ref curIdx, 1); match.LeagueId = Convert.ToInt32(MatchSerializer.ParseVarInt(bytes, ref curIdx)); } return(match); }