Ejemplo n.º 1
0
        public bool ReadMoviesCameras(Location location)
        {
            ArchiveFileEntry mskEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".msk");

            if (mskEntry == null)
            {
                return(true);
            }

            using (MskFileReader mskReader = new MskFileReader(mskEntry.OpenReadableContentStream()))
            {
                MovieCameras cameras = new MovieCameras(mskReader.Rects.Length);
                foreach (MskRect rect in mskReader.Rects)
                {
                    MovieCamera camera = new MovieCamera
                    {
                        TopLeft     = rect.Top,
                        TopRight    = rect.Bottom,
                        BottomRight = rect.Right,
                        BottomLeft  = rect.Left
                    };
                    cameras.Add(camera);
                }
                location.MovieCameras = cameras;
            }

            location.SaveRequest &= ~LocationProperty.MoviesCameras;
            location.Importable  &= ~LocationProperty.MoviesCameras;
            return(true);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Add <see cref="ZipArchiveEntry"/> into tree structure.
        /// </summary>
        /// <param name="root"></param>
        /// <param name="zipArchiveEntries"></param>
        /// <param name="streamProvider">stream provider for files</param>
        /// <returns>this</returns>
        static ArchiveDirectoryEntry AddArchiveEntries(ArchiveDirectoryEntry root, IEnumerable <ZipArchiveEntry> zipArchiveEntries, IStreamProvider streamProvider)
        {
            foreach (ZipArchiveEntry ze in zipArchiveEntries)
            {
                // Is entry a file
                if (!ze.FullName.EndsWith("/") || ze.Length > 0L)
                {
                    // Split to filename and path
                    int    slashIx  = ze.FullName.LastIndexOf('/');
                    string filename = ze.FullName.Substring(slashIx + 1);
                    string dirPath  = slashIx < 0 ? "" : ze.FullName.Substring(0, slashIx);

                    // Create file entry
                    ArchiveFileEntry fileEntry = new ArchiveFileEntry(streamProvider, ze.FullName, filename, ze.Length, ze.LastWriteTime);

                    // Create dir
                    ArchiveDirectoryEntry dir = root.GetOrCreateDirectory(dirPath);

                    // Add to dir
                    dir.files[filename] = fileEntry;
                }
                else
                {
                    // Create dir
                    root.GetOrCreateDirectory(ze.FullName);
                }
            }

            // Return the whole tree
            return(root);
        }
Ejemplo n.º 3
0
        public bool ReadCamera(Location location)
        {
            ArchiveFileEntry caEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".ca");

            if (caEntry == null)
            {
                return(true);
            }

            using (CaFileReader caReader = new CaFileReader(caEntry.OpenReadableContentStream()))
            {
                FieldCameras cameras = new FieldCameras(caReader.Rects.Length);
                foreach (CaCamera rect in caReader.Rects)
                {
                    FieldCamera camera = new FieldCamera
                    {
                        XAxis    = rect.XAxis,
                        YAxis    = rect.YAxis,
                        ZAxis    = rect.ZAxis,
                        Position = rect.Position,
                        Zoom     = rect.Zoom
                    };
                    cameras.Add(camera);
                }
                location.FieldCameras = cameras;
            }

            location.SaveRequest &= ~LocationProperty.FieldCamera;
            location.Importable  &= ~LocationProperty.FieldCamera;
            return(true);
        }
Ejemplo n.º 4
0
        public bool ReadMonologues(Location location)
        {
            ArchiveFileEntry msdEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".msd");

            if (msdEntry == null)
            {
                return(true);
            }

            using (MsdFileReader msdReader = new MsdFileReader(msdEntry.OpenReadableContentStream()))
            {
                string[]           strings    = msdReader.ReadAllMonologues();
                LocalizableStrings monologues = new LocalizableStrings(strings.Length);
                foreach (string str in strings)
                {
                    LocalizableString localizableString = new LocalizableString(str, str);
                    monologues.Add(localizableString);
                }
                location.Monologues = monologues;
            }

            location.SaveRequest &= ~LocationProperty.Monologues;
            location.Importable  &= ~LocationProperty.Monologues;
            return(true);
        }
Ejemplo n.º 5
0
        public static GameFont HiResFromGameData()
        {
            using (DisposableStack disposables = new DisposableStack(2))
            {
                GameImage firstImage, secondImage;

                ArchiveDirectoryEntry mainDirectory  = Archives.GetEntry <ArchiveDirectoryEntry>(MainPath);
                ArchiveDirectoryEntry menuDirectory  = Archives.GetEntry <ArchiveDirectoryEntry>(MenuPath);
                ArchiveDirectoryEntry hiresDirectory = menuDirectory.GetChildEntry <ArchiveDirectoryEntry>(HiResDirectoryName);
                ArchiveFileEntry      tdwEntry       = mainDirectory.GetChildEntry <ArchiveFileEntry>(HiResCharactersWidthsFileName);
                ArchiveFileEntry      image01        = hiresDirectory.GetChildEntry <ArchiveFileEntry>(HiResFontImage1FileName);
                ArchiveFileEntry      image02        = hiresDirectory.GetChildEntry <ArchiveFileEntry>(HiResFontImage2FileName);

                byte[] widths;
                using (TdwFileReader tdwReader = new TdwFileReader(tdwEntry.OpenReadableContentStream()))
                    widths = tdwReader.Table;

                using (TexFileReader texReader = new TexFileReader(image01.OpenReadableContentStream()))
                {
                    firstImage = GameImageReader.FromTex(texReader);
                    disposables.Add(firstImage.Layer);
                }

                using (TexFileReader texReader = new TexFileReader(image02.OpenReadableContentStream()))
                    secondImage = disposables.Add(GameImageReader.FromTex(texReader));

                int       x        = firstImage.X;
                int       y        = firstImage.Y;
                GLTexture palettes = firstImage.Palettes;
                GLTexture layer    = GLTextureFactory.HorizontalJoin(firstImage.Layer, secondImage.Layer);
                GameImage image    = new GameImage(x, y, layer, palettes);

                return(new GameFont(image, widths));
            }
        }
