예제 #1
0
    private void StartParseThread(string filePath)
    {
        using (var filestream = File.OpenRead(filePath))
        {
            using (var parser = new DemoParser(filestream))
            {
                parser.HeaderParsed       += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnHeaderParsed, s, e, "header PArsed"));
                parser.RoundOfficiallyEnd += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnRoundEnd, s, e, "rounf official end"));
                parser.RoundStart         += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnRoundStart, s, e, "round start"));
                parser.PlayerTeam         += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnPlayerTeam, s, e, "Player team"));
                parser.SmokeNadeStarted   += (s, e) => _parsingEventsQueue.Enqueue(new ParserEvent <object>(_eventsHandler.OnSmokeNadeStarted, s, e));
                parser.MatchStarted       += (s, e) => MatchStarted = true;
                parser.WeaponFired        += _eventsHandler.OnWeaponFired;
                parser.PlayerHurt         += _eventsHandler.OnPlayerHurt;
                parser.TickDone           += _eventsHandler.OnTickDone;

                parser.ParseHeader();
                parser.ParseToEnd();

                OnParsingComplete();

                Thread.CurrentThread.Abort();
            }
        }
    }
예제 #2
0
    /// <summary>
    /// Parses the replay till the matchHasStarted event occurs
    /// Initializes game-specific info
    /// </summary>
    /// <returns>true if it successully ran through</returns>
    public bool ParseToMatchStart()
    {
        using (var fileStream = File.OpenRead(_filePath))
        {
            using (DemoParser parser = new DemoParser(fileStream))
            {
                parser.ParseHeader();
                Map        = parser.Header.MapName;
                _matchTime = parser.Header.PlaybackTime;

                CancellationTokenSource tokenSource = new CancellationTokenSource();
                CancellationToken       token       = tokenSource.Token;

                parser.MatchStarted += (sender, e) =>
                {
                    Counterterrorists = parser.PlayingParticipants.Where(a => a.Team == Team.CounterTerrorist).ToArray();
                    Terrorists        = parser.PlayingParticipants.Where(a => a.Team == Team.Terrorist).ToArray();

                    Terrorists.CopyTo(Players, 0);
                    Counterterrorists.CopyTo(Players, 5);

                    tokenSource.Cancel();
                };
                parser.ParseToEnd(token);
            }

            return(true);
        }
    }
예제 #3
0
        public void Start()
        {
            MatchData = new Match();

            using (var compressedStream = _matchInformation != null ? Helpers.GetStreamFromUrl(_matchInformation.roundstats.map) : replayStream)
                using (var outputStream = new MemoryStream())
                {
                    if (replayCompressed)
                    {
                        BZip2.Decompress(compressedStream, outputStream, false);
                        outputStream.Seek(0L, SeekOrigin.Begin);
                        parser = new DemoParser(outputStream);
                    }
                    else
                    {
                        parser = new DemoParser(compressedStream);
                    }

                    parser.MatchStarted += MatchStarted_Event;
                    parser.ParseHeader();
                    parser.ParseToEnd();

                    MatchEnded_Event();
                }
        }
예제 #4
0
 public void rifleKill(Player killer, DemoParser parser)
 {
     if (getWeaponType(killer.ActiveWeapon.Weapon) == 0)
     {
         playerData[killer.SteamID].addNumber(parser.Map, PlayerData.STAT.RIFLE_FRAG, killer.Team, 1);
     }
 }
예제 #5
0
        public void Parse(IBitStream bitstream, DemoParser parser)
        {
            while (!bitstream.ChunkFinished)
            {
                var desc     = bitstream.ReadProtobufVarInt();
                var wireType = desc & 7;
                var fieldnum = desc >> 3;

                if (wireType == 2 && fieldnum == 1)
                {
                    Name = bitstream.ReadProtobufString();
                }
                else if (wireType == 2 && fieldnum == 2)
                {
                    Value = bitstream.ReadProtobufString();
                }
                else if (wireType == 0 && fieldnum == 3)
                {
                    DictionaryName = (uint)bitstream.ReadProtobufVarInt();
                }
                else
                {
                    throw new InvalidDataException();
                }
            }

            Raise(parser);
        }
