Пример #1
0
        public PackagedFileInfo WriteFile(AbstractFileInfo info)
        {
            // Assume that all files are written uncompressed (worst-case) when calculating package sizes
            uint size = info.Size();

            if (_streams.Last().Position + size > MaxPackageSize)
            {
                // Start a new package file if the current one is full.
                string partPath = Package.MakePartFilename(_path, _streams.Count);
                var    nextPart = File.Open(partPath, FileMode.Create, FileAccess.Write);
                _streams.Add(nextPart);
            }

            Stream stream   = _streams.Last();
            var    packaged = new PackagedFileInfo
            {
                PackageStream    = stream,
                Name             = info.Name,
                UncompressedSize = size,
                ArchivePart      = (UInt32)(_streams.Count - 1),
                OffsetInFile     = (UInt32)stream.Position,
                Flags            = BinUtils.MakeCompressionFlags(Compression, CompressionLevel)
            };

            Stream packagedStream = info.MakeStream();

            byte[] compressed;
            try
            {
                using (var reader = new BinaryReader(packagedStream, Encoding.UTF8, true))
                {
                    byte[] uncompressed = reader.ReadBytes((int)reader.BaseStream.Length);
                    compressed = BinUtils.Compress(uncompressed, Compression, CompressionLevel);
                    stream.Write(compressed, 0, compressed.Length);
                }
            }
            finally
            {
                info.ReleaseStream();
            }

            packaged.SizeOnDisk = (UInt32)(stream.Position - packaged.OffsetInFile);
            packaged.Crc        = Crc32.Compute(compressed, 0);

            int padLength = PaddingLength();

            if (stream.Position % padLength <= 0)
            {
                return(packaged);
            }

            if ((_package.Metadata.Flags & PackageFlags.Solid) == 0)
            {
                // Pad the file to a multiple of 64 bytes
                var pad = new byte[padLength - stream.Position % padLength];
                for (var i = 0; i < pad.Length; i++)
                {
                    pad[i] = 0xAD;
                }

                stream.Write(pad, 0, pad.Length);
            }

            return(packaged);
        }
Пример #2
0
        private void DiscoverPackagedFile(AbstractFileInfo file)
        {
            if (file.Name.EndsWith("meta.lsx", StringComparison.Ordinal))
            {
                var match = metaRe.Match(file.Name);
                if (match != null && match.Success)
                {
                    AddMetadataToMod(match.Groups[1].Value, file);
                }
            }

            if (CollectStoryGoals)
            {
                if (file.Name.EndsWith(".txt", StringComparison.Ordinal) && file.Name.Contains("/Story/RawFiles/Goals"))
                {
                    var match = scriptRe.Match(file.Name);
                    if (match != null && match.Success)
                    {
                        AddScriptToMod(match.Groups[1].Value, match.Groups[2].Value, file);
                    }
                }

                if (file.Name.EndsWith("/Story/story_orphanqueries_ignore_local.txt", StringComparison.Ordinal))
                {
                    var match = orphanQueryIgnoresRe.Match(file.Name);
                    if (match != null && match.Success)
                    {
                        GetMod(match.Groups[1].Value).OrphanQueryIgnoreList = file;
                    }
                }

                if (file.Name.EndsWith("/Story/RawFiles/story_header.div", StringComparison.Ordinal))
                {
                    var match = storyDefinitionsRe.Match(file.Name);
                    if (match != null && match.Success)
                    {
                        GetMod(match.Groups[1].Value).StoryHeaderFile = file;
                    }
                }

                if (file.Name.EndsWith("/Story/RawFiles/TypeCoercionWhitelist.txt", StringComparison.Ordinal))
                {
                    var match = typeCoercionWhitelistRe.Match(file.Name);
                    if (match != null && match.Success)
                    {
                        GetMod(match.Groups[1].Value).TypeCoercionWhitelistFile = file;
                    }
                }
            }

            if (CollectStats)
            {
                if (file.Name.EndsWith(".txt", StringComparison.Ordinal) && file.Name.Contains("/Stats/Generated/Data"))
                {
                    var match = statRe.Match(file.Name);
                    if (match != null && match.Success)
                    {
                        AddStatToMod(match.Groups[1].Value, match.Groups[2].Value, file);
                    }
                }
            }

            if (CollectGlobals)
            {
                if (file.Name.EndsWith(".lsf", StringComparison.Ordinal) && file.Name.Contains("/Globals/"))
                {
                    var match = globalsRe.Match(file.Name);
                    if (match != null && match.Success)
                    {
                        AddGlobalsToMod(match.Groups[1].Value, match.Groups[0].Value, file);
                    }
                }
            }

            if (CollectLevels)
            {
                if (file.Name.EndsWith(".lsf", StringComparison.Ordinal) && file.Name.Contains("/Levels/"))
                {
                    var match = levelObjectsRe.Match(file.Name);
                    if (match != null && match.Success)
                    {
                        AddLevelObjectsToMod(match.Groups[1].Value, match.Groups[0].Value, file);
                    }
                }
            }
        }
Пример #3
0
 private void WriteProgressUpdate(AbstractFileInfo file, long numerator, long denominator)
 {
     ProgressUpdate(file.Name, numerator, denominator, file);
 }
Пример #4
0
 private void AddLevelObjectsToMod(string modName, string path, AbstractFileInfo file)
 {
     GetMod(modName).LevelObjects[path] = file;
 }
Пример #5
0
 private void AddGlobalsToMod(string modName, string path, AbstractFileInfo file)
 {
     GetMod(modName).Globals[path] = file;
 }
Пример #6
0
 private void AddScriptToMod(string modName, string scriptName, AbstractFileInfo file)
 {
     GetMod(modName).Scripts[scriptName] = file;
 }
Пример #7
0
 private void AddStatToMod(string modName, string path, AbstractFileInfo file)
 {
     GetMod(modName).Stats[path] = file;
 }
Пример #8
0
 private void AddMetadataToMod(string modName, AbstractFileInfo file)
 {
     GetMod(modName).Meta = file;
 }