Exemplo n.º 1
0
        private static int findMatchStartRound(FileStream fileStream)
        {
            int result = 0;
            using (var parser = new DemoParser(fileStream))
            {
                parser.ParseHeader();
                int roundNumber = 0;

                parser.MatchStarted += (sender, e) =>
                {
                    if (roundNumber <= 16)
                    {
                        roundNumber = 0;
                        result++;
                    }
                };

                parser.RoundEnd += (object sender, RoundEndedEventArgs e) =>
                {
                    roundNumber++;
                };

                parser.ParseToEnd();
            }

            Console.WriteLine("Match starts at round number " + result);
            return result;
        }
Exemplo n.º 2
0
 public Match Parse(FileInfo fileInfo)
 {
     _Match.DemoName = fileInfo.Name;
     using (var stream = new FileStream(fileInfo.FullName, FileMode.Open))
     {
         var parser = new DemoInfo.DemoParser(stream);
         parser.MatchStarted += OnMatchStarted;
         parser.PlayerKilled += OnPlayerKilled;
         parser.PlayerTeam   += OnPlayerTeam;
         parser.RoundEnd     += OnRoundEnd;
         parser.ParseHeader();
         _Match.Map = parser.Map;
         parser.ParseToEnd();
         RemoveSpectators();
     }
     return(_Match);
 }
        public static void GenerateFrags(DemoParser parser)
        {
            parser.ParseHeader ();

            // Make a print on round-start so you can see the actual frags per round.
            parser.RoundStart += (sender, e) => Console.WriteLine ("New Round, Current Score: T {0} : {1} CT", parser.TScore, parser.CTScore);

            parser.PlayerKilled += (sender, e) => {
                if(e.Killer == null) {
                    // The player has murdered himself (falling / own nade / ...)
                    Console.WriteLine("<World><0><None>");
                } else {
                    Console.Write("<{0}><{1}><{2}>", e.Killer.Name, e.Killer.SteamID, ShortTeam(e.Killer.Team));
                }

                if(e.Assister == null) {
                    // nothing
                } else {
                    Console.Write(" + <{0}><{1}><{2}>", e.Assister.Name, e.Assister.SteamID, ShortTeam(e.Assister.Team));
                }

                Console.Write(" [{0}]", e.Weapon.Weapon);

                if(e.Headshot) {
                    Console.Write("[HS]");
                }

                if(e.PenetratedObjects > 0) {
                    Console.Write("[Wall]");
                }

                Console.Write(" ");

                Console.Write("<{0}><{1}><{2}>", e.DeathPerson.Name, e.DeathPerson.SteamID, ShortTeam(e.DeathPerson.Team));

                Console.WriteLine();
            };

            parser.ParseToEnd ();
        }
Exemplo n.º 4
0
 public string GetMapName()
 {
     if (string.IsNullOrEmpty(mapName))
     {
         if (availableOffline)
         {
             using (FileStream fs = new FileStream(GetMatchFilePath(), FileMode.Open, FileAccess.Read))
                 using (DemoInfo.DemoParser dp = new DemoInfo.DemoParser(fs))
                 {
                     dp.ParseHeader();
                     mapName = dp.Map;
                 }
         }
         else
         {
             var lastRound = GetLastRoundStats();
             if (lastRound != null)
             {
                 mapName = ((GameType)lastRound.reservation.game_type).ToString();
             }
         }
     }
     return(mapName);
 }
Exemplo n.º 5
0
        static List<String> parseDemo(string fileName)
        {
            List<String> playerIDs = new List<String>();
            using (var fileStream = File.OpenRead(fileName))
            {
                using (var parser = new DemoParser(fileStream))
                {
                    //hasMatchStarted framkallar viðvörun um að mögulegt sé
                    //að það verði aldrei notað, með þessu slökkvum við á
                    //þessari viðvörun.
                    #pragma warning disable 0219
                    bool hasMatchStarted = false;
                    #pragma warning restore 0219

                    parser.ParseHeader();

                    parser.MatchStarted += (sender, e) =>
                    {
                        hasMatchStarted = true;

                        foreach (var player in parser.PlayingParticipants)
                        {
                            string test = player.SteamID.ToString();
                            playerIDs.Add(test);
                        }
                    };
                    //Þetta fyrir neðan er algjörlega ógeðslegt, ég veit.
                    //En er samt nauðsynlegt svo að playerIDs verði fyllt.
                    for (int i = 0; i < 3000; i++)
                    {
                        parser.ParseNextTick();
                    }
                }
            }
            return playerIDs;
        }
Exemplo n.º 6
0
        public static void Main(string[] args)
        {
            using (var input = File.OpenRead(args[0]))
            {
                var parser = new DemoParser(input);

                parser.ParseHeader();

                parser.WeaponFired += (sender, e) => {
                    Console.WriteLine("Weapon_fire");
                    Console.WriteLine("{");
                    Console.WriteLine("velx=" + e.Shooter.Velocity.X);
                    Console.WriteLine("vely=" + e.Shooter.Velocity.Y);
                    Console.WriteLine("weapon=" + e.Weapon.Weapon);
                    Console.WriteLine("playername=" + e.Shooter.Name);
                    Console.WriteLine("playersteamid=" + e.Shooter.SteamID);
                    Console.WriteLine("}");

                };

                parser.ParseToEnd();
                Console.WriteLine("End");
            }
        }
Exemplo n.º 7
0
		public static Demo ParseDemoHeader(string pathDemoFile)
		{
			DemoParser parser = new DemoParser(File.OpenRead(pathDemoFile));

			DateTime dateFile = File.GetCreationTime(pathDemoFile);
			string dateAsString = dateFile.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);

			Demo demo = new Demo
			{
				Name = Path.GetFileName(pathDemoFile),
				Path = pathDemoFile,
				Date = dateAsString
			};

			try
			{
				parser.ParseHeader();
			}
			catch (InvalidDataException)
			{
				// Silently ignore no CSGO demos
				return null;
			}

			DemoHeader header = parser.Header;
			DateTime dateTime = File.GetCreationTime(pathDemoFile);
			int seconds = (int)(dateTime.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
			demo.Id = header.MapName.Replace("/", "") + seconds + header.SignonLength + header.PlaybackFrames;
			demo.ClientName = header.ClientName;
			demo.Hostname = header.ServerName;
			if (header.PlaybackTicks != 0 && header.PlaybackTime != 0)
			{
				demo.ServerTickrate = header.PlaybackTicks / header.PlaybackTime;
			}
			if (header.PlaybackFrames != 0 && header.PlaybackTime != 0)
			{
				demo.Tickrate = (int)Math.Round((double)header.PlaybackFrames / header.PlaybackTime);
			}
			demo.Duration = header.PlaybackTime;
			demo.MapName = header.MapName;
			demo.Source = DetermineDemoSource(demo, parser, header);

			return demo;
		}
