示例#1
0
        public void ReadAll()
        {
            BaseStream.Seek(0, SeekOrigin.Begin);

            if (Magic != ReadUInt32())
            {
                throw new InvalidCR2WFileException("Not a CR2W file");
            }

            fileheader.fileversion = ReadUInt32();

            if (!(fileheader.fileversion >= 159 && fileheader.fileversion <= 163))
            {
                throw new InvalidCR2WFileException($"Unknown Version: {fileheader.fileversion}");
            }

            fileheader.flags        = ReadUInt32();
            fileheader.timestamp    = ReadUInt64();
            fileheader.buildversion = ReadUInt32();
            fileheader.disksize     = ReadUInt32();
            fileheader.memsize      = ReadUInt32();
            fileheader.crc32        = ReadUInt32();
            fileheader.numchunks    = ReadUInt32();

            var ts = new CDateTime(fileheader.timestamp);

            Writer.WriteLine("FileName:       {0}", Path.GetFileName(FilePath));
            Writer.WriteLine("FileVersion:    {0}", fileheader.fileversion);
            Writer.WriteLine("Flags:          {0}", fileheader.flags);
            Writer.WriteLine("DateTime:       {0}.{1}", ts.ToString(), ts.Value.Millisecond);
            Writer.WriteLine("BuildVersion:   {0}", fileheader.buildversion);
            Writer.WriteLine("DiskSize:       {0}", fileheader.disksize);
            Writer.WriteLine("MemSize:        {0}", fileheader.memsize);
            Writer.WriteLine("CRC32:          0x{0:X}", fileheader.crc32);
            Writer.WriteLine("NumChunks:      {0}", fileheader.numchunks);

            GetHeaders();

            Writer.WriteLine("\nComputed CRC32: 0x{0:X}", CalculateHeaderCRC32(fileheader));

            GetStrings();
            GetNames();
            GetResources();
            GetTable4();
            GetObjects();
            GetBuffers();
            GetEmbedded();

            ReadObjectData();
        }
