예제 #1
0
파일: XmlGame.cs 프로젝트: henke37/BizHawk
		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());
			}
		}
예제 #2
0
		// 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;
		}
예제 #3
0
		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();
		}