Ejemplo n.º 6
0
        public bool ReadInformation(Location location)
        {
            ArchiveFileEntry infEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".inf");

            if (infEntry == null)
            {
                return(true);
            }

            using (InfFileReader infReader = new InfFileReader(infEntry.OpenReadableContentStream()))
            {
                InfEntry  entry  = infReader.Entry;
                FieldInfo result = new FieldInfo(
                    entry.Name,
                    entry.Direction,
                    entry.HeightCameraFocus,
                    entry.CameraRanges,
                    entry.ScreenRanges,
                    entry.Gateways.Select(g => new FieldGateway(g.SourceLine, g.TargetFieldID, g.TargetPoint, g.Unknown1, g.Unknown2, g.Unknown3)).ToArray(),
                    entry.Triggers.Select(t => new FieldTrigger(t.DoorID, t.SourceLine)).ToArray(),
                    entry.PvP,
                    entry.Unknown);

                location.Info = result;
            }

            location.SaveRequest &= ~LocationProperty.Information;
            location.Importable  &= ~LocationProperty.Information;
            return(true);
        }
Ejemplo n.º 7
0
        public override void ExtractArchiveFile(ArchiveFileEntry afe)
        {
            var entry = afe as Img1DirectoryEntry;
            FolderBrowserDialog fbd = new FolderBrowserDialog();

            if (fbd.ShowDialog() == DialogResult.OK)
            {
                File.WriteAllBytes(fbd.SelectedPath + "\\" + entry.Name, entry.Data);
            }
        }
Ejemplo n.º 8
0
        public void WriteScripts(AsmCollection asmCollection)
        {
            ArchiveFileEntry jsmEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".jsm");

            if (jsmEntry == null)
            {
                return;
            }

            JsmHeader           header     = new JsmHeader();
            List <JsmGroup>     groups     = new List <JsmGroup>(8);
            List <JsmScript>    scripts    = new List <JsmScript>(32);
            List <JsmOperation> operations = new List <JsmOperation>(512);

            foreach (AsmModule module in asmCollection.GetOrderedModules())
            {
                JsmGroup group = new JsmGroup(module.ExecutionOrder, module.Label, (byte)module.Count, (JsmModuleType)module.Type);
                header.IncrementCount(group.Type);
                groups.Add(group);
            }

            foreach (AsmModule module in asmCollection.GetOrderedModulesByIndex())
            {
                foreach (AsmEvent evt in module.GetOrderedEvents())
                {
                    JsmScript script = new JsmScript((ushort)operations.Count, evt.Flag);
                    scripts.Add(script);

                    foreach (JsmOperation command in evt)
                    {
                        operations.Add(command);
                    }
                }
            }

            scripts.Add(new JsmScript((ushort)operations.Count, false));

            header.ScriptsOffset    = (ushort)(8 + groups.Count * 2);
            header.OperationsOffset = (ushort)(header.ScriptsOffset + scripts.Count * 2);

            using (JsmFileWriter jsmWriter = new JsmFileWriter(jsmEntry.OpenWritableCapacityStream()))
                jsmWriter.WriteScripts(header, groups, scripts, operations);

            //ArchiveFileEntry symEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".sym");
            //if (symEntry == null)
            //    return;

            //using (SymFileWriter symWriter = new SymFileWriter(symEntry.OpenWritableCapacityStream()))
            //{
            //}
        }
Ejemplo n.º 9
0
        public bool ReadParticles(Location location)
        {
            ArchiveFileEntry pmdEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".pmd");
            ArchiveFileEntry pmpEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".pmp");

            if (pmdEntry == null || pmpEntry == null)
            {
                return(true);
            }

            SafeHGlobalHandle pmdContent, pmpContent;

            using (Stream input = pmdEntry.OpenReadableContentStream())
            {
                pmdContent = new SafeHGlobalHandle((int)input.Length);
                try
                {
                    using (Stream output = pmdContent.OpenStream(FileAccess.Write))
                        input.CopyTo(output);
                }
                catch
                {
                    pmdContent.SafeDispose();
                    throw;
                }
            }

            using (Stream input = pmpEntry.OpenReadableContentStream())
            {
                pmpContent = new SafeHGlobalHandle((int)input.Length);
                try
                {
                    using (Stream output = pmpContent.OpenStream(FileAccess.Write))
                        input.CopyTo(output);
                }
                catch
                {
                    pmpContent.SafeDispose();
                    throw;
                }
            }

            Particles result = new Particles(pmdContent, pmpContent);

            location.Particles = result;

            location.SaveRequest &= ~LocationProperty.Particles;
            location.Importable  &= ~LocationProperty.Particles;
            return(true);
        }
Ejemplo n.º 10
0
        public override void ViewFile(ArchiveFileEntry afe, bool hex = false)
        {
            var entry = afe as Img1DirectoryEntry;

            var filepath = entry.Name;
            var data     = entry.Data;

            if (hex)
            {
                ViewHexFile(filepath, data);
                return;
            }

            switch (entry.Extension.Replace(".", string.Empty).ToLower())
            {
            case "dff":
                ViewDffFile(filepath, data);
                break;

            case "txd":
                ViewTxdFile(filepath, data);
                break;

            case "dat":
                ViewTextFile(filepath, data);
                break;

            case "ini":
                ViewTextFile(filepath, data);
                break;

            case "txt":
                ViewTextFile(filepath, data);
                break;

            case "cfg":
                ViewTextFile(filepath, data);
                break;

            case "xml":
                ViewXmlFile(filepath, data);
                break;

            default:
                ViewHexFile(filepath, data);
                break;
            }
        }
