Ejemplo n.º 1
0
        public LogData ParseLog(string filename)
        {
            try {
            var file = File.Open(filename, FileMode.Open);
            var bs = new BufferedStream(file);
            var stream = new StreamReader(bs);

            var summonerMap = new Dictionary<string, int>();
            int netUID = -2;
            var mergedTeam = new List<Summoner>();
            double startTime = -1, lastTimeStamp = -1;
            bool disconnect = false;
            DateTime startDate = new DateTime();
            Match match;

            var ret = new LogData();
            ret.LogFile = filename;

            string line;
            string gameMode = "";
            HashSet<string> gameMutators = new HashSet<string>();
            while ((line = stream.ReadLine()) != null) {
              string[] parts = line.Split(new char[] {'|'}, 5, StringSplitOptions.None);
              if (parts.Length == 1) {
            // Old format e.g. --- Log started at Sun Apr 29 23:34:01 2012
            match = LOG_START_REGEX1.Match(line);
            if (match.Success) {
              var parsedDate = String.Format("{0} {1}, {2} {3}",
                match.Groups[2].Value, // month
                match.Groups[3].Value, // day
                match.Groups[5].Value, // year
                match.Groups[4].Value  // time
              );
              if (!DateTime.TryParse(parsedDate, out startDate)) {
                Logger.LogMessage(filename + ": Invalid date in " + match.Groups[0].Value);
              }
            }
              }

              // v6.6 and above remove the excessive "Xkb added" columns.
              if (parts.Length != 3 && parts.Length != 5) {
            continue;
              }

              double timeStamp = 0;
              if (!double.TryParse(parts[0].Trim(), NumberStyles.Number, new CultureInfo("en-US"), out timeStamp)) {
            // This line is corrupted. Ignore it
            continue;
              }
              lastTimeStamp = timeStamp;
              string text = parts.Last().Substring(1);

              if ((match = LOG_START_REGEX2.Match(text)).Success) {
            if (!DateTime.TryParse(match.Groups[1].Value, out startDate)) {
              Logger.LogMessage(filename + ": Invalid date " + match.Groups[1].Value);
            }
              } else if ((match = GAME_ID_REGEX.Match(text)).Success) { // Obtain game ID.
            ret.GameID = match.Groups[1].Value;
            if (match.Groups[3].Success) {
              ret.Server = match.Groups[3].Value;
            }
              } else if ((match = BUILD_REGEX.Match(text)).Success) {
            // game version
            ret.GameVersion = new Version(match.Groups[1].Value);
              } else if ((match = MAP_REGEX.Match(text)).Success) { // Obtain map ID
            int mapID = int.Parse(match.Groups[1].Value);
            if (!MapDictionary.TryGetValue(mapID, out ret.Map)) {
              ret.Map = "Unknown Map";
            }
              } else if ((match = NET_UID_REGEX.Match(text)).Success) { // client's ID
            netUID = int.Parse(match.Groups[1].Value);
              } else if (text.Contains("Started ReplayDownloadManager")) {
            // indicates that this was a spectated game.
            ret.Spectated = true;
              } else if (text == "GAMESTATE_GAMELOOP Begin") {
            // this indicates the game actually loaded.
            startTime = timeStamp;
            Debug.Assert(!startDate.Equals(new DateTime()), "Game started with undefined start date");
            ret.GameStartDate = startDate.AddSeconds(startTime);
              } else if ((match = KILLER_REGEX.Match(text)).Success && !ret.Spectated) {
            var killer = match.Groups[1].Value;
            if (summonerMap.ContainsKey(killer)) {
              ret.Deaths.Add(summonerMap[killer]);
            } else {
              // Most likely tower or minion.
              ret.Deaths.Add(-1);
            }
              } else if (text == "Disconnected") {
            disconnect = true;
              } else if (text == "End game message processing!") {
            // indicates game end.
            ret.GameLength = (int) (timeStamp - startTime + 0.5);
            disconnect = false;
              } else if (text == "Finished Play game" && ret.GameLength == 0) {
            // The end game message always comes first. If it didn't, that means we forcibly left the game.
            ret.GameLength = (int) (timeStamp - startTime + 0.5);
            ret.ExitCode = LogData.ExitCodes.LEAVE;
              } else if ((match = EXITCODE_REGEX.Match(text)).Success) {
            switch (match.Groups[1].Value) {
              case "WIN":
                ret.ExitCode = LogData.ExitCodes.WIN;
                break;
              case "LOSE":
                ret.ExitCode = LogData.ExitCodes.LOSE;
                break;
              case "ABANDON":
                ret.ExitCode = LogData.ExitCodes.LEAVE;
                break;
            }
              } else if ((match = GAME_MODE_REGEX.Match(text)).Success) {
            gameMode = match.Groups[1].Value.ToLower();
              } else if ((match = GAME_MUTATOR_REGEX.Match(text)).Success) {
            gameMutators.Add(match.Groups[1].Value.ToLower());
              } else if (text.Contains("TwistedAura.dds")) {
            ret.Map = "Twisted Treeline"; // 3v3 doesn't have a special game mode, but this texture gets loaded
              } else if (text.Contains(" SRUAP_")) {
            ret.Map = "Summoner's Rift (New)";
              } else {
            if (ret.GameVersion >= CLIENT_ID_VERSION) {
              match = CHAMPION_REGEX1.Match(text);
              if (match.Success) {
                var summoner = new Summoner() {
                  Champion = FixChampionName(match.Groups[1].Value),
                  SkinID = int.Parse(match.Groups[2].Value),
                  Name = match.Groups[5].Value
                };

                var teamID = int.Parse(match.Groups[3].Value);
                var clientID = int.Parse(match.Groups[4].Value);

                if (clientID == -1) {
                  ret.BotGame = true;
                  summoner.IsBot = true;
                }

                List<Summoner> team = (teamID == 100 ? ret.BlueTeam : ret.PurpleTeam);
                if (!summonerMap.ContainsKey(summoner.Name)) {
                  team.Add(summoner);
                  summonerMap[summoner.Name] = summonerMap.Count;
                }
                if (!ret.Spectated && clientID == netUID) {
                  ret.PlayerName = summoner.Name;
                }
              }
            } else {
              match = CHAMPION_REGEX2.Match(text);
              if (match.Success) {
                var summoner = new Summoner() {
                  Champion = FixChampionName(match.Groups[1].Value),
                  Name = match.Groups[4].Value
                };

                if (match.Groups[3].Success) {
                  summoner.SkinID = int.Parse(match.Groups[3].Value);
                } else {
                  summoner.SkinID = -1;
                }

                // Guess the team.. might not be accurate for 1v5 bot games and such.
                if (!summonerMap.ContainsKey(summoner.Name)) {
                  mergedTeam.Add(summoner);
                  summonerMap[summoner.Name] = summonerMap.Count;
                }
              }
            }
              }
            }

            if (ret.Map == null) {
              if (gameMode == "classic") {
            ret.Map = "Summoner's Rift";
            if (gameMutators.Contains("urf")) {
              ret.Map += " (URF)";
            }
              } else if (gameMode == "aram") {
            ret.Map = "Howling Abyss";
              } else if (gameMode == "odin") {
            ret.Map = "Crystal Scar";
              } else if (gameMode == "ascension") {
            ret.Map = "Crystal Scar (Ascension)";
              }
            }

            // Overrides existing Twisted Treeline detection.
            if (gameMutators.Contains("6v6")) {
              ret.Map = "Twisted Treeline (Hexakill)";
            }

            if (startTime == -1) {
              return null; // Game crashed before loading.
            }

            if (ret.GameLength == 0) {
              // Game crashed in the middle somewhere.
              ret.GameLength = (int) (lastTimeStamp - startTime + 0.5);
              ret.ExitCode = LogData.ExitCodes.CRASH;
            }

            if (disconnect) {
              ret.ExitCode = LogData.ExitCodes.CRASH;
            }

            if (mergedTeam.Count > 0) {
              // Assume half the players are on both teams. Doesn't account for uneven teams, of course..
              int l = (mergedTeam.Count + 1)/2;
              ret.BlueTeam = mergedTeam.Take(l).ToList();
              ret.PurpleTeam = mergedTeam.Skip(l).ToList();

              if (ret.BlueTeam.All((x) => x.Name.EndsWith(" Bot")) ||
              ret.PurpleTeam.All((x) => x.Name.EndsWith(" Bot"))) {
            ret.BotGame = true;
              }
            }

            return ret;
              } catch (Exception ex) {
            Logger.LogException(ex);
            return null;
              }
        }
Ejemplo n.º 2
0
        private void AddSummoner(Summoner s, FlowLayoutPanel flow, bool leftSide, bool isPlayer)
        {
            var label = new Label() {
            Text = leftSide ? s.Name + " (" + s.Champion + ")" : "(" + s.Champion + ") " + s.Name,
            Margin = new Padding(0, 2, 0, 3),
            Font = new Font(headerLabel.Font.FontFamily, 9.5f, isPlayer ? FontStyle.Bold : FontStyle.Regular),
            AutoSize = true,
            Cursor = Cursors.Hand,
              };
              label.Click += (sender, e) => mainForm.OpenSummonerDetails(s.Name);

              var bitmap = Resources.ResourceManager.GetObject(Util.Sanitize(s.Champion)) as Bitmap;
              if (bitmap == null) {
            bitmap = Resources.unknown;
              }

              var icon = new PictureBox() {
            Width = 16,
            Height = 16,
            BackColor = Color.Silver,
            BackgroundImage = bitmap,
              };

              flow.Controls.Add(icon);
              flow.Controls.Add(label);
              flow.SetFlowBreak(label, true);
        }