예제 #1
0
파일: ArcHibiki.cs 프로젝트: minhrg/GARbro
        Stream OpenLstIndex(ArcView file, string dat_name, HibikiDatScheme scheme)
        {
            var lst_name = Path.ChangeExtension(file.Name, ".lst");

            if (VFS.FileExists(lst_name))
            {
                return(VFS.OpenStream(lst_name));
            }
            else if ("init.dat" == dat_name)
            {
                return(file.CreateStream());
            }
            // try to open 'init.dat' archive in the same directory
            var init_dat = VFS.CombinePath(VFS.GetDirectoryName(file.Name), "init.dat");

            if (!VFS.FileExists(init_dat))
            {
                return(file.CreateStream());
            }
            try
            {
                using (var init = VFS.OpenView(init_dat))
                    using (var init_arc = TryOpenWithScheme(init, ReadCount(init), scheme))
                    {
                        lst_name = Path.GetFileName(lst_name);
                        var lst_entry = init_arc.Dir.First(e => e.Name == lst_name);
                        return(init_arc.OpenEntry(lst_entry));
                    }
            }
            catch
            {
                return(file.CreateStream());
            }
        }
예제 #2
0
        /// <summary>
        /// We don't want to make the installer index all the archives, that's just a waste of time, so instead
        /// we'll pass just enough information to VFS to let it know about the files we have.
        /// </summary>
        private void PrimeVFS()
        {
            HashedArchives.Do(a => VFS.AddKnown(new VirtualFile()
            {
                Paths = new string[] { a.Value },
                Hash  = a.Key
            }));
            VFS.RefreshIndexes();


            ModList.Directives
            .OfType <FromArchive>()
            .Do(f =>
            {
                var updated_path = new string[f.ArchiveHashPath.Length];
                f.ArchiveHashPath.CopyTo(updated_path, 0);
                updated_path[0] = VFS.HashIndex[updated_path[0]].Where(e => e.IsConcrete).First().FullPath;
                VFS.AddKnown(new VirtualFile()
                {
                    Paths = updated_path
                });
            });

            VFS.BackfillMissing();
        }
