Esempio n. 1
0
        /// <summary>
        /// Constructor for playback.
        /// </summary>
        /// <param name="fileName">Relative or absolute path (including file name).</param>
        /// <param name="readMetaData">If true, will read data like Tibia version, recorder version and duration.</param>
        /// <param name="readPackets">If true, will buffer all packets to memory.</param>
        /// <param name="readMouseMovements">If true, will try to read a mouse movement file (*.kcammouse) with the same file name as the recording.</param>
        internal Recording(string fileName, bool readMetaData, bool readPackets, bool readMouseMovements)
        {
            this.Type = RecordingType.Playback;
            if (File.Exists(fileName))
            {
                this.Packets = new List <Recording.Packet>();

                if (fileName.EndsWith(".kcam"))
                {
                    Recorder = Enums.Recorder.TibianicTools;
                }
                else if (fileName.EndsWith(".tmv"))
                {
                    Recorder = Enums.Recorder.TibiaMovie;
                }
                else if (fileName.EndsWith(".cam"))
                {
                    Recorder = Enums.Recorder.IryontCam;
                }
                else
                {
                    return;
                }
                FileName = fileName; RecorderVersion = "?"; TibiaVersion = "?"; Duration = 0;
                //if (fileName.Contains("\\")) { FileNameShort = fileName.Substring(fileName.LastIndexOf('\\') + 1); }
                //else { FileNameShort = fileName; }
                if (readMetaData || readPackets || readMouseMovements)
                {
                    switch (this.Recorder)
                    {
                    case Enums.Recorder.IryontCam:
                        try
                        {
                            using (FileStream fstream = File.OpenRead(this.FileName))
                            {
                                using (BinaryReader reader = new BinaryReader(fstream))
                                {
                                    if (readPackets)
                                    {
                                        uint tickFirst = 0;
                                        // add first packet
                                        tickFirst = (uint)reader.ReadUInt64();
                                        ushort len  = reader.ReadUInt16();
                                        byte[] data = new byte[len + 2];
                                        Array.Copy(BitConverter.GetBytes(len), data, 2);
                                        byte[] packet = reader.ReadBytes(len);
                                        Array.Copy(packet, 0, data, 2, packet.Length);
                                        this.Packets.Add(new Recording.Packet(0, data));
                                        while (reader.BaseStream.Position < reader.BaseStream.Length)
                                        {
                                            uint tick = (uint)reader.ReadUInt64() - tickFirst;
                                            len  = reader.ReadUInt16();
                                            data = new byte[len + 2];
                                            Array.Copy(BitConverter.GetBytes(len), data, 2);
                                            packet = reader.ReadBytes(len);
                                            Array.Copy(packet, 0, data, 2, packet.Length);
                                            this.Packets.Add(new Recording.Packet(tick, data));
                                        }
                                        Recording.Packet lastPacket = this.Packets[this.Packets.Count - 1];
                                        this.Duration = lastPacket.Time;
                                    }
                                }
                            }
                        }
                        catch { this.isCorrupt = true; }
                        break;

                    case Enums.Recorder.TibiaMovie:
                        /*using (FileStream stream = File.OpenRead(fileName))
                         * {
                         *  if (readMetaData)
                         *  {
                         *      byte[] metaData = new byte[8];
                         *      stream.Read(metaData, 0, 8);
                         *      metaData = Utils.TibiaCam.Zlib.Decompress(metaData);
                         *      RecorderVersion = BitConverter.ToUInt16(metaData, 0).ToString();
                         *      TibiaVersion = BitConverter.ToUInt16(metaData, 2).ToString();
                         *      Duration = BitConverter.ToUInt32(metaData, 4);
                         *  }
                         *  if (readPackets)
                         *  {
                         *      byte[] buffer = new byte[stream.Length - 8];
                         *      if (!readMetaData) stream.Position += 8;
                         *      stream.Read(buffer, 0, buffer.Length);
                         *      Utils.TibiaCam.Zlib.Decompress(buffer);
                         *      Packets = Utils.TibiaCam.Zlib.BytesToPacket(Utils.TibiaCam.Zlib.Decompress(buffer));
                         *  }
                         *  stream.Close();
                         * }*/
                        break;

                    case Enums.Recorder.TibianicTools:
                        if (readMouseMovements)
                        {
                            string mouseFileName = fileName + "mouse";
                            if (File.Exists(mouseFileName))
                            {
                                try { this.MouseRecording = new MouseRecording(mouseFileName); }
                                catch { this.MouseRecording = null; }
                            }
                        }
                        try
                        {
                            Stream stream    = Utils.TibiaCam.DecompressCamToStream(fileName);
                            int    firstByte = stream.ReadByte();
                            stream.Position = 0;
                            if (firstByte == (int)'T')     // true for 1.2 and older
                            {
                                isOld = true;
                                List <string> strings = new List <string>();
                                StreamReader  reader  = new StreamReader(stream);
                                TibiaVersion    = reader.ReadLine().Replace("TibiaVersion=", "");
                                RecorderVersion = reader.ReadLine().Replace("TibiaCamVersion=", "");
                                Duration        = (uint)double.Parse(reader.ReadLine().Replace("TotalRunningTime=", ""));
                                if (readPackets)
                                {
                                    while (true)
                                    {
                                        string line = reader.ReadLine();
                                        if (line == null || line.Length == 0)
                                        {
                                            break;
                                        }
                                        strings.Add(line);
                                    }
                                    stream.Close();
                                    stream.Dispose();
                                    List <Recording.Packet> packets = new List <Recording.Packet>();
                                    foreach (string line in strings)
                                    {
                                        string temp  = line;
                                        uint   sleep = uint.Parse(temp.Substring(0, temp.IndexOf(':')));
                                        temp = temp.Remove(0, temp.IndexOf(':') + 1);
                                        string[]       split  = temp.Split(' ');
                                        Objects.Packet packet = new Objects.Packet();
                                        for (int j = 0; j < split.Length; j++)
                                        {
                                            packet.AddByte(byte.Parse(split[j], System.Globalization.NumberStyles.AllowHexSpecifier));
                                        }
                                        packet.GetPosition = 0;
                                        packets.Add(new Recording.Packet(sleep, packet.ToBytes()));
                                    }
                                    Packets = packets;
                                }
                            }
                            else
                            {
                                isOld = false;
                                BinaryReader reader   = new BinaryReader(stream);
                                byte[]       metadata = new byte[8]; // 2 bytes TibiaVersion, 2 bytes CamVersion, 4 bytes RunningLength(ms)
                                reader.Read(metadata, 0, 8);         // fill metadata
                                if (readMetaData)
                                {
                                    TibiaVersion    = metadata[0] + "." + metadata[1];
                                    RecorderVersion = metadata[2] + "." + metadata[3];
                                    Duration        = BitConverter.ToUInt32(metadata, 4);
                                }
                                if (readPackets)
                                {
                                    List <Recording.Packet> packets = new List <Recording.Packet>();
                                    while (reader.BaseStream.Position < reader.BaseStream.Length)
                                    {
                                        uint sleep = reader.ReadUInt32();
                                        uint len   = reader.ReadUInt32();   // should be changed to UInt16 in future versions as packets never exceed 65k bytes
                                        // merge split packets
                                        ushort packetLen = reader.ReadUInt16();
                                        if (packetLen > len - 2)
                                        {
                                            Objects.Packet p = new Objects.Packet();
                                            reader.BaseStream.Position += 4;
                                            p.AddUInt16(packetLen);
                                            p.AddBytes(reader.ReadBytes((int)len - 2));
                                            uint totalBytesRead = len - 2;
                                            while (totalBytesRead < packetLen)
                                            {
                                                reader.ReadUInt32();     // sleep, not needed
                                                len = reader.ReadUInt32();
                                                p.AddBytes(reader.ReadBytes((int)len));
                                                totalBytesRead += len;
                                            }
                                            packets.Add(new Recording.Packet(sleep, p.ToBytes()));
                                        }
                                        else
                                        {
                                            reader.BaseStream.Position -= 2;
                                            packets.Add(new Recording.Packet(sleep, reader.ReadBytes((int)len)));
                                        }
                                    }
                                    Packets = packets;
                                    // if duration is 0, get duration from last packet
                                    if (this.Duration == 0)
                                    {
                                        Recording.Packet p = this.Packets[this.Packets.Count - 1];
                                        this.Duration = p.Time;
                                    }
                                }
                                reader.Close();
                                stream.Close();
                                stream.Dispose();
                                if (readMouseMovements)
                                {
                                    string name = fileName.Substring(0, fileName.LastIndexOf('.'));
                                    name += ".kcammouse";
                                    if (File.Exists(name))
                                    {
                                        MouseRecording = new MouseRecording(name);
                                    }
                                    else
                                    {
                                        MouseRecording = null;
                                    }
                                }
                            }
                        }
                        catch { isCorrupt = true; }
                        break;
                    }
                }
            }
        }
