예제 #1
0
        /// <summary> Erases the entire chat log of a file. </summary>
        /// <param name="fileName"> The file name.  </param>
        public static void ClearChatLog(string fileName)
        {
            var replay = new Replay();

            // File in the version numbers for later use.
            MpqHeader.ParseHeader(replay, fileName);

            using (var archive = new CArchive(fileName))
            {
                var files = archive.FindFiles("replay.*");
                {
                    const string CurFile  = "replay.message.events";
                    var          fileSize = (from f in files where f.FileName.Equals(CurFile) select f).Single().Size;

                    var buffer = new byte[fileSize];

                    archive.ExportFile(CurFile, buffer);

                    var arr = ClearChatLog(buffer);
                    archive.ImportFile("replay.message.events", arr);
                }

                archive.Close();
            }
        }
예제 #2
0
        /// <summary> Adds a single chat message to a replay. </summary>
        /// <param name="fileName"> The file name.  </param>
        /// <param name="messages"> The messages to add.  </param>
        public static void AddChatMessageToReplay(string fileName, IEnumerable <ChatMessage> messages)
        {
            var replay = new Replay();

            // File in the version numbers for later use.
            MpqHeader.ParseHeader(replay, fileName);

            using (var archive = new CArchive(fileName))
            {
                var files = archive.FindFiles("replay.*");
                {
                    const string CurFile  = "replay.message.events";
                    var          fileSize = (from f in files where f.FileName.Equals(CurFile) select f).Single().Size;

                    var buffer = new byte[fileSize];

                    archive.ExportFile(CurFile, buffer);

                    foreach (var message in messages)
                    {
                        buffer = GenerateChatMessage(
                            buffer,
                            message.Message,
                            message.MessageTarget,
                            message.PlayerId,
                            (int)message.Timestamp.TotalSeconds);
                    }

                    archive.ImportFile("replay.message.events", buffer);
                }

                archive.Close();
            }
        }
예제 #3
0
        /// <summary> Adds a single chat message to a replay. </summary>
        /// <param name="fileName"> The file name.  </param>
        /// <param name="message"> The message.  </param>
        /// <param name="target"> The target. </param>
        /// <param name="playerId"> The player id.  </param>
        /// <param name="numSeconds"> The number of in-game seconds to insert the message at.  </param>
        public static void AddChatMessageToReplay(
            string fileName, string message, ChatMessageTarget target, int playerId, int numSeconds)
        {
            var replay = new Replay();

            // File in the version numbers for later use.
            MpqHeader.ParseHeader(replay, fileName);

            using (var archive = new CArchive(fileName))
            {
                var files = archive.FindFiles("replay.*");
                {
                    const string CurFile  = "replay.message.events";
                    var          fileSize = (from f in files where f.FileName.Equals(CurFile) select f).Single().Size;

                    var buffer = new byte[fileSize];

                    archive.ExportFile(CurFile, buffer);

                    var arr = GenerateChatMessage(buffer, message, target, playerId, numSeconds);
                    archive.ImportFile("replay.message.events", arr);
                }

                archive.Close();
            }
        }
        /// <summary> Parses a .SC2Replay file and returns relevant replay information.  </summary>
        /// <param name="fileName"> Full path to a .SC2Replay file.  </param>
        /// <param name="noEvents"> True if you don't want to parse events (uses about 5~10 MB on a pro replay, half on an amateur replay) </param>
        /// <returns> Returns the fully parsed Replay object. </returns>
        public static Replay Parse(string fileName, bool noEvents = false)
        {
            if (File.Exists(fileName) == false)
            {
                throw new FileNotFoundException("The specified file does not exist.", fileName);
            }

            var replay = new Replay();

            // File in the version numbers for later use.
            MpqHeader.ParseHeader(replay, fileName);

            CArchive archive;

            try
            {
                archive = new CArchive(fileName);
            }
            catch (IOException)
            {
                // Usually thrown if the archive name contains korean. Copy it to a local file and open.
                var tmpPath = Path.GetTempFileName();

                File.Copy(fileName, tmpPath, true);

                archive = new CArchive(tmpPath);
            }

            try
            {
                var files = archive.FindFiles("replay.*");
                {
                    const string CurFile = "replay.initData";

                    var fileSize = (from f in files where f.FileName.Equals(CurFile) select f).Single().Size;

                    var buffer = new byte[fileSize];

                    archive.ExportFile(CurFile, buffer);

                    ReplayInitData.Parse(replay, buffer);
                }

                {
                    // Local scope allows the byte[] to be GC sooner, and prevents misreferences
                    const string CurFile = "replay.details";

                    var fileSize = (from f in files where f.FileName.Equals(CurFile) select f).Single().Size;

                    var buffer = new byte[fileSize];

                    archive.ExportFile(CurFile, buffer);

                    ReplayDetails.Parse(replay, buffer);
                }

                {
                    const string CurFile  = "replay.attributes.events";
                    var          fileSize = (from f in files where f.FileName.Equals(CurFile) select f).Single().Size;

                    var buffer = new byte[fileSize];

                    archive.ExportFile(CurFile, buffer);

                    ReplayAttributeEvents.Parse(replay, buffer);
                }

                {
                    const string CurFile  = "replay.message.events";
                    var          fileSize = (from f in files where f.FileName.Equals(CurFile) select f).Single().Size;

                    var buffer = new byte[fileSize];

                    archive.ExportFile(CurFile, buffer);
                    try
                    {
                        replay.ChatMessages = ReplayMessageEvents.Parse(buffer);
                    }
                    catch // Chat may have been removed without maintaining the structure
                          // Example:  LiquidHayPro vs MFTarga.SC2Replay from TLPro pack #36
                          // You can see a date on the file in MPQ editor, and viewing the
                          // replay in SC2 results in no chat at all.
                    {
                        replay.ChatMessages = new List <ChatMessage>();
                    }
                }

                try
                {
                    if (!noEvents)
                    {
                        const string CurFile = "replay.game.events";

                        var fileSize = (from f in files where f.FileName.Equals(CurFile) select f).Single().Size;

                        var buffer = new byte[fileSize];

                        archive.ExportFile(CurFile, buffer);

                        replay.PlayerEvents = ReplayGameEvents.Parse(replay, buffer);
                    }
                }
                catch (Exception)
                {
                    // Likely to happen with any non-standard (i.e. format isn't melee nvn, locked alliances) replay.
                }
            }
            finally
            {
                archive.Dispose();
            }

            replay.Timestamp = File.GetCreationTime(fileName);

            return(replay);
        }