예제 #6
0
        public void Parse(IBitStream bitstream, DemoParser parser)
        {
            while (!bitstream.ChunkFinished)
            {
                var desc     = bitstream.ReadProtobufVarInt();
                var wireType = desc & 7;
                var fieldnum = desc >> 3;

                if (wireType == 0 && fieldnum == 1)
                {
                    AccountId = bitstream.ReadProtobufVarInt();
                }
                else if (wireType == 0 && fieldnum == 2)
                {
                    RankOld = bitstream.ReadProtobufVarInt();
                }
                else if (wireType == 0 && fieldnum == 3)
                {
                    RankNew = bitstream.ReadProtobufVarInt();
                }
                else if (wireType == 0 && fieldnum == 4)
                {
                    NumWins = bitstream.ReadProtobufVarInt();
                }
                else if (wireType == 5 && fieldnum == 5)
                {
                    RankChange = bitstream.ReadFloat();
                }
            }

            Raise(parser);
        }
예제 #7
0
        /// <summary>
        /// Decodes the bytes in the packet-entites message.
        /// </summary>
        /// <param name="packetEntities">Packet entities.</param>
        /// <param name="reader">Reader.</param>
        /// <param name="parser">Parser.</param>
        public static void Apply(PacketEntities packetEntities, IBitStream reader, DemoParser parser)
        {
            int currentEntity = -1;

            for (int i = 0; i < packetEntities.UpdatedEntries; i++)
            {
                //First read which entity is updated
                currentEntity += 1 + (int)reader.ReadUBitInt();

                //Find out whether we should create, destroy or update it.
                // Leave flag
                if (!reader.ReadBit())
                {
                    // enter flag
                    if (reader.ReadBit())
                    {
                        //create it
                        var e = ReadEnterPVS(reader, currentEntity, parser);

                        parser.Entities[currentEntity] = e;

                        e.ApplyUpdate(reader);
                    }
                    else
                    {
                        if (currentEntity < 0 || currentEntity >= parser.Entities.Length)
                        {
                            return;
                        }
                        // preserve / update
                        Entity e = parser.Entities[currentEntity];
                        if (e == null)
                        {
                            return;
                        }

                        e.ApplyUpdate(reader);
                    }
                }
                else
                {
                    Entity e = parser.Entities[currentEntity];
                    if (e == null)
                    {
                        return;
                    }

                    e.ServerClass.AnnounceDestroyedEntity(e);

                    // leave / destroy
                    e.Leave();
                    parser.Entities[currentEntity] = null;

                    //dunno, but you gotta read this.
                    if (reader.ReadBit())
                    {
                    }
                }
            }
        }
예제 #8
0
    public void AddSmokeNadeEffect(DemoParser parser, SmokeEventArgs eventArgs)
    {
        if (!NadeEffectFrames.Any(n => n.Tick == parser.CurrentTick))
        {
            NadeEffectFrames.Add(new NadeEffectFrame()
            {
                Tick        = parser.CurrentTick,
                Round       = MatchInfoManager.Instance.Rounds.Last().Number,
                NadeEffects = new List <NadeEffect>()
            });
        }

        if (eventArgs.ThrownBy == null)
        {
            return;
        }

        var nadeEffect = new NadeEffect()
        {
            Guid     = Guid.NewGuid(),
            Duration = 18,
            Thrower  = eventArgs.ThrownBy.SteamID.ToString(),
            NadeType = EquipmentElement.Smoke,
            Position = (DemoInfoHelper.SourceToUnityVector(eventArgs.Position.Copy()) / GraphicsManager.PlaybackScale) - GraphicsManager.Instance.Map.Offset
        };

        NadeEffectFrames.Last().NadeEffects.Add(nadeEffect);
    }
예제 #9
0
        public void Parse(IBitStream bitstream, DemoParser parser)
        {
            while (!bitstream.ChunkFinished)
            {
                var desc     = bitstream.ReadProtobufVarInt();
                var wireType = desc & 7;
                var fieldnum = desc >> 3;
                if (wireType != 0)
                {
                    throw new InvalidDataException();
                }

                var val = (uint)bitstream.ReadProtobufVarInt();

                switch (fieldnum)
                {
                case 1:
                    Tick = val;
                    break;

                case 4:
                    HostComputationTime = val;
                    break;

                case 5:
                    HostComputationTimeStdDeviation = val;
                    break;

                case 6:
                    HostFramestartTimeStdDeviation = val;
                    break;
                }
            }
        }
