Exemple #1
0
        /// <summary>
        /// Parses a level rules file bytes.
        /// </summary>
        /// <param name="fileBytes">The bytes of the level rules to parse.</param>
        public override void ParseFileBytes(byte[] fileBytes)
        {
            // sanity check
            if (fileBytes == null)
            {
                throw new ArgumentNullException("fileBytes", "File bytes cannot be null!");
            }
            _xmlLevelRules = new XmlLevelRules();
            int offset = 0;


            // file header checks
            UInt32 fileMagicWord = FileTools.ByteArrayToUInt32(fileBytes, ref offset);

            if (fileMagicWord != FileMagicWord)
            {
                throw new Exceptions.UnexpectedMagicWordException();
            }

            UInt32 fileVersion = FileTools.ByteArrayToUInt32(fileBytes, ref offset);

            if (fileVersion != RequiredVersion)
            {
                throw new Exceptions.NotSupportedFileVersionException();
            }


            // main file header
            _xmlLevelRules.FileHeader = FileTools.ByteArrayToStructure <LevelRulesHeader>(fileBytes, ref offset);
            LevelRulesHeader header = _xmlLevelRules.FileHeader;


            // static rules
            if (header.StaticRulesCount != 0 && header.StaticRulesFooterOffset != 0)
            {
                _xmlLevelRules.LevelRules = new LevelRule[header.StaticRulesCount];
                int staticRulesFooterOffset = (int)header.StaticRulesFooterOffset;
                for (int i = 0; i < header.StaticRulesCount; i++)
                {
                    int roomsCount = FileTools.ByteArrayToInt32(fileBytes, staticRulesFooterOffset);
                    staticRulesFooterOffset += 8;
                    int roomsOffset = FileTools.ByteArrayToInt32(fileBytes, staticRulesFooterOffset);
                    staticRulesFooterOffset += 8;

                    _xmlLevelRules.LevelRules[i] = new LevelRule
                    {
                        StaticRooms = FileTools.ByteArrayToArray <Room>(fileBytes, roomsOffset, roomsCount)
                    };
                    offset += Marshal.SizeOf(typeof(Room)) * roomsCount + 16;
                    _UpdateRoomsDesc(_xmlLevelRules.LevelRules[i].StaticRooms);
                }
            }
            else if (header.RandomRulesCount != 0 && header.RandomRulesFooterOffset != 0)
            {
                _xmlLevelRules.LevelRules = new LevelRule[header.RandomRulesCount]; // checked all files an no files have both static and random, so no chance of overwriting static above
                LevelRulesRandomFooter[] levelRulesFooters = FileTools.ByteArrayToArray <LevelRulesRandomFooter>(fileBytes, (int)header.RandomRulesFooterOffset, (int)header.RandomRulesCount);
                offset += Marshal.SizeOf(typeof(LevelRulesRandomFooter)) * (int)header.RandomRulesCount;

                for (int i = 0; i < header.RandomRulesCount; i++)
                {
                    _xmlLevelRules.LevelRules[i] = new LevelRule
                    {
                        // get rule connector rooms
                        ConnectorRooms = FileTools.ByteArrayToArray <Room>(fileBytes, (Int32)levelRulesFooters[i].ConnectorRuleOffset, (Int32)levelRulesFooters[i].ConnectorRoomCount),

                        // then the actual level rules
                        Rules = new Room[levelRulesFooters[i].RuleCount][]
                    };
                    offset += Marshal.SizeOf(typeof(Room)) * (int)levelRulesFooters[i].ConnectorRoomCount;
                    _UpdateRoomsDesc(_xmlLevelRules.LevelRules[i].ConnectorRooms);

                    for (int j = 0; j < levelRulesFooters[i].RuleCount; j++)
                    {
                        _xmlLevelRules.LevelRules[i].Rules[j] = FileTools.ByteArrayToArray <Room>(fileBytes, (Int32)levelRulesFooters[i].RuleOffsets[j], levelRulesFooters[i].RoomCounts[j]);
                        offset += Marshal.SizeOf(typeof(Room)) * levelRulesFooters[i].RoomCounts[j];
                        _UpdateRoomsDesc(_xmlLevelRules.LevelRules[i].Rules[j]);
                    }
                }
            }


            // final debug check CT_Rule100 is corrupt or something - has extra bytes at end of it
            //Debug.Assert(offset == fileBytes.Length);
        }