Ejemplo n.º 11
0
        public bool ReadPvP(Location location)
        {
            ArchiveFileEntry pvpEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".pvp");

            if (pvpEntry == null)
            {
                return(true);
            }

            using (PvpFileReader pvpReader = new PvpFileReader(pvpEntry.OpenReadableContentStream()))
                location.PVP = pvpReader.Value;

            location.SaveRequest &= ~LocationProperty.PvP;
            location.Importable  &= ~LocationProperty.PvP;
            return(true);
        }
Ejemplo n.º 12
0
        public static Location[] GetLocationList(Action <long> totalCallback, Action <long> progressCallback)
        {
            List <Location> result = new List <Location>(850);

            try
            {
                string           mapFilePath = Path.Combine(SourcePath, MaplistFileName);
                ArchiveFileEntry mapFile     = Archives.GetEntry <ArchiveFileEntry>(mapFilePath);

                totalCallback.Invoke(result.Capacity);

                using (FileSegment stream = mapFile.OpenReadableContentStream())
                    using (StreamReader sr = stream.GetStreamReader())
                        while (!sr.EndOfStream)
                        {
                            string name = sr.ReadLine();
                            if (name == "testno")
                            {
                                progressCallback.Invoke(1);
                                continue;
                            }

                            Location location = FindLocation(name);
                            if (location == null)
                            {
                                progressCallback.Invoke(1);
                                continue;
                            }

                            result.Add(location);
                            location.LoadBaseInformation();
                            progressCallback.Invoke(1);
                        }

                totalCallback.Invoke(result.Count);
            }
            catch
            {
                result.SafeDispose();
                throw;
            }

            return(result.ToArray());
        }
Ejemplo n.º 13
0
        public bool GetBackgroundReader(Location location)
        {
            ArchiveFileEntry mapEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".map");
            ArchiveFileEntry mimEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".mim");

            if (mapEntry == null || mimEntry == null)
            {
                return(true);
            }

            MimFileReader mimReader = new MimFileReader(mimEntry.OpenReadableContentStream());
            MapFileReader mapReader = new MapFileReader(mapEntry.OpenReadableContentStream());

            location.BackgroundReader = new MimGLTextureReader(mimReader, mapReader, true);

            location.SaveRequest &= ~LocationProperty.Background;
            location.Importable  &= ~LocationProperty.Background;
            return(true);
        }
Ejemplo n.º 14
0
        public ArchiveFile(Archive archive, ArchiveFileInfo fileInfo, ArchiveFileEntry fileHeader)
        {
            this.ar         = archive;
            this.info       = fileInfo;
            this.fileHeader = fileHeader;

            this.stream           = this.ar.File.OpenRead();
            this.chunkEntries     = this.ar.Table.ReadChunkTableRange(this.stream, this.fileHeader.firstChunkIdx, this.fileHeader.lastChunkIdx);
            this.chunkFileOffsets = new long[this.chunkEntries.Length];

            this.position = 0;
            this.length   = 0;

            for (int i = 0; i < this.chunkEntries.Length; i++)
            {
                this.chunkFileOffsets[i] = this.length;
                this.length += this.chunkEntries[i].originalSize;
            }
        }
Ejemplo n.º 15
0
        public bool ReadAmbient(Location location)
        {
            ArchiveFileEntry sfxEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".sfx");

            if (sfxEntry == null)
            {
                return(true);
            }

            using (SfxFileReader sfxReader = new SfxFileReader(sfxEntry.OpenReadableContentStream()))
            {
                Ambient result = new Ambient(sfxReader.SoundIds);
                location.Ambient = result;
            }

            location.SaveRequest &= ~LocationProperty.Ambient;
            location.Importable  &= ~LocationProperty.Ambient;
            return(true);
        }
Ejemplo n.º 16
0
        public bool ReadModels(Location location)
        {
            ArchiveFileEntry oneEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue("chara.one");

            if (oneEntry == null)
            {
                return(true);
            }

            using (OneFileReader oneReader = new OneFileReader(oneEntry.OpenReadableContentStream()))
            {
                SafeHGlobalHandle result = oneReader.ReadData();
                location.Models = result;
            }

            location.SaveRequest &= ~LocationProperty.Models;
            location.Importable  &= ~LocationProperty.Models;
            return(true);
        }