예제 #10
0
        /// <summary>
        /// Read protobuf messages
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="parser"></param>
        public void ParsePacket(Stream stream, DemoParser parser)
        {
            var reader = new BinaryReader(stream);

            while (stream.Position < stream.Length)
            {
                int cmd = reader.ReadVarInt32();

                Type toParse = null;

                if (Enum.IsDefined(typeof(SVC_Messages), cmd))
                {
                    SVC_Messages msg = (SVC_Messages)cmd;
                    toParse = MessagesCSVC["DemoParser_Core.Messages.CSVCMsg_" + msg.ToString().Substring(4)];
                }
                else if (Enum.IsDefined(typeof(NET_Messages), cmd))
                {
                    NET_Messages msg = (NET_Messages)cmd;
                    toParse = MessagesCNET["DemoParser_Core.Messages.CNETMsg_" + msg.ToString().Substring(4)];
                }
                else
                {
                    reader.ReadBytes(reader.ReadVarInt32());
                    continue;
                }

                IExtensible message = reader.ReadProtobufMessage(toParse, ProtoBuf.PrefixStyle.Base128);

                //This method apply message only to Handler able to deal with that type of message
                if (ParseType.ContainsKey(toParse))
                {
                    ParseType[toParse].TryApplyMessage(message, parser);
                }
            }
        }
예제 #11
0
 public void sniperKill(Player killer, DemoParser parser)
 {
     if (getWeaponType(killer.ActiveWeapon.Weapon) == 2)
     {
         playerData[killer.SteamID].addNumber(parser.Map, PlayerData.STAT.SNIPER_FRAG, killer.Team, 1);
     }
 }
예제 #12
0
        public void ParseStringTable(IBitStream reader, string tableName, DemoParser parser)
        {
            var numStrings = (int)reader.ReadInt(16);

            if (tableName == "modelprecache")
            {
                parser.modelprecache.Clear();
            }

            for (var i = 0; i < numStrings; i++)
            {
                var stringName = reader.ReadString();

                if (stringName.Length >= 100)
                {
                    throw new Exception("Roy said I should throw this.");
                }

                if (reader.ReadBit())
                {
                    var userDataSize = (int)reader.ReadInt(16);

                    var data = reader.ReadBytes(userDataSize);

                    if (tableName == "userinfo")
                    {
                        var info = PlayerInfo.ParseFrom(new BinaryReader(new MemoryStream(data)));

                        parser.RawPlayers[int.Parse(stringName)] = info;
                    }
                    else if (tableName == "instancebaseline")
                    {
                        var classid = int.Parse(stringName); //wtf volvo?

                        parser.instanceBaseline[classid] = data;
                    }
                    else if (tableName == "modelprecache")
                    {
                        parser.modelprecache.Add(stringName);
                    }
                }
            }

            // Client side stuff
            if (reader.ReadBit())
            {
                var numstrings = (int)reader.ReadInt(16);
                for (var i = 0; i < numstrings; i++)
                {
                    reader.ReadString(); // stringname

                    if (reader.ReadBit())
                    {
                        var userDataSize = (int)reader.ReadInt(16);

                        reader.ReadBytes(userDataSize);
                    }
                }
            }
        }
        private static Entity ReadEnterPVS(IBitStream reader, int id, DemoParser parser)
        {
            int serverClassID = (int)reader.ReadInt(parser.SendTableParser.ClassBits);

            ServerClass entityClass = parser.SendTableParser.ServerClasses[serverClassID];

            reader.ReadInt(10); //Entity serial.

            Entity newEntity = new Entity(id, entityClass);

            newEntity.ServerClass.AnnounceNewEntity(newEntity);

            object[] fastBaseline;
            if (parser.PreprocessedBaselines.TryGetValue(serverClassID, out fastBaseline))
            {
                PropertyEntry.Emit(newEntity, fastBaseline);
            }
            else
            {
                var preprocessedBaseline = new List <object>();
                if (parser.instanceBaseline.ContainsKey(serverClassID))
                {
                    using (var collector = new PropertyCollector(newEntity, preprocessedBaseline))
                        using (var bitStream = BitStreamUtil.Create(parser.instanceBaseline[serverClassID]))
                            newEntity.ApplyUpdate(bitStream);
                }

                parser.PreprocessedBaselines.Add(serverClassID, preprocessedBaseline.ToArray());
            }

            return(newEntity);
        }
예제 #14
0
 private static void InitDemo()
 {
     demoParser           = new DemoParser(File.OpenRead("pov_qwerty.dem"));
     demoParser.TickDone += parser_TickDone;
     demoParser.ParseHeader();
     demoParser.ParseToEnd();
 }
예제 #15
0
 public void pistolKill(Player killer, DemoParser parser)
 {
     if (getWeaponType(killer.ActiveWeapon.Weapon) == 3)
     {
         playerData[killer.SteamID].addNumber(parser.Map, PlayerData.STAT.PISTOL_FRAG, killer.Team, 1);
     }
 }
