Example #1
0
        /// <summary>
        /// Appends a file to the index and accompanying data file.
        /// </summary>
        /// <param name="directory">The directory that will be stored in the index.</param>
        /// <param name="fileName">The filename that will be stored in the index.</param>
        /// <param name="bytesToWrite">Byte array of the file to add.</param>
        /// <param name="fileTime">File time to set to the file.</param>
        /// <returns>Returns true if the operation was successful.</returns>
        public override bool AddFile(String directory, String fileName, byte[] bytesToWrite, DateTime?fileTime = null)
        {
            if (bytesToWrite == null || bytesToWrite.Length == 0)
            {
                throw new ArgumentNullException("bytesToWrite", "Bytes to write cannot be empty!");
            }

            bool doCompress = NoCompressionExt.All(extentsion => !fileName.EndsWith(extentsion));

            if (fileTime == null)
            {
                fileTime = DateTime.Now;
            }

            FileEntryStruct fileStruct = new FileEntryStruct
            {
                StartToken         = Token.Info,
                SizeUncompressed   = bytesToWrite.Length,
                SizeCompressed     = doCompress ? 1 : 0,
                FileTime           = fileTime.Value.ToFileTime(),
                NameHash           = Crypt.GetStringSHA1UInt32(fileName),
                DirectoryHash      = Crypt.GetStringSHA1UInt32(directory),
                First4BytesOfFile  = FileTools.ByteArrayToInt32(bytesToWrite, 0),
                Second4BytesOfFile = FileTools.ByteArrayToInt32(bytesToWrite, 4),
                EndToken           = Token.Info,
            };

            PackFileEntry fileEntry = new FileEntry(fileStruct);

            fileEntry.Directory = directory;
            fileEntry.Name      = fileName;

            Files.Add(fileEntry);

            _AddFileToDat(bytesToWrite, fileEntry);

            // todo: create new applicable file entry object as well?
            // todo: remove existing file bytes if applicable...

            return(true);
        }
Example #2
0
        public int[] ReadScriptTable(int offset)
        {
            if (offset == 0)
            {
                return(null);
            }
            int position = offset;
            int value    = FileTools.ByteArrayToInt32(_scriptBuffer, position);

            while (value != 0)
            {
                if (ScriptOpCodeSizes.Case01.Contains(value))
                {
                    position += (3 * sizeof(int));
                }
                else if (ScriptOpCodeSizes.Case02.Contains(value))
                {
                    position += (2 * sizeof(int));
                }
                else if (ScriptOpCodeSizes.Case03.Contains(value))
                {
                    position += (1 * sizeof(int));
                }
                else if (ScriptOpCodeSizes.BitField.Contains(value))
                {
                    position += (2 * sizeof(int));
                }
                else
                {
                    return(null);
                }

                value = FileTools.ByteArrayToInt32(_scriptBuffer, position);
            }

            int length = (position + sizeof(int) - offset) / sizeof(int);

            return(FileTools.ByteArrayToInt32Array(_scriptBuffer, ref offset, length));
        }
Example #3
0
        public StringsFile(byte[] buffer, String filePath)
        {
            IsStringsFile = true;

            FilePath = filePath;
            StringId = _GetStringId(filePath);
            if (StringId == null)
            {
                throw new Exceptions.DataFileStringIdNotFound(filePath);
            }
            Attributes = DataFileMap[StringId];

            // create field delegators
            FieldInfo[] dataFileFields = Attributes.RowType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            dataFileFields = dataFileFields.OrderBy(f => f.MetadataToken).ToArray(); // order by defined order - GetFields does not guarantee ordering
            Delegator      = new ObjectDelegator(dataFileFields);

            Rows = new List <Object>();

            int  peek  = FileTools.ByteArrayToInt32(buffer, 0);
            bool isCSV = (peek != Token.Header);

            HasIntegrity = ((isCSV)) ? ParseCSV(buffer) : ParseData(buffer);
        }
Example #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!");
            }
            _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);
        }
Example #5
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);
        }
Example #6
0
        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);
        }
Example #7
0
 private static bool _CheckToken(byte[] buffer, ref int offset, int token)
 {
     return(token == FileTools.ByteArrayToInt32(buffer, ref offset));
 }
Example #8
0
        public override sealed bool ParseData(byte[] buffer)
        {
            if ((buffer == null))
            {
                return(false);
            }
            int offset = 0;

            StringsHeader stringsHeader = FileTools.ByteArrayToStructure <StringsHeader>(buffer, ref offset);

            for (int i = 0; i < stringsHeader.Count; i++)
            {
                StringBlock stringBlock = new StringBlock
                {
                    ReferenceId = FileTools.ByteArrayToInt32(buffer, ref offset),
                    Unknown     = FileTools.ByteArrayToInt32(buffer, ref offset)
                };

                int count = FileTools.ByteArrayToInt32(buffer, ref offset);
                stringBlock.StringId = FileTools.ByteArrayToStringASCII(buffer, offset);
                offset += count + 1;

                stringBlock.Reserved = FileTools.ByteArrayToInt32(buffer, ref offset);

                count = FileTools.ByteArrayToInt32(buffer, ref offset);
                stringBlock.String = FileTools.ByteArrayToStringUnicode(buffer, offset, count);
                offset            += count;

                int attributeCount = FileTools.ByteArrayToInt32(buffer, ref offset);

                for (int j = 0; j < attributeCount; j++)
                {
                    count = FileTools.ByteArrayToInt32(buffer, ref offset);
                    int byteCount = (count + 1) * 2;

                    switch (j)
                    {
                    case 0:
                        stringBlock.Attribute1 = FileTools.ByteArrayToStringUnicode(buffer, offset, byteCount);
                        break;

                    case 1:
                        stringBlock.Attribute2 = FileTools.ByteArrayToStringUnicode(buffer, offset, byteCount);
                        break;

                    case 2:
                        stringBlock.Attribute3 = FileTools.ByteArrayToStringUnicode(buffer, offset, byteCount);
                        break;

                    case 3:
                        stringBlock.Attribute4 = FileTools.ByteArrayToStringUnicode(buffer, offset, byteCount);
                        break;
                    }

                    offset += byteCount;
                }

                Rows.Add(stringBlock);
            }

            return(HasIntegrity = ((offset == buffer.Length)) ? true : false);
        }