Exemple #2
0
        /// <summary>
        /// Parses a level rules file bytes.
        /// </summary>
        /// <param name="fileBytes">The bytes of the level rules to parse.</param>
        public override void ParseFileBytes(byte[] fileBytes)
        {
            // sanity check
            if (fileBytes == null)
            {
                throw new ArgumentNullException("fileBytes", "File bytes cannot be null!");
            }
            _mliStruct = new MLIStruct();

            // file header checks
            int    offset        = 0;
            UInt32 fileMagicWord = FileTools.ByteArrayToUInt32(fileBytes, ref offset);

            if (fileMagicWord != FileMagicWord)
            {
                throw new Exceptions.UnexpectedMagicWordException();
            }

            UInt32 fileVersion = FileTools.ByteArrayToUInt32(fileBytes, ref offset);

            if (fileVersion != RequiredVersion)
            {
                throw new Exceptions.NotSupportedFileVersionException();
            }

            // first block
            int flag  = FileTools.ByteArrayToInt32(fileBytes, ref offset);
            int count = FileTools.ByteArrayToInt32(fileBytes, ref offset);

            if (flag == 1)
            {
                _mliStruct.UnknownStruct1Array = FileTools.ByteArrayToArray <UnknownStruct1>(fileBytes, ref offset, count);
            }

            if (flag == 1 && _mliStruct.UnknownStruct1Array[0].UnknownInt321 == 0x0A)
            {
                // shorts block
                int shortCount = FileTools.ByteArrayToInt32(fileBytes, ref offset);
                if (shortCount > 0)
                {
                    _mliStruct.UnknownShortArray = FileTools.ByteArrayToShortArray(fileBytes, ref offset, shortCount);
                }

                // floats block
                int floatTripletCount = FileTools.ByteArrayToInt32(fileBytes, ref offset);
                if (floatTripletCount > 0)
                {
                    _mliStruct.UnknownStruct2Array = FileTools.ByteArrayToArray <UnknownStruct2>(fileBytes, ref offset, floatTripletCount);
                }
            }

            // last two unknown blocks
            int count1 = FileTools.ByteArrayToInt32(fileBytes, fileBytes.Length - 8);
            int count2 = FileTools.ByteArrayToInt32(fileBytes, fileBytes.Length - 4);

            if (count1 > 0)
            {
                _mliStruct.UnknownStruct3Array1 = FileTools.ByteArrayToArray <UnknownStruct3>(fileBytes, ref offset, count1);
            }
            if (count2 > 0)
            {
                _mliStruct.UnknownStruct3Array2 = FileTools.ByteArrayToArray <UnknownStruct3>(fileBytes, ref offset, count2);
            }
            offset += 8; // for 2x count fields

            // final debug check
            Debug.Assert(offset == fileBytes.Length);
        }
Exemple #3
0
        private void _ParseDataType(byte[] buffer)
        {
            int offset = 0;

            // header
            FileHeader fileHeader = FileTools.ByteArrayToStructure <FileHeader>(buffer, ref offset);

            if (fileHeader.FileToken != Token.Head)
            {
                throw new Exceptions.UnexpectedTokenException("Expected Head token but got 0x" + fileHeader.FileToken.ToString("X8"));
            }
            if (fileHeader.FileVersion != RequiredVersion)
            {
                throw new Exceptions.NotSupportedFileVersionException(RequiredVersion, fileHeader.FileVersion);
            }

            // Read the strings section
            StringsHeader stringsHeader = FileTools.ByteArrayToStructure <StringsHeader>(buffer, ref offset);

            if (stringsHeader.StringsToken != Token.Sect)
            {
                throw new Exceptions.UnexpectedTokenException(Token.Sect, stringsHeader.StringsToken);
            }
            List <String> strings = new List <String>();

            for (int i = 0; i < stringsHeader.StringsCount; i++)
            {
                strings.Add(FileTools.ByteArrayToStringASCII(buffer, offset));
                offset += strings[i].Length + 1; // +1 for \0
            }

            // String Details
            UInt32 stringsDetailsToken = FileTools.ByteArrayToUInt32(buffer, ref offset);

            if (stringsDetailsToken != Token.Sect)
            {
                throw new Exceptions.UnexpectedTokenException(Token.Sect, stringsDetailsToken);
            }
            // Skip over the details struct because we don't need it.
            offset += stringsHeader.StringsCount * Marshal.SizeOf(typeof(StringDetailsStruct));

            // Files Structure details
            UInt32 filesToken = FileTools.ByteArrayToUInt32(buffer, ref offset);

            if (filesToken != Token.Sect)
            {
                throw new Exceptions.UnexpectedTokenException(Token.Sect, stringsDetailsToken);
            }
            FileDetails.AddRange(FileTools.ByteArrayToArray <FileEntryStruct>(buffer, ref offset, fileHeader.FileCount));

            // The Files list is the public interface
            for (int i = 0; i < fileHeader.FileCount; i++)
            {
                PackFileEntry fileEntry = new FileEntry(FileDetails[i])
                {
                    Pack = this,
                    Path = System.IO.Path.Combine(strings[FileDetails[i].DirectoryIndex], strings[FileDetails[i].NameIndex]),
                };

                Files.Add(fileEntry);
            }

            HasIntegrity = true;
        }