예제 #16
0
        private void ParseDemo(FileStream file)
        {
            _parser = new DemoParser(file);
            _parser.ParseHeader();
            _parser.MatchStarted    += Parser_MatchStarted;
            _parser.RoundStart      += Parser_RoundStart;
            _parser.PlayerKilled    += Parser_PlayerKilled;
            _parser.RoundEnd        += Parser_RoundEnd;
            _parser.TickDone        += Parser_TickDone;
            _parser.BombPlanted     += Parser_BombPlanted;
            _parser.BombDefused     += Parser_BombDefused;
            _parser.BombExploded    += Parser_BombExploded;
            _parser.PlayerBind      += Parser_PlayerBind;
            _parser.FreezetimeEnded += Parser_FreezetimeEnded;
            _parser.PlayerHurt      += Parser_PlayerHurt;

            _progress.Report($"Parse file: \"{_demoFileName}\" Size: {new FileInfo(file.Name).Length.ToSize(LongExtension.SizeUnits.MB)}Mb");

            var sw = new Stopwatch();

            sw.Start();
            _parser.ParseToEnd();
            sw.Stop();

            MatchFinish();

            _progress.Report($"It took: {sw.Elapsed:mm':'ss':'fff}");
        }
예제 #17
0
        public void AnalyzeNewGame(string path)
        {
            GameInfo g = new GameInfo();

            using (var fileStream = File.OpenRead(path)) {
                using (var demo = new DemoParser(fileStream)) {
                    g.ParseHeader(demo);

                    List <string> TeamNames = g.GetTeamNames(demo);

                    string Team1 = TeamNames[0];
                    string Team2 = TeamNames[1];

                    // First we need to check if the map is the right type and from the right team
                    if (g.GetMapName(demo) == null || (!g.GetMapName(demo).Equals(MapName) || !g.CheckTeamName(demo, TeamName)))
                    {
                        Console.WriteLine("{0} vs {1} could not be analyzed. Map : {2} {3}", Team1, Team2, g.GetMapName(demo), MapName);
                        return;
                    }

                    Console.WriteLine("{0} vs {1} is currently being analyzed", Team1, Team2);
                }
            }


            using (var fileStream = File.OpenRead(path)) {
                using (var demo = new DemoParser(fileStream)) {
                    g.ParseGame(demo);
                    AllGames.Add(g);
                }
            }
        }
예제 #18
0
        private void addPlayers(String fileName)
        {
            var parser = new DemoParser(File.OpenRead(fileName));

            parser.ParseHeader();
            int count = 0;

            while (count < 10)
            {
                for (int i = 0; i < 100; i++)
                {
                    parser.ParseNextTick();
                }
                count = 0;
                foreach (var p in parser.PlayingParticipants)
                {
                    count++;
                }
            }
            List <long> tempList = new List <long>();

            foreach (var player in parser.PlayingParticipants)
            {
                tempList.Add(player.SteamID);
            }
            playersInFile.Add(fileName, tempList);
        }
예제 #19
0
        public void Parse(IBitStream bitstream, DemoParser parser)
        {
            while (!bitstream.ChunkFinished)
            {
                var desc     = bitstream.ReadProtobufVarInt();
                var wireType = desc & 7;
                var fieldnum = desc >> 3;

                if (wireType == 0 && fieldnum == 1)
                {
                    EntityIndex = bitstream.ReadProtobufVarInt();
                }
                else if (wireType == 2 && fieldnum == 2)
                {
                    Text = bitstream.ReadProtobufString();
                }
                else if (wireType == 0 && fieldnum == 3)
                {
                    _chat = bitstream.ReadProtobufVarInt();
                }
                else if (wireType == 0 && fieldnum == 4)
                {
                    _textAllChat = bitstream.ReadProtobufVarInt();
                }
                else
                {
                    throw new InvalidDataException();
                }
            }
            Raise(parser);
        }
예제 #20
0
        private void OpenMenuItem_Click(object sender, RoutedEventArgs e)
        {
            Reset();

            var ofd = new OpenFileDialog();

            ofd.Filter = "Demo files (*.dem)|*.dem";

            if (ofd.ShowDialog(this) == true)
            {
                using (var parser = new DemoParser(ofd.OpenFile()))
                {
                    parser.ParseHeader();

                    try
                    {
                        _demo.Parse(parser);
                    }
                    catch (DemoDataException ex)
                    {
                        MessageBox.Show($"Failed to load demo: {ex.Message}", "Unable to load demo", MessageBoxButton.OK, MessageBoxImage.Error);
                    }

                    minimap.LoadMap(parser.Header.MapName);
                    timeline.Init(_demo.Rounds, _demo.LastTick);
                }
            }
        }