Ejemplo n.º 17
0
        public static void HiResToGameData(GameFont gameFont)
        {
            using (DisposableStack disposables = new DisposableStack(2))
            {
                GLTexture leftTexture;
                GLTexture rightTexture;
                GLTextureFactory.HorizontalSplit(gameFont.CharactersImage.Layer, out leftTexture, out rightTexture);
                disposables.Add(leftTexture);
                disposables.Add(rightTexture);

                ArchiveDirectoryEntry mainDirectory  = Archives.GetEntry <ArchiveDirectoryEntry>(GameFontReader.MainPath);
                ArchiveDirectoryEntry menuDirectory  = Archives.GetEntry <ArchiveDirectoryEntry>(GameFontReader.MenuPath);
                ArchiveDirectoryEntry hiresDirectory = menuDirectory.GetChildEntry <ArchiveDirectoryEntry>(GameFontReader.HiResDirectoryName);
                ArchiveFileEntry      tdwEntry       = mainDirectory.GetChildEntry <ArchiveFileEntry>(GameFontReader.HiResCharactersWidthsFileName);
                ArchiveFileEntry      image01        = hiresDirectory.GetChildEntry <ArchiveFileEntry>(GameFontReader.HiResFontImage1FileName);
                ArchiveFileEntry      image02        = hiresDirectory.GetChildEntry <ArchiveFileEntry>(GameFontReader.HiResFontImage2FileName);

                using (Stream output = tdwEntry.OpenWritableCapacityStream())
                    using (TdwFileWriter tdwWriter = new TdwFileWriter(output))
                    {
                        tdwWriter.WriteFontCharactersWidths(gameFont.CharactersWidths);
                        tdwEntry.UpdateMetrics((int)output.Position, tdwEntry.ContentOffset, Compression.None);
                    }

                using (Stream output = image01.OpenWritableCapacityStream())
                    using (TexFileWriter texWriter = new TexFileWriter(output))
                    {
                        texWriter.WriteImage(leftTexture, gameFont.CharactersImage.Palettes);
                        image01.UpdateMetrics((int)output.Position, image01.ContentOffset, Compression.None);
                    }

                using (Stream output = image02.OpenWritableCapacityStream())
                    using (TexFileWriter texWriter = new TexFileWriter(output))
                    {
                        texWriter.WriteImage(rightTexture, gameFont.CharactersImage.Palettes);
                        image02.UpdateMetrics((int)output.Position, image02.ContentOffset, Compression.None);
                    }

                Archives.GetInfo(ArchiveName.Main).Update();
                Archives.GetInfo(ArchiveName.Menu).Update();
            }
        }
Ejemplo n.º 18
0
        public bool ReadWalkmesh(Location location)
        {
            ArchiveFileEntry idEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".id");

            if (idEntry == null)
            {
                return(true);
            }

            using (IdFileReader idReader = new IdFileReader(idEntry.OpenReadableContentStream()))
            {
                WalkmeshTriangle[]    triangles   = idReader.Triangles.Select(t => new WalkmeshTriangle(t.Vertices.Select(v => v.Point).ToArray())).ToArray();
                WalkmeshPassability[] passability = idReader.Accesses.Select(a => new WalkmeshPassability(a.Accesses)).ToArray();
                Walkmesh result = new Walkmesh(triangles, passability);
                location.Walkmesh = result;
            }

            location.SaveRequest &= ~LocationProperty.Walkmesh;
            location.Importable  &= ~LocationProperty.Walkmesh;
            return(true);
        }
Ejemplo n.º 19
0
        public bool ReadEncounters(Location location)
        {
            ArchiveFileEntry mrtEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".mrt");
            ArchiveFileEntry ratEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".rat");

            if (mrtEntry == null || ratEntry == null)
            {
                return(true);
            }

            using (MrtFileReader mrtReader = new MrtFileReader(mrtEntry.OpenReadableContentStream()))
                using (RatFileReader ratReader = new RatFileReader(ratEntry.OpenReadableContentStream()))
                {
                    Encounters result = new Encounters(mrtReader.Troops, (byte)(ratReader.Rates & 0xFF));
                    location.Encounters = result;
                }

            location.SaveRequest &= ~LocationProperty.Encounters;
            location.Importable  &= ~LocationProperty.Encounters;
            return(true);
        }
Ejemplo n.º 20
0
        public static GameFont FromGameData(ArchiveDirectoryEntry directory, string name)
        {
            ArchiveFileEntry tdwEntry = (ArchiveFileEntry)directory.Childs.TryGetValue(name + ".tdw");

            if (tdwEntry == null)
            {
                return(null);
            }

            using (TdwFileReader tdwReader = new TdwFileReader(tdwEntry.OpenReadableContentStream()))
                using (TimFileReader timReader = tdwReader.TimReader)
                {
                    if (timReader == null)
                    {
                        return(null);
                    }

                    GameImage image = GameImageReader.FromTim(timReader);
                    return(new GameFont(image, tdwReader.Table));
                }
        }
Ejemplo n.º 21
0
        public void WriteMonologues(LocalizableStrings monologues)
        {
            ArchiveFileEntry msdEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".msd");

            if (msdEntry == null)
            {
                if (!monologues.IsNullOrEmpty())
                {
                    throw new NotImplementedException();
                }

                return;
            }

            using (Stream output = msdEntry.OpenWritableCapacityStream())
                using (MsdFileWriter msdWriter = new MsdFileWriter(output))
                {
                    msdWriter.WriteAllMonologues(monologues.Select(m => m.Current));
                    msdEntry.UpdateMetrics((int)output.Position, msdEntry.ContentOffset, Compression.None);
                }
        }
Ejemplo n.º 22
0
        public bool ReadPlaceables(Location location)
        {
            ArchiveFileEntry pcbEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".pcb");

            if (pcbEntry == null)
            {
                return(true);
            }

            using (PcbFileReader pcbReader = new PcbFileReader(pcbEntry.OpenReadableContentStream()))
            {
                Placeables placeables = new Placeables(pcbReader.Entries.Length);
                for (int i = 0; i < placeables.Capacity; i++)
                {
                    placeables.Add(new Placeable(pcbReader.Entries[i].Unknown));
                }
                location.Placeables = placeables;
            }

            location.SaveRequest &= ~LocationProperty.Placeables;
            location.Importable  &= ~LocationProperty.Placeables;
            return(true);
        }
Ejemplo n.º 23
0
        public async Task Read(Stream stream)
        {
            byte[] buffer = new byte[Marshal.SizeOf <ArchiveFileEntry>()];
            stream.Read(buffer, 0, buffer.Length);

            BinaryReader reader = new BinaryReader(new MemoryStream(buffer));

            ArchiveFileEntry fileHeader = new ArchiveFileEntry();

            fileHeader.NameHash           = reader.ReadUInt64();
            fileHeader.Filetime           = reader.ReadInt64();
            fileHeader.Flags              = reader.ReadUInt32();
            fileHeader.firstChunkIdx      = reader.ReadUInt32();
            fileHeader.lastChunkIdx       = reader.ReadUInt32();
            fileHeader.firstDependencyIdx = reader.ReadUInt32();
            fileHeader.lastDependencyIdx  = reader.ReadUInt32();

            this.fileHeader = fileHeader;

            try
            {
                this.resolvedName = ArchiveManager.ResolveFileHash(this.fileHeader.NameHash);
            } catch (Exception) {}
        }
