Make RomPath consistent between xml and not xml
Previous implementation was broken and differed between the two in practice in the case of archives. Standard single file just passed archive loaded, without archive binding info. Xml case was even more nonsense, giving a completely nonexistent path using the internal archived file name. RomPath now will properly report the binding info in the case of archives. Cores should be very careful with using RomPath with file apis, as the | used for binding info is not a valid file char and will throw most file apis (some cores were already doing this, I've fixed most of the cores not doing so save for UAE and DSDA). TODO: Need to fix the edge case of the file being in the same archive as the xml (represented specially in xml and that code path seems to already been broken)
This commit is contained in:
parent
75fc58041e
commit
cb50a24c0c
|
@ -559,7 +559,7 @@ namespace BizHawk.Client.Common
|
|||
RomData = rom.RomData,
|
||||
FileData = rom.FileData,
|
||||
Extension = rom.Extension,
|
||||
RomPath = file.FullPathWithoutMember,
|
||||
RomPath = file.CanonicalFullPath,
|
||||
Game = game,
|
||||
},
|
||||
},
|
||||
|
@ -657,6 +657,11 @@ namespace BizHawk.Client.Common
|
|||
// (in general, this is kind of bad as CHD hard drives might be useful for other future cores?)
|
||||
private static bool IsDiscForXML(string system, string path)
|
||||
{
|
||||
if (HawkFile.PathContainsPipe(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(path);
|
||||
if (system is VSystemID.Raw.Arcade && ".chd".EqualsIgnoreCase(ext))
|
||||
{
|
||||
|
@ -682,21 +687,21 @@ namespace BizHawk.Client.Common
|
|||
Comm = nextComm,
|
||||
Game = game,
|
||||
Roms = xmlGame.Assets
|
||||
.Where(kvp => !IsDiscForXML(system, kvp.Key))
|
||||
.Select(kvp => (IRomAsset)new RomAsset
|
||||
.Where(pfd => !IsDiscForXML(system, pfd.Filename))
|
||||
.Select(IRomAsset (pfd) => new RomAsset
|
||||
{
|
||||
RomData = kvp.Value,
|
||||
FileData = kvp.Value, // TODO: Hope no one needed anything special here
|
||||
Extension = Path.GetExtension(kvp.Key),
|
||||
RomPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path.SubstringBefore('|'))!, kvp.Key!)),
|
||||
Game = Database.GetGameInfo(kvp.Value, Path.GetFileName(kvp.Key)),
|
||||
RomData = pfd.FileData, // TODO: Do RomGame RomData conversions here
|
||||
FileData = pfd.FileData,
|
||||
Extension = Path.GetExtension(pfd.Filename),
|
||||
RomPath = pfd.Path,
|
||||
Game = Database.GetGameInfo(pfd.FileData, Path.GetFileName(pfd.Filename)),
|
||||
})
|
||||
.ToList(),
|
||||
Discs = xmlGame.AssetFullPaths
|
||||
.Where(p => IsDiscForXML(system, p))
|
||||
.Select(discPath => (p: discPath, d: DiscExtensions.CreateAnyType(discPath, str => DoLoadErrorCallback(str, system, LoadErrorType.DiscError))))
|
||||
Discs = xmlGame.Assets
|
||||
.Where(pfd => IsDiscForXML(system, pfd.Path))
|
||||
.Select(pfd => (p: pfd.Path, d: DiscExtensions.CreateAnyType(pfd.Path, str => DoLoadErrorCallback(str, system, LoadErrorType.DiscError))))
|
||||
.Where(a => a.d != null)
|
||||
.Select(a => (IDiscAsset)new DiscAsset
|
||||
.Select(IDiscAsset (a) => new DiscAsset
|
||||
{
|
||||
DiscData = a.d,
|
||||
DiscType = new DiscIdentifier(a.d).DetectDiscType(),
|
||||
|
|
|
@ -8,6 +8,7 @@ using BizHawk.Common.IOExtensions;
|
|||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Arcades.MAME;
|
||||
using BizHawk.Emulation.DiscSystem;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -15,8 +16,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public XmlDocument Xml { get; set; }
|
||||
public GameInfo GI { get; } = new();
|
||||
public IList<KeyValuePair<string, byte[]>> Assets { get; } = new List<KeyValuePair<string, byte[]>>();
|
||||
public IList<string> AssetFullPaths { get; } = new List<string>(); // TODO: Hack work around, to avoid having to refactor Assets into a object array, should be refactored!
|
||||
public IList<(string Path, string Filename, byte[] FileData)> Assets { get; } = [ ];
|
||||
|
||||
/// <exception cref="InvalidOperationException">internal error</exception>
|
||||
public static XmlGame Create(HawkFile f)
|
||||
|
@ -79,19 +79,26 @@ namespace BizHawk.Client.Common
|
|||
using var hf = new HawkFile(fullPath, allowArchives: !MAMEMachineDB.IsMAMEMachine(fullPath));
|
||||
if (hf.IsArchive)
|
||||
{
|
||||
var archiveItem = hf.ArchiveItems.First(ai => ai.Name == filename.Split('|').Skip(1).First());
|
||||
var archiveItem = hf.ArchiveItems.First(ai => ai.Name == filename.SubstringAfter('|'));
|
||||
hf.Unbind();
|
||||
hf.BindArchiveMember(archiveItem);
|
||||
data = hf.GetStream().ReadAllBytes();
|
||||
|
||||
filename = filename.Split('|').Skip(1).First();
|
||||
filename = filename.SubstringAfter('|');
|
||||
fullPath += $"|{filename}";
|
||||
}
|
||||
else
|
||||
{
|
||||
var path = fullPath.SubstringBefore('|');
|
||||
data = RomGame.Is3DSRom(Path.GetExtension(path).ToUpperInvariant())
|
||||
? Array.Empty<byte>()
|
||||
: File.ReadAllBytes(path);
|
||||
var ext = Path.GetExtension(fullPath).ToUpperInvariant();
|
||||
var isArcadeChd = ret.GI.System == VSystemID.Raw.Arcade && ext == ".CHD";
|
||||
if (RomGame.Is3DSRom(ext) || (Disc.IsValidExtension(ext) && !isArcadeChd))
|
||||
{
|
||||
data = [ ];
|
||||
}
|
||||
else
|
||||
{
|
||||
data = File.ReadAllBytes(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -100,8 +107,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
ret.Assets.Add(new(filename, data));
|
||||
ret.AssetFullPaths.Add(fullPath);
|
||||
ret.Assets.Add((fullPath, filename, data));
|
||||
var sha1 = SHA1Checksum.Compute(data);
|
||||
hashStream.Write(sha1, 0, sha1.Length);
|
||||
}
|
||||
|
|
|
@ -3841,10 +3841,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
for (int xg = 0; xg < xmlGame.Assets.Count; xg++)
|
||||
{
|
||||
var ext = Path.GetExtension(xmlGame.AssetFullPaths[xg])?.ToLowerInvariant();
|
||||
|
||||
var (filename, data) = xmlGame.Assets[xg];
|
||||
if (Disc.IsValidExtension(ext))
|
||||
var (_, filename, data) = xmlGame.Assets[xg];
|
||||
// data length is 0 in the case of discs or 3DS roms
|
||||
if (data.Length == 0)
|
||||
{
|
||||
xSw.WriteLine(Path.GetFileNameWithoutExtension(filename));
|
||||
xSw.WriteLine("SHA1:N/A");
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Windows.Forms;
|
|||
using BizHawk.Client.Common;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.PathExtensions;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Arcades.MAME;
|
||||
using BizHawk.Emulation.DiscSystem;
|
||||
|
@ -304,9 +305,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
case ".xml":
|
||||
{
|
||||
var xml = XmlGame.Create(new(path));
|
||||
foreach (var kvp in xml.Assets)
|
||||
foreach (var pfd in xml.Assets)
|
||||
{
|
||||
InternalDebugHash(kvp.Key);
|
||||
InternalDebugHash(pfd.Path);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -239,7 +239,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private uint HashArcade(string path)
|
||||
{
|
||||
// Arcade wants to just hash the filename (with no extension)
|
||||
var name = Encoding.UTF8.GetBytes(Path.GetFileNameWithoutExtension(path));
|
||||
var name = Encoding.UTF8.GetBytes(Path.GetFileNameWithoutExtension(path.SubstringAfter('|')));
|
||||
var hash = MD5Checksum.ComputeDigestHex(name);
|
||||
return IdentifyHash(hash);
|
||||
}
|
||||
|
@ -451,23 +451,23 @@ namespace BizHawk.Client.EmuHawk
|
|||
else if (ext == ".xml")
|
||||
{
|
||||
var xml = XmlGame.Create(new(ioa.SimplePath));
|
||||
foreach (var kvp in xml.Assets)
|
||||
foreach (var pfd in xml.Assets)
|
||||
{
|
||||
if (consoleID is ConsoleID.Arcade)
|
||||
{
|
||||
ret.Add(HashArcade(kvp.Key));
|
||||
ret.Add(HashArcade(pfd.Path));
|
||||
break;
|
||||
}
|
||||
|
||||
if (consoleID is ConsoleID.Nintendo3DS)
|
||||
{
|
||||
ret.Add(Hash3DS(kvp.Key));
|
||||
ret.Add(Hash3DS(pfd.Filename));
|
||||
break;
|
||||
}
|
||||
|
||||
ret.Add(Disc.IsValidExtension(Path.GetExtension(kvp.Key))
|
||||
? HashDisc(kvp.Key, consoleID)
|
||||
: IdentifyRom(kvp.Value));
|
||||
ret.Add(pfd.FileData.Length == 0
|
||||
? HashDisc(pfd.Path, consoleID)
|
||||
: IdentifyRom(pfd.FileData));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -101,7 +101,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
try
|
||||
{
|
||||
var xmlGame = XmlGame.Create(new HawkFile(xmlPath));
|
||||
AddFiles(xmlGame.AssetFullPaths);
|
||||
AddFiles(xmlGame.Assets.Select(static pfd => pfd.Path).ToList());
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -153,6 +153,23 @@ namespace BizHawk.Common.StringExtensions
|
|||
public static bool StartsWithIgnoreCase(this string haystack, string needle)
|
||||
=> haystack.StartsWith(needle, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
/// <returns>
|
||||
/// the substring of <paramref name="str"/> after the first occurrence of <paramref name="delimiter"/>, or
|
||||
/// the original <paramref name="str"/> if not found
|
||||
/// </returns>
|
||||
public static string SubstringAfter(this string str, char delimiter)
|
||||
=> str.SubstringAfter(delimiter, notFoundValue: str);
|
||||
|
||||
/// <returns>
|
||||
/// the substring of <paramref name="str"/> after the first occurrence of <paramref name="delimiter"/>, or
|
||||
/// the original <paramref name="str"/> if not found
|
||||
/// </returns>
|
||||
public static string SubstringAfter(this string str, char delimiter, string notFoundValue)
|
||||
{
|
||||
var index = str.IndexOf(delimiter);
|
||||
return index < 0 ? notFoundValue : str.Substring(index + 1, str.Length - index - 1);
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// the substring of <paramref name="str"/> after the first occurrence of <paramref name="delimiter"/>, or
|
||||
/// the original <paramref name="str"/> if not found
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
|
|||
[CoreConstructor(VSystemID.Raw.Arcade)]
|
||||
public MAME(CoreLoadParameters<object, MAMESyncSettings> lp)
|
||||
{
|
||||
_gameFileName = Path.GetFileName(lp.Roms[0].RomPath).ToLowerInvariant();
|
||||
_gameFileName = Path.GetFileName(lp.Roms[0].RomPath.SubstringAfter('|')).ToLowerInvariant();
|
||||
_syncSettings = lp.SyncSettings ?? new();
|
||||
|
||||
ServiceProvider = new BasicServiceProvider(this);
|
||||
|
@ -172,8 +172,8 @@ namespace BizHawk.Emulation.Cores.Arcades.MAME
|
|||
// mame expects chd files in a folder of the game name
|
||||
string MakeFileName(IRomAsset rom)
|
||||
=> rom.Extension.ToLowerInvariant() is ".chd"
|
||||
? gameName + '/' + Path.GetFileNameWithoutExtension(rom.RomPath).ToLowerInvariant() + rom.Extension.ToLowerInvariant()
|
||||
: Path.GetFileNameWithoutExtension(rom.RomPath).ToLowerInvariant() + rom.Extension.ToLowerInvariant();
|
||||
? gameName + '/' + Path.GetFileNameWithoutExtension(rom.RomPath.SubstringAfter('|')).ToLowerInvariant() + rom.Extension.ToLowerInvariant()
|
||||
: Path.GetFileNameWithoutExtension(rom.RomPath.SubstringAfter('|')).ToLowerInvariant() + rom.Extension.ToLowerInvariant();
|
||||
|
||||
foreach (var rom in roms)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@ using System.Runtime.InteropServices;
|
|||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.PathExtensions;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Components.W65816;
|
||||
using BizHawk.Emulation.Cores.Nintendo.SNES;
|
||||
|
@ -24,7 +25,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES
|
|||
var ser = new BasicServiceProvider(this);
|
||||
ServiceProvider = ser;
|
||||
|
||||
this._romPath = Path.ChangeExtension(loadParameters.Roms[0].RomPath, null);
|
||||
this._romPath = Path.ChangeExtension(loadParameters.Roms[0].RomPath.SubstringAfter('|'), null);
|
||||
CoreComm = loadParameters.Comm;
|
||||
_syncSettings = loadParameters.SyncSettings ?? new SnesSyncSettings();
|
||||
SystemId = loadParameters.Game.System;
|
||||
|
|
|
@ -2,6 +2,7 @@ using System.ComponentModel;
|
|||
using System.IO;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.Cores.Waterbox;
|
||||
|
||||
|
@ -29,7 +30,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES9X
|
|||
SystemId = VSystemID.Raw.SNES,
|
||||
})
|
||||
{
|
||||
this._romPath = Path.ChangeExtension(loadParameters.Roms[0].RomPath, null);
|
||||
this._romPath = Path.ChangeExtension(loadParameters.Roms[0].RomPath.SubstringAfter('|'), null);
|
||||
this._currentMsuTrack = new ProxiedFile();
|
||||
|
||||
LibSnes9x.OpenAudio openAudioCb = MsuOpenAudio;
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||
|
||||
using BizHawk.BizInvoke;
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Emulation.DiscSystem;
|
||||
|
||||
|
@ -56,7 +57,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
|
|||
{
|
||||
return DoInit<T>(
|
||||
lp.Roms.Select(r => (r.RomData,
|
||||
Path.GetFileName(r.RomPath[(r.RomPath.LastIndexOf('|') + 1)..])!.ToLowerInvariant())).ToArray(),
|
||||
Path.GetFileName(r.RomPath.SubstringAfter('|')).ToLowerInvariant())).ToArray(),
|
||||
lp.Discs.Select(d => d.DiscData).ToArray(),
|
||||
wbxFilename,
|
||||
lp.Roms.FirstOrDefault()?.Extension,
|
||||
|
|
Loading…
Reference in New Issue