예제 #21
0
 public EseaAnalyzer(Demo demo)
 {
     Parser = new DemoParser(File.OpenRead(demo.Path));
     // Reset to have update on UI
     demo.ResetStats();
     Demo = demo;
     RegisterEvents();
 }
예제 #22
0
        public static DemoParser CsgoDemoParser(string file)
        {
            var csgodemo = new DemoParser(File.OpenRead(file));

            csgodemo.ParseHeader();
            csgodemo.ParseToEnd();
            return(csgodemo);
        }
예제 #23
0
 public Program()
 {
     db     = new DBConnection();
     parser = new DemoParser(File.OpenRead("test.dem"));
     //db.createTables();
     //in the end ex was kind of useless, but it was fun to play with.
     dataStreams = new DataStreamManager(parser);
 }
예제 #24
0
        public async Task <string> GetDemos(DateTime startTime, DateTime endTime)
        {
            if (_running)
            {
                return("Already getting demos!");
            }

            _runStartTime = DateTime.Now;
            _running      = true;

            //Get tags now, so they are in memory.
            _hubTags = await GetFaceHubTags();

            //Populate the matches list
            await GetMatches(startTime, endTime);

            if (_gameInfo.Count == 0)
            {
                var msg = "No matches were found on any endpoint!";
                await _log.LogMessage(msg);

                _running = false;
                return(msg);
            }

            //Start downloading the files and unzip
            await HandleMatchDemos();

            //Parse the demos
            await HandleDemoParsing();

            //Handle games after they are parsed
            await HandleParsedGames();

            //Handle heat map generation
            await HandleHeatmapGeneration();

            //Send the files to the uploader
            _uploadSuccessCount = await DemoParser.UploadFaceitDemosAndRadars(_uploadDictionary);

            //Delete the old .dem files, we don't need them anymore
            DeleteOldFiles();

            //Update the files on the website
            await UpdateWebsiteFiles();

            var report = await GetReport();

            if (report.Length > 1900)
            {
                report = report.Substring(0, 1900) + "\n`[OUTPUT TRUNCATED]`";
            }

            await _log.LogMessage(report);

            _running = false;
            return(report);
        }
예제 #25
0
		public EbotAnalyzer(Demo demo)
		{
			Parser = new DemoParser(File.OpenRead(demo.Path));
			// Reset to have update on UI
			demo.ResetStats();
			Demo = demo;
			RegisterEvents();
			IsMatchStarted = true;
		}
예제 #26
0
        private static void DemoTest1()
        {
            parser = new DemoParser(File.OpenRead("commu.dem"));

            parser.TickDone += parser_TickDone;

            parser.ParseHeader();
            parser.ParseToEnd();
        }
예제 #27
0
        private static void DemoTest()
        {
            parser = new DemoParser(File.OpenRead("match730_003317647861457354858_2030613425_135.dem"));

            parser.TickDone += parser_TickDone;

            parser.ParseHeader();
            parser.ParseToEnd();
        }
 /// <summary>
 /// Checks if the team we are looking for
 /// is one of the two teams playing
 /// </summary>
 /// <param name="parser"></param>
 /// <returns>true if the team we are looking for is in the game</returns>
 public bool CheckTeamName(DemoParser parser, string TeamName)
 {
     if (Team1.Equals(TeamName, StringComparison.InvariantCultureIgnoreCase) ||
         Team2.Equals(TeamName, StringComparison.InvariantCultureIgnoreCase))
     {
         return(true);
     }
     return(false);
 }
예제 #29
0
 private void DisposeDemoParser()
 {
     if (demoParser != null)
     {
         RemoveListeners(demoParser);
         demoParser.Dispose();
         demoParser = null;
     }
 }
 /// <summary>
 /// Get the name of the Teams.
 /// </summary>
 /// <param name="parser"></param>
 /// <returns></returns>
 public List <string> GetTeamNames(DemoParser parser)
 {
     Team1 = parser.TClanName;
     Team2 = parser.CTClanName;
     return(new List <string>()
     {
         Team1, Team2
     });
 }