Exemplo n.º 8
0
    public static void CreateMatchInfo(MatchInfo match, out CDataGCCStrike15_v2_MatchInfo matchInfo, out ExtraMatchStats extraStats, System.Threading.CancellationToken cancelToken)
    {
        matchInfo  = null;
        extraStats = null;
        if (match.availableOffline)
        {
            CDataGCCStrike15_v2_MatchInfo tempMatchInfo = new CDataGCCStrike15_v2_MatchInfo();
            ExtraMatchStats tempExtraStats = new ExtraMatchStats();

            #region File Name Data
            ulong reservationId          = 0;
            bool  reservationIdSpecified = false;

            string[] fileNameSplits = match.fileName.Split('_');
            if (match.fileName.IndexOf("match730_") == 0 && fileNameSplits.Length == 4)
            {
                try
                {
                    reservationId          = Convert.ToUInt64(fileNameSplits[1]);
                    reservationIdSpecified = true;

                    WatchableMatchInfo watchablematchinfo = new WatchableMatchInfo();
                    watchablematchinfo.tv_port       = Convert.ToUInt32(fileNameSplits[2]);
                    watchablematchinfo.server_ip     = Convert.ToUInt32(fileNameSplits[3]);
                    tempMatchInfo.watchablematchinfo = watchablematchinfo;
                }
                catch (Exception)
                { }
            }
            #endregion

            using (FileStream fileStream = File.Open(match.GetMatchFilePath(), FileMode.Open, FileAccess.Read))
                using (DemoInfo.DemoParser dp = new DemoInfo.DemoParser(fileStream))
                {
                    #region Data Analysis
                    #region Match Info Variables
                    int matchStartTick = 0;

                    CMsgGCCStrike15_v2_MatchmakingServerRoundStats currentRoundStats = null;
                    Dictionary <uint, int>         totalAssists        = new Dictionary <uint, int>();
                    Dictionary <uint, int>         totalDeaths         = new Dictionary <uint, int>();
                    Dictionary <uint, int>         totalEnemyHeadshots = new Dictionary <uint, int>();
                    Dictionary <uint, int>         totalEnemyKills     = new Dictionary <uint, int>();
                    Dictionary <uint, int>         totalKills          = new Dictionary <uint, int>();
                    Dictionary <uint, int>         totalMvps           = new Dictionary <uint, int>();
                    Dictionary <uint, int>         totalScores         = new Dictionary <uint, int>();
                    List <List <DemoInfo.Player> > playerTeams         = new List <List <DemoInfo.Player> >();

                    //List<uint> accountIds = new List<uint>();
                    int[] totalTeamScore = new int[2];
                    #endregion

                    Action <uint> AddPlayerToCurrentRound = (accountId) =>
                    {
                        currentRoundStats.reservation.account_ids.Add(accountId);
                        currentRoundStats.assists.Add(0);
                        currentRoundStats.deaths.Add(0);
                        currentRoundStats.enemy_headshots.Add(0);
                        currentRoundStats.enemy_kills.Add(0);
                        currentRoundStats.kills.Add(0);
                        currentRoundStats.mvps.Add(0);
                        currentRoundStats.scores.Add(0);
                    };
                    Func <uint, int> GetPlayerIndex = (accountId) =>
                    {
                        int playerIndex = currentRoundStats.reservation.account_ids.IndexOf(accountId);
                        if (playerIndex < 0)
                        {
                            AddPlayerToCurrentRound(accountId);
                            playerIndex = currentRoundStats.reservation.account_ids.Count - 1;
                        }
                        return(playerIndex);
                    };

                    EventHandler <DemoInfo.MatchStartedEventArgs> matchStartedHandler = (obj, msea) =>
                    {
                        matchStartTick = dp.CurrentTick;

                        foreach (var player in dp.PlayerInformations)
                        {
                            if (player != null && player.SteamID > 0)
                            {
                                uint accountId = new SteamKit2.SteamID((ulong)player.SteamID).AccountID;

                                #region Extra Stats Data
                                tempExtraStats.accountIds.Add(accountId);
                                tempExtraStats.playerNames.Add(player.Name);
                                #endregion

                                var teamToAddTo = playerTeams.Find((team) => team.Exists((teamPlayer) => teamPlayer.Team == player.Team));
                                if (teamToAddTo == null)
                                {
                                    teamToAddTo = new List <DemoInfo.Player>();
                                    playerTeams.Add(teamToAddTo);
                                }
                                teamToAddTo.Add(player);
                            }
                        }
                    };
                    EventHandler <DemoInfo.RoundStartedEventArgs> roundStartedHandler = (obj, rsea) =>
                    {
                        #region Match Info Data
                        currentRoundStats = new CMsgGCCStrike15_v2_MatchmakingServerRoundStats();
                        tempMatchInfo.roundstatsall.Add(currentRoundStats);

                        currentRoundStats.team_scores.AddRange(totalTeamScore);

                        CMsgGCCStrike15_v2_MatchmakingGC2ServerReserve reservation = new CMsgGCCStrike15_v2_MatchmakingGC2ServerReserve();
                        currentRoundStats.reservation = reservation;
                        foreach (var player in dp.PlayerInformations)
                        {
                            if (player != null && player.SteamID > 0)
                            {
                                AddPlayerToCurrentRound(new SteamKit2.SteamID((ulong)player.SteamID).AccountID);
                            }
                        }
                        #endregion
                        #region Extra Stats Data
                        tempExtraStats.roundStartTicks.Add(dp.CurrentTick);
                        #endregion
                    };
                    EventHandler <DemoInfo.PlayerKilledEventArgs> playerKilledHandler = (obj, pkea) =>
                    {
                        if (currentRoundStats != null)
                        {
                            if (pkea.Victim?.SteamID > 0)
                            {
                                uint victimAccountId = new SteamKit2.SteamID((ulong)pkea.Victim.SteamID).AccountID;
                                int  victimIndex     = GetPlayerIndex(victimAccountId);
                                UnityEngine.Debug.Assert(victimIndex > -1, "How do we not have this player yet?? @tick " + dp.CurrentTick + " index: " + victimIndex + " accountId: " + victimAccountId + " name " + pkea.Victim.Name);
                                if (victimIndex > -1)
                                {
                                    if (!totalDeaths.ContainsKey(victimAccountId))
                                    {
                                        totalDeaths[victimAccountId] = 0;
                                    }
                                    currentRoundStats.deaths[victimIndex] = ++totalDeaths[victimAccountId];
                                }
                            }
                            if (pkea.Killer?.SteamID > 0)
                            {
                                uint killerAccountId = new SteamKit2.SteamID((ulong)pkea.Killer.SteamID).AccountID;
                                int  killerIndex     = GetPlayerIndex(killerAccountId);
                                UnityEngine.Debug.Assert(killerIndex > -1, "How do we not have this player yet?? @tick " + dp.CurrentTick + " index: " + killerIndex + " accountId: " + killerAccountId + " name " + pkea.Killer.Name);
                                if (killerIndex > -1)
                                {
                                    if (!totalKills.ContainsKey(killerAccountId))
                                    {
                                        totalKills[killerAccountId] = 0;
                                    }
                                    currentRoundStats.kills[killerIndex] = ++totalKills[killerAccountId];

                                    bool enemyKill = pkea.Victim.TeamID != pkea.Killer.TeamID;
                                    if (!totalEnemyKills.ContainsKey(killerAccountId))
                                    {
                                        totalEnemyKills[killerAccountId] = 0;
                                    }
                                    currentRoundStats.enemy_kills[killerIndex] += enemyKill ? ++totalEnemyKills[killerAccountId] : 0;
                                    if (!totalEnemyHeadshots.ContainsKey(killerAccountId))
                                    {
                                        totalEnemyHeadshots[killerAccountId] = 0;
                                    }
                                    currentRoundStats.enemy_headshots[killerIndex] += enemyKill && pkea.Headshot ? ++totalEnemyHeadshots[killerAccountId] : 0;
                                }
                            }
                            if (pkea.Assister?.SteamID > 0)
                            {
                                uint assisterAccountId = new SteamKit2.SteamID((ulong)pkea.Assister.SteamID).AccountID;
                                int  assisterIndex     = GetPlayerIndex(assisterAccountId);
                                UnityEngine.Debug.Assert(assisterIndex > -1, "How do we not have this player yet?? @tick " + dp.CurrentTick + " index: " + assisterIndex + " accountId: " + assisterAccountId + " name " + pkea.Assister.Name);
                                if (assisterIndex > -1)
                                {
                                    if (!totalAssists.ContainsKey(assisterAccountId))
                                    {
                                        totalAssists[assisterAccountId] = 0;
                                    }
                                    currentRoundStats.assists[assisterIndex] = ++totalAssists[assisterAccountId];
                                }
                            }
                        }
                    };
                    EventHandler <DemoInfo.RoundMVPEventArgs> roundMVPHandler = (obj, rmea) =>
                    {
                        if (rmea.Player?.SteamID > 0)
                        {
                            uint playerAccountId = new SteamKit2.SteamID((ulong)rmea.Player.SteamID).AccountID;
                            if (!totalMvps.ContainsKey(playerAccountId))
                            {
                                totalMvps[playerAccountId] = 0;
                            }

                            int playerIndex = GetPlayerIndex(playerAccountId);
                            UnityEngine.Debug.Assert(playerIndex > -1, "How do we not have this player yet?? @tick " + dp.CurrentTick + " index: " + playerIndex + " accountId: " + playerAccountId + " name " + rmea.Player.Name);
                            if (playerIndex > -1 && playerIndex < currentRoundStats.mvps.Count)
                            {
                                currentRoundStats.mvps[playerIndex] = ++totalMvps[playerAccountId];
                            }
                        }
                    };
                    EventHandler <DemoInfo.RoundEndedEventArgs> roundEndedHandler = (obj, reea) =>
                    {
                        #region Match Info Data
                        Debug.Assert(currentRoundStats != null, "How can you end a round without starting it!? @tick " + dp.CurrentTick);
                        if (currentRoundStats != null)
                        {
                            if (reea.Winner != DemoInfo.Team.Spectate)
                            {
                                int teamIndex = playerTeams.FindIndex((team) => team[0].Team == reea.Winner);
                                if (teamIndex > -1 && teamIndex < totalTeamScore.Length)
                                {
                                    currentRoundStats.team_scores[teamIndex] = ++totalTeamScore[teamIndex];
                                }
                            }
                            currentRoundStats.match_duration = (int)((dp.CurrentTick - matchStartTick) * dp.TickTime);

                            foreach (var player in dp.PlayerInformations)
                            {
                                if (player != null && player.SteamID > 0)
                                {
                                    uint playerAccountId = new SteamKit2.SteamID((ulong)player.SteamID).AccountID;
                                    int  playerIndex     = GetPlayerIndex(playerAccountId);
                                    Debug.Assert(playerIndex > -1, "How do we not have this player yet?? @tick " + dp.CurrentTick + " index: " + playerIndex + " accountId: " + playerAccountId + " name " + player.Name);
                                    currentRoundStats.scores[playerIndex] = player.AdditionaInformations.Score;
                                }
                            }
                        }
                        #endregion
                        #region Extra Stats Data
                        tempExtraStats.roundEndTicks.Add(dp.CurrentTick);
                        tempExtraStats.roundWinner.Add((int)reea.Winner);
                        #endregion
                    };
                    #endregion

                    dp.MatchStarted += matchStartedHandler;
                    dp.RoundStart   += roundStartedHandler;
                    dp.PlayerKilled += playerKilledHandler;
                    dp.RoundMVP     += roundMVPHandler;
                    dp.RoundEnd     += roundEndedHandler;

                    dp.ParseHeader();
                    while (dp.ParseNextTick() && !cancelToken.IsCancellationRequested)
                    {
                        match.infoProgress = dp.CurrentTick / (float)dp.Header.PlaybackFrames;
                    }

                    dp.MatchStarted -= matchStartedHandler;
                    dp.RoundStart   -= roundStartedHandler;
                    dp.PlayerKilled -= playerKilledHandler;
                    dp.RoundMVP     -= roundMVPHandler;
                    dp.RoundEnd     -= roundEndedHandler;

                    #region Last round stats
                    if (reservationIdSpecified)
                    {
                        currentRoundStats.reservationid = reservationId;
                    }
                    currentRoundStats.reservation.game_type = (uint)(GameType)Enum.Parse(typeof(GameType), dp.Map);

                    if (totalTeamScore[0] != totalTeamScore[1])
                    {
                        var winningTeam = (DemoInfo.Team)currentRoundStats.round_result;
                        currentRoundStats.match_result = (winningTeam == DemoInfo.Team.Terrorist ? 1 : 2); //1 is CT, 2 is T. I do the switching because of team switching at half
                    }
                    else
                    {
                        currentRoundStats.match_result = 0;
                    }
                    #endregion
                }

            if (cancelToken.IsCancellationRequested)
            {
                tempMatchInfo  = null;
                tempExtraStats = null;
            }
            matchInfo  = tempMatchInfo;
            extraStats = tempExtraStats;
        }
    }
