public IList<string> AssetFullPaths { get; set; } // TODO: Hack work around, to avoid having to refactor Assets into a object array, should be refactored! public static XmlGame Create(HawkFile f) { try { var x = new XmlDocument(); x.Load(f.GetStream()); var y = x.SelectSingleNode("./BizHawk-XMLGame"); if (y == null) { return null; } var ret = new XmlGame { GI = { System = y.Attributes["System"].Value, Name = y.Attributes["Name"].Value, Status = RomStatus.Unknown }, Xml = x }; string fullpath = string.Empty; var n = y.SelectSingleNode("./LoadAssets"); if (n != null) { var HashStream = new MemoryStream(); int? OriginalIndex = null; foreach (XmlNode a in n.ChildNodes) { string filename = a.Attributes["FileName"].Value; byte[] data = new byte[0]; if (filename[0] == '|') { // in same archive var ai = f.FindArchiveMember(filename.Substring(1)); if (ai != null) { if (OriginalIndex == null) { OriginalIndex = f.GetBoundIndex(); } f.Unbind(); f.BindArchiveMember(ai); data = f.GetStream().ReadAllBytes(); } else { throw new Exception("Couldn't load XMLGame Asset \"" + filename + "\""); } } else { // relative path fullpath = Path.GetDirectoryName(f.CanonicalFullPath.Split('|').First()) ?? string.Empty; fullpath = Path.Combine(fullpath, filename.Split('|').First()); try { using (var hf = new HawkFile(fullpath)) { if (hf.IsArchive) { var archiveItem = hf.ArchiveItems.First(ai => ai.Name == filename.Split('|').Skip(1).First()); hf.Unbind(); hf.BindArchiveMember(archiveItem); data = hf.GetStream().ReadAllBytes(); } else { data = File.ReadAllBytes(fullpath.Split('|').First()); } } } catch { throw new Exception("Couldn't load XMLGame LoadAsset \"" + filename + "\""); } } ret.Assets.Add(new KeyValuePair<string, byte[]>(filename, data)); ret.AssetFullPaths.Add(fullpath); using (var sha1 = System.Security.Cryptography.SHA1.Create()) { sha1.TransformFinalBlock(data, 0, data.Length); HashStream.Write(sha1.Hash, 0, sha1.Hash.Length); } } ret.GI.Hash = HashStream.GetBuffer().HashSHA1(0, (int)HashStream.Length); HashStream.Close(); if (OriginalIndex != null) { f.Unbind(); f.BindArchiveMember((int)OriginalIndex); } } else { ret.GI.Hash = "0000000000000000000000000000000000000000"; } return ret; } catch (Exception ex) { throw new InvalidOperationException(ex.ToString()); } }
// LSMV file format: http://tasvideos.org/Lsnes/Movieformat.html private static BkmMovie ImportLSMV(string path, out string errorMsg, out string warningMsg) { errorMsg = warningMsg = string.Empty; var m = new BkmMovie(path); var hf = new HawkFile(path); // .LSMV movies are .zip files containing data files. if (!hf.IsArchive) { errorMsg = "This is not an archive."; return null; } string platform = "SNES"; foreach (var item in hf.ArchiveItems) { if (item.Name == "authors") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string authors = Encoding.UTF8.GetString(stream.ReadAllBytes()); string author_list = ""; string author_last = ""; using (StringReader reader = new StringReader(authors)) { string line; // Each author is on a different line. while ((line = reader.ReadLine()) != null) { string author = line.Trim(); if (author != "") { if (author_last != "") { author_list += author_last + ", "; } author_last = author; } } } if (author_list != "") { author_list += "and "; } if (author_last != "") { author_list += author_last; } m.Header[HeaderKeys.AUTHOR] = author_list; hf.Unbind(); } else if (item.Name == "coreversion") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string coreversion = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Comments.Add(COREORIGIN + " " + coreversion); hf.Unbind(); } else if (item.Name == "gamename") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string gamename = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[HeaderKeys.GAMENAME] = gamename; hf.Unbind(); } else if (item.Name == "gametype") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string gametype = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); // TODO: Handle the other types. switch (gametype) { case "gdmg": platform = "GB"; break; case "ggbc": case "ggbca": platform = "GBC"; break; case "sgb_ntsc": case "sgb_pal": platform = "SNES"; Global.Config.GB_AsSGB = true; break; } bool pal = (gametype == "snes_pal" || gametype == "sgb_pal"); m.Header[HeaderKeys.PAL] = pal.ToString(); hf.Unbind(); } else if (item.Name == "input") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string input = Encoding.UTF8.GetString(stream.ReadAllBytes()); int lineNum = 0; using (StringReader reader = new StringReader(input)) { lineNum++; string line; while ((line = reader.ReadLine()) != null) { if (line == "") { continue; } m = ImportTextFrame(line, lineNum, m, path, platform, ref warningMsg); if (errorMsg != "") { hf.Unbind(); return null; } } } hf.Unbind(); } else if (item.Name.StartsWith("moviesram.")) { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); byte[] moviesram = stream.ReadAllBytes(); if (moviesram.Length != 0) { errorMsg = "Movies that begin with SRAM are not supported."; hf.Unbind(); return null; } hf.Unbind(); } else if (item.Name == "port1") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string port1 = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[PORT1] = port1; hf.Unbind(); } else if (item.Name == "port2") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string port2 = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[PORT2] = port2; hf.Unbind(); } else if (item.Name == "projectid") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string projectid = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[PROJECTID] = projectid; hf.Unbind(); } else if (item.Name == "rerecords") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string rerecords = Encoding.UTF8.GetString(stream.ReadAllBytes()); int rerecordCount; // Try to parse the re-record count as an integer, defaulting to 0 if it fails. try { rerecordCount = int.Parse(rerecords); } catch { rerecordCount = 0; } m.Rerecords = (ulong)rerecordCount; hf.Unbind(); } else if (item.Name.EndsWith(".sha256")) { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string rom = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); int pos = item.Name.LastIndexOf(".sha256"); string name = item.Name.Substring(0, pos); m.Header[SHA256 + "_" + name] = rom; hf.Unbind(); } else if (item.Name == "savestate") { errorMsg = "Movies that begin with a savestate are not supported."; return null; } else if (item.Name == "subtitles") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string subtitles = Encoding.UTF8.GetString(stream.ReadAllBytes()); using (StringReader reader = new StringReader(subtitles)) { string line; while ((line = reader.ReadLine()) != null) m = ImportTextSubtitle(line, m, path); } hf.Unbind(); } else if (item.Name == "starttime.second") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string startSecond = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[STARTSECOND] = startSecond; hf.Unbind(); } else if (item.Name == "starttime.subsecond") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string startSubSecond = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[STARTSUBSECOND] = startSubSecond; hf.Unbind(); } else if (item.Name == "systemid") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string systemid = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Comments.Add(EMULATIONORIGIN + " " + systemid); hf.Unbind(); } } m.Header[HeaderKeys.PLATFORM] = platform; LibsnesCore.SnesSyncSettings ss = new LibsnesCore.SnesSyncSettings(); ss.Profile = "Compatibility"; m.SyncSettingsJson = ConfigService.SaveWithType(ss); return m; }
void RunImportJob(IEnumerable<string> files) { bool didSomething = false; var basepath = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null); string errors = ""; foreach(var f in files) { using (var hf = new HawkFile(f)) { if (hf.IsArchive) { //blech. the worst extraction code in the universe. string extractpath = System.IO.Path.GetTempFileName() + ".dir"; DirectoryInfo di = null; di = System.IO.Directory.CreateDirectory(extractpath); try { foreach (var ai in hf.ArchiveItems) { hf.BindArchiveMember(ai); var stream = hf.GetStream(); var ms = new MemoryStream(); Util.CopyStream(hf.GetStream(), ms, stream.Length); string outfile = ai.Name; string myname = Path.GetFileName(outfile); outfile = Path.Combine(extractpath, myname); File.WriteAllBytes(outfile, ms.ToArray()); hf.Unbind(); didSomething |= RunImportJobSingle(basepath, outfile, ref errors); } } finally { di.Delete(true); } } else didSomething |= RunImportJobSingle(basepath, f, ref errors); } } if (errors != "") System.Windows.Forms.MessageBox.Show(errors, "Error importing these files"); if (didSomething) DoScan(); }