예제 #1
0
        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
                };

                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
                            var 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));

                        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
        } = new List <string>();                                                   // TODO: Hack work around, to avoid having to refactor Assets into a object array, should be refactored!

        /// <exception cref="InvalidOperationException">internal error</exception>
        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 = "";

                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;
                        if (filename[0] == '|')
                        {
                            // in same archive
                            var ai = f.FindArchiveMember(filename.Substring(1));
                            if (ai != null)
                            {
                                originalIndex ??= f.BoundIndex;
                                f.Unbind();
                                f.BindArchiveMember(ai.Value);
                                data = f.GetStream().ReadAllBytes();
                            }
                            else
                            {
                                throw new Exception($"Couldn't load XMLGame Asset \"{filename}\"");
                            }
                        }
                        else
                        {
                            // relative path
                            fullPath = Path.GetDirectoryName(f.CanonicalFullPath.Split('|').First()) ?? "";
                            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();

                                    filename = filename.Split('|').Skip(1).First();
                                }
                                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);
                        var sha1 = SHA1Checksum.Compute(data);
                        hashStream.Write(sha1, 0, sha1.Length);
                    }

                    ret.GI.Hash = SHA1Checksum.ComputeDigestHex(hashStream.GetBufferAsSpan());
                    hashStream.Close();
                    if (originalIndex != null)
                    {
                        f.Unbind();
                        f.BindArchiveMember((int)originalIndex);
                    }
                }
                else
                {
                    ret.GI.Hash = SHA1Checksum.Zero;
                }

                return(ret);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException(ex.ToString());
            }
        }