Esempio n. 2
0
        internal void Save(string fileName)
        {
            if (this.Type != RecordingType.Record)
            {
                return;
            }
            if (this.Packets.Count == 0)
            {
                return;
            }
            if (this.MouseRecording != null && this.MouseRecording.IsRecording)
            {
                this.MouseRecording.StopRecording();
            }
            if (string.IsNullOrEmpty(fileName))
            {
                fileName = "Unnamed";
                int i = 0;
                while (File.Exists(fileName + "-" + i + ".kcam"))
                {
                    i++;
                }
                fileName += "-" + i + ".kcam";
            }
            else if (File.Exists(fileName))
            {
                File.Delete(fileName);
            }
            Recording.Packet lastPacket = Packets[Packets.Count - 1];
            this.Duration = lastPacket.Time;
            //Utils.TibiaCam.CompressCam(Packets, fileName);
            using (MemoryStream memstream = new MemoryStream())
            {
                string[] split = this.TibiaVersion.Split('.');
                memstream.Write(new byte[] { byte.Parse(split[0]), byte.Parse(split[1]) }, 0, 2); // holy shit this is ugly, fucken backwards compability
                split = this.RecorderVersion.Split('.');
                memstream.Write(new byte[] { byte.Parse(split[0]), byte.Parse(split[1]) }, 0, 2);
                memstream.Write(BitConverter.GetBytes(this.Duration), 0, 4);
                foreach (Recording.Packet p in this.Packets)
                {
                    memstream.Write(BitConverter.GetBytes(p.Time), 0, 4);
                    memstream.Write(BitConverter.GetBytes((uint)p.Data.Length), 0, 4);
                    memstream.Write(p.Data, 0, p.Data.Length);
                }
                memstream.Position = 0;

                using (FileStream fstream = File.Create(fileName + (!fileName.EndsWith(".kcam") ? ".kcam" : string.Empty)))
                {
                    using (DeflateStream compressStream = new DeflateStream(fstream, CompressionMode.Compress))
                    {
                        compressStream.Write(memstream.ToArray(), 0, (int)memstream.Length);
                    }
                }
            }

            if (this.MouseRecording != null)
            {
                string mouseFileName = fileName + "mouse";
                this.MouseRecording.Save(mouseFileName);
                //this.MouseRecording = null;
            }

            this.Packets.Clear();
        }