Beispiel #1
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> 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();
            }
        }
Beispiel #3
0
        /// <summary> Inserts the given chat message into the file buffer. </summary>
        /// <param name="buffer"> The file buffer.  </param>
        /// <param name="message"> The message to insert.  </param>
        /// <param name="target"> The target. </param>
        /// <param name="playerId"> The player id.  </param>
        /// <param name="seconds"> The number of in-game seconds to insert the message.  </param>
        /// <returns> The final buffer with the inserted message.  </returns>
        /// <exception cref="NotSupportedException"> Thrown if the message is longer than 64 character.  </exception>
        private static byte[] GenerateChatMessage(
            byte[] buffer, string message, ChatMessageTarget target, int playerId, int seconds)
        {
            if (message.Length >= 256)
            {
                throw new NotSupportedException("This call does not support strings longer than 256 characters.");
            }

            int targetValue = seconds * 16;

            var completeFile = new List <byte>();

            bool hasBeenWritten   = false;
            bool adjustTimestamps = false;

            using (var stream = new MemoryStream(buffer))
            {
                using (var reader = new BinaryReader(stream))
                {
                    int totalTime  = 0;
                    int shiftValue = 0;

                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        // While not EOF
                        int timestamp = ParseTimestamp(reader);

                        totalTime += timestamp;

                        if (hasBeenWritten == false && totalTime > targetValue)
                        {
                            var orgValue = totalTime - timestamp;

                            shiftValue = targetValue - orgValue;

                            var shiftTimestamp = CreateTimestamp(shiftValue);

                            #region Writing the chat message

                            var bytes = new List <byte>();

                            bytes.AddRange(shiftTimestamp);
                            bytes.Add((byte)playerId); // playerid

                            // &8 for +64, &16 for +128

                            var messageOut = Encoding.UTF8.GetBytes(message);

                            int length = messageOut.Length;

                            if (length < 64)
                            {
                                var opcode = (byte)target;
                                bytes.Add(opcode); // opcode

                                bytes.Add((byte)length);
                                bytes.AddRange(messageOut);
                            }
                            else if (length < 128)
                            {
                                var opcode = (byte)((byte)target | 8);
                                bytes.Add(opcode);

                                length -= 64;

                                bytes.Add((byte)length);
                                bytes.AddRange(messageOut);
                            }
                            else if (length < 192)
                            {
                                var opcode = (byte)((byte)target | 16);
                                bytes.Add(opcode);

                                length -= 128;

                                bytes.Add((byte)length);
                                bytes.AddRange(messageOut);
                            }
                            else if (length < 256)
                            {
                                var opcode = (byte)((byte)target | 24);
                                bytes.Add(opcode);

                                length -= 192;

                                bytes.Add((byte)length);
                                bytes.AddRange(messageOut);
                            }

                            completeFile.AddRange(bytes);

                            #endregion

                            hasBeenWritten   = true;
                            adjustTimestamps = true;
                        }

                        completeFile.AddRange(
                            adjustTimestamps ? CreateTimestamp(timestamp - shiftValue) : CreateTimestamp(timestamp));

                        completeFile.Add(reader.ReadByte()); // PlayerID

                        var opCode = reader.ReadByte();

                        completeFile.Add(opCode);

                        if (opCode == 0x80)
                        {
                            completeFile.AddRange(reader.ReadBytes(4));
                        }
                        else if (opCode == 0x83)
                        {
                            completeFile.AddRange(reader.ReadBytes(8));
                        }
                        else if ((opCode & 0x80) == 0)
                        {
                            var length = reader.ReadByte();

                            completeFile.Add(length);

                            if ((opCode & 8) == 8)
                            {
                                length += 64;
                            }

                            if ((opCode & 16) == 16)
                            {
                                length += 128;
                            }

                            completeFile.AddRange(reader.ReadBytes(length));
                        }
                    }

                    // If we reach the end and the message still hasn't been entered...
                    if (hasBeenWritten == false)
                    {
                        var shiftTimestamp = CreateTimestamp(targetValue - totalTime);

                        var bytes = new List <byte>();

                        bytes.AddRange(shiftTimestamp);
                        bytes.Add((byte)playerId); // playerid

                        // &8 for +64, &16 for +128

                        var messageOut = Encoding.UTF8.GetBytes(message);

                        int length = messageOut.Length;

                        if (length < 64)
                        {
                            var opcode = (byte)target;
                            bytes.Add(opcode); // opcode

                            bytes.Add((byte)length);
                            bytes.AddRange(messageOut);
                        }
                        else if (length < 128)
                        {
                            var opcode = (byte)((byte)target | 8);
                            bytes.Add(opcode);

                            length -= 64;

                            bytes.Add((byte)length);
                            bytes.AddRange(messageOut);
                        }
                        else if (length < 192)
                        {
                            var opcode = (byte)((byte)target | 16);
                            bytes.Add(opcode);

                            length -= 128;

                            bytes.Add((byte)length);
                            bytes.AddRange(messageOut);
                        }
                        else if (length < 256)
                        {
                            var opcode = (byte)((byte)target | 24);
                            bytes.Add(opcode);

                            length -= 192;

                            bytes.Add((byte)length);
                            bytes.AddRange(messageOut);
                        }

                        completeFile.AddRange(bytes);
                    }
                }
            }

            return(completeFile.ToArray());
        }
        /// <summary> Inserts the given chat message into the file buffer. </summary>
        /// <param name="buffer"> The file buffer.  </param>
        /// <param name="message"> The message to insert.  </param>
        /// <param name="target"> The target. </param>
        /// <param name="playerId"> The player id.  </param>
        /// <param name="seconds"> The number of in-game seconds to insert the message.  </param>
        /// <returns> The final buffer with the inserted message.  </returns>
        /// <exception cref="NotSupportedException"> Thrown if the message is longer than 64 character.  </exception>
        private static byte[] GenerateChatMessage(
            byte[] buffer, string message, ChatMessageTarget target, int playerId, int seconds)
        {
            if (message.Length >= 256)
            {
                throw new NotSupportedException("This call does not support strings longer than 256 characters.");
            }

            int targetValue = seconds * 16;

            var completeFile = new List<byte>();

            bool hasBeenWritten = false;
            bool adjustTimestamps = false;

            using (var stream = new MemoryStream(buffer))
            {
                using (var reader = new BinaryReader(stream))
                {
                    int totalTime = 0;
                    int shiftValue = 0;

                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                    {
                        // While not EOF
                        int timestamp = ParseTimestamp(reader);

                        totalTime += timestamp;

                        if (hasBeenWritten == false && totalTime > targetValue)
                        {
                            var orgValue = totalTime - timestamp;

                            shiftValue = targetValue - orgValue;

                            var shiftTimestamp = CreateTimestamp(shiftValue);

                            #region Writing the chat message

                            var bytes = new List<byte>();

                            bytes.AddRange(shiftTimestamp);
                            bytes.Add((byte)playerId); // playerid

                            // &8 for +64, &16 for +128

                            var messageOut = Encoding.UTF8.GetBytes(message);

                            int length = messageOut.Length;

                            if (length < 64)
                            {
                                var opcode = (byte)target;
                                bytes.Add(opcode); // opcode

                                bytes.Add((byte)length);
                                bytes.AddRange(messageOut);
                            }
                            else if (length < 128)
                            {
                                var opcode = (byte)((byte)target | 8);
                                bytes.Add(opcode);

                                length -= 64;

                                bytes.Add((byte)length);
                                bytes.AddRange(messageOut);
                            }
                            else if (length < 192)
                            {
                                var opcode = (byte)((byte)target | 16);
                                bytes.Add(opcode);

                                length -= 128;

                                bytes.Add((byte)length);
                                bytes.AddRange(messageOut);
                            }
                            else if (length < 256)
                            {
                                var opcode = (byte)((byte)target | 24);
                                bytes.Add(opcode);

                                length -= 192;

                                bytes.Add((byte)length);
                                bytes.AddRange(messageOut);
                            }

                            completeFile.AddRange(bytes);

                            #endregion

                            hasBeenWritten = true;
                            adjustTimestamps = true;
                        }

                        completeFile.AddRange(
                            adjustTimestamps ? CreateTimestamp(timestamp - shiftValue) : CreateTimestamp(timestamp));

                        completeFile.Add(reader.ReadByte()); // PlayerID

                        var opCode = reader.ReadByte();

                        completeFile.Add(opCode);

                        if (opCode == 0x80)
                        {
                            completeFile.AddRange(reader.ReadBytes(4));
                        }
                        else if (opCode == 0x83)
                        {
                            completeFile.AddRange(reader.ReadBytes(8));
                        }
                        else if ((opCode & 0x80) == 0)
                        {
                            var length = reader.ReadByte();

                            completeFile.Add(length);

                            if ((opCode & 8) == 8)
                            {
                                length += 64;
                            }

                            if ((opCode & 16) == 16)
                            {
                                length += 128;
                            }

                            completeFile.AddRange(reader.ReadBytes(length));
                        }
                    }

                    // If we reach the end and the message still hasn't been entered...
                    if (hasBeenWritten == false)
                    {
                        var shiftTimestamp = CreateTimestamp(targetValue - totalTime);

                        var bytes = new List<byte>();

                        bytes.AddRange(shiftTimestamp);
                        bytes.Add((byte)playerId); // playerid

                        // &8 for +64, &16 for +128

                        var messageOut = Encoding.UTF8.GetBytes(message);

                        int length = messageOut.Length;

                        if (length < 64)
                        {
                            var opcode = (byte)target;
                            bytes.Add(opcode); // opcode

                            bytes.Add((byte)length);
                            bytes.AddRange(messageOut);
                        }
                        else if (length < 128)
                        {
                            var opcode = (byte)((byte)target | 8);
                            bytes.Add(opcode);

                            length -= 64;

                            bytes.Add((byte)length);
                            bytes.AddRange(messageOut);
                        }
                        else if (length < 192)
                        {
                            var opcode = (byte)((byte)target | 16);
                            bytes.Add(opcode);

                            length -= 128;

                            bytes.Add((byte)length);
                            bytes.AddRange(messageOut);
                        }
                        else if (length < 256)
                        {
                            var opcode = (byte)((byte)target | 24);
                            bytes.Add(opcode);

                            length -= 192;

                            bytes.Add((byte)length);
                            bytes.AddRange(messageOut);
                        }

                        completeFile.AddRange(bytes);
                    }
                }
            }

            return completeFile.ToArray();
        }