Exemplo n.º 9
0
        static void Main(string[] args)
        {
            int demosParsed = 0;
            int errors = 0;
            String[] directories = Directory.GetDirectories(@"D:\demos\extracted\");

            foreach (String directory in directories)
            {
                if(directory.Length != 28 || !directory.StartsWith(@"D:\demos\extracted\demo190"))
                {
                    continue;
                }

                foreach(String file in Directory.GetFiles(directory))
                {
                    DemoParser parser = new DemoParser(File.OpenRead(file));

                    try
                    {
                        parser.ParseHeader();

                        Program program = new Program(parser);
                        parser.ParseToEnd();

                        demosParsed++;
                    } catch (Exception e)
                    {
                        parser = null;
                        errors++;
                        break;
                    }
                }

                if(demosParsed > 100)
                {
                    break;
                }
            }

            Console.WriteLine("Errors: " + errors);
            Console.WriteLine("Demos Parsed: " + demosParsed);

            Console.Read();
        }
Exemplo n.º 10
0
        public static void Analyze(string demoPath)
        {
            using (var fileStream = File.OpenRead(demoPath))
            {
                Console.WriteLine("Parsing demo " + demoPath);
                using (var parser = new DemoParser(fileStream))
                {
                    parser.ParseHeader();

                    string map = parser.Map;

                    Console.WriteLine("Map: " + map);

                    bool hasMatchStarted = false;
                    bool firstBlood = true;
                    int round = 0;
                    Dictionary<Player, int> killsThisRound = new Dictionary<Player, int>();
                    Dictionary<Player, int> entryFrags = new Dictionary<Player, int>();
                    Dictionary<Player, int> entryFragAttempts = new Dictionary<Player, int>();
                    Dictionary<Player, Rating> ratings = new Dictionary<Player, Rating>();

                    parser.MatchStarted += (sender, e) =>
                    {
                        hasMatchStarted = true;
                    };

                    parser.RoundStart += (sender, e) =>
                    {
                        if (!hasMatchStarted)
                            return;

                        firstBlood = true;
                        round++;
                        killsThisRound.Clear();
                        foreach (var player in parser.PlayingParticipants)
                        {
                            if (!ratings.ContainsKey(player))
                            {
                                ratings.Add(player, new Rating());
                            }

                            ratings[player].roundsPlayed++;
                        }
                    };

                    parser.RoundEnd += (sender, e) =>
                    {
                        if (!hasMatchStarted)
                            return;

                        //firstBlood = true;
                        //round++;
                        //killsThisRound.Clear();
                        foreach (var player in killsThisRound.Keys)
                        {
                            if (!ratings.ContainsKey(player))
                            {
                                ratings.Add(player,new Rating());
                            }

                            ratings[player].multipleKillsDictionary[killsThisRound[player]]++;
                        }
                    };

                    parser.PlayerKilled += (object sender, PlayerKilledEventArgs e) => {

                    if (!hasMatchStarted)
                        return;
                        //the killer is null if you're killed by the world - eg. by falling
                        if (e.Killer != null)
                        {
                            if (!killsThisRound.ContainsKey(e.Killer))
                                killsThisRound[e.Killer] = 0;

                            if(e.Killer.Team == e.Victim.Team)
                            {
                                //killsThisRound[e.Killer]--;

                            }
                            else
                            {
                                killsThisRound[e.Killer]++;
                            }
                            //Remember how many kills each player made this rounds

                            if (!ratings.ContainsKey(e.Victim))
                            {
                                ratings.Add(e.Victim, new Rating());
                            }

                            ratings[e.Victim].deaths++;

                            if (firstBlood)
                            {
                                if (!entryFrags.ContainsKey(e.Killer))
                                    entryFrags[e.Killer] = 0;

                                entryFrags[e.Killer]++;

                                if (!entryFragAttempts.ContainsKey(e.Killer))
                                    entryFragAttempts[e.Killer] = 0;

                                entryFragAttempts[e.Killer]++;

                                if (!entryFragAttempts.ContainsKey(e.Victim))
                                    entryFragAttempts[e.Victim] = 0;

                                entryFragAttempts[e.Victim]++;

                                firstBlood = false;
                            }
                        }
                    };

                    parser.ParseToEnd();

                    //foreach(var player in killsThisRound.Keys)
                    //{
                    //    if (!entryFragAttempts.ContainsKey(player))
                    //    {
                    //        entryFragAttempts[player] = 0;
                    //    }

                    //    if (!entryFrags.ContainsKey(player))
                    //    {
                    //        entryFrags[player] = 0;
                    //    }

                    //    Console.WriteLine(player.Name + "(" + player.Team + ")" + " entry frags: " + entryFrags[player] + "/" + entryFragAttempts[player]);
                    //}

                    foreach (var player in ratings.Keys)
                    {
                        Console.WriteLine(player.Name + "(" + player.Team + ")" + " rating: " + ratings[player].getRating());
                    }

                }
            }
        }
Exemplo n.º 11
0
		public static Demo ParseDemoHeader(string pathDemoFile)
		{
			DemoParser parser = new DemoParser(File.OpenRead(pathDemoFile));

			DateTime dateFile = File.GetCreationTime(pathDemoFile);
			Demo demo = new Demo
			{
				Name = Path.GetFileName(pathDemoFile),
				Path = pathDemoFile,
				Date = dateFile
			};

			try
			{
				parser.ParseHeader();
			}
			catch (Exception)
			{
				// Silently ignore no CSGO demos or unreadable file
				return null;
			}

			DemoHeader header = parser.Header;
			DateTime dateTime = File.GetCreationTime(pathDemoFile);
			int seconds = (int)(dateTime.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
			demo.Id = header.MapName.Replace("/", "") + "_" + seconds + header.SignonLength + header.PlaybackFrames;
			demo.ClientName = header.ClientName;
			demo.Hostname = header.ServerName;
			if (header.PlaybackTicks != 0 && header.PlaybackTime != 0)
			{
				demo.ServerTickrate = header.PlaybackTicks / header.PlaybackTime;
			}
			if (header.PlaybackFrames != 0 && header.PlaybackTime != 0)
			{
				demo.Tickrate = (int)Math.Round((double)header.PlaybackFrames / header.PlaybackTime);
			}
			demo.Duration = header.PlaybackTime;
			demo.MapName = header.MapName;
			demo.Source = DetermineDemoSource(demo, header);

			// Read .info file to get the real match date
			string infoFilePath = demo.Path + ".info";
			if (File.Exists(infoFilePath))
			{
				using (FileStream file = File.OpenRead(infoFilePath))
				{
					try
					{
						CDataGCCStrike15_v2_MatchInfo infoMsg = Serializer.Deserialize<CDataGCCStrike15_v2_MatchInfo>(file);
						DateTime unixTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
						demo.Date = unixTime.AddSeconds(infoMsg.matchtime);
					}
					catch (Exception)
					{
						// silently ignore old .info files
						// Maybe add the old message to handle it?
					}
				}
			}

			return demo;
		}
Exemplo n.º 12
0
        public static void Main(string[] args)
        {
            // First, check wether the user needs assistance:
            if (args.Length == 0 || args [0] == "--help") {
                PrintHelp ();
                return;
            }

            if (args [0] == "--scoreboard") {
                using (var fileStream = File.OpenRead (args[1])) {
                    using (var parser = new DemoParser(fileStream)) {
                        ScoreboardGenerator.GenerateScoreboards(parser);
                    }
                }
                return;
            }

            if (args [0] == "--frags") {
                using (var fileStream = File.OpenRead (args[1])) {
                    using (var parser = new DemoParser(fileStream)) {
                        FragGenerator.GenerateFrags(parser);
                    }
                }
                return;
            }

            // Every argument is a file, so let's iterate over all the arguments
            // So you can call this program like
            // > StatisticsGenerator.exe hello.dem bye.dem
            // It'll generate the statistics.
            foreach (var fileName in args) {
                // Okay, first we need to initalize a demo-parser
                // It takes a stream, so we simply open with a filestream
                using (var fileStream = File.OpenRead (fileName)) {
                    // By using "using" we make sure that the fileStream is properly disposed
                    // the same goes for the DemoParser which NEEDS to be disposed (else it'll
                    // leak memory and kittens will die.

                    Console.WriteLine ("Parsing demo " + fileName);

                    using (var parser = new DemoParser (fileStream)) {
                        // So now we've initialized a demo-parser.
                        // let's parse the head of the demo-file to get which map the match is on!
                        // this is always the first step you need to do.
                        parser.ParseHeader ();

                        // and now, do some magic: grab the match!
                        string map = parser.Map;

                        // And now, generate the filename of the resulting file
                        string outputFileName = fileName + "." + map + ".csv";
                        // and open it.
                        var outputStream = new StreamWriter (outputFileName);

                        //And write a header so you know what is what in the resulting file
                        outputStream.WriteLine (GenerateCSVHeader ());

                        // Cool! Now let's get started generating the analysis-data.

                        //Let's just declare some stuff we need to remember

                        // Here we'll save how far a player has travelled each round.
                        // Here we remember wheter the match has started yet.
                        bool hasMatchStarted = false;

                        int ctStartroundMoney = 0, tStartroundMoney = 0, ctEquipValue = 0, tEquipValue = 0, ctSaveAmount = 0, tSaveAmount = 0;

                        float ctWay = 0, tWay = 0;

                        int defuses = 0;
                        int plants = 0;

                        Dictionary<Player, int> killsThisRound = new Dictionary<Player, int> ();

                        List<Player> ingame = new List<Player> ();

                        // Since most of the parsing is done via "Events" in CS:GO, we need to use them.
                        // So you bind to events in C# as well.

                        // AFTER we have bound the events, we start the parser!

                        parser.MatchStarted += (sender, e) => {
                            hasMatchStarted = true;
                            //Okay let's output who's really in this game!

                            Console.WriteLine("Participants: ");
                            Console.WriteLine("  Terrorits \"{0}\": ", parser.CTClanName);

                            foreach(var player in parser.PlayingParticipants.Where(a => a.Team == Team.Terrorist))
                                Console.WriteLine ("    {0} {1} (Steamid: {2})", player.AdditionaInformations.Clantag, player.Name, player.SteamID);

                            Console.WriteLine("  Counter-Terrorits \"{0}\": ", parser.TClanName);
                            foreach(var player in parser.PlayingParticipants.Where(a => a.Team == Team.CounterTerrorist))
                                Console.WriteLine ("    {0} {1} (Steamid: {2})", player.AdditionaInformations.Clantag, player.Name, player.SteamID);

                            // Okay, problem: At the end of the demo
                            // a player might have already left the game,
                            // so we need to store some information
                            // about the players before they left :)
                            ingame.AddRange(parser.PlayingParticipants);
                        };

                        parser.PlayerKilled += (object sender, PlayerKilledEventArgs e) => {
                            //the killer is null if you're killed by the world - eg. by falling
                            if(e.Killer != null) {
                                if(!killsThisRound.ContainsKey(e.Killer))
                                    killsThisRound[e.Killer] = 0;

                                //Remember how many kills each player made this rounds
                                killsThisRound[e.Killer]++;
                            }
                        };

                        parser.RoundStart += (sender, e) => {
                            if(!hasMatchStarted)
                                return;

                            //How much money had each team at the start of the round?
                            ctStartroundMoney = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).Sum(a => a.Money);
                            tStartroundMoney = parser.Participants.Where(a => a.Team == Team.Terrorist).Sum(a => a.Money);

                            //And how much they did they save from the last round?
                            ctSaveAmount = parser.Participants.Where(a => a.Team == Team.CounterTerrorist && a.IsAlive).Sum(a => a.CurrentEquipmentValue);
                            tSaveAmount = parser.Participants.Where(a => a.Team == Team.Terrorist && a.IsAlive).Sum(a => a.CurrentEquipmentValue);

                            //And let's reset those statistics
                            ctWay = 0; tWay = 0;
                            plants = 0; defuses = 0;

                            killsThisRound.Clear();
                        };

                        parser.FreezetimeEnded += (sender, e) => {
                            if(!hasMatchStarted)
                                return;

                            // At the end of the freezetime (when players can start walking)
                            // calculate the equipment value of each team!
                            ctEquipValue = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).Sum(a => a.CurrentEquipmentValue);
                            tEquipValue = parser.Participants.Where(a => a.Team == Team.Terrorist).Sum(a => a.CurrentEquipmentValue);
                        };

                        parser.BombPlanted += (sender, e) => {
                            if(!hasMatchStarted)
                                return;

                            plants++;
                        };

                        parser.BombDefused += (sender, e) => {
                            if(!hasMatchStarted)
                                return;

                            defuses++;
                        };

                        parser.TickDone += (sender, e) => {
                            if(!hasMatchStarted)
                                return;

                            // Okay, let's measure how far each team travelled.
                            // As you might know from school the amount walked
                            // by a player is the sum of it's velocities

                            foreach(var player in parser.PlayingParticipants)
                            {
                                // We multiply it by the time of one tick
                                // Since the velocity is given in
                                // ingame-units per second
                                float currentWay = (float)(player.Velocity.Absolute * parser.TickTime);

                                // This is just an example of what kind of stuff you can do
                                // with this parser.
                                // Of course you could find out who makes the most footsteps, and find out
                                // which player ninjas the most - just to give you an example

                                if(player.Team == Team.CounterTerrorist)
                                    ctWay += currentWay;
                                else if(player.Team == Team.Terrorist)
                                    tWay += currentWay;
                            }
                        };

                        //So now lets do some fancy output
                        parser.RoundEnd += (sender, e) => {
                            if(!hasMatchStarted)
                                return;

                            // We do this in a method-call since we'd else need to duplicate code
                            // The much parameters are there because I simply extracted a method
                            // Sorry for this - you should be able to read it anywys :)
                            PrintRoundResults (parser, outputStream, ctStartroundMoney, tStartroundMoney, ctEquipValue, tEquipValue, ctSaveAmount, tSaveAmount, ctWay, tWay, defuses, plants, killsThisRound);
                        };

                        //Now let's parse the demo!
                        parser.ParseToEnd ();

                        //And output the result of the last round again.
                        PrintRoundResults (parser, outputStream, ctStartroundMoney, tStartroundMoney, ctEquipValue, tEquipValue, ctSaveAmount, tSaveAmount, ctWay, tWay, defuses, plants, killsThisRound);

                        //Lets just display an end-game-scoreboard!

                        Console.WriteLine("Finished! Results: ");
                        Console.WriteLine("  Terrorits \"{0}\": ", parser.CTClanName);

                        foreach(var player in ingame.Where(a => a.Team == Team.Terrorist))
                            Console.WriteLine (
                                "    {0} {1} (Steamid: {2}): K: {3}, D: {4}, A: {5}",
                                player.AdditionaInformations.Clantag,
                                player.Name, player.SteamID,
                                player.AdditionaInformations.Kills,
                                player.AdditionaInformations.Deaths,
                                player.AdditionaInformations.Assists
                            );

                        Console.WriteLine("  Counter-Terrorits \"{0}\": ", parser.TClanName);
                        foreach(var player in ingame.Where(a => a.Team == Team.CounterTerrorist))
                            Console.WriteLine (
                                "    {0} {1} (Steamid: {2}): K: {3}, D: {4}, A: {5}",
                                player.AdditionaInformations.Clantag,
                                player.Name, player.SteamID,
                                player.AdditionaInformations.Kills,
                                player.AdditionaInformations.Deaths,
                                player.AdditionaInformations.Assists
                            );

                        outputStream.Close ();
                    }

                }
            }
        }