Ejemplo n.º 24
0
        private static LocalizableStrings LoadAreaNames()
        {
            lock (_glossaryNode)
            {
                if (_glossaryNode.Value != null)
                {
                    XmlElement node = _glossaryNode.Value.GetChildElement("AreaNames");
                    return(LocalizableString.FromXml(node));
                }

                ArchiveDirectoryEntry dir    = Archives.GetEntry <ArchiveDirectoryEntry>(SourcePath);
                ArchiveFileEntry      entry1 = dir.GetChildEntry <ArchiveFileEntry>(AreaNamesFileName);

                LocalizableStrings result = new LocalizableStrings(256);

                using (DictionaryFileReader dicReader = new DictionaryFileReader(entry1.OpenReadableContentStream()))
                    foreach (string title in dicReader.Titles)
                    {
                        result.Add(new LocalizableString(title, title));
                    }

                return(result);
            }
        }
Ejemplo n.º 25
0
        public static void Main(string[] args)
        {
            bool         verbose       = false;
            bool         showHelp      = false;
            uint         baseRevision  = 0;
            uint         revision      = 0;
            string       deletionsPath = null;
            bool         noCrypto      = false;
            const Endian endian        = Endian.Little;

            var options = new OptionSet()
            {
                {
                    "R|baseRevision=", "specify archive base revision",
                    v => baseRevision = v == null ? 0 : uint.Parse(v)
                },
                { "r|revision=", "specify archive revision", v => revision = v == null ? 0 : uint.Parse(v) },
                { "d|deletions=", "path of deletions file", v => deletionsPath = v },
                { "no-crypto", "don't use any encryption", v => noCrypto = v != null },
                { "v|verbose", "show verbose messages", v => verbose = v != null },
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extras.Count < 1 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ output_ipf input_directory+", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Pack files from input directories into a archive.");
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            var    inputPaths = new List <string>();
            string outputPath;

            if (extras.Count == 1)
            {
                inputPaths.Add(extras[0]);
                outputPath = Path.ChangeExtension(extras[0], ".ipf");
            }
            else
            {
                outputPath = Path.ChangeExtension(extras[0], ".ipf");
                inputPaths.AddRange(extras.Skip(1));
            }

            var pendingEntries = new SortedDictionary <string, PendingEntry>();

            if (verbose == true)
            {
                Console.WriteLine("Finding files...");
            }

            foreach (var relativePath in inputPaths)
            {
                string inputPath = Path.GetFullPath(relativePath);

                if (inputPath.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture)) == true)
                {
                    inputPath = inputPath.Substring(0, inputPath.Length - 1);
                }

                foreach (string path in Directory.GetFiles(inputPath, "*", SearchOption.AllDirectories))
                {
                    string fullPath = Path.GetFullPath(path);

                    string partPath = fullPath.Substring(inputPath.Length + 1)
                                      .Replace(Path.DirectorySeparatorChar, '/')
                                      .Replace(Path.AltDirectorySeparatorChar, '/');

                    var key = partPath.ToLowerInvariant();

                    if (pendingEntries.ContainsKey(key) == true)
                    {
                        Console.WriteLine("Ignoring duplicate of {0}: {1}", partPath, fullPath);

                        if (verbose == true)
                        {
                            Console.WriteLine("  Previously added from: {0}",
                                              pendingEntries[key]);
                        }

                        continue;
                    }

                    var archiveSeparatorIndex = partPath.IndexOf('/');
                    if (archiveSeparatorIndex < 0)
                    {
                        continue;
                    }

                    var archiveName = partPath.Substring(0, archiveSeparatorIndex);
                    var fileName    = partPath.Substring(archiveSeparatorIndex + 1);

                    pendingEntries[key] = new PendingEntry(fullPath, archiveName, fileName);
                }
            }

            using (var output = File.Create(outputPath))
            {
                var fileEntries     = new List <ArchiveFileEntry>();
                var deletionEntries = new List <ArchiveDeletionEntry>();

                if (string.IsNullOrEmpty(deletionsPath) == false)
                {
                    if (verbose == true)
                    {
                        Console.WriteLine("Reading deletions...");
                    }

                    var serializer = JsonSerializer.Create();
                    using (var input = File.OpenRead(deletionsPath))
                        using (var streamReader = new StreamReader(input))
                            using (var jsonReader = new JsonTextReader(streamReader))
                            {
                                var jsonDeletionEntries = serializer.Deserialize <JsonArchiveDeletionEntry[]>(jsonReader);
                                deletionEntries.AddRange(jsonDeletionEntries.Select(jde => new ArchiveDeletionEntry()
                                {
                                    Name    = jde.Name,
                                    Archive = jde.Archive,
                                }));
                            }
                }

                if (verbose == true)
                {
                    Console.WriteLine("Writing file data...");
                }

                long current = 0;
                long total   = pendingEntries.Count;
                var  padding = total.ToString(CultureInfo.InvariantCulture).Length;

                foreach (var pendingEntry in pendingEntries.Select(kv => kv.Value))
                {
                    var fullPath    = pendingEntry.FullPath;
                    var archiveName = pendingEntry.ArchiveName;
                    var fileName    = pendingEntry.FileName;

                    current++;

                    if (verbose == true)
                    {
                        Console.WriteLine("[{0}/{1}] {2} => {3}",
                                          current.ToString(CultureInfo.InvariantCulture).PadLeft(padding),
                                          total,
                                          archiveName,
                                          fileName);
                    }

                    var bytes = File.ReadAllBytes(fullPath);

                    var fileEntry = new ArchiveFileEntry();
                    fileEntry.Name             = fileName;
                    fileEntry.Archive          = archiveName;
                    fileEntry.Hash             = CRC32.Compute(bytes, 0, bytes.Length);
                    fileEntry.UncompressedSize = (uint)bytes.Length;
                    fileEntry.Offset           = (uint)output.Position;

                    if (fileEntry.ShouldCompress == true)
                    {
                        int compressionLevel = Deflater.BEST_COMPRESSION;

                        byte[] compressedBytes;

                        using (var temp = new MemoryStream())
                        {
                            var zlib = new DeflaterOutputStream(temp, new Deflater(compressionLevel, true));
                            zlib.WriteBytes(bytes);
                            zlib.Finish();
                            temp.Flush();
                            temp.Position = 0;

                            compressedBytes = temp.ToArray();
                        }

                        if (noCrypto == false)
                        {
                            var crypto = new ArchiveCrypto();
                            crypto.Encrypt(compressedBytes, 0, compressedBytes.Length);
                        }

                        output.WriteBytes(compressedBytes);

                        fileEntry.CompressedSize = (uint)compressedBytes.Length;
                    }
                    else
                    {
                        fileEntry.CompressedSize = fileEntry.UncompressedSize;
                        output.WriteBytes(bytes);
                    }

                    fileEntries.Add(fileEntry);
                }

                if (verbose == true)
                {
                    Console.WriteLine("Writing file table...");
                }

                long fileTableOffset = output.Position;
                for (int i = 0; i < fileEntries.Count; i++)
                {
                    fileEntries[i].Write(output, endian);
                }

                if (verbose == true)
                {
                    Console.WriteLine("Writing deletion table...");
                }

                long deletionTableOffset = output.Position;
                for (int i = 0; i < deletionEntries.Count; i++)
                {
                    deletionEntries[i].Write(output, endian);
                }

                if (verbose == true)
                {
                    Console.WriteLine("Writing header...");
                }

                ArchiveHeader header;
                header.FileTableCount      = (ushort)fileEntries.Count;
                header.FileTableOffset     = (uint)fileTableOffset;
                header.DeletionTableCount  = (ushort)deletionEntries.Count;
                header.DeletionTableOffset = (uint)deletionTableOffset;
                header.Magic        = ArchiveHeader.Signature;
                header.BaseRevision = baseRevision;
                header.Revision     = revision;
                header.Write(output, endian);

                if (verbose == true)
                {
                    Console.WriteLine("Done!");
                }
            }
        }
