From dbe0229810d481c7be135ba562bb5256fe285ac8 Mon Sep 17 00:00:00 2001 From: nattthebear Date: Thu, 21 Jan 2021 07:50:50 -0500 Subject: [PATCH] Use SharpZipLib for lsmv import instead of hawkfile (#2589) Use the same library and ideas that savestate and movie loading use. --- .../movie/import/LsmvImport.cs | 82 +++++++------------ 1 file changed, 29 insertions(+), 53 deletions(-) diff --git a/src/BizHawk.Client.Common/movie/import/LsmvImport.cs b/src/BizHawk.Client.Common/movie/import/LsmvImport.cs index 6db604642a..1ad1e80243 100644 --- a/src/BizHawk.Client.Common/movie/import/LsmvImport.cs +++ b/src/BizHawk.Client.Common/movie/import/LsmvImport.cs @@ -6,6 +6,7 @@ using BizHawk.Common.IOExtensions; using BizHawk.Emulation.Common; using BizHawk.Emulation.Cores; using BizHawk.Emulation.Cores.Nintendo.SNES; +using ICSharpCode.SharpZipLib.Zip; namespace BizHawk.Client.Common.movie.import { @@ -14,20 +15,26 @@ namespace BizHawk.Client.Common.movie.import [ImporterFor("LSNES", ".lsmv")] internal class LsmvImport : MovieImporter { + private static readonly byte[] Zipheader = { 0x50, 0x4b, 0x03, 0x04 }; private LibsnesControllerDeck _deck; 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) + using (var fs = new FileStream(SourceFile.FullName, FileMode.Open, FileAccess.Read)) { - Result.Errors.Add("This is not an archive."); - return; + byte[] data = new byte[4]; + fs.Read(data, 0, 4); + if (!data.SequenceEqual(Zipheader)) + { + Result.Errors.Add("This is not a zip file."); + return; + } } + using var zip = new ZipFile(SourceFile.FullName); + var ss = new LibsnesCore.SnesSyncSettings { LeftPort = LibsnesControllerDeck.ControllerType.Gamepad, @@ -37,12 +44,11 @@ namespace BizHawk.Client.Common.movie.import string platform = "SNES"; - foreach (var item in hf.ArchiveItems) + foreach (ZipEntry item in zip) { if (item.Name == "authors") { - hf.BindArchiveMember(item.Index); - var stream = hf.GetStream(); + using var stream = zip.GetInputStream(item); string authors = Encoding.UTF8.GetString(stream.ReadAllBytes()); string authorList = ""; string authorLast = ""; @@ -77,28 +83,22 @@ namespace BizHawk.Client.Common.movie.import } Result.Movie.HeaderEntries[HeaderKeys.Author] = authorList; - hf.Unbind(); } else if (item.Name == "coreversion") { - hf.BindArchiveMember(item.Index); - var stream = hf.GetStream(); + using var stream = zip.GetInputStream(item); 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(); + using var stream = zip.GetInputStream(item); 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(); + using var stream = zip.GetInputStream(item); string gametype = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); // TODO: Handle the other types. @@ -120,12 +120,10 @@ namespace BizHawk.Client.Common.movie.import 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(); + using var stream = zip.GetInputStream(item); string input = Encoding.UTF8.GetString(stream.ReadAllBytes()); int lineNum = 0; @@ -156,53 +154,43 @@ namespace BizHawk.Client.Common.movie.import ImportTextFrame(line, platform); } } - - hf.Unbind(); } else if (item.Name.StartsWith("moviesram.")) { - hf.BindArchiveMember(item.Index); - var stream = hf.GetStream(); + using var stream = zip.GetInputStream(item); byte[] movieSram = stream.ReadAllBytes(); if (movieSram.Length != 0) { + // TODO: Why don't we support this? 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(); + using var stream = zip.GetInputStream(item); 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(); + using var stream = zip.GetInputStream(item); 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(); + using var stream = zip.GetInputStream(item); 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(); + using var stream = zip.GetInputStream(item); string rerecords = Encoding.UTF8.GetString(stream.ReadAllBytes()); int rerecordCount; @@ -217,17 +205,14 @@ namespace BizHawk.Client.Common.movie.import } Result.Movie.Rerecords = (ulong)rerecordCount; - hf.Unbind(); } else if (item.Name.EndsWith(".sha256")) { - hf.BindArchiveMember(item.Index); - var stream = hf.GetStream(); + using var stream = zip.GetInputStream(item); 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") { @@ -236,8 +221,7 @@ namespace BizHawk.Client.Common.movie.import } else if (item.Name == "subtitles") { - hf.BindArchiveMember(item.Index); - var stream = hf.GetStream(); + using var stream = zip.GetInputStream(item); string subtitles = Encoding.UTF8.GetString(stream.ReadAllBytes()); using (var reader = new StringReader(subtitles)) { @@ -251,32 +235,24 @@ namespace BizHawk.Client.Common.movie.import } } } - - hf.Unbind(); } else if (item.Name == "starttime.second") { - hf.BindArchiveMember(item.Index); - var stream = hf.GetStream(); + using var stream = zip.GetInputStream(item); 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(); + using var stream = zip.GetInputStream(item); 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(); + using var stream = zip.GetInputStream(item); string systemId = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); Result.Movie.Comments.Add($"{EmulationOrigin} {systemId}"); - hf.Unbind(); } }