Exemplo n.º 13
0
		public static void Main(string[] args)
		{

			using (var input = File.OpenRead(args[0])) {
				var parser = new DemoParser(input);
				
				parser.ParseHeader ();

				#if DEBUG
				Dictionary<Player, int> failures = new Dictionary<Player, int>();
				parser.TickDone += (sender, e) => {
					//Problem: The HP coming from CCSPlayerEvent are sent 1-4 ticks later
					//I guess this is because the think()-method of the CCSPlayerResource isn't called
					//that often. Haven't checked though.
					foreach(var p in parser.PlayingParticipants)
					{
						//Make sure the array is never empty ;)
						failures[p] = failures.ContainsKey(p) ? failures[p] : 0;

						if(p.HP == p.AdditionaInformations.ScoreboardHP)
							failures[p] = 0;
						else
							failures[p]++; //omg this is hacky. 

						//Okay, if it's wrong 2 seconds in a row, something's off
						//Since there should be a tick where it's right, right?
						//And if there's something off (e.g. two players are swapped)
						//there will be 2 seconds of ticks where it's wrong
						//So no problem here :)
						Debug.Assert(
							failures[p] < parser.TickRate * 2, 
							string.Format(
								"The player-HP({0}) of {2} (Clan: {3}) and it's Scoreboard HP ({1}) didn't match for {4} ticks. ", 
								p.HP, p.AdditionaInformations.ScoreboardHP, p.Name, p.AdditionaInformations.Clantag, parser.TickRate * 2
							)
						);

					}
				};

				

				if (args.Length >= 2) {
					// progress reporting requested
					using (var progressFile = File.OpenWrite(args[1]))
					using (var progressWriter = new StreamWriter(progressFile) { AutoFlush = false }) {
						int lastPercentage = -1;
						while (parser.ParseNextTick()) {
							var newProgress = (int)(parser.ParsingProgess * 100);
							if (newProgress != lastPercentage) {
								progressWriter.Write(lastPercentage = newProgress);
								progressWriter.Flush();
							}
						}
					}

					return;
				}
				#endif
				
				parser.ParseToEnd();
			}
		}