示例#2
0
        void ParseVariale(string type, int size, string offset)
        {
            var arr = type.Split(new char[] { ':' }, 2);

            switch (arr[0])
            {
                #region .NET Types
            case "Uint8":
            {
                Writer.WriteLine(" {0}", ReadByte());
            }
                return;

            case "Uint16":
            {
                Writer.WriteLine(" {0}", ReadUInt16());
            }
                return;

            case "Uint32":
            {
                Writer.WriteLine(" {0}", ReadUInt32());
            }
                return;

            case "Uint64":
            {
                Writer.WriteLine(" {0}", ReadUInt64());
            }
                return;

            case "Int8":
            {
                Writer.WriteLine(" {0}", ReadSByte());
            }
                return;

            case "Int16":
            {
                Writer.WriteLine(" {0}", ReadInt16());
            }
                return;

            case "Int32":
            {
                Writer.WriteLine(" {0}", ReadInt32());
            }
                return;

            case "Int64":
            {
                Writer.WriteLine(" {0}", ReadInt64());
            }
                return;

            case "Float":
            {
                Writer.WriteLine(" {0}", ReadSingle());
            }
                return;

            case "String":
            {
                var(flag, length) = ReadVLQInt32();
                var encoding = flag ? Encoding.ASCII : Encoding.Unicode;
                var chars    = new char[length];
                var byteSize = encoding.GetByteCount(chars);
                var bytes    = ReadBytes(byteSize);
                encoding.GetChars(bytes, 0, byteSize, chars, 0);
                Writer.WriteLine(" {0}", new string(chars));
            }
                return;

            case "Bool":
            {
                Writer.WriteLine(" {0}", ReadBoolean());
            }
                return;

                #endregion
                #region RED Types
            case "StringAnsi":
            {
                var length = ReadByte();
                var bytes  = ReadBytes(length);
                Writer.WriteLine(" {0}", new StringAnsi(bytes));
            }
                return;

            case "CName":
            {
                Writer.WriteLine(" {0}", names[ReadUInt16()].Value);
            }
                return;

            case "CGUID":
            {
                Writer.WriteLine(" {0}", new CGUID(ReadBytes(16)).ToString());
            }
                return;

            case "LocalizedString":
            {
                Writer.WriteLine(" {0}", ReadUInt32());
            }
                return;

            case "ptr":
            {
                Writer.WriteLine(" Object {0}", ReadUInt32());
            }
                return;

            case "soft":
            {
                var id = ReadUInt16();
                if (id == 0)
                {
                    Writer.WriteLine(" NULL");
                    return;
                }
                var res = resources[id - 1];
                Writer.WriteLine(" {0} {1} ({2})", res.Type, res.Path, res.Flags);
            }
                return;

            case "array":
            {
                arr = arr[1].Split(new char[] { ',' }, 3);
                var len = ReadUInt32();
                Writer.WriteLine(" {0}", len);
                Writer.WriteLine("{0}{{", offset.Substring(1));
                for (uint i = 0; i < len; i++)
                {
                    Writer.Write("{0}Id {1}:", offset, i);
                    ParseVariale(arr[2], size, $"\t{offset}");
                }
                Writer.WriteLine("{0}}}", offset.Substring(1));
            }
                return;

            case "handle":
            {
                var id = ReadInt32();
                if (id >= 0)
                {
                    Writer.WriteLine(" Object: {0}", id);
                }
                else
                {
                    id *= -1;
                    var res = resources[id - 1];
                    Writer.WriteLine(" {0} {1} ({2})", res.Type, res.Path, res.Flags);
                }
            }
                return;

            case "SAppearanceAttachment":
            {
                Writer.WriteLine();
                Writer.WriteLine("{0}{{", offset.Substring(1));
                ReadVariable(offset);
                var bytecount = ReadInt32();
                var unknown   = ReadBytes(bytecount - 4);
                Writer.WriteLine("{0}Unknown Bytes: {1}", offset, bytecount - 4);
                Writer.WriteLine("{0}}}", offset.Substring(1));
            }
                return;

            case "IdTag":
            {
                var dynamic = ReadBoolean();
                var guid    = new CGUID(ReadBytes(16));
                if (dynamic)
                {
                    Writer.WriteLine(" [Dynamic: {0}]", guid.ToString());
                }
                else
                {
                    Writer.WriteLine(" [Static: {0}]", guid.ToString());
                }
            }
                return;

            case "EngineTransform":
            {
                Writer.Write(" [ ");
                var flags = ReadByte();
                if ((flags & 1) == 1)
                {
                    Writer.Write("Posistion:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                if ((flags & 2) == 2)
                {
                    Writer.Write("Rotation:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                if ((flags & 4) == 4)
                {
                    Writer.Write("Scale:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                Writer.WriteLine("]");
            }
                return;

            case "EngineQsTransform":
            {
                Writer.Write(" [ ");
                var flags = ReadByte();
                if ((flags & 1) == 1)
                {
                    Writer.Write("Posistion:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                if ((flags & 2) == 2)
                {
                    Writer.Write("Rotation:{0},{1},{2},{3} ", ReadSingle(), ReadSingle(), ReadSingle(), ReadSingle());
                }
                if ((flags & 4) == 4)
                {
                    Writer.Write("Scale:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                Writer.WriteLine("]");
            }
                return;

            case "TagList":
            {
                // This could be a vlq int value but so far there is no tag list
                // size big enough to use more than one bytes.
                var count = ReadByte();
                var tags  = new string[count];
                for (var i = 0; i < count; i++)
                {
                    tags[i] = names[ReadUInt16()].Value;
                }
                Writer.WriteLine(" [{0}]", string.Join(",", tags));
            }
                return;

            case "EntityHandle":
            {
                /*
                 *  Read the first byte which will tell you what type of entity handle it is.
                 *  Values:
                 *      0 - None - 0 bytes
                 *      1 - Entity Guid - 32 bytes
                 *      2 - IdTag - 17 bytes
                 *
                 *      Then read off that variable type.
                 *
                 *      IdTag:
                 *          1 Byte - 0 = Static, 1 = Dynamic
                 *          16 Bytes - Guid Value
                 *      Entity:
                 *          16 Bytes - Guid Value
                 *          16 Bytes - Unknown
                 */
                var handletype = ReadByte();
                switch (handletype)
                {
                //Entity
                case 1:
                    var eguid = new CGUID(ReadBytes(16));
                    var unkn  = ReadBytes(16);
                    Writer.WriteLine(" [Entity - {0}]", eguid.ToString());
                    break;

                //IdTag
                case 2:
                    var dynamic = ReadBoolean();
                    var guid    = new CGUID(ReadBytes(16));
                    if (dynamic)
                    {
                        Writer.WriteLine(" [Dynamic: {0}]", guid.ToString());
                    }
                    else
                    {
                        Writer.WriteLine(" [Static: {0}]", guid.ToString());
                    }
                    break;
                }
            }
                return;

            case "static":
            {
                var length = ReadUInt32();
                arr = arr[1].Split(new char[] { ',' }, 2);
                Writer.WriteLine(" {0}", length);
                Writer.WriteLine("{0}{{", offset.Substring(1));
                for (uint i = 0; i < length; i++)
                {
                    Writer.Write("{0}Id {1}:", offset, i);
                    ParseVariale(arr[1], size, $"\t{offset}");
                }
                Writer.WriteLine("{0}}}", offset.Substring(1));
            }
                return;

            case "CDateTime":
            {
                var datetime = new CDateTime(ReadUInt64());
                Writer.WriteLine(" {0}.{1}", datetime.ToString(), datetime.Value.Millisecond);
            }
                return;

            case "SharedDataBuffer":
            {
                var datasize = ReadInt32();
                var bytes    = ReadBytes(datasize);
                Writer.WriteLine(" {0} bytes", datasize);
            }
                return;

            case "DataBuffer":
            {
                var datasize = ReadInt32();
                var bytes    = ReadBytes(datasize);
                Writer.WriteLine(" {0} bytes", datasize);
            }
                return;

            case "DeferredDataBuffer":
            {
                Writer.WriteLine(" {0}", ReadUInt16());
            }
                return;

            case "SMeshTypeResourceLODLevel":
            {
                Writer.WriteLine(" {0}", ReadSingle());
            }
                return;

            case "CPhysicalCollision":
            {
                var unknown   = ReadUInt32();
                var nameCount = ReadByte();

                Writer.WriteLine();
                Writer.WriteLine("{0}{{", offset.Substring(1));
                Writer.WriteLine("{0}unknown Uint32 {1}", offset, unknown);
                Writer.WriteLine("{0}Types", offset);
                Writer.WriteLine("{0}{{", offset);
                for (byte i = 0; i < nameCount; i++)
                {
                    Writer.WriteLine("\t{0}Id {1}: {2}", offset, i, names[ReadUInt16()].Value);
                }
                Writer.WriteLine("{0}}}", offset);
                Writer.WriteLine("{0}Bytes {1}", offset, String.Join(", ", ReadBytes(16)));
                Writer.WriteLine("{0}}}", offset.Substring(1));
            }
                return;

                #endregion
            }

            //Detects types such as [7]Float etc...
            var regEx = Regex.Match(type, @"^\[([0-9]+)\]([\x00-\x7F]+)$");
            if (regEx.Success)
            {
                var arraySize = ReadUInt32();
                if (arraySize != Convert.ToUInt32(regEx.Groups[1].Value))
                {
                    throw new FormatException();
                }
                Writer.WriteLine(" {0}", arraySize);
                Writer.WriteLine("{0}{{", offset.Substring(1));
                for (uint i = 0; i < arraySize; i++)
                {
                    Writer.Write("{0}Id {1}:", offset, i);
                    ParseVariale(regEx.Groups[2].Value, size, $"\t{offset}");
                }
                Writer.WriteLine("{0}}}", offset.Substring(1));
                return;
            }

            var myType = AssemblyDictionary.GetTypeByName(type);
            if (myType != null && myType.IsEnum)
            {
                if (myType.IsDefined(typeof(FlagsAttribute), false))
                {
                    var values = new List <string>();
                    while (true)
                    {
                        var flag = ReadUInt16();
                        if (flag == 0)
                        {
                            break;
                        }
                        values.Add(names[flag].Value);
                    }
                    if (values.Count != 0)
                    {
                        Writer.WriteLine(" {0}", Enum.Parse(myType, String.Join(",", values)));
                    }
                    else
                    {
                        Writer.WriteLine(" {0}", "None");
                    }
                }
                else
                {
                    var value = names[ReadUInt16()].Value;
                    Writer.WriteLine(" {0}", value);
                }
                return;
            }

            Writer.WriteLine();
            Writer.WriteLine("{0}{{", offset.Substring(1));
            ReadVariable(offset);
            Writer.WriteLine("{0}}}", offset.Substring(1));
        }
示例#3
0
        void ParseVariale(string type, int size, string offset)
        {
            var arr = type.Split(new char[] { ':' }, 2);

            switch (arr[0])
            {
            case "Uint8":
            {
                Writer.WriteLine(" {0}", ReadByte());
            }
                return;

            case "Uint16":
            {
                Writer.WriteLine(" {0}", ReadUInt16());
            }
                return;

            case "Uint32":
            {
                Writer.WriteLine(" {0}", ReadUInt32());
            }
                return;

            case "Uint64":
            {
                Writer.WriteLine(" {0}", ReadUInt64());
            }
                return;

            case "Int8":
            {
                Writer.WriteLine(" {0}", ReadSByte());
            }
                return;

            case "Int16":
            {
                Writer.WriteLine(" {0}", ReadInt16());
            }
                return;

            case "Int32":
            {
                Writer.WriteLine(" {0}", ReadInt32());
            }
                return;

            case "Int64":
            {
                Writer.WriteLine(" {0}", ReadInt64());
            }
                return;

            case "Float":
            {
                Writer.WriteLine(" {0}", ReadSingle());
            }
                return;

            case "Double":
            {
                Writer.WriteLine(" {0}", ReadDouble());
            }
                return;

            case "String":
            {
                var length = ReadVLQInt32();
                if (length < 0)
                {
                    Writer.WriteLine(" {0}", Encoding.ASCII.GetString(ReadBytes(length * -1)));
                }
                else
                {
                    Writer.WriteLine(" {0}", Encoding.Unicode.GetString(ReadBytes(length * 2)));
                }
            }
                return;

            case "StringAnsi":
            {
                var b   = ReadByte();
                var nxt = (b & (1 << 7)) != 0;
                int len = b & ((1 << 7) - 1);

                if (nxt)
                {
                    Writer.WriteLine(" {0}", Encoding.Unicode.GetString(ReadBytes(len * 2)));
                }
                else
                {
                    Writer.WriteLine(" {0}", Encoding.ASCII.GetString(ReadBytes(len)));
                }
            }
                return;

            case "Bool":
            {
                Writer.WriteLine(" {0}", ReadBoolean());
            }
                return;

            case "CName":
            {
                Writer.WriteLine(" {0}", names[ReadUInt16()].Value);
            }
                return;

            case "CGUID":
            {
                Writer.WriteLine(" {0}", new CGUID(ReadBytes(16)).ToString());
            }
                return;

            case "LocalizedString":
            {
                Writer.WriteLine(" {0}", ReadUInt32());
            }
                return;

            case "ptr":
            {
                Writer.WriteLine(" Object {0}", ReadUInt32());
            }
                return;

            case "soft":
            {
                var res = resources[ReadUInt16() - 1];
                Writer.WriteLine(" {0} {1} ({2})", res.Type, res.Path, res.Flags);
            }
                return;

            case "array":
            {
                var len = ReadUInt32();
                arr = arr[1].Split(new char[] { ',' }, 3);
                Writer.WriteLine(" {0}", len);
                Writer.WriteLine("{0}{{", offset.Substring(1));
                for (uint i = 0; i < len; i++)
                {
                    Writer.Write("{0}Id {1}:", offset, i);
                    ParseVariale(arr[2], size, $"\t{offset}");
                }
                Writer.WriteLine("{0}}}", offset.Substring(1));
            }
                return;

            case "handle":
            {
                var id = ReadInt32();
                if (id >= 0)
                {
                    Writer.WriteLine(" Object: {0}", id);
                }
                else
                {
                    id *= -1;
                    var res = resources[id - 1];
                    Writer.WriteLine(" {0} {1} ({2})", res.Type, res.Path, res.Flags);
                }
            }
                return;

            case "SAppearanceAttachment":
            {
                Writer.WriteLine();
                Writer.WriteLine("{0}{{", offset.Substring(1));
                ReadVariable(offset);
                var bytecount = ReadInt32();
                var unknown   = ReadBytes(bytecount - 4);
                Writer.WriteLine("{0}Unknown Bytes: {1}", offset, bytecount - 4);
                Writer.WriteLine("{0}}}", offset.Substring(1));
            }
                return;

            case "IdTag":
            {
                var dynamic = ReadBoolean();
                var guid    = new CGUID(ReadBytes(16));
                if (dynamic)
                {
                    Writer.WriteLine(" [Dynamic: {0}]", guid.ToString());
                }
                else
                {
                    Writer.WriteLine(" [Static: {0}]", guid.ToString());
                }
            }
                return;

            case "EngineTransform":
            {
                Writer.Write(" [ ");
                var flags = ReadByte();
                if ((flags & 1) == 1)
                {
                    Writer.Write("Posistion:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                if ((flags & 2) == 2)
                {
                    Writer.Write("Rotation:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                if ((flags & 4) == 4)
                {
                    Writer.Write("Scale:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                Writer.WriteLine("]");
            }
                return;

            case "EngineQsTransform":
            {
                Writer.Write("[ ");
                var flags = ReadByte();
                if ((flags & 1) == 1)
                {
                    Writer.Write("Posistion:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                if ((flags & 2) == 2)
                {
                    Writer.Write("Rotation:{0},{1},{2},{3} ", ReadSingle(), ReadSingle(), ReadSingle(), ReadSingle());
                }
                if ((flags & 4) == 4)
                {
                    Writer.Write("Scale:{0},{1},{2} ", ReadSingle(), ReadSingle(), ReadSingle());
                }
                Writer.WriteLine("]");
            }
                return;

            case "TagList":
            {
                var count = ReadByte();
                var tags  = new string[count];
                for (var i = 0; i < count; i++)
                {
                    tags[i] = names[ReadUInt16()].Value;
                }
                Writer.WriteLine(" [{0}]", string.Join(",", tags));
            }
                return;

            case "EntityHandle":
            {
                /*
                 *  Read the first byte which will tell you what type of entity handle it is.
                 *  Values:
                 *      0 - None - 0 bytes
                 *      1 - Entity Guid - 32 bytes
                 *      2 - IdTag - 17 bytes
                 *
                 *      Then read off that variable type.
                 *
                 *      IdTag:
                 *          1 Byte - 0 = Static, 1 = Dynamic
                 *          16 Bytes - Guid Value
                 *      Entity:
                 *          16 Bytes - Guid Value
                 *          16 Bytes - Unknown
                 *
                 */
                var handletype = ReadByte();
                switch (handletype)
                {
                //Entity
                case 1:
                    var eguid = new CGUID(ReadBytes(16));
                    var unkn  = ReadBytes(16);
                    Writer.WriteLine(" [Entity - {0}]", eguid.ToString());
                    break;

                //IdTag
                case 2:
                    var dynamic = ReadBoolean();
                    var guid    = new CGUID(ReadBytes(16));
                    if (dynamic)
                    {
                        Writer.WriteLine(" [Dynamic: {0}]", guid.ToString());
                    }
                    else
                    {
                        Writer.WriteLine(" [Static: {0}]", guid.ToString());
                    }
                    break;
                }
            }
                return;

            case "static":
            {
                var length = ReadUInt32();
                arr = arr[1].Split(new char[] { ',' }, 2);
                Writer.WriteLine(" {0}", length);
                Writer.WriteLine("{0}{{", offset.Substring(1));
                for (uint i = 0; i < length; i++)
                {
                    Writer.Write("{0}Id {1}:", offset, i);
                    ParseVariale(arr[1], size, $"\t{offset}");
                }
                Writer.WriteLine("{0}}}", offset.Substring(1));
            }
                return;

            case "CDateTime":
            {
                var datetime = new CDateTime(ReadUInt64());
                Writer.WriteLine(" {0}.{1}", datetime.ToString(), datetime.Value.Millisecond);
            }
                return;

            case "SharedDataBuffer":
            {
                var datasize = ReadInt32();
                var bytes    = ReadBytes(datasize);
                Writer.WriteLine(" {0} bytes", datasize);
            }
                return;

            case "DataBuffer":
            {
                var datasize = ReadInt32();
                var bytes    = ReadBytes(datasize);
                Writer.WriteLine(" {0} bytes", datasize);
            }
                return;

            case "DeferredDataBuffer":
            {
                Writer.WriteLine(" {0}", ReadUInt16());
            }
                return;

            case "CPhysicalCollision":
            {
                var unknown   = ReadUInt32();
                var nameCount = ReadByte();

                Writer.WriteLine();
                Writer.WriteLine("{0}{{", offset.Substring(1));
                Writer.WriteLine("{0}unknown Uint32 {1}", offset, unknown);
                Writer.WriteLine("{0}Types", offset);
                Writer.WriteLine("{0}{{", offset);
                for (byte i = 0; i < nameCount; i++)
                {
                    Writer.WriteLine("\t{0}Id {1}: {2}", offset, i, names[ReadUInt16()].Value);
                }
                Writer.WriteLine("{0}}}", offset);
                Writer.WriteLine("{0}Bytes {1}", offset, String.Join(", ", ReadBytes(16)));
                Writer.WriteLine("{0}}}", offset.Substring(1));
            }
                return;
            }

            Type myType = Type.GetType($"CR2W.Types.W3.{type}");

            if (myType != null)
            {
                if (myType.IsEnum)
                {
                    if (myType.IsDefined(typeof(FlagsAttribute), false))
                    {
                        var values = new List <string>();
                        while (true)
                        {
                            var flag = ReadUInt16();
                            if (flag == 0)
                            {
                                break;
                            }
                            values.Add(names[flag].Value);
                        }
                        if (values.Count != 0)
                        {
                            Writer.WriteLine(" {0}", Enum.Parse(myType, String.Join(",", values)));
                        }
                        else
                        {
                            Writer.WriteLine(" {0}", "None");
                        }
                    }
                    else
                    {
                        var value = names[ReadUInt16()].Value;
                        Writer.WriteLine(" {0}", value);
                    }
                    return;
                }
            }

            Writer.WriteLine();
            Writer.WriteLine("{0}{{", offset.Substring(1));
            ReadVariable(offset);
            Writer.WriteLine("{0}}}", offset.Substring(1));
        }