Exemple #4
0
        /// <summary>
        /// Parses a level rules file bytes.
        /// </summary>
        /// <param name="fileBytes">The bytes of the level rules to parse.</param>
        public override void ParseFileBytes(byte[] fileBytes)
        {
            // sanity check
            if (fileBytes == null)
            {
                throw new ArgumentNullException("fileBytes", "File bytes cannot be null!");
            }
            RoomDefinition = new RoomDefinitionStruct();

            // file header checks
            int    offset        = 0;
            UInt32 fileMagicWord = FileTools.ByteArrayToUInt32(fileBytes, ref offset);

            if (fileMagicWord != FileMagicWord)
            {
                throw new Exceptions.UnexpectedMagicWordException();
            }

            UInt32 fileVersion = FileTools.ByteArrayToUInt32(fileBytes, ref offset);

            if (fileVersion != RequiredVersion)
            {
                throw new Exceptions.NotSupportedFileVersionException();
            }

            // main file header
            RoomDefinition.FileHeader = FileTools.ByteArrayToStructure <RoomDefinitionHeader>(fileBytes, ref offset);
            RoomDefinitionHeader header = RoomDefinition.FileHeader;

            // read UnknownStruct1 array
            offset = (int)header.Offset110;
            int count10C = header.Count10C;

            if (offset > 0 && count10C > 0)
            {
                RoomDefinition.UnknownStruct1Array = _ReadUnknownStruct1Array(fileBytes, ref offset, count10C); // FileTools.ByteArrayToArray<UnknownStruct1>(fileBytes, ref offset, count10C);
            }

            // read UnknownStruct2 array
            offset = (int)header.Offset120;
            int count118 = header.Count118;

            if (offset > 0 && count118 > 0)
            {
                RoomDefinition.UnknownStruct2Array = _ReadUnknownStruct2Array(fileBytes, ref offset, count118); // FileTools.ByteArrayToArray<UnknownStruct2>(fileBytes, ref offset, count118);
            }

            // read UnknownStruct3 arrays
            offset = (int)header.Offset288;
            int count29C = header.Count29C;
            int count298 = header.Count298;

            if (offset > 0 && count29C > 0 && count298 > 0)
            {
                RoomDefinition.UnknownStruct3Arrays = new UnknownStruct3[count29C][];
                for (int i = 0; i < count29C; i++)
                {
                    RoomDefinition.UnknownStruct3Arrays[i] = _ReadUnknownStruct3Array(fileBytes, ref offset, count298); // FileTools.ByteArrayToArray<UnknownStruct3>(fileBytes, ref offset, count298);
                }
            }
            // read UnknownStruct3 Int32 array
            offset = (int)header.Offset2A0;
            int count2A8 = header.Count2A8;

            if (offset > 0 && count2A8 > 0)
            {
                RoomDefinition.UnknownStruct3Int32Array = FileTools.ByteArrayToInt32Array(fileBytes, ref offset, count2A8);
            }

            // read room vertices array
            offset = (int)header.VerticesOffset;
            int vertexCount = header.VertexCount;

            if (offset > 0 && vertexCount > 0)
            {
                RoomDefinition.Vertices = _ReadVector3Array(fileBytes, ref offset, vertexCount); // FileTools.ByteArrayToArray<Vector3>(fileBytes, ref offset, vertexCount);
            }

            // read UnknownStruct5 array
            offset = (int)header.Offset278;
            int count280 = header.Count280;

            if (offset > 0 && count280 > 0)
            {
                RoomDefinition.UnknownStruct5Array = FileTools.ByteArrayToArray <UnknownStruct5>(fileBytes, ref offset, count280);
            }

            // read UnknownStruct6 array
            offset = (int)header.Offset130;
            int count12C = header.Count12C;

            if (offset > 0 && count12C > 0)
            {
                RoomDefinition.UnknownStruct6Array = FileTools.ByteArrayToArray <UnknownStruct6>(fileBytes, ref offset, count12C);
            }

            // read UnknownStruct7 array (not seen read like this - but it works) - has same structure (3xfloat) as UnknownStruct4
            offset = (int)header.Offset178;
            int count174 = header.Count174;

            if (offset > 0 && count174 > 0)
            {
                RoomDefinition.UnknownStruct7Array = _ReadUnknownStruct7Vector3Array(fileBytes, ref offset, count174); // FileTools.ByteArrayToArray<Vector3>(fileBytes, ref offset, count174);
            }

            // read UnknownStruct8 array (not seen read like this - but it works)
            offset = (int)header.Offset188;
            int count184 = header.Count184;

            if (offset > 0 && count184 > 0)
            {
                RoomDefinition.UnknownStruct8Array = _ReadUnknownStruct7Array(fileBytes, ref offset, count184); // FileTools.ByteArrayToArray<UnknownStruct7>(fileBytes, ref offset, count184);
            }

            // read UnknownStruct9 array
            offset = (int)header.Offset168;
            int countUnknown7 = header.Count160;

            if (offset > 0 && countUnknown7 > 0)
            {
                RoomDefinition.UnknownStructFooter = FileTools.ByteArrayToArray <UnknownStruct5>(fileBytes, ref offset, countUnknown7);
            }

            // final debug check
            Debug.Assert(offset == fileBytes.Length);
        }
        private static bool _ParsePropertiesScript(byte[] data, ref int offset, ref ExcelFunction excelScript)
        {
            ExcelFunction.Parameter parameter = new ExcelFunction.Parameter();

            // token and version checks
            if (!_CheckToken(data, ref offset, Token.mysh))
            {
                return(false);
            }
            UInt32 version = FileTools.ByteArrayToUInt32(data, ref offset);

            if (version != Token.MyshVersion)
            {
                return(false);
            }


            // general parameter values
            int charCount = FileTools.ByteArrayToInt32(data, ref offset);

            if (charCount >= 0x1000)
            {
                return(false);
            }
            parameter.Name    = FileTools.ByteArrayToStringASCII(data, ref offset, charCount);
            parameter.Unknown = FileTools.ByteArrayToUInt32(data, ref offset);


            // what kind of parameter is it
            parameter.TypeId = FileTools.ByteArrayToUInt32(data, ref offset);
            int paramLength;

            switch (parameter.TypeId)
            {
            case 0x38:     // 56 // "nPowerChange" from TCv4 Skills
                paramLength = 4;
                break;

            case 0x39:     // 57 // oldstats, x, sel, dmgtype, ?
                paramLength = 4;
                break;

            case 0x3C:     // 60 // dam, ?
                paramLength = 5;
                break;

            case 0x41:     // 65 // dmg_elec, dmg_fire, etc
                paramLength = 8;
                break;

            default:
                Debug.Assert(false, "Unknown MYSH TypeId = " + parameter.TypeId);
                return(false);
            }
            parameter.TypeValues = FileTools.ByteArrayToInt32Array(data, ref offset, paramLength);

            excelScript.Parameters.Add(parameter);
            if (parameter.TypeId != 0x41)
            {
                return(true);                          // only 0x41 has paramaters and a script values block following it
            }
            // get remaining parameters
            int paramCount = parameter.TypeValues[5];

            for (int i = 0; i < paramCount; i++)
            {
                if (!_ParsePropertiesScript(data, ref offset, ref excelScript))
                {
                    return(false);
                }
            }


            // the actual script values
            int valuesByteCount = FileTools.ByteArrayToInt32(data, ref offset);

            if (valuesByteCount <= 0)
            {
                return(false);
            }
            excelScript.ScriptByteCode = new byte[valuesByteCount];
            Buffer.BlockCopy(data, offset, excelScript.ScriptByteCode, 0, valuesByteCount);
            offset += valuesByteCount;

            return(true);
        }