Exemplo n.º 14
0
        static void parseDemo(FileStream fileStream, string fileName, int matchStartEventNumber)
        {
            using (var parser = new DemoParser(fileStream))
            {
                string demoName = Path.GetFileName(fileName);
                // So now we've initialized a demo-parser.
                // let's parse the head of the demo-file to get which map the match is on!
                // this is always the first step you need to do.
                parser.ParseHeader();

                // and now, do some magic: grab the match!
                string map = parser.Map;

                // And now, generate the filename of the resulting file
                string output_roundResults = fileName + "_roundResults.csv";
                string output_killEvents = fileName + "_killEvents.csv";
                string output_matchResults = fileName + "_matchResults.csv";
                /*string output_smokeNades = fileName + "_smokeNades.csv";
                string output_fireNades = fileName + "_fireNades.csv";
                string output_flashNades = fileName + "_flashNades.csv";
                string output_decoyNades = fileName + "_decoyNades.csv";
                string output_heNades = fileName + "_heNades.csv";*/
                // and open it.
                var outputStream_roundResults = new StreamWriter(output_roundResults, false, Encoding.UTF8);
                var outputStream_killEvents = new StreamWriter(output_killEvents, false, Encoding.UTF8);
                var outputStream_matchResults = new StreamWriter(output_matchResults, false, Encoding.UTF8);
                /*var outputStream_smokeNades = new StreamWriter(output_smokeNades, false, Encoding.UTF8);
                var outputStream_fireNades = new StreamWriter(output_fireNades, false, Encoding.UTF8);
                var outputStream_flashNades = new StreamWriter(output_flashNades, false, Encoding.UTF8);
                var outputStream_decoyNades = new StreamWriter(output_decoyNades, false, Encoding.UTF8);
                var outputStream_heNades = new StreamWriter(output_heNades, false, Encoding.UTF8);*/

                //And write a header so you know what is what in the resulting file
                //outputStream.WriteLine(GenerateCSVHeader());

                int ctStartroundMoney = 0, tStartroundMoney = 0, ctEquipValue = 0, tEquipValue = 0, ctSaveAmount = 0, tSaveAmount = 0;
                int numberOfEventsMatchStarted = 0;
                int roundNumber = 0;

                List<String> ctWeapons = new List<String>();
                List<String> tWeapons = new List<String>();

                float ctWay = 0, tWay = 0;

                bool teamsSwap = false;

                int CTScore = 0;
                int TScore = 0;

                int defuses = 0;
                int plants = 0;

                string firstRoundWinner = "";
                string lastRoundWinner = "";

                Dictionary<Player, int> killsThisRound = new Dictionary<Player, int>();

                // Since most of the parsing is done via "Events" in CS:GO, we need to use them.
                // So you bind to events in C# as well.

                // AFTER we have bound the events, we start the parser!

                parser.MatchStarted += (sender, e) =>
                {
                    numberOfEventsMatchStarted++;
                };

                parser.PlayerKilled += (object sender, PlayerKilledEventArgs e) =>
                {

                    if (numberOfEventsMatchStarted!=matchStartEventNumber)
                        return;

                    //the killer is null if you're killed by the world - eg. by falling
                    if (e.Killer != null)
                    {
                        if (!killsThisRound.ContainsKey(e.Killer))
                            killsThisRound[e.Killer] = 0;

                        //Remember how many kills each player made this rounds
                        try
                        {
                            killsThisRound[e.Killer]++;
                            string killerSteamID = e.Killer.SteamID.ToString();
                            Vector killerPosition = e.Killer.Position;
                            string killingWeapon = e.Weapon.Weapon.ToString();
                            bool isHeadshot = e.Headshot;
                            int penetratedObjects = e.PenetratedObjects;
                            string victimSteamID = e.Victim.SteamID.ToString();
                            Vector victimPosition = e.Victim.Position;
                            PrintKillEvent(parser, outputStream_killEvents, demoName, map, killerSteamID, killerPosition, killingWeapon, isHeadshot, penetratedObjects, victimSteamID, victimPosition);
                        }
                        catch (Exception)
                        {
                            return;
                        }
                    }
                };

                parser.RoundStart += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;
                    //How much money had each team at the start of the round?
                    ctStartroundMoney = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).Sum(a => a.Money);
                    tStartroundMoney = parser.Participants.Where(a => a.Team == Team.Terrorist).Sum(a => a.Money);

                    //And how much they did they save from the last round?
                    ctSaveAmount = parser.Participants.Where(a => a.Team == Team.CounterTerrorist && a.IsAlive).Sum(a => a.CurrentEquipmentValue);
                    tSaveAmount = parser.Participants.Where(a => a.Team == Team.Terrorist && a.IsAlive).Sum(a => a.CurrentEquipmentValue);

                    //And let's reset those statistics
                    ctWay = 0; tWay = 0;
                    plants = 0; defuses = 0;
                    ctWeapons = new List<String>();
                    tWeapons = new List<String>();

                    killsThisRound.Clear();
                };

                parser.FreezetimeEnded += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    // At the end of the freezetime (when players can start walking)
                    // calculate the equipment value of each team!
                    ctEquipValue = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).Sum(a => a.CurrentEquipmentValue);
                    List<Player> ctPLayers = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).ToList();
                    tEquipValue = parser.Participants.Where(a => a.Team == Team.Terrorist).Sum(a => a.CurrentEquipmentValue);
                    List<Player> tPLayers = parser.Participants.Where(a => a.Team == Team.Terrorist).ToList();

                    foreach (Player p in ctPLayers)
                    {
                        foreach (Equipment e2 in p.Weapons)
                            ctWeapons.Add(e2.Weapon.ToString());
                        ctWeapons.Add("END");
                    }
                    foreach (Player p in tPLayers)
                    {
                        foreach (Equipment e2 in p.Weapons)
                            tWeapons.Add(e2.Weapon.ToString());
                        tWeapons.Add("END");
                    }
                };

                parser.BombPlanted += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    plants++;
                };

                /*parser.SmokeNadeStarted += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    Vector nadePosition = e.Position;
                    PrintSmokeEvent(parser, outputStream_smokeNades, demoName, map, nadePosition);

                };

                parser.FireNadeStarted += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    Vector nadePosition = e.Position;
                    PrintFireNadeEvent(parser, outputStream_fireNades, demoName, map, nadePosition);

                };

                parser.FlashNadeExploded += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    Vector nadePosition = e.Position;
                    PrintFlashNadeEvent(parser, outputStream_flashNades, demoName, map, nadePosition);

                };

                parser.DecoyNadeStarted += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    Vector nadePosition = e.Position;
                    PrintDecoyNadeEvent(parser, outputStream_decoyNades, demoName, map, nadePosition);

                };

                parser.ExplosiveNadeExploded += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    Vector nadePosition = e.Position;
                    PrintHeNadeExplosionEvent(parser, outputStream_heNades, demoName, map, nadePosition);

                };*/

                parser.BombDefused += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    defuses++;
                };

                parser.LastRoundHalf += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    teamsSwap = true;

                };

                parser.TickDone += (sender, e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                        return;

                    // Okay, let's measure how far each team travelled.
                    // As you might know from school the amount walked
                    // by a player is the sum of it's velocities

                    foreach (var player in parser.PlayingParticipants)
                    {
                        // We multiply it by the time of one tick
                        // Since the velocity is given in
                        // ingame-units per second
                        float currentWay = (float)(player.Velocity.Absolute * parser.TickTime);

                        // This is just an example of what kind of stuff you can do
                        // with this parser.
                        // Of course you could find out who makes the most footsteps, and find out
                        // which player ninjas the most - just to give you an example

                        if (player.Team == Team.CounterTerrorist)
                            ctWay += currentWay;
                        else if (player.Team == Team.Terrorist)
                            tWay += currentWay;
                    }
                };

                //So now lets do some fancy output
                parser.RoundEnd += (object sender, RoundEndedEventArgs e) =>
                {
                    if (numberOfEventsMatchStarted != matchStartEventNumber)
                    {
                        return;
                    }

                    roundNumber++;

                    // We do this in a method-call since we'd else need to duplicate code
                    // The much parameters are there because I simply extracted a method
                    // Sorry for this - you should be able to read it anywys :)
                    string winningFaction = e.Winner.ToString();

                    if (roundNumber == 1)
                    {
                        if (winningFaction.Equals("CounterTerrorist"))
                        {
                            firstRoundWinner = parser.CTClanName;
                        }
                        if (winningFaction.Equals("Terrorist"))
                        {
                            firstRoundWinner = parser.TClanName;
                        }
                    }

                    if (winningFaction.Equals("CounterTerrorist"))
                    {
                        CTScore++;
                        lastRoundWinner = parser.CTClanName;
                    }
                    if (winningFaction.Equals("Terrorist"))
                    {
                        lastRoundWinner = parser.TClanName;
                        TScore++;
                    }

                    PrintRoundResults(parser, outputStream_roundResults, demoName, map, CTScore, TScore, ctStartroundMoney, tStartroundMoney, ctEquipValue, tEquipValue, ctSaveAmount, tSaveAmount, ctWay, tWay, defuses, plants, killsThisRound, winningFaction, ctWeapons, tWeapons);

                    if (teamsSwap)
                    {
                        teamsSwap = false;
                        int tempCTscore = CTScore;
                        int tempTscore = TScore;
                        CTScore = tempTscore;
                        TScore = tempCTscore;
                    }

                };

                //Now let's parse the demo!
                parser.ParseToEnd();

                PrintMatchResults(parser, outputStream_matchResults, demoName, map, parser.CurrentTime, parser.Header.ClientName, parser.Header.NetworkProtocol, parser.Header.Protocol, parser.Header.SignonLength, parser.Header.PlaybackTime, firstRoundWinner, lastRoundWinner);

                outputStream_roundResults.Close();
                outputStream_killEvents.Close();
                outputStream_matchResults.Close();
               /* outputStream_smokeNades.Close();
                outputStream_fireNades.Close();
                outputStream_flashNades.Close();
                outputStream_decoyNades.Close();
                outputStream_heNades.Close();*/
            }
        }
        public static void GenerateScoreboards(DemoParser parser)
        {
            int i = 0;

            parser.ParseHeader ();

            Console.WriteLine ("map: " + parser.Map);

            int roundEndedCount = 0;

            parser.RoundEnd += (object sender, RoundEndedEventArgs e) => {
                // The reason I'm doing this after tick_done is that
                // entity-updates only come in the same tick as round_end
                // comes, meaning the score-update might not be transmitted yet
                // which would be sad - we always want the current score!
                // so we wait 1 second.

                roundEndedCount = 1;
            };

            parser.TickDone += (object sender, TickDoneEventArgs e) => {
                if(roundEndedCount == 0)
                    return;

                roundEndedCount ++;

                // Wait twice the tickrate of the demo (~2 seconds) to make sure the
                // screen has been updated. I *LOVE* demo files :)
                if(roundEndedCount < parser.TickRate * 2) {
                    return;
                }

                roundEndedCount = 0;

                Console.WriteLine ("------------------------------------------------------------");

                Console.WriteLine ("Round {0}, CT: {1}, T: {2}", ++i, parser.CTScore, parser.TScore);

                Console.WriteLine("Ts\t" + parser.TClanName);
                Console.WriteLine("Tag\tName\tSteamID\tKills\tDeaths\tAssists\tScore\t");
                foreach(var player in parser.PlayingParticipants.Where(a => a.Team == Team.Terrorist))
                    Console.WriteLine (
                        "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}",
                        player.AdditionaInformations.Clantag,
                        player.Name, player.SteamID,
                        player.AdditionaInformations.Kills,
                        player.AdditionaInformations.Deaths,
                        player.AdditionaInformations.Assists,
                        player.AdditionaInformations.Score
                    );

                Console.WriteLine("CTs\t" + parser.CTClanName);
                Console.WriteLine("Tag\tName\tSteamID\tKills\tDeaths\tAssists\tScore\t");
                foreach(var player in parser.PlayingParticipants.Where(a => a.Team == Team.CounterTerrorist))
                    Console.WriteLine (
                        "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}",
                        player.AdditionaInformations.Clantag,
                        player.Name, player.SteamID,
                        player.AdditionaInformations.Kills,
                        player.AdditionaInformations.Deaths,
                        player.AdditionaInformations.Assists,
                        player.AdditionaInformations.Score
                    );

                Console.WriteLine ();

            };

            parser.ParseToEnd ();
        }