예제 #31
0
		public void ParseStringTable(IBitStream reader, string tableName, DemoParser parser)
		{
            int numStrings = (int)reader.ReadInt(16);

			if (tableName == "modelprecache") {
				parser.modelprecache.Clear ();
			}

            for (int i = 0; i < numStrings; i++)
            {
                string stringName = reader.ReadString();

                if (stringName.Length >= 100)
                    throw new Exception("Roy said I should throw this.");

                if (reader.ReadBit())
                {
                    int userDataSize = (int)reader.ReadInt(16);

                    byte[] data = reader.ReadBytes(userDataSize);

					if (tableName == "userinfo") {
						PlayerInfo info = PlayerInfo.ParseFrom(new BinaryReader(new MemoryStream(data)));

						parser.RawPlayers[int.Parse(stringName)] = info;
					} else if (tableName == "instancebaseline") {
						int classid = int.Parse(stringName); //wtf volvo?

						parser.instanceBaseline[classid] = data; 
					} else if (tableName == "modelprecache") {
						parser.modelprecache.Add (stringName);
					}
                }
            }

            // Client side stuff
	        if ( reader.ReadBit() )
	        {
		        int numstrings = (int)reader.ReadInt(16);
		        for ( int i = 0 ; i < numstrings; i++ )
		        {
			        reader.ReadString(); // stringname

			        if ( reader.ReadBit() )
			        {
				        int userDataSize = ( int )reader.ReadInt(16);

				        reader.ReadBytes( userDataSize );

			        }
			        else
			        {
			        }
		        }
	        }
        }
예제 #32
0
		public void ParsePacket(IBitStream reader, DemoParser parser)
        {
			int numTables = reader.ReadByte();

			for (int i = 0; i < numTables; i++) {
				string tableName = reader.ReadString();

				ParseStringTable(reader, tableName, parser);
			}
        }
예제 #33
0
		public bool TryApplyMessage(ProtoBuf.IExtensible message, DemoParser parser)
		{
			CSVCMsg_UserMessage userMessage = message as CSVCMsg_UserMessage;
			if (userMessage == null)
				return false;

			var messageType = (Messages.ECstrike15UserMessages)userMessage.msg_type;
			// TODO: maybe, like, implement something here one day?
			//Problem: There is no real useful info here if I see it correcly. Sorry.
			return true;
		}
		public static void Apply(UpdateStringTable update, IBitStream reader, DemoParser parser)
		{
			CreateStringTable create = parser.stringTables[update.TableId];
			if (create.Name == "userinfo" || create.Name == "modelprecache" || create.Name == "instancebaseline") {
				/*
				 * Ignore updates for everything except the 3 used tables.
				 * Create a fake CreateStringTable message and parse it.
				 */
				create.NumEntries = update.NumChangedEntries;
				CreateStringTableUserInfoHandler.Apply(create, reader, parser);
			}
		}
예제 #35
0
		/// <summary>
		/// Parses a demo-packet. 
		/// </summary>
		/// <param name="bitstream">Bitstream.</param>
		/// <param name="demo">Demo.</param>
		public static void ParsePacket(IBitStream bitstream, DemoParser demo)
        {
			//As long as there is stuff to read
			while (!bitstream.ChunkFinished)
            {
				int cmd = bitstream.ReadProtobufVarInt(); //What type of packet is this?
				int length = bitstream.ReadProtobufVarInt(); //And how long is it?
				bitstream.BeginChunk(length * 8); //read length bytes
				if (cmd == (int)SVC_Messages.svc_PacketEntities) { //Parse packet entities
					new PacketEntities().Parse(bitstream, demo); 
				} else if (cmd == (int)SVC_Messages.svc_GameEventList) { //and all this other stuff
					new GameEventList().Parse(bitstream, demo);
				} else if (cmd == (int)SVC_Messages.svc_GameEvent) {
					new GameEvent().Parse(bitstream, demo);
				} else if (cmd == (int)SVC_Messages.svc_CreateStringTable) {
					new CreateStringTable().Parse(bitstream, demo);
				} else if (cmd == (int)SVC_Messages.svc_UpdateStringTable) {
					new UpdateStringTable().Parse(bitstream, demo);
				} else if (cmd == (int)NET_Messages.net_Tick) { //and all this other stuff
						new NETTick().Parse(bitstream, demo);
				} else {
					//You can use this flag to see what information the other packets contain, 
					//if you want. Then you can look into the objects. Has some advnatages, and some disdavantages (mostly speed), 
					//so we use our own lightning-fast parsing code. 
					#if SLOW_PROTOBUF 
					Type toParse = null;

					if (Enum.IsDefined(typeof(SVC_Messages), cmd)) {
						SVC_Messages msg = (SVC_Messages)cmd;
						toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CSVCMsg_" + msg.ToString().Substring(4));
					} else if (Enum.IsDefined(typeof(NET_Messages), cmd)) {
						NET_Messages msg = (NET_Messages)cmd;
						toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CNETMsg_" + msg.ToString().Substring(4));
					}

					var data = bitstream.ReadBytes(length);
					if (toParse == null)
						continue;

					ProtoBuf.IExtensible result;
					using (var memstream = new MemoryStream(data))
						result = memstream.ReadProtobufMessage(toParse);

					foreach (var parser in Parsers)
						if (parser.TryApplyMessage(result, demo) && (parser.Priority > 0))
							break;
					#endif
				}
				bitstream.EndChunk();
            }
        }