예제 #3
0
        void LoadPreviewText(PreviewFile preview)
        {
            Stream file = null;

            try
            {
                file = VFS.OpenBinaryStream(preview.Entry).AsStream;
                if (!TextView.IsTextFile(file))
                {
                    ResetPreviewPane();
                    return;
                }
                var enc = EncodingChoice.SelectedItem as Encoding;
                if (null == enc)
                {
                    enc = TextView.GuessEncoding(file);
                    EncodingChoice.SelectedItem = enc;
                }
                TextView.DisplayStream(file, enc);
                ActiveViewer     = TextView;
                CurrentTextInput = file;
                file             = null;
            }
            catch (Exception X)
            {
                SetStatusText(X.Message);
            }
            finally
            {
                if (file != null)
                {
                    file.Dispose();
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Changes the current directory to newDir
        /// </summary>
        /// <param name="newDir">The new working directory</param>
        /// <returns>Errorcode</returns>
        public static ErrorCode ChDir(string newDir)
        {
            newDir = VFS.CreateAbsolutePath(newDir);
            Node node = VFS.GetByAbsolutePath(newDir);

            if (node == null)
            {
                Heap.Free(newDir);
                return(ErrorCode.ENOENT);
            }

            if (node.Flags != NodeFlags.DIRECTORY)
            {
                Heap.Free(newDir);
                Heap.Free(node);
                return(ErrorCode.ENOTDIR);
            }

            Heap.Free(node);

            // GetByAbsolutePath makes sure there's a slash on the end
            Tasking.CurrentTask.CurrentDirectory = newDir;

            return(ErrorCode.SUCCESS);
        }
예제 #5
0
파일: ImageERI.cs 프로젝트: uboaa/GARbro
        internal EriReader ReadImageData(IBinaryStream stream, EriMetaData meta)
        {
            stream.Position = meta.StreamPos;
            Color[] palette = null;
            using (var input = new EriFile(stream.AsStream))
            {
                for (;;) // ReadSection throws an exception in case of EOF
                {
                    var section = input.ReadSection();
                    if ("Stream  " == section.Id)
                    {
                        continue;
                    }
                    if ("ImageFrm" == section.Id)
                    {
                        break;
                    }
                    if ("Palette " == section.Id && meta.BPP <= 8 && section.Length <= 0x400)
                    {
                        palette = ReadPalette(stream.AsStream, (int)section.Length);
                        continue;
                    }
                    input.BaseStream.Seek(section.Length, SeekOrigin.Current);
                }
            }
            var reader = new EriReader(stream.AsStream, meta, palette);

            reader.DecodeImage();

            if (!string.IsNullOrEmpty(meta.Description))
            {
                var    tags = ParseTagInfo(meta.Description);
                string ref_file;
                if (tags.TryGetValue("reference-file", out ref_file))
                {
                    ref_file = ref_file.TrimEnd(null);
                    if (!string.IsNullOrEmpty(ref_file))
                    {
                        if ((meta.BPP + 7) / 8 < 3)
                        {
                            throw new InvalidFormatException();
                        }

                        ref_file = VFS.CombinePath(VFS.GetDirectoryName(meta.FileName), ref_file);
                        using (var ref_src = VFS.OpenBinaryStream(ref_file))
                        {
                            var ref_info = ReadMetaData(ref_src) as EriMetaData;
                            if (null == ref_info)
                            {
                                throw new FileNotFoundException("Referenced image not found", ref_file);
                            }
                            ref_info.FileName = ref_file;
                            var ref_reader = ReadImageData(ref_src, ref_info);
                            reader.AddImageBuffer(ref_reader);
                        }
                    }
                }
            }
            return(reader);
        }
예제 #6
0
        public override ArcFile TryOpen(ArcView file)
        {
            var arc_name = Path.GetFileName(file.Name);
            var parsed   = OldDatOpener.ArcNameParser.ParseName(arc_name);

            if (null == parsed)
            {
                return(null);
            }
            var toc_name = VFS.CombinePath(VFS.GetDirectoryName(file.Name), parsed.Item1);
            var toc      = ReadToc(toc_name, 4);

            if (null == toc)
            {
                return(null);
            }
            using (var index = new DatIndexReader(toc, file))
            {
                if (!index.Read())
                {
                    return(null);
                }
                return(ArchiveFromDir(file, index.Dir, index.HasImages));
            }
        }
예제 #7
0
파일: PlarfGame.cs 프로젝트: myblindy/plarf
        private void LoadGameData()
        {
            ResourceClasses = new List <ResourceClass>();
            foreach (var resfile in VFS.GetFiles(@"ResourceClasses", "*.dat"))
            {
                using (var resfilestream = VFS.OpenStream(resfile))
                    ResourceClasses.Add(new ResourceClass(new DataFile(resfilestream)));
            }

            ResourceTemplates = new Dictionary <string, Resource>();
            foreach (var resfile in VFS.GetFiles(@"Resources", "*.dat"))
            {
                using (var resfilestream = VFS.OpenStream(resfile))
                {
                    var res = new Resource(new DataFile(resfilestream));
                    ResourceTemplates.Add(res.Name, res);
                }
            }

            using (var hfilestream = VFS.OpenStream("human.dat"))
                HumanTemplate = new Human(new DataFile(hfilestream));

            BuildingClasses = new Dictionary <string, Building>();
            foreach (var bfile in VFS.GetFiles(@"Buildings", "*.dat"))
            {
                using (var bfilestream = VFS.OpenStream(bfile))
                {
                    var b = Building.FromDataFile(new DataFile(bfilestream));
                    BuildingClasses.Add(b.Name, b);
                }
            }

            WorkerTypes = BuildingClasses.Values.Select(b => b.WorkerType).Where(t => t != null).ToList();
        }
예제 #8
0
        //
        //文件删除测试
        //api http://open.dbank.com/wiki/index.php?title=Nsp.VFS.rmfile
        //
        public void RmfileTest()
        {
            //获取VFS服务对象
            VFS vfs = nC.service <VFS>(typeof(VFS));

            try
            {
                string[] files = { "/Netdisk/test.cpp", "/Netdisk/penjin.txt", "/Netdisk/libiconv.rar" };
                Result   rmres = vfs.rmfile(files, false, null);

                //打印结果
                int i;
                Console.Write("删除成功:\n");
                for (i = 0; i < rmres.successList.Length; i++)
                {
                    Console.Write(rmres.successList[i].name + " ");
                }
                Console.WriteLine();
                Console.Write("删除失败:\n");
                for (i = 0; i < rmres.failList.Length; i++)
                {
                    Console.WriteLine(rmres.failList[i].name + " 原因 " + rmres.failList[i].errMsg);
                }
                Console.WriteLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
예제 #9
0
 /// <summary>
 // Try to parse file containing game meta-information.
 /// </summary>
 internal string TryParseMeta(string meta_arc_name)
 {
     if (!VFS.FileExists(meta_arc_name))
     {
         return(null);
     }
     using (var unpacker = new TocUnpacker(meta_arc_name))
     {
         if (unpacker.Length > 0x1000)
         {
             return(null);
         }
         var data = unpacker.Unpack(8);
         if (null == data)
         {
             return(null);
         }
         using (var content = new BinMemoryStream(data))
         {
             int title_length = content.ReadInt32();
             if (title_length <= 0 || title_length > content.Length)
             {
                 return(null);
             }
             var title = content.ReadBytes(title_length);
             if (title.Length != title_length)
             {
                 return(null);
             }
             return(Encodings.cp932.GetString(title));
         }
     }
 }
예제 #10
0
        public bool LoadInis()
        {
            if (Engine == EngineType.YurisRevenge)
            {
                _rules = VFS.Open <IniFile>("rulesmd.ini");
                _art   = VFS.Open <IniFile>("artmd.ini");
            }
            else if (Engine == EngineType.Firestorm)
            {
                _rules = VFS.Open <IniFile>("rules.ini");
                _art   = VFS.Open <IniFile>("art.ini");

                Logger.Info("Merging Firestorm rules with TS rules");
                _rules.MergeWith(VFS.Open <IniFile>("firestrm.ini"));
                _art.MergeWith(VFS.Open <IniFile>("artfs.ini"));
            }
            else
            {
                _rules = VFS.Open <IniFile>("rules.ini");
                _art   = VFS.Open <IniFile>("art.ini");
            }

            if (_rules == null || _art == null)
            {
                Logger.Fatal("Rules or art config file could not be loaded! You cannot render a YR/FS map" +
                             " without the expansion installed");
                return(false);
            }
            return(true);
        }
예제 #11
0
 byte[] ReadBaseImage(Stream file, RctMetaData meta)
 {
     file.Position = meta.DataOffset;
     byte[] name_bin = new byte[meta.AddSize];
     if (name_bin.Length != file.Read(name_bin, 0, name_bin.Length))
     {
         throw new EndOfStreamException();
     }
     try
     {
         string name     = Encodings.cp932.GetString(name_bin, 0, name_bin.Length - 1);
         string dir_name = Path.GetDirectoryName(meta.FileName);
         name = VFS.CombinePath(dir_name, name);
         if (VFS.FileExists(name))
         {
             using (var base_file = VFS.OpenSeekableStream(name))
             {
                 var base_info = ReadMetaData(base_file) as RctMetaData;
                 if (null != base_info && 0 == base_info.AddSize &&
                     meta.Width == base_info.Width && meta.Height == base_info.Height)
                 {
                     base_info.FileName = name;
                     return(ReadPixelsData(base_file, base_info));
                 }
             }
         }
     }
     catch { /* ignore baseline image read errors */ }
     return(null);
 }
예제 #12
0
        public override ImageData Read(IBinaryStream file, ImageMetaData info)
        {
            BitmapPalette palette = null;
            PixelFormat   format  = PixelFormats.Gray8;

            foreach (var pal_name in GetPaletteNames(info.FileName))
            {
                if (!VFS.FileExists(pal_name))
                {
                    continue;
                }
                try
                {
                    using (var pal = VFS.OpenStream(pal_name))
                    {
                        palette = ReadPalette(pal, 0x100, PaletteFormat.Bgr);
                        format  = PixelFormats.Indexed8;
                    }
                }
                catch { /* ignore palette read errors */ }
                break;
            }
            file.Position = 0x10;
            var pixels = file.ReadBytes((int)info.Width * (int)info.Height);

            return(ImageData.Create(info, format, palette, pixels));
        }
예제 #13
0
        void ImportKeys(string source_name)
        {
            var script_lpk = VFS.CombinePath(Path.GetDirectoryName(source_name), "SCRIPT.LPK");

            using (var script_file = VFS.OpenView(script_lpk))
                using (var script_arc = Open(ScriptName, script_file, CurrentScheme, null))
                {
                    if (null == script_arc)
                    {
                        throw new UnknownEncryptionScheme();
                    }
                    var entry = script_arc.Dir.FirstOrDefault(e => e.Name.Equals("gameinit.sob", StringComparison.InvariantCultureIgnoreCase));
                    if (null == entry)
                    {
                        throw new FileNotFoundException("Missing 'gameinit.sob' entry in SCRIPT.LPK");
                    }
                    using (var gameinit = script_arc.OpenEntry(entry))
                    {
                        var init_data = new byte[gameinit.Length];
                        gameinit.Read(init_data, 0, init_data.Length);
                        if (!ParseGameInit(init_data))
                        {
                            throw new UnknownEncryptionScheme();
                        }
                    }
                }
        }
예제 #14
0
        public override ImageData Read(Stream stream, ImageMetaData info)
        {
            var         meta   = (DziMetaData)info;
            PixelFormat format = PixelFormats.Bgra32;
            var         bitmap = new WriteableBitmap((int)meta.Width, (int)meta.Height, ImageData.DefaultDpiX,
                                                     ImageData.DefaultDpiY, format, null);
            int actual_width  = 0;
            int actual_height = 0;

            byte[] pixels = null;
            foreach (var tile in meta.Tiles.First())
            {
                var image_entry = VFS.GetFiles(tile.FileName + ".*").FirstOrDefault();
                if (null == image_entry)
                {
                    throw new FileNotFoundException("Tile not found", tile.FileName);
                }
                using (var input = VFS.OpenStream(image_entry))
                {
                    var image = Read(image_entry.Name, input);
                    if (null == image)
                    {
                        throw new FileFormatException("Unknown DZI tile format");
                    }
                    var converted = image.Bitmap;
                    if (converted.Format != format)
                    {
                        converted = new FormatConvertedBitmap(converted, format, null, 0);
                    }
                    int stride    = converted.PixelWidth * 4;
                    int tile_size = stride * converted.PixelHeight;
                    if (null == pixels || pixels.Length < tile_size)
                    {
                        pixels = new byte[tile_size];
                    }
                    converted.CopyPixels(pixels, stride, 0);
                    var width  = Math.Min(converted.PixelWidth, bitmap.PixelWidth - tile.X);
                    var height = Math.Min(converted.PixelHeight, bitmap.PixelHeight - tile.Y);
                    var rect   = new Int32Rect(tile.X, tile.Y, width, height);
                    bitmap.WritePixels(rect, pixels, stride, 0);
                    if (tile.X + width > actual_width)
                    {
                        actual_width = tile.X + width;
                    }
                    if (tile.Y + height > actual_height)
                    {
                        actual_height = tile.Y + height;
                    }
                }
            }
            BitmapSource result = bitmap;

            if (actual_width < bitmap.PixelWidth || actual_height < bitmap.PixelHeight)
            {
                var rect = new Int32Rect(0, 0, actual_width, actual_height);
                result = new CroppedBitmap(bitmap, rect);
            }
            result.Freeze();
            return(new ImageData(result, meta));
        }
예제 #15
0
        private static EngineType DetectEngineFromRules(MapFile mf,
                                                        IniFile rulesTS, IniFile rulesFS, IniFile rulesRA2, IniFile rulesYR,
                                                        TheaterSettings theaterTS, TheaterSettings theaterFS, TheaterSettings theaterRA2, TheaterSettings theaterYR,
                                                        VFS vfsTS, VFS vfsFS, VFS vfsRA2, VFS vfsYR)
        {
            double tsScore  = PercentageObjectsKnown(mf, vfsTS, rulesTS, theaterTS);
            double fsScore  = PercentageObjectsKnown(mf, vfsFS, rulesFS, theaterFS);
            double ra2Score = PercentageObjectsKnown(mf, vfsRA2, rulesRA2, theaterRA2);
            double yrScore  = PercentageObjectsKnown(mf, vfsYR, rulesYR, theaterYR);

            double maxScore = Math.Max(Math.Max(Math.Max(tsScore, fsScore), ra2Score), yrScore);

            if (maxScore == ra2Score)
            {
                return(EngineType.RedAlert2);
            }
            else if (maxScore == yrScore)
            {
                return(EngineType.YurisRevenge);
            }
            else if (maxScore == tsScore)
            {
                return(EngineType.TiberianSun);
            }
            else if (maxScore == fsScore)
            {
                return(EngineType.Firestorm);
            }
            return(EngineType.YurisRevenge);            // default
        }
예제 #16
0
        public override ArcFile TryOpen(ArcView file)
        {
            string lst_name = Path.ChangeExtension(file.Name, ".lst");

            if (lst_name == file.Name || !VFS.FileExists(lst_name))
            {
                return(null);
            }
            var lst_entry = VFS.FindFile(lst_name);
            int count     = (int)(lst_entry.Size / 0x16);

            if (count > 0xffff || count * 0x16 != lst_entry.Size)
            {
                return(null);
            }
            using (var lst = VFS.OpenView(lst_entry))
            {
                var  dir          = new List <Entry> (count);
                uint index_offset = 0;
                for (int i = 0; i < count; ++i)
                {
                    string name  = lst.View.ReadString(index_offset, 14);
                    var    entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Offset = lst.View.ReadUInt32(index_offset + 14);
                    entry.Size   = lst.View.ReadUInt32(index_offset + 18);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += 0x16;
                }
                return(new ArcFile(file, this, dir));
            }
        }
예제 #17
0
파일: ArcBIN.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!VFS.IsPathEqualsToFileName(file.Name, "0000.bin"))
            {
                return(null);
            }
            if ((file.MaxOffset % BitmapSize) != 0)
            {
                return(null);
            }
            int count = (int)(file.MaxOffset / BitmapSize);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            uint offset = 0;
            var  dir    = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var entry = new Entry {
                    Name   = string.Format("{0:D4}.bmp", i),
                    Type   = "image",
                    Offset = offset,
                    Size   = BitmapSize,
                };
                dir.Add(entry);
                offset += BitmapSize;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #18
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (VFS.IsVirtual || !file.Name.HasExtension(".dat"))
            {
                return(null);
            }
            var db_files = VFS.GetFiles(VFS.CombinePath(VFS.GetDirectoryName(file.Name), "*.db"));

            if (!db_files.Any())
            {
                return(null);
            }
            using (var igs = new IgsDbReader(file.Name))
            {
                foreach (var db_name in db_files.Select(e => e.Name))
                {
                    int arc_id;
                    if (igs.GetArchiveId(db_name, out arc_id))
                    {
                        var dir = igs.ReadIndex(arc_id);
                        if (0 == dir.Count)
                        {
                            return(null);
                        }
                        return(new ArcFile(file, this, dir));
                    }
                }
                return(null);
            }
        }
예제 #19
0
        //
        //列举目录测试
        //api http://open.dbank.com/wiki/index.php?title=Nsp.VFS.lsdir
        //
        public void LsdirTest()
        {
            VFS vfs = nC.service <VFS>(typeof(VFS));

            try
            {
                string[] fields = { "name", "url", "size", "type" };
                LsResult lsres  = vfs.lsdir("/Netdisk/", fields, 3);
                Console.WriteLine(lsres.childList[0].name + " " + lsres.childList[0].type);

                //lsdir新接口参数
                Dictionary <string, object> option = new Dictionary <string, object>();
                option.Add("type", 3);
                option.Add("vertion", null);
                lsres = vfs.lsdir("/Netdisk/", fields, option);

                Console.WriteLine("{0,-32}{1,16}{2,16}", "名称", "类型", "大小");
                for (int i = 0; i < lsres.childList.Length; i++)
                {
                    Console.WriteLine("{0,-32}{1,16}{2,16:N}", lsres.childList[i].name, lsres.childList[i].type, lsres.childList[i].size);
                }
            }
            catch (Exception ex) {
                Console.WriteLine(ex.ToString());
            }
        }
예제 #20
0
파일: ImageRCT.cs 프로젝트: zxc120/GARbro
        ImageData ApplyMaskToImage(RctMetaData info, byte[] image, string mask_name)
        {
            using (var mask_file = VFS.OpenBinaryStream(mask_name))
            {
                var mask_info = s_rc8_format.Value.ReadMetaData(mask_file);
                if (null == mask_info ||
                    info.Width != mask_info.Width || info.Height != mask_info.Height)
                {
                    throw new InvalidFormatException();
                }

                using (var reader = new Rc8Format.Reader(mask_file, mask_info))
                {
                    reader.Unpack();
                    var palette    = reader.Palette;
                    int dst_stride = (int)info.Width * 4;
                    var pixels     = new byte[dst_stride * (int)info.Height];
                    var alpha      = reader.Data;
                    int a_src      = 0;
                    int src        = 0;
                    for (int dst = 0; dst < pixels.Length; dst += 4)
                    {
                        pixels[dst]     = image[src++];
                        pixels[dst + 1] = image[src++];
                        pixels[dst + 2] = image[src++];
                        var color = palette[alpha[a_src++]];
                        pixels[dst + 3] = (byte)~((color.B + color.G + color.R) / 3);
                    }
                    return(ImageData.Create(info, PixelFormats.Bgra32, null, pixels, dst_stride));
                }
            }
        }
예제 #21
0
        public Dictionary <string, ArcView> GenerateResourceMap(List <Entry> dir)
        {
            var res_map   = new Dictionary <string, ArcView>();
            var asset_dir = VFS.GetDirectoryName(m_res_name);

            foreach (AssetEntry entry in dir)
            {
                if (null == entry.Bundle)
                {
                    continue;
                }
                if (res_map.ContainsKey(entry.Bundle.Name))
                {
                    continue;
                }
                var bundle_name = VFS.CombinePath(asset_dir, entry.Bundle.Name);
                if (!VFS.FileExists(bundle_name))
                {
                    entry.Bundle = null;
                    entry.Offset = entry.AssetObject.Offset;
                    entry.Size   = entry.AssetObject.Size;
                    continue;
                }
                res_map[entry.Bundle.Name] = VFS.OpenView(bundle_name);
            }
            return(res_map);
        }
예제 #22
0
파일: ImageRCT.cs 프로젝트: zxc120/GARbro
 byte[] ReadBaseImage(IBinaryStream file, RctMetaData meta)
 {
     try
     {
         file.Position = meta.DataOffset;
         var    name     = file.ReadCString(meta.BaseNameLength);
         string dir_name = VFS.GetDirectoryName(meta.FileName);
         name = VFS.CombinePath(dir_name, name);
         if (VFS.FileExists(name))
         {
             using (var base_file = VFS.OpenBinaryStream(name))
             {
                 var base_info = ReadMetaData(base_file) as RctMetaData;
                 if (null != base_info &&
                     meta.Width == base_info.Width && meta.Height == base_info.Height)
                 {
                     base_info.BaseRecursionDepth = meta.BaseRecursionDepth + 1;
                     base_info.FileName           = name;
                     return(ReadPixelsData(base_file, base_info));
                 }
             }
         }
     }
     catch { /* ignore baseline image read errors */ }
     return(null);
 }
예제 #23
0
        public override ArcFile TryOpen(ArcView file)
        {
            var arc_name = Path.GetFileName(file.Name);
            var parsed   = ArcNameParser.ParseName(arc_name);

            if (null == parsed)
            {
                return(null);
            }
            var toc_name = VFS.CombinePath(VFS.GetDirectoryName(file.Name), parsed.Item1);
            var toc      = ReadToc(toc_name, 4);

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

            bool has_images = false;
            var  dir        = new List <Entry>();

            using (var toc_stream = new MemoryStream(toc))
                using (var index = new StreamReader(toc_stream))
                {
                    string line;
                    while ((line = index.ReadLine()) != null)
                    {
                        var fields = line.Split(',');
                        if (fields.Length != 5)
                        {
                            return(null);
                        }
                        var    name = Path.ChangeExtension(fields[0], fields[4]);
                        string type = "";
                        if ("b" == fields[4])
                        {
                            type       = "image";
                            has_images = true;
                        }
                        else if ("k" == fields[4] || "j" == fields[4])
                        {
                            type = "audio";
                        }
                        var entry = new PackedEntry
                        {
                            Name         = name,
                            Type         = type,
                            Offset       = UInt32.Parse(fields[3]),
                            Size         = UInt32.Parse(fields[2]),
                            UnpackedSize = UInt32.Parse(fields[1]),
                        };
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        entry.IsPacked = entry.UnpackedSize != entry.Size;
                        dir.Add(entry);
                    }
                }
            return(ArchiveFromDir(file, dir, has_images));
        }
예제 #24
0
        public override IImageDecoder OpenImage(ArcFile arc, Entry entry)
        {
            OrgMetaData info;

            if (VFS.IsPathEqualsToFileName(arc.File.Name, "MASK.DAT"))
            {
                info = new OrgMetaData {
                    Width  = arc.File.View.ReadUInt32(entry.Offset),
                    Height = arc.File.View.ReadUInt32(entry.Offset + 4),
                    BPP    = 8,
                    IsMask = true,
                };
            }
            else
            {
                byte has_alpha = arc.File.View.ReadByte(entry.Offset);
                byte type      = arc.File.View.ReadByte(entry.Offset + 1);
                if (has_alpha > 1 || type < 1 || type > 3)
                {
                    return(base.OpenImage(arc, entry));
                }
                info = new OrgMetaData {
                    Width    = arc.File.View.ReadUInt16(entry.Offset + 2),
                    Height   = arc.File.View.ReadUInt16(entry.Offset + 4),
                    HasAlpha = has_alpha != 0,
                    Method   = type,
                    BPP      = 32,
                };
            }
            var input = arc.File.CreateStream(entry.Offset, entry.Size);

            return(new OrgImageDecoder(input, info));
        }
예제 #25
0
        /// <summary>
        /// Starts a new process based on the given path and arguments
        /// </summary>
        /// <param name="path">The path</param>
        /// <param name="argv">The arguments</param>
        /// <param name="flags">Spawn flags</param>
        /// <returns>Errorcode or PID</returns>
        public static int StartProcess(string path, string[] argv, Task.SpawnFlags flags)
        {
            if (argv == null)
            {
                Panic.DoPanic("argv == null");
            }

            Node node = VFS.GetByAbsolutePath(path);

            if (node == null)
            {
                return(-(int)ErrorCode.ENOENT);
            }

            // Open and create buffer
            VFS.Open(node, (int)FileMode.O_RDONLY);
            byte[] buffer = new byte[node.Size];
            if (buffer == null)
            {
                Heap.Free(node);
                VFS.Close(node);
                return(-(int)ErrorCode.ENOMEM);
            }

            // Fill buffer contents
            VFS.Read(node, 0, node.Size, buffer);
            VFS.Close(node);

            // Pass execution to ELF loader
            int status = ELFLoader.Execute(buffer, node.Size, argv, flags);

            Heap.Free(buffer);
            Heap.Free(node);
            return(status);
        }
예제 #26
0
        public override ArcFile TryOpen(ArcView file)
        {
            string lstname = file.Name + ".lst"; //we find the name of the file with the name of the original file

            if (!VFS.FileExists(lstname))
            {
                return(null);
            }
            using (var lst = VFS.OpenView(lstname)) //lst is a view on the file lst that is created with the name of the file of the view
            {
                List <Entry> dir = null;
                try
                {
                    dir = OpenMoon(lst, file.MaxOffset);
                }
                catch { /* ignore parse errors */ }
                if (null == dir)
                {
                    dir = OpenNexton(lst, file.MaxOffset);
                }
                if (null == dir)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
        }
예제 #27
0
        /// <summary>
        /// Opens a file
        /// </summary>
        /// <param name="path">The path</param>
        /// <param name="flags">The flags</param>
        /// <returns>The file descriptor ID</returns>
        public static int Open(string path, int flags)
        {
            if (path.Length == 0)
            {
                return(-(int)ErrorCode.EINVAL);
            }

            Node node = null;

            // Check if O_CREATE
            if ((flags & 0x0200) > 0)
            {
                node = VFS.GetOffsetNodeByPath(path, 1);

                node = VFS.Create(node, "test");
                if (node == null)
                {
                    return(-(int)ErrorCode.ENOENT);
                }
            }
            else
            {
                node = VFS.GetByPath(path);
                if (node == null)
                {
                    return(-(int)ErrorCode.ENOENT);
                }

                VFS.Open(node, flags);
            }

            FileDescriptors descriptors = Tasking.CurrentTask.FileDescriptors;

            return(descriptors.AddNode(node));
        }
예제 #28
0
 ImageData ApplyMaskToWipData(ImageMetaData info, byte[] image, string mask_name)
 {
     using (var mask_file = VFS.OpenBinaryStream(mask_name))
     {
         if (mask_file.Signature != Signature)
         {
             throw new InvalidFormatException();
         }
         var mask_info = ReadMetaData(mask_file) as WipMetaData;
         if (null == mask_info || 8 != mask_info.BPP ||
             info.Width != mask_info.Width || info.Height != mask_info.Height)
         {
             throw new InvalidFormatException();
         }
         using (var reader = new Reader(mask_file, mask_info))
         {
             reader.Unpack();
             var palette    = reader.Palette;
             int dst_stride = (int)info.Width * 4;
             var pixels     = new byte[dst_stride * (int)info.Height];
             int plane_size = (int)info.Width * (int)info.Height;
             var alpha      = reader.Data;
             int dst        = 0;
             for (int src = 0; src < plane_size; ++src)
             {
                 pixels[dst++] = image[src];
                 pixels[dst++] = image[src + plane_size];
                 pixels[dst++] = image[src + plane_size * 2];
                 var color = palette[alpha[src]];
                 pixels[dst++] = (byte)((color.B + color.G + color.R) / 3);
             }
             return(ImageData.Create(info, PixelFormats.Bgra32, null, pixels, dst_stride));
         }
     }
 }
예제 #29
0
        /// <summary>
        /// Look for 'key.fkey' file within nearby directories specified by KeyLocations.
        /// </summary>
        static byte[] FindKeyFile(ArcView arc_file)
        {
            // QLIE archives with key could be opened at the physical file system level only
            if (VFS.IsVirtual)
            {
                return(null);
            }
            var dir_name = Path.GetDirectoryName(arc_file.Name);

            foreach (var path in KeyLocations)
            {
                var name = Path.Combine(dir_name, path, "key.fkey");
                if (File.Exists(name))
                {
                    Trace.WriteLine("reading key from " + name, "[QLIE]");
                    return(File.ReadAllBytes(name));
                }
            }
            var pattern = VFS.CombinePath(dir_name, @"..\*.exe");

            foreach (var exe_file in VFS.GetFiles(pattern))
            {
                using (var exe = new ExeFile.ResourceAccessor(exe_file.Name))
                {
                    var reskey = exe.GetResource("RESKEY", "#10");
                    if (reskey != null)
                    {
                        return(reskey);
                    }
                }
            }
            return(null);
        }
예제 #30
0
        public override ArcFile TryOpen(ArcView file)
        {
            string lstname = file.Name + ".lst";

            if (!VFS.FileExists(lstname))
            {
                return(null);
            }
            using (var lst = VFS.OpenView(lstname))
            {
                List <Entry> dir = null;
                try
                {
                    dir = OpenMoon(lst, file.MaxOffset);
                }
                catch { /* ignore parse errors */ }
                if (null == dir)
                {
                    dir = OpenNexton(lst, file.MaxOffset);
                }
                if (null == dir)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
        }
예제 #31
0
        /// <summary>Detect map type.</summary>
        /// <param name="rules">The rules.ini file to be used.</param>
        /// <returns>The engine to be used to render this map.</returns>
        public static EngineType DetectEngineType(MapFile mf)
        {
            var vfsTS = new VFS();
            var vfsFS = new VFS();
            var vfsRA2 = new VFS();
            var vfsYR = new VFS();

            if (Directory.Exists(VFS.TSInstallDir)) {
                vfsTS.LoadMixes(VFS.TSInstallDir, EngineType.TiberianSun);
                vfsFS.LoadMixes(VFS.TSInstallDir, EngineType.Firestorm);
            }

            if (Directory.Exists(VFS.RA2InstallDir)) {
                vfsRA2.LoadMixes(VFS.RA2InstallDir, EngineType.RedAlert2);
                vfsYR.LoadMixes(VFS.RA2InstallDir, EngineType.YurisRevenge);
            }

            IniFile rulesTS = vfsTS.OpenFile<IniFile>("rules.ini");
            IniFile rulesFS = vfsFS.OpenFile<IniFile>("rules.ini");
            if (rulesFS != null)
                rulesFS.MergeWith(vfsFS.OpenFile<IniFile>("firestrm.ini"));

            IniFile rulesRA2 = vfsRA2.OpenFile<IniFile>("rules.ini");
            IniFile rulesYR = vfsYR.OpenFile<IniFile>("rulesmd.ini");

            TheaterType theater = Theater.TheaterTypeFromString(mf.ReadString("Map", "Theater"));
            TheaterSettings thsTS = ModConfig.DefaultsTS.GetTheater(theater);
            TheaterSettings thsFS = ModConfig.DefaultsFS.GetTheater(theater);
            TheaterSettings thsRA2 = ModConfig.DefaultsRA2.GetTheater(theater);
            TheaterSettings thsYR = ModConfig.DefaultsYR.GetTheater(theater);

            if (thsTS != null)
                foreach (var f in thsTS.Mixes)
                    vfsTS.AddItem(f);

            if (thsFS != null)
                foreach (var f in thsFS.Mixes)
                    vfsFS.AddItem(f);

            if (thsRA2 != null)
                foreach (var f in thsRA2.Mixes)
                    vfsRA2.AddItem(f);

            if (thsYR != null)
                foreach (var f in thsYR.Mixes)
                    vfsYR.AddItem(f);

            var ret = DetectEngineFromRules(mf, rulesTS, rulesFS, rulesRA2, rulesYR, thsTS, thsFS, thsRA2, thsYR, vfsTS, vfsFS, vfsRA2, vfsYR);
            Logger.Debug("Engine type detected as {0}", ret);
            return ret;
        }
예제 #32
0
		private static EngineType DetectEngineFromRules(MapFile mf,
			IniFile rulesTS, IniFile rulesFS, IniFile rulesRA2, IniFile rulesYR,
			TheaterSettings theaterTS, TheaterSettings theaterFS, TheaterSettings theaterRA2, TheaterSettings theaterYR,
			VFS vfsTS, VFS vfsFS, VFS vfsRA2, VFS vfsYR) {

			double tsScore = PercentageObjectsKnown(mf, vfsTS, rulesTS, theaterTS);
			double fsScore = PercentageObjectsKnown(mf, vfsFS, rulesFS, theaterFS);
			double ra2Score = PercentageObjectsKnown(mf, vfsRA2, rulesRA2, theaterRA2);
			double yrScore = PercentageObjectsKnown(mf, vfsYR, rulesYR, theaterYR);

			double maxScore = Math.Max(Math.Max(Math.Max(tsScore, fsScore), ra2Score), yrScore);
			if (maxScore == ra2Score) return EngineType.RedAlert2;
			else if (maxScore == yrScore) return EngineType.YurisRevenge;
			else if (maxScore == tsScore) return EngineType.TiberianSun;
			else if (maxScore == fsScore) return EngineType.Firestorm;
			return EngineType.YurisRevenge; // default
		}
예제 #33
0
		private static double PercentageObjectsKnown(MapFile mf, VFS vfs, IniFile rules, TheaterSettings ths) {
			if (rules == null || ths == null) return 0.0;
			var theaterIni = vfs.OpenFile<IniFile>(ths.TheaterIni);
			if (theaterIni == null) return 0.0;

			Func<MapObject, IniFile.IniSection, bool> objectKnown = (obj, section) => {
				if (obj is NamedMapObject) {
					string name = (obj as NamedMapObject).Name;
					return section.OrderedEntries.Any(kvp => kvp.Value.ToString().Equals(name, StringComparison.InvariantCultureIgnoreCase));
				}
				else if (obj is NumberedMapObject) {
					int number = (obj as NumberedMapObject).Number;
					return section.HasKey(number.ToString());
				}
				return false; // should not happen
			};

			int known = 0;
			int total = 0;

			var tiles = mf.Tiles.Where(t => t != null).DistinctBy(t => t.TileNum);
			var tilesCollection = new TileCollection(ths, vfs.OpenFile<IniFile>(ths.TheaterIni));
			tilesCollection.InitTilesets();
			known += mf.Tiles.Count(o => o.TileNum <= tilesCollection.NumTiles);
			total += mf.Tiles.Count();

			var infs = mf.Infantries.DistinctBy(o => o.Name);
			known += infs.Count(o => objectKnown(o, rules.GetSection("InfantryTypes")));
			total += infs.Count();

			var terrains = mf.Infantries.DistinctBy(o => o.Name);
			known += terrains.Count(o => objectKnown(o, rules.GetSection("TerrainTypes")));
			total += terrains.Count();

			var units = mf.Infantries.DistinctBy(o => o.Name);
			known += units.Count(o => objectKnown(o, rules.GetSection("VehicleTypes")));
			total += units.Count();

			var aircrafts = mf.Aircrafts.DistinctBy(o => o.Name);
			known += aircrafts.Count(o => objectKnown(o, rules.GetSection("AircraftTypes")));
			total += aircrafts.Count();

			var smudges = mf.Smudges.DistinctBy(o => o.Name);
			known += smudges.Count(o => objectKnown(o, rules.GetSection("SmudgeTypes")));
			total += smudges.Count();

			var structures = mf.Structures.DistinctBy(o => o.Name);
			known += structures.Count(o => objectKnown(o, rules.GetSection("BuildingTypes"))
				|| objectKnown(o, rules.GetSection("OverlayTypes")));
			total += structures.Count();

			var overlays = mf.Overlays.DistinctBy(o => o.Number);
			known += overlays.Count(o => objectKnown(o, rules.GetSection("OverlayTypes")));
			total += overlays.Count();


			return known / (double)total;
		}
예제 #34
0
        /// <summary>Gets the determine map name. </summary>
        /// <returns>The filename to save the map as</returns>
        public static string DetermineMapName(MapFile map, EngineType engine)
        {
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(map.FileName);

            IniFile.IniSection basic = map.GetSection("Basic");
            if (basic.ReadBool("Official") == false)
                return StripPlayersFromName(MakeValidFileName(basic.ReadString("Name", fileNameWithoutExtension)));

            string mapExt = Path.GetExtension(Settings.InputFile);
            string missionName = "";
            string mapName = "";
            PktFile.PktMapEntry pktMapEntry = null;
            MissionsFile.MissionEntry missionEntry = null;

            // campaign mission
            if (!basic.ReadBool("MultiplayerOnly") && basic.ReadBool("Official")) {
                string missionsFile;
                switch (engine) {
                    case EngineType.TiberianSun:
                    case EngineType.RedAlert2:
                        missionsFile = "mission.ini";
                        break;
                    case EngineType.Firestorm:
                        missionsFile = "mission1.ini";
                        break;
                    case EngineType.YurisRevenge:
                        missionsFile = "missionmd.ini";
                        break;
                    default:
                        throw new ArgumentOutOfRangeException("engine");
                }
                var mf = VFS.Open<MissionsFile>(missionsFile);
                if (mf != null)
                    missionEntry = mf.GetMissionEntry(Path.GetFileName(map.FileName));
                if (missionEntry != null)
                    missionName = (engine >= EngineType.RedAlert2) ? missionEntry.UIName : missionEntry.Name;
            }

            else {
                // multiplayer map
                string pktEntryName = fileNameWithoutExtension;
                PktFile pkt = null;

                if (FormatHelper.MixArchiveExtensions.Contains(mapExt)) {
                    // this is an 'official' map 'archive' containing a PKT file with its name
                    try {
                        var mix = new MixFile(File.Open(Settings.InputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
                        pkt = mix.OpenFile(fileNameWithoutExtension + ".pkt", FileFormat.Pkt) as PktFile;
                        // pkt file is cached by default, so we can close the handle to the file
                        mix.Close();

                        if (pkt != null && pkt.MapEntries.Count > 0)
                            pktEntryName = pkt.MapEntries.First().Key;
                    }
                    catch (ArgumentException) { }
                }

                else {
                    // determine pkt file based on engine
                    switch (engine) {
                        case EngineType.TiberianSun:
                        case EngineType.RedAlert2:
                            pkt = VFS.Open<PktFile>("missions.pkt");
                            break;
                        case EngineType.Firestorm:
                            pkt = VFS.Open<PktFile>("multi01.pkt");
                            break;
                        case EngineType.YurisRevenge:
                            pkt = VFS.Open<PktFile>("missionsmd.pkt");
                            break;
                        default:
                            throw new ArgumentOutOfRangeException("engine");
                    }
                }

                // fallback for multiplayer maps with, .map extension,
                // no YR objects so assumed to be ra2, but actually meant to be used on yr
                if (mapExt == ".map" && pkt != null && !pkt.MapEntries.ContainsKey(pktEntryName) && engine >= EngineType.RedAlert2) {
                    var vfs = new VFS();
                    vfs.AddItem(Settings.InputFile);
                    pkt = vfs.OpenFile<PktFile>("missionsmd.pkt");
                }

                if (pkt != null && !string.IsNullOrEmpty(pktEntryName))
                    pktMapEntry = pkt.GetMapEntry(pktEntryName);
            }

            // now, if we have a map entry from a PKT file,
            // for TS we are done, but for RA2 we need to look in the CSV file for the translated mapname
            if (engine <= EngineType.Firestorm) {
                if (pktMapEntry != null)
                    mapName = pktMapEntry.Description;
                else if (missionEntry != null) {
                    if (engine == EngineType.TiberianSun) {
                        string campaignSide;
                        string missionNumber;

                        if (missionEntry.Briefing.Length >= 3) {
                            campaignSide = missionEntry.Briefing.Substring(0, 3);
                            missionNumber = missionEntry.Briefing.Length > 3 ? missionEntry.Briefing.Substring(3) : "";
                            missionName = "";
                            mapName = string.Format("{0} {1} - {2}", campaignSide, missionNumber.TrimEnd('A').PadLeft(2, '0'), missionName);
                        }
                        else if (missionEntry.Name.Length >= 10) {
                            mapName = missionEntry.Name;
                        }
                    }
                    else {
                        // FS map names are constructed a bit easier
                        mapName = missionName.Replace(":", " - ");
                    }
                }
                else if (!string.IsNullOrEmpty(basic.ReadString("Name")))
                    mapName = basic.ReadString("Name", fileNameWithoutExtension);
            }

                // if this is a RA2/YR mission (csfEntry set) or official map with valid pktMapEntry
            else if (missionEntry != null || pktMapEntry != null) {
                string csfEntryName = missionEntry != null ? missionName : pktMapEntry.Description;

                string csfFile = engine == EngineType.YurisRevenge ? "ra2md.csf" : "ra2.csf";
                _logger.Info("Loading csf file {0}", csfFile);
                var csf = VFS.Open<CsfFile>(csfFile);
                mapName = csf.GetValue(csfEntryName.ToLower());

                if (missionEntry != null) {
                    if (mapName.Contains("Operation: ")) {
                        string missionMapName = Path.GetFileName(map.FileName);
                        if (char.IsDigit(missionMapName[3]) && char.IsDigit(missionMapName[4])) {
                            string missionNr = Path.GetFileName(map.FileName).Substring(3, 2);
                            mapName = mapName.Substring(0, mapName.IndexOf(":")) + " " + missionNr + " -" +
                                      mapName.Substring(mapName.IndexOf(":") + 1);
                        }
                    }
                }
                else {
                    // not standard map
                    if ((pktMapEntry.GameModes & PktFile.GameMode.Standard) == 0) {
                        if ((pktMapEntry.GameModes & PktFile.GameMode.Megawealth) == PktFile.GameMode.Megawealth)
                            mapName += " (Megawealth)";
                        if ((pktMapEntry.GameModes & PktFile.GameMode.Duel) == PktFile.GameMode.Duel)
                            mapName += " (Land Rush)";
                        if ((pktMapEntry.GameModes & PktFile.GameMode.NavalWar) == PktFile.GameMode.NavalWar)
                            mapName += " (Naval War)";
                    }
                }
            }

            // not really used, likely empty, but if this is filled in it's probably better than guessing
            if (mapName == "" && basic.SortedEntries.ContainsKey("Name"))
                mapName = basic.ReadString("Name");

            if (mapName == "") {
                _logger.Warn("No valid mapname given or found, reverting to default filename {0}", fileNameWithoutExtension);
                mapName = fileNameWithoutExtension;
            }
            else {
                _logger.Info("Mapname found: {0}", mapName);
            }

            mapName = StripPlayersFromName(MakeValidFileName(mapName)).Replace("  ", " ");
            return mapName;
        }