Exemplo n.º 16
0
        static void Main(string[] args)
        {
            if (args.Length == 0 || args[0] == "-help")
            {
                DisplayHelp();
                return;
            }

            /*
             * One argument per demofile, thus we iterate over all of them
             * > generator.exe demo1.dem demo2.dem
             */
            foreach (var fileName in args)
            {
                /*
                 * Initializing DemoParser with fileStream needs to be done
                 * with "using". Orig.Author warned about memoryleaks if we
                 * do not dispose fileStream / DemoParser.
                 */
                using (var fileStream = File.OpenRead(fileName))
                {
                    Console.WriteLine("Beginning parsing of " +fileName);
                    using (var parser = new DemoParser(fileStream)){
                        /*
                         * After initialization, always parse demoheader
                         * Create outPutFile&Stream
                         * Create CSVHeader for outPutFile
                         */
                        parser.ParseHeader();
                        DateTime timenow = DateTime.Now;

                        string map = parser.Map;
                        string outPutFileName = timenow.ToString("d") + "." + map + ".csv";
                        var outPutStream = new StreamWriter(outPutFileName);
                        outPutStream.WriteLine(GenerateCSVHeader());

                        /*
                         * Let's get srated on analyzing demo
                         * According to DemoInfo author, CSGO
                         * is mainly based on events. Therefore
                         * we use binding and event driven programing
                         * to do our bidding.
                         */

                        bool hasMatchStarted = false;
                        List<Player> ingame = new List<Player>();
                        Dictionary<Player, List<double>> dicPlayerFiredVelocity = new Dictionary<Player, List<double>>();
                        parser.MatchStarted += (sender, e) =>
                        {
                            hasMatchStarted = true;
                            ingame.AddRange(parser.PlayingParticipants);
                        };

                        parser.RoundStart += (sender, e) =>
                        {
                            if (!hasMatchStarted) { return; }
                            dicPlayerFiredVelocity.Clear();

                        };
                        /*
                         * Event WeaponFired has 2 parameters,
                         * Shooter(Player) & Weapon(Weapon)
                         */
                        parser.WeaponFired += (sender, e) =>
                        {
                            if (hasMatchStarted)
                            {
                                if (dicPlayerFiredVelocity.ContainsKey(e.Shooter))
                                {
                                    dicPlayerFiredVelocity[e.Shooter].Add(e.Shooter.Velocity.Absolute);

                                }
                                else
                                {
                                    dicPlayerFiredVelocity.Add(e.Shooter, new List<double> { e.Shooter.Velocity.Absolute });
                                }
                            }
                        };

                        /*
                         * On roundEnd, print information to
                         * outputstream
                         */
                        parser.RoundEnd += (sender, e) =>
                        {
                            if (!hasMatchStarted) { return; }
                            OutPutStreamRoundResults(parser, outPutStream, dicPlayerFiredVelocity);
                        };

                        /*
                         * Call this after binding events
                         * Parses demofile to the end.
                         * Remember to close StreamWriter.
                         */

                        parser.ParseToEnd();
                        outPutStream.Close();
                    }
                }
            }
        }
        public static void DoStuff(string[] args)
        {
            foreach (var fileName in args) {
                using (var fileStream = File.OpenRead (fileName)) {
                    Console.WriteLine ("Parsing demo " + fileName);
                    using (var parser = new DemoParser (fileStream)) {
                        parser.ParseHeader ();
                        string map = parser.Map, outputFileName = fileName + "." + map + ".csv";
                        var outputStream = new StreamWriter (outputFileName);
                        bool hasMatchStarted = false;
                        int ctStartroundMoney = 0, tStartroundMoney = 0, ctEquipValue = 0, tEquipValue = 0, ctSaveAmount = 0, tSaveAmount = 0;
                        float ctWay = 0, tWay = 0;
                        int defuses = 0;
                        int plants = 0;
                        Dictionary<Player, int> killsThisRound = new Dictionary<Player, int> ();

                        parser.MatchStarted += (sender, e) => {
                            hasMatchStarted = true;
                        };

                        parser.PlayerKilled += (object sender, PlayerKilledEventArgs e) => {
                            if(e.Killer != null) {
                                if(!killsThisRound.ContainsKey(e.Killer))
                                    killsThisRound[e.Killer] = 0;
                                killsThisRound[e.Killer]++;
                            }
                        };

                        parser.RoundStart += (sender, e) => {
                            if(!hasMatchStarted)
                                return;
                            ctStartroundMoney = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).Sum(a => a.Money);
                            tStartroundMoney = parser.Participants.Where(a => a.Team == Team.Terrorist).Sum(a => a.Money);
                            ctSaveAmount = parser.Participants.Where(a => a.Team == Team.CounterTerrorist && a.IsAlive).Sum(a => a.CurrentEquipmentValue);
                            tSaveAmount = parser.Participants.Where(a => a.Team == Team.Terrorist && a.IsAlive).Sum(a => a.CurrentEquipmentValue);
                            ctWay = 0; tWay = 0;
                            plants = 0; defuses = 0;
                            killsThisRound.Clear();
                        };

                        parser.FreezetimeEnded += (sender, e) => {
                            if(!hasMatchStarted)
                                return;
                            ctEquipValue = parser.Participants.Where(a => a.Team == Team.CounterTerrorist).Sum(a => a.CurrentEquipmentValue);
                            tEquipValue = parser.Participants.Where(a => a.Team == Team.Terrorist).Sum(a => a.CurrentEquipmentValue);
                        };

                        parser.BombPlanted += (sender, e) => {
                            if(!hasMatchStarted)
                                return;
                            plants++;
                        };

                        parser.BombDefused += (sender, e) => {
                            if(!hasMatchStarted)
                                return;
                            defuses++;
                        };

                        parser.TickDone += (sender, e) => {
                            if(!hasMatchStarted)
                                return;
                            foreach(var player in parser.PlayingParticipants)
                            {
                                float currentWay = (float)(player.Velocity.Absolute * parser.TickTime);
                                if(player.Team == Team.CounterTerrorist)
                                    ctWay += currentWay;
                                else if(player.Team == Team.Terrorist)
                                    tWay += currentWay;
                            }
                        };

                        parser.RoundEnd += (sender, e) => {
                            if(!hasMatchStarted)
                                return;
                            PrintRoundResults (parser, outputStream, ctStartroundMoney, tStartroundMoney, ctEquipValue, tEquipValue, ctSaveAmount, tSaveAmount, ctWay, tWay, defuses, plants, killsThisRound);
                        };

                        parser.ParseToEnd ();
                        PrintRoundResults (parser, outputStream, ctStartroundMoney, tStartroundMoney, ctEquipValue, tEquipValue, ctSaveAmount, tSaveAmount, ctWay, tWay, defuses, plants, killsThisRound);
                        outputStream.Close ();
                    }
                }
            }
        }