Пример #1
0
        private 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 = $"{Path.GetTempFileName()}.dir";
                    DirectoryInfo di          = 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();

                            if (_cbAllowImport.Checked || Manager.CanFileBeImported(outfile))
                            {
                                didSomething |= RunImportJobSingle(basePath, outfile, ref errors);
                            }
                        }
                    }
                    finally
                    {
                        di.Delete(true);
                    }
                }
                else
                {
                    if (_cbAllowImport.Checked || Manager.CanFileBeImported(hf.CanonicalFullPath))
                    {
                        didSomething |= RunImportJobSingle(basePath, f, ref errors);
                    }
                }
            }

            if (!string.IsNullOrEmpty(errors))
            {
                MessageBox.Show(errors, "Error importing these files");
            }

            if (didSomething)
            {
                DoScan();
            }
        }
Пример #2
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();
            }
        }
Пример #3
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());
            }
        }
Пример #4
0
        protected override void RunImport()
        {
            Result.Movie.HeaderEntries[HeaderKeys.Core] = CoreNames.Bsnes;

            var hf = new HawkFile(SourceFile.FullName);

            // .LSMV movies are .zip files containing data files.
            if (!hf.IsArchive)
            {
                Result.Errors.Add("This is not an archive.");
                return;
            }

            var ss = new LibsnesCore.SnesSyncSettings
            {
                LeftPort  = LibsnesControllerDeck.ControllerType.Gamepad,
                RightPort = LibsnesControllerDeck.ControllerType.Gamepad
            };

            _deck = new LibsnesControllerDeck(ss);

            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 authorList = "";
                    string authorLast = "";
                    using (var 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 (authorLast != "")
                                {
                                    authorList += $"{authorLast}, ";
                                }

                                authorLast = author;
                            }
                        }
                    }

                    if (authorList != "")
                    {
                        authorList += "and ";
                    }

                    if (authorLast != "")
                    {
                        authorList += authorLast;
                    }

                    Result.Movie.HeaderEntries[HeaderKeys.Author] = authorList;
                    hf.Unbind();
                }
                else if (item.Name == "coreversion")
                {
                    hf.BindArchiveMember(item.Index);
                    var    stream      = hf.GetStream();
                    string coreVersion = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim();
                    Result.Movie.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();
                    Result.Movie.HeaderEntries[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";
                        Config.GbAsSgb = true;
                        break;
                    }

                    bool pal = gametype == "snes_pal" || gametype == "sgb_pal";
                    Result.Movie.HeaderEntries[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 (var reader = new StringReader(input))
                    {
                        lineNum++;
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            if (line == "")
                            {
                                continue;
                            }

                            // Insert an empty frame in lsmv snes movies
                            // https://github.com/TASVideos/BizHawk/issues/721
                            // Both emulators send the input to bsnes core at the same V interval, but:
                            // lsnes' frame boundary occurs at V = 241, after which the input is read;
                            // BizHawk's frame boundary is just before automatic polling;
                            // This isn't a great place to add this logic but this code is a mess
                            if (lineNum == 1 && platform == "SNES")
                            {
                                // Note that this logic assumes the first non-empty log entry is a valid input log entry
                                // and that it is NOT a subframe input entry.  It seems safe to assume subframe input would not be on the first line
                                Result.Movie.AppendFrame(EmptyLmsvFrame());
                            }

                            ImportTextFrame(line, platform);
                        }
                    }

                    hf.Unbind();
                }
                else if (item.Name.StartsWith("moviesram."))
                {
                    hf.BindArchiveMember(item.Index);
                    var    stream    = hf.GetStream();
                    byte[] movieSram = stream.ReadAllBytes();
                    if (movieSram.Length != 0)
                    {
                        Result.Errors.Add("Movies that begin with SRAM are not supported.");
                        hf.Unbind();
                        return;
                    }
                }
                else if (item.Name == "port1")
                {
                    hf.BindArchiveMember(item.Index);
                    var    stream = hf.GetStream();
                    string port1  = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim();
                    Result.Movie.HeaderEntries["port1"] = port1;
                    ss.LeftPort = LibsnesControllerDeck.ControllerType.Gamepad;
                    _deck       = new LibsnesControllerDeck(ss);
                    hf.Unbind();
                }
                else if (item.Name == "port2")
                {
                    hf.BindArchiveMember(item.Index);
                    var    stream = hf.GetStream();
                    string port2  = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim();
                    Result.Movie.HeaderEntries["port2"] = port2;
                    ss.RightPort = LibsnesControllerDeck.ControllerType.Gamepad;
                    _deck        = new LibsnesControllerDeck(ss);
                    hf.Unbind();
                }
                else if (item.Name == "projectid")
                {
                    hf.BindArchiveMember(item.Index);
                    var    stream    = hf.GetStream();
                    string projectId = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim();
                    Result.Movie.HeaderEntries["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;
                    }

                    Result.Movie.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);
                    Result.Movie.HeaderEntries[$"SHA256_{name}"] = rom;
                    hf.Unbind();
                }
                else if (item.Name == "savestate")
                {
                    Result.Errors.Add("Movies that begin with a savestate are not supported.");
                    return;
                }
                else if (item.Name == "subtitles")
                {
                    hf.BindArchiveMember(item.Index);
                    var    stream    = hf.GetStream();
                    string subtitles = Encoding.UTF8.GetString(stream.ReadAllBytes());
                    using (var reader = new StringReader(subtitles))
                    {
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            var subtitle = ImportTextSubtitle(line);
                            if (!string.IsNullOrEmpty(subtitle))
                            {
                                Result.Movie.Subtitles.AddFromString(subtitle);
                            }
                        }
                    }

                    hf.Unbind();
                }
                else if (item.Name == "starttime.second")
                {
                    hf.BindArchiveMember(item.Index);
                    var    stream      = hf.GetStream();
                    string startSecond = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim();
                    Result.Movie.HeaderEntries["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();
                    Result.Movie.HeaderEntries["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();
                    Result.Movie.Comments.Add($"{EmulationOrigin} {systemId}");
                    hf.Unbind();
                }
            }

            Result.Movie.HeaderEntries[HeaderKeys.Platform] = platform;
            Result.Movie.SyncSettingsJson = ConfigService.SaveWithType(ss);
            Config.PreferredCores["SNES"] = CoreNames.Bsnes;             // TODO: convert to snes9x if it is the user's preference
        }
Пример #5
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());
            }
        }