예제 #36
0
		/// <summary>
		/// Reads an update that occures when a new edict enters the PVS (potentially visible system)
		/// </summary>
		/// <returns>The new Entity.</returns>
        private static Entity ReadEnterPVS(IBitStream reader, int id, DemoParser parser)
        {
			//What kind of entity?
            int serverClassID = (int)reader.ReadInt(parser.SendTableParser.ClassBits);

			//So find the correct server class
            ServerClass entityClass = parser.SendTableParser.ServerClasses[serverClassID];

            reader.ReadInt(10); //Entity serial. 
			//Never used anywhere I guess. Every parser just skips this


			Entity newEntity = new Entity(id, entityClass);

			//give people the chance to subscribe to events for this
			newEntity.ServerClass.AnnounceNewEntity(newEntity);

			//And then parse the instancebaseline. 
			//basically you could call
			//newEntity.ApplyUpdate(parser.instanceBaseline[entityClass]; 
			//This code below is just faster, since it only parses stuff once
			//which is faster. 

			object[] fastBaseline;
			if (parser.PreprocessedBaselines.TryGetValue(serverClassID, out fastBaseline))
				PropertyEntry.Emit(newEntity, fastBaseline);
			else {
				var preprocessedBaseline = new List<object>();
				if (parser.instanceBaseline.ContainsKey(serverClassID))
					using (var collector = new PropertyCollector(newEntity, preprocessedBaseline))
					using (var bitStream = BitStreamUtil.Create(parser.instanceBaseline[serverClassID]))
						newEntity.ApplyUpdate(bitStream);

				parser.PreprocessedBaselines.Add(serverClassID, preprocessedBaseline.ToArray());
			}

            return newEntity;
        }
예제 #37
0
		/// <summary>
		/// Decodes the bytes in the packet-entites message. 
		/// </summary>
		/// <param name="packetEntities">Packet entities.</param>
		/// <param name="reader">Reader.</param>
		/// <param name="parser">Parser.</param>
		public static void Apply(PacketEntities packetEntities, IBitStream reader, DemoParser parser)
        {
			int currentEntity = -1;

			for (int i = 0; i < packetEntities.UpdatedEntries; i++) {

				//First read which entity is updated
				currentEntity += 1 + (int)reader.ReadUBitInt();

				//Find out whether we should create, destroy or update it. 
				// Leave flag
				if (!reader.ReadBit()) {
					// enter flag
					if (reader.ReadBit()) {
						//create it
						var e = ReadEnterPVS(reader, currentEntity, parser);

						parser.Entities[currentEntity] = e;

						e.ApplyUpdate(reader);
					} else {
						// preserve / update
						Entity e = parser.Entities[currentEntity];
						e.ApplyUpdate(reader);
					}
				} else {
					// leave / destroy
					parser.Entities [currentEntity].Leave ();
					parser.Entities[currentEntity] = null;

					//dunno, but you gotta read this. 
					if (reader.ReadBit()) {
					}
				}
			}
        }