Ejemplo n.º 26
0
        public static void Main(string[] args)
        {
            bool showHelp       = false;
            bool overwriteFiles = false;
            bool noCrypto       = false;
            bool verbose        = false;

            var options = new OptionSet()
            {
                { "no-crypto", "don't use any encryption", v => noCrypto = v != null },
                { "o|overwrite", "overwrite existing files", v => overwriteFiles = v != null },
                { "v|verbose", "be verbose", v => verbose = v != null },
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extras.Count < 1 || extras.Count > 2 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_ipf [output_dir]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            var inputPath  = Path.GetFullPath(extras[0]);
            var outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, null) + "_unpack";

            const Endian endian = Endian.Little;

            using (var input = File.OpenRead(inputPath))
            {
                if (input.Length < ArchiveHeader.Size)
                {
                    throw new FormatException();
                }

                input.Seek(-ArchiveHeader.Size, SeekOrigin.End);

                var header = ArchiveHeader.Read(input, endian);
                if (header.Magic != ArchiveHeader.Signature)
                {
                    throw new FormatException();
                }

                var fileEntries = new ArchiveFileEntry[header.FileTableCount];
                if (header.FileTableCount > 0)
                {
                    input.Position = header.FileTableOffset;
                    for (int i = 0; i < header.FileTableCount; i++)
                    {
                        fileEntries[i] = ArchiveFileEntry.Read(input, endian);
                    }
                }

                var deletionEntries = new ArchiveDeletionEntry[header.DeletionTableCount];
                if (header.DeletionTableCount > 0)
                {
                    input.Position = header.DeletionTableOffset;
                    for (int i = 0; i < header.DeletionTableCount; i++)
                    {
                        deletionEntries[i] = ArchiveDeletionEntry.Read(input, endian);
                    }
                }

                long current = 0;
                long total   = fileEntries.Length;
                var  padding = total.ToString(CultureInfo.InvariantCulture).Length;

                if (header.DeletionTableCount > 0)
                {
                    Directory.CreateDirectory(outputPath);

                    using (var output = File.Create(Path.Combine(outputPath, "deletions.json")))
                        using (var streamWriter = new StreamWriter(output))
                            using (var writer = new JsonTextWriter(streamWriter))
                            {
                                writer.Indentation = 2;
                                writer.IndentChar  = ' ';
                                writer.Formatting  = Formatting.Indented;
                                writer.WriteStartArray();
                                foreach (var deletionEntry in deletionEntries)
                                {
                                    writer.WriteStartObject();
                                    writer.WritePropertyName("archive");
                                    writer.WriteValue(deletionEntry.Archive);
                                    writer.WritePropertyName("name");
                                    writer.WriteValue(deletionEntry.Name);
                                    writer.WriteEndObject();
                                }
                                writer.WriteEndArray();
                            }
                }

                foreach (var entry in fileEntries)
                {
                    current++;

                    var entryPath = Path.Combine(outputPath,
                                                 entry.Archive.Replace('/', Path.DirectorySeparatorChar),
                                                 entry.Name.Replace('/', Path.DirectorySeparatorChar));
                    if (overwriteFiles == false && File.Exists(entryPath) == true)
                    {
                        continue;
                    }

                    if (verbose == true)
                    {
                        Console.WriteLine("[{0}/{1}] {2}",
                                          current.ToString(CultureInfo.InvariantCulture).PadLeft(padding),
                                          total,
                                          entry.Name);
                    }

                    input.Seek(entry.Offset, SeekOrigin.Begin);

                    var entryDirectory = Path.GetDirectoryName(entryPath);
                    if (entryDirectory != null)
                    {
                        Directory.CreateDirectory(entryDirectory);
                    }

                    using (var output = File.Create(entryPath))
                    {
                        input.Seek(entry.Offset, SeekOrigin.Begin);

                        if (entry.ShouldCompress == false)
                        {
                            output.WriteFromStream(input, entry.CompressedSize);
                        }
                        else
                        {
                            var bytes = input.ReadBytes(entry.CompressedSize);

                            if (noCrypto == false)
                            {
                                var crypto = new ArchiveCrypto();
                                crypto.Decrypt(bytes, 0, bytes.Length);
                            }

                            using (var temp = new MemoryStream(bytes, false))
                            {
                                var zlib = new InflaterInputStream(temp, new Inflater(true));
                                output.WriteFromStream(zlib, entry.UncompressedSize);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 27
0
 /// <summary>
 /// Gets the full file name with file extension for the specified <see cref="ArchiveFileEntry"/>
 /// </summary>
 /// <param name="fileEntry"></param>
 /// <returns></returns>
 public static string GetFullResourceName(ArchiveFileEntry fileEntry)
 {
     return(GetFullResourceName(fileEntry.FileName, fileEntry.FileType));
 }
Ejemplo n.º 28
0
        public bool ReadScripts(Location location)
        {
            ArchiveFileEntry jsmEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".jsm");

            if (jsmEntry == null)
            {
                return(true);
            }

            AsmCollection result;

            using (JsmFileReader jsmReader = new JsmFileReader(jsmEntry.OpenReadableContentStream()))
            {
                AsmModule previousModule = null;
                result = new AsmCollection(jsmReader.Groups.Length);
                for (ushort g = 0, s = 0, o = 0; g < jsmReader.Groups.Length; g++)
                {
                    JsmGroup  jsmGroup = jsmReader.Groups[g];
                    AsmModule asmGroup = AsmModuleFactory.Create(jsmGroup.Type);
                    asmGroup.Index          = g;
                    asmGroup.ExecutionOrder = jsmGroup.ExecutionOrder;
                    asmGroup.Label          = jsmGroup.Label;
                    asmGroup.Title          = jsmGroup.Label.ToString("D3");
                    asmGroup.PreviousModule = previousModule;
                    if (previousModule != null)
                    {
                        previousModule.NextModule = asmGroup;
                    }
                    previousModule = asmGroup;
                    result.Add(asmGroup.Label, asmGroup);

                    for (int i = 0; i < jsmGroup.ScriptsCount; i++)
                    {
                        JsmScript jsmScript = jsmReader.Scripts[s++];
                        AsmEvent  asmScript = new AsmEvent(asmGroup, jsmScript.OperationsCount)
                        {
                            Flag  = jsmScript.Flag,
                            Label = (ushort)(asmGroup.Label + i)
                        };
                        asmGroup.SetEventByIndex(i, asmScript);

                        for (int k = 0; k < jsmScript.OperationsCount; k++)
                        {
                            JsmOperation jsmOperation = jsmReader.Opertations[o++];
                            asmScript.Add(jsmOperation);
                        }
                    }
                }
            }

            ArchiveFileEntry symEntry = (ArchiveFileEntry)_locationDirectory.Childs.TryGetValue(_name + ".sym");

            if (symEntry == null)
            {
                location.Scripts = result;
                return(true);
            }

            using (SymFileReader symReader = new SymFileReader(symEntry.OpenReadableContentStream()))
            {
                foreach (AsmModule module in result.GetOrderedModules())
                {
                    module.Title = symReader.Labels[module.Label];

                    foreach (AsmEvent evt in module.GetOrderedEvents())
                    {
                        evt.Title = symReader.Labels[evt.Label];
                    }
                }
            }

            location.Scripts = result;

            location.SaveRequest &= ~LocationProperty.Scripts;
            location.Importable  &= ~LocationProperty.Scripts;
            return(true);
        }
Ejemplo n.º 29
0
        public static void Main(string[] args)
        {
            bool showHelp = false;
            bool verbose  = false;
            bool noCrypto = false;

            var options = new OptionSet()
            {
                { "no-crypto", "don't use any encryption", v => noCrypto = v != null },
                { "v|verbose", "be verbose", v => verbose = v != null },
                { "h|help", "show this message and exit", v => showHelp = v != null },
            };

            List <string> extras;

            try
            {
                extras = options.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("{0}: ", GetExecutableName());
                Console.WriteLine(e.Message);
                Console.WriteLine("Try `{0} --help' for more information.", GetExecutableName());
                return;
            }

            if (extras.Count < 1 || extras.Count > 2 || showHelp == true)
            {
                Console.WriteLine("Usage: {0} [OPTIONS]+ input_dir [output_dir]", GetExecutableName());
                Console.WriteLine();
                Console.WriteLine("Options:");
                options.WriteOptionDescriptions(Console.Out);
                return;
            }

            const Endian endian = Endian.Little;

            var inputPath  = Path.GetFullPath(extras[0]);
            var outputPath = extras.Count > 1 ? extras[1] : Path.ChangeExtension(inputPath, null) + "_unpack";

            var archiveInfosUnsorted = new List <ArchiveInfo>();

            var basePathInfo = new List <KeyValuePair <string, string> >();

            basePathInfo.Add(new KeyValuePair <string, string>(Path.Combine(inputPath, "data"), "*.ipf"));
            basePathInfo.Add(new KeyValuePair <string, string>(Path.Combine(inputPath, "patch"), "*_001001.ipf"));

            foreach (var kv in basePathInfo)
            {
                var basePath = kv.Key;
                var filter   = kv.Value;

                if (Directory.Exists(basePath) == false)
                {
                    continue;
                }

                foreach (var archivePath in Directory.GetFiles(basePath, filter))
                {
                    using (var input = File.OpenRead(archivePath))
                    {
                        if (input.Length < ArchiveHeader.Size)
                        {
                            throw new FormatException();
                        }

                        input.Seek(-ArchiveHeader.Size, SeekOrigin.End);

                        var header = ArchiveHeader.Read(input, endian);
                        if (header.Magic != ArchiveHeader.Signature)
                        {
                            throw new FormatException();
                        }

                        archiveInfosUnsorted.Add(
                            new ArchiveInfo(archivePath,
                                            header.BaseRevision,
                                            header.Revision,
                                            header.FileTableCount + header.DeletionTableCount));
                    }
                }
            }

            var archiveInfos = archiveInfosUnsorted.OrderBy(ai => ai.BaseRevision)
                               .ThenBy(ai => ai.Revision)
                               .ThenBy(ai => ai.Path)
                               .ToList();

            long current = 0;
            long total   = archiveInfos.Sum(ai => ai.TotalCount);
            var  padding = total.ToString(CultureInfo.InvariantCulture).Length;

            var dataPaths = new Dictionary <string, List <string> >();

            foreach (var archiveInfo in archiveInfos)
            {
                using (var input = File.OpenRead(archiveInfo.Path))
                {
                    if (input.Length < ArchiveHeader.Size)
                    {
                        throw new FormatException();
                    }

                    input.Seek(-ArchiveHeader.Size, SeekOrigin.End);

                    var header = ArchiveHeader.Read(input, endian);
                    if (header.Magic != ArchiveHeader.Signature)
                    {
                        throw new FormatException();
                    }

                    var fileEntries = new ArchiveFileEntry[header.FileTableCount];
                    if (header.FileTableCount > 0)
                    {
                        input.Position = header.FileTableOffset;
                        for (int i = 0; i < header.FileTableCount; i++)
                        {
                            fileEntries[i] = ArchiveFileEntry.Read(input, endian);
                        }
                    }

                    var deletionEntries = new ArchiveDeletionEntry[header.DeletionTableCount];
                    if (header.DeletionTableCount > 0)
                    {
                        input.Position = header.DeletionTableOffset;
                        for (int i = 0; i < header.DeletionTableCount; i++)
                        {
                            deletionEntries[i] = ArchiveDeletionEntry.Read(input, endian);
                        }
                    }

                    foreach (var entry in deletionEntries)
                    {
                        current++;

                        if (entry.Archive == "data")
                        {
                            var dataPath = entry.Name.ToLowerInvariant();

                            if (dataPaths.ContainsKey(dataPath) == false)
                            {
                                // probably an incorrect entry pointing to a directory
                                continue;
                            }

                            foreach (var entryPath in dataPaths[dataPath])
                            {
                                if (File.Exists(entryPath) == true)
                                {
                                    File.Delete(entryPath);
                                }
                            }

                            dataPaths.Remove(entry.Name);
                        }
                        else
                        {
                            throw new NotImplementedException();

                            var entryPath = Path.Combine(outputPath, entry.Archive, entry.Name);
                            if (File.Exists(entryPath) == true)
                            {
                                File.Delete(entryPath);
                            }
                        }
                    }

                    foreach (var entry in fileEntries)
                    {
                        current++;

                        var entryPath = Path.Combine(outputPath,
                                                     entry.Archive.Replace('/', Path.DirectorySeparatorChar),
                                                     entry.Name.Replace('/', Path.DirectorySeparatorChar));

                        var dataPath = entry.Name.ToLowerInvariant();
                        if (dataPaths.ContainsKey(dataPath) == false)
                        {
                            dataPaths[dataPath] = new List <string>();
                        }

                        if (dataPaths[dataPath].Contains(entryPath) == false)
                        {
                            dataPaths[dataPath].Add(entryPath);
                        }

                        if (verbose == true)
                        {
                            Console.WriteLine("[{0}/{1}] {2}/{3}",
                                              current.ToString(CultureInfo.InvariantCulture).PadLeft(padding),
                                              total,
                                              entry.Archive,
                                              entry.Name);
                        }

                        input.Seek(entry.Offset, SeekOrigin.Begin);

                        var entryDirectory = Path.GetDirectoryName(entryPath);
                        if (entryDirectory != null)
                        {
                            Directory.CreateDirectory(entryDirectory);
                        }

                        using (var output = File.Create(entryPath))
                        {
                            input.Seek(entry.Offset, SeekOrigin.Begin);

                            if (entry.ShouldCompress == false)
                            {
                                output.WriteFromStream(input, entry.CompressedSize);
                            }
                            else
                            {
                                var bytes = input.ReadBytes(entry.CompressedSize);

                                if (noCrypto == false)
                                {
                                    var crypto = new ArchiveCrypto();
                                    crypto.Decrypt(bytes, 0, bytes.Length);
                                }

                                using (var temp = new MemoryStream(bytes, false))
                                {
                                    var zlib = new InflaterInputStream(temp, new Inflater(true));
                                    output.WriteFromStream(zlib, entry.UncompressedSize);
                                }
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 30
0
 public virtual void ExtractArchiveFile(ArchiveFileEntry afe)
 {
 }