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()); } }
/// <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(); }
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(); } } }
/// <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); }
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); }
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)); } }
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(); }
// //文件删除测试 //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()); } }
/// <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)); } } }
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); }
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); }
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)); }
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(); } } } }
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)); }
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 }
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)); } }
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)); }
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); } }
// //列举目录测试 //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()); } }
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)); } } }
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); }
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); }
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)); }
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)); }
/// <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); }
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)); } }
/// <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)); }
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)); } } }
/// <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); }
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)); } }
/// <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; }
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 }
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; }
/// <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; }