예제 #38
0
		public bool TryApplyMessage(ProtoBuf.IExtensible message, DemoParser parser)
		{
			CSVCMsg_UserMessage userMessage = message as CSVCMsg_UserMessage;

			if (userMessage == null || !Enum.IsDefined(typeof(ECstrike15UserMessages), userMessage.msg_type))
				return false;

			ECstrike15UserMessages msg = (ECstrike15UserMessages)userMessage.msg_type;
			Type toParse = Assembly.GetExecutingAssembly().GetType("DemoInfo.Messages.CCSUsrMsg_" + msg.ToString().Substring(6));

			using (var memstream = new MemoryStream(userMessage.msg_data))
			{
				ProtoBuf.IExtensible data = memstream.ReadProtobufMessage(toParse);
				if (data != null)
				{
					switch (data.GetType().Name)
					{
						case "CCSUsrMsg_SayText":
							{
								SayTextEventArgs e = new SayTextEventArgs();
								CCSUsrMsg_SayText sayMsg = (CCSUsrMsg_SayText)data;
								e.Text = sayMsg.text;
								e.TextAllChat = sayMsg.textallchat;
								e.Chat = sayMsg.chat;
								parser.RaiseSayText(e);
								break;
							}
						case "CCSUsrMsg_SayText2":
							{
								SayText2EventArgs e = new SayText2EventArgs();
								CCSUsrMsg_SayText2 sayMsg = (CCSUsrMsg_SayText2)data;
								e.TextAllChat = sayMsg.textallchat;
								e.Chat = sayMsg.chat;

								// get the player who wrote the message
								foreach (KeyValuePair<int, Player> keyValuePair in parser.Players)
								{
									if (keyValuePair.Value.Name == sayMsg.@params[0])
									{
										e.Sender = parser.Players[keyValuePair.Key];
										break;
									}
								}

								// @params is a 4 length array but only 2 are used [0] = nickname [1] = message text
								e.Text = sayMsg.@params[0] + " : " + sayMsg.@params[1];
								parser.RaiseSayText2(e);
								break;
							}
						case "CCSUsrMsg_ServerRankUpdate":
							{
								ServerRankUpdateEventArgs e = new ServerRankUpdateEventArgs
								{
									RankStructList = new List<ServerRankUpdateEventArgs.RankStruct>()
								};

								CCSUsrMsg_ServerRankUpdate rankMsg = (CCSUsrMsg_ServerRankUpdate)data;

								foreach (CCSUsrMsg_ServerRankUpdate.RankUpdate rankUpdate in (rankMsg.rank_update))
								{
									ServerRankUpdateEventArgs.RankStruct rankStruct = new ServerRankUpdateEventArgs.RankStruct
									{
										New = rankUpdate.rank_new,
										Old = rankUpdate.rank_old,
										NumWins = rankUpdate.num_wins,
										RankChange = rankUpdate.rank_change,
										SteamId = rankUpdate.account_id + VALVE_MAGIC_NUMBER
									};
									e.RankStructList.Add(rankStruct);
								}

								parser.RaiseServerRankUpdate(e);

								break;
							}
						default:
							// TODO: maybe, like, implement something here one day?
							//Problem: There is no real useful info here if I see it correcly. Sorry.
							//var messageType = (Messages.ECstrike15UserMessages)userMessage.msg_type;
							return true;
					}
				}
				return false;
			}
		}
        public static void Apply(CreateStringTable table, IBitStream reader, DemoParser parser)
        {
			if (table.Name == "modelprecache") {
                while (parser.modelprecache.Count < table.MaxEntries) {
                    parser.modelprecache.Add(null);
                }
			}

			if (reader.ReadBit())
				throw new NotImplementedException("Encoded with dictionaries, unable to decode");

			int nTemp = table.MaxEntries;
			int nEntryBits = 0;
			while ((nTemp >>= 1) != 0)
				++nEntryBits;

			List<string> history = new List<string>();

			int lastEntry = -1;

			for (int i = 0; i < table.NumEntries; i++) {
				int entryIndex = lastEntry + 1;
				// d in the entity-index
				if (!reader.ReadBit()) {
					entryIndex = (int)reader.ReadInt(nEntryBits);
				}

				lastEntry = entryIndex;

				// Read the name of the string into entry.
				string entry = "";
				if (entryIndex < 0 || entryIndex >= table.MaxEntries) {
					throw new InvalidDataException("bogus string index");
				}

				if (reader.ReadBit()) {
					bool substringcheck = reader.ReadBit();

					if (substringcheck) {
						int index = (int)reader.ReadInt(5);
						int bytestocopy = (int)reader.ReadInt(5);

						entry = history[index].Substring(0, bytestocopy);

						entry += reader.ReadString(1024);
					} else {
						entry = reader.ReadString(1024);
					}
				}

				if (entry == null)
					entry = "";

				if (history.Count > 31)
					history.RemoveAt(0);

				history.Add(entry);

				// Read in the user data.
				byte[] userdata = new byte[0];
				if (reader.ReadBit()) {
					if (table.UserDataFixedSize) {
						userdata = reader.ReadBits(table.UserDataSizeBits);
					} else {
						int bytesToRead = (int)reader.ReadInt(14);

						userdata = reader.ReadBytes(bytesToRead);
					}
				}

				if (userdata.Length == 0)
					break;

				if (table.Name == "userinfo") {
					// Now we'll parse the players out of it.
					BinaryReader playerReader = new BinaryReader(new MemoryStream(userdata));
					PlayerInfo info = PlayerInfo.ParseFrom(playerReader);

					parser.RawPlayers[entryIndex] = info;
				} else if (table.Name == "instancebaseline") {
					int classid = int.Parse(entry); //wtf volvo?

					parser.instanceBaseline[classid] = userdata;
                }
                else if (table.Name == "modelprecache") {
                    parser.modelprecache[entryIndex] = entry;
                }
			}

			parser.stringTables.Add(table);
        }