move most logic from PathManager to extension methods in BizHawk.Common

This commit is contained in:
adelikat 2020-03-15 15:45:11 -05:00
parent 348cbd18df
commit 33a14327b7
25 changed files with 165 additions and 136 deletions

View File

@ -1,11 +1,6 @@
using System; using System.IO;
using System.Linq;
using System.IO;
using System.Reflection; using System.Reflection;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common namespace BizHawk.Client.Common
{ {
public static class PathManager public static class PathManager
@ -53,93 +48,5 @@ namespace BizHawk.Client.Common
{ {
DefaultIniPath = newDefaultIniPath; DefaultIniPath = newDefaultIniPath;
} }
// Decides if a path is non-empty, not . and not .\
public static bool PathIsSet(string path)
{
if (!string.IsNullOrWhiteSpace(path))
{
return path != "." && path != ".\\";
}
return false;
}
public static string RemoveInvalidFileSystemChars(string name)
{
var newStr = name;
var chars = Path.GetInvalidFileNameChars();
return chars.Aggregate(newStr, (current, c) => current.Replace(c.ToString(), ""));
}
public static string FilesystemSafeName(GameInfo game)
{
var filesystemSafeName = game.Name
.Replace("|", "+")
.Replace(":", " -") // Path.GetFileName scraps everything to the left of a colon unfortunately, so we need this hack here
.Replace("\"", "") // Ivan IronMan Stewart's Super Off-Road has quotes in game name
.Replace("/", "+"); // Mario Bros / Duck hunt has a slash in the name which GetDirectoryName and GetFileName treat as if it were a folder
// zero 06-nov-2015 - regarding the below, i changed my mind. for libretro i want subdirectories here.
var filesystemDir = Path.GetDirectoryName(filesystemSafeName);
filesystemSafeName = Path.GetFileName(filesystemSafeName);
filesystemSafeName = RemoveInvalidFileSystemChars(filesystemSafeName);
// zero 22-jul-2012 - i don't think this is used the same way it used to. game.Name shouldn't be a path, so this stuff is illogical.
// if game.Name is a path, then someone should have made it not-a-path already.
// return Path.Combine(Path.GetDirectoryName(filesystemSafeName), Path.GetFileNameWithoutExtension(filesystemSafeName));
// adelikat:
// This hack is to prevent annoying things like Super Mario Bros..bk2
if (filesystemSafeName.EndsWith("."))
{
filesystemSafeName = filesystemSafeName.Remove(filesystemSafeName.Length - 1, 1);
}
return Path.Combine(filesystemDir, filesystemSafeName);
}
public static string MakeRelativeTo(string absolutePath, string basePath)
{
if (IsSubfolder(basePath, absolutePath))
{
return absolutePath.Replace(basePath, ".");
}
return absolutePath;
}
/// <remarks>Algorithm for Windows taken from https://stackoverflow.com/a/7710620/7467292</remarks>
public static bool IsSubfolder(string parentPath, string childPath)
{
if (OSTailoredCode.IsUnixHost)
{
#if true
return OSTailoredCode.SimpleSubshell("realpath", $"-L \"{childPath}\"", $"invalid path {childPath} or missing realpath binary")
.StartsWith(OSTailoredCode.SimpleSubshell("realpath", $"-L \"{parentPath}\"", $"invalid path {parentPath} or missing realpath binary"));
#else // written for Unix port but may be useful for Windows when moving to .NET Core
var parentUriPath = new Uri(parentPath.TrimEnd('.')).AbsolutePath.TrimEnd('/');
try
{
for (var childUri = new DirectoryInfo(childPath).Parent; childUri != null; childUri = childUri?.Parent)
{
if (new Uri(childUri.FullName).AbsolutePath.TrimEnd('/') == parentUriPath) return true;
}
}
catch
{
// ignored
}
return false;
#endif
}
var parentUri = new Uri(parentPath);
for (var childUri = new DirectoryInfo(childPath).Parent; childUri != null; childUri = childUri?.Parent)
{
if (new Uri(childUri.FullName) == parentUri) return true;
}
return false;
}
} }
} }

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using BizHawk.Common.PathExtensions;
using Newtonsoft.Json; using Newtonsoft.Json;
namespace BizHawk.Client.Common namespace BizHawk.Client.Common
@ -47,7 +48,7 @@ namespace BizHawk.Client.Common
} }
// we don't have anything for the system in question. add a set of stock paths // we don't have anything for the system in question. add a set of stock paths
var systemPath = $"{PathManager.RemoveInvalidFileSystemChars(system)}_INTERIM"; var systemPath = $"{system.RemoveInvalidFileSystemChars()}_INTERIM";
var systemDisp = $"{system} (INTERIM)"; var systemDisp = $"{system} (INTERIM)";
Paths.AddRange(new[] Paths.AddRange(new[]

View File

@ -1,6 +1,7 @@
using System; using System;
using System.IO; using System.IO;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common namespace BizHawk.Client.Common
@ -208,11 +209,11 @@ namespace BizHawk.Client.Common
var path = collection[systemId, "ROM"]; var path = collection[systemId, "ROM"];
if (path == null || !PathManager.PathIsSet(path.Path)) if (!path.Path.PathIsSet())
{ {
path = collection["Global", "ROM"]; path = collection["Global", "ROM"];
if (path != null && PathManager.PathIsSet(path.Path)) if (path.Path.PathIsSet())
{ {
return collection.AbsolutePathFor(path.Path, null); return collection.AbsolutePathFor(path.Path, null);
} }
@ -223,7 +224,7 @@ namespace BizHawk.Client.Common
public static string SaveRamAbsolutePath(this PathEntryCollection collection, GameInfo game, bool movieIsActive) public static string SaveRamAbsolutePath(this PathEntryCollection collection, GameInfo game, bool movieIsActive)
{ {
var name = PathManager.FilesystemSafeName(game); var name = game.Name.FilesystemSafeName();
if (movieIsActive) if (movieIsActive)
{ {
name += $".{Path.GetFileNameWithoutExtension(Global.MovieSession.Movie.Filename)}"; name += $".{Path.GetFileNameWithoutExtension(Global.MovieSession.Movie.Filename)}";
@ -238,11 +239,11 @@ namespace BizHawk.Client.Common
// Shenanigans // Shenanigans
public static string RetroSaveRamAbsolutePath(this PathEntryCollection collection, GameInfo game, bool movieIsActive, string movieFilename) public static string RetroSaveRamAbsolutePath(this PathEntryCollection collection, GameInfo game, bool movieIsActive, string movieFilename)
{ {
var name = PathManager.FilesystemSafeName(game); var name = game.Name.FilesystemSafeName();
name = Path.GetDirectoryName(name); name = Path.GetDirectoryName(name);
if (name == "") if (name == "")
{ {
name = PathManager.FilesystemSafeName(game); name = game.Name.FilesystemSafeName();
} }
if (movieIsActive) if (movieIsActive)
@ -259,11 +260,11 @@ namespace BizHawk.Client.Common
// Shenanigans // Shenanigans
public static string RetroSystemAbsolutePath(this PathEntryCollection collection, GameInfo game) public static string RetroSystemAbsolutePath(this PathEntryCollection collection, GameInfo game)
{ {
var name = PathManager.FilesystemSafeName(game); var name = game.Name.FilesystemSafeName();
name = Path.GetDirectoryName(name); name = Path.GetDirectoryName(name);
if (string.IsNullOrEmpty(name)) if (string.IsNullOrEmpty(name))
{ {
name = PathManager.FilesystemSafeName(game); name = game.Name.FilesystemSafeName();
} }
var pathEntry = collection[game.System, "System"] var pathEntry = collection[game.System, "System"]
@ -317,7 +318,10 @@ namespace BizHawk.Client.Common
? collection.GlobalBaseAbsolutePath() ? collection.GlobalBaseAbsolutePath()
: collection.AbsolutePathFor(collection.BaseFor(system), system); : collection.AbsolutePathFor(collection.BaseFor(system), system);
#if true #if true
if (!PathManager.IsSubfolder(parentPath, absolutePath)) return absolutePath; if (!absolutePath.IsSubfolderOf(parentPath))
{
return absolutePath;
}
return OSTailoredCode.IsUnixHost return OSTailoredCode.IsUnixHost
? "./" + OSTailoredCode.SimpleSubshell("realpath", $"--relative-to=\"{parentPath}\" \"{absolutePath}\"", $"invalid path {absolutePath} or missing realpath binary") ? "./" + OSTailoredCode.SimpleSubshell("realpath", $"--relative-to=\"{parentPath}\" \"{absolutePath}\"", $"invalid path {absolutePath} or missing realpath binary")

View File

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text; using System.Text;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.Common namespace BizHawk.Client.Common
{ {
@ -138,8 +139,7 @@ namespace BizHawk.Client.Common
sb sb
.Append(file.Enabled ? "1" : "0") .Append(file.Enabled ? "1" : "0")
.Append(' ') .Append(' ')
.Append(PathManager.MakeRelativeTo(Global.Config.PathEntries.AbsolutePathFor(file.Path, ""), .Append(Global.Config.PathEntries.AbsolutePathFor(file.Path, "").MakeRelativeTo(Path.GetDirectoryName(path)))
Path.GetDirectoryName(path)))
.AppendLine(); .AppendLine();
} }
} }

View File

@ -2,6 +2,7 @@
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Emulation.Cores.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Nintendo.Gameboy;
using BizHawk.Emulation.Cores.Nintendo.GBHawk; using BizHawk.Emulation.Cores.Nintendo.GBHawk;
@ -292,7 +293,7 @@ namespace BizHawk.Client.Common.MovieConversionExtensions
if (Global.Game != null) if (Global.Game != null)
{ {
movie.GameName = PathManager.FilesystemSafeName(Global.Game); movie.GameName = Global.Game.Name.FilesystemSafeName();
movie.Hash = Global.Game.Hash; movie.Hash = Global.Game.Hash;
if (Global.Game.FirmwareHash != null) if (Global.Game.FirmwareHash != null)
{ {

View File

@ -6,6 +6,7 @@ using System.Windows.Forms;
using BizHawk.Bizware.BizwareGL; using BizHawk.Bizware.BizwareGL;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -32,7 +33,7 @@ namespace BizHawk.Client.EmuHawk
{ {
var ofd = new OpenFileDialog var ofd = new OpenFileDialog
{ {
FileName = $"{PathManager.FilesystemSafeName(Global.Game)}.syncless.txt", FileName = $"{Global.Game.Name.FilesystemSafeName()}.syncless.txt",
InitialDirectory = Global.Config.PathEntries.AvAbsolutePath() InitialDirectory = Global.Config.PathEntries.AvAbsolutePath()
}; };

View File

@ -19,6 +19,7 @@ using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Emulation.Cores.Computers.AppleII; using BizHawk.Emulation.Cores.Computers.AppleII;
using BizHawk.Client.ApiHawk; using BizHawk.Client.ApiHawk;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Cores.Atari.A7800Hawk; using BizHawk.Emulation.Cores.Atari.A7800Hawk;
using BizHawk.Emulation.Cores.Computers.Commodore64; using BizHawk.Emulation.Cores.Computers.Commodore64;
using BizHawk.Emulation.Cores.Nintendo.Gameboy; using BizHawk.Emulation.Cores.Nintendo.Gameboy;
@ -535,7 +536,7 @@ namespace BizHawk.Client.EmuHawk
var filename = MovieSession.Movie.Filename; var filename = MovieSession.Movie.Filename;
if (string.IsNullOrWhiteSpace(filename)) if (string.IsNullOrWhiteSpace(filename))
{ {
filename = PathManager.FilesystemSafeName(Game); filename = Game.Name.FilesystemSafeName();
} }
var file = ToolFormBase.SaveFileDialog( var file = ToolFormBase.SaveFileDialog(

View File

@ -27,6 +27,7 @@ using BizHawk.Emulation.Cores.Nintendo.GBHawkLink;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Client.EmuHawk.CoreExtensions; using BizHawk.Client.EmuHawk.CoreExtensions;
using BizHawk.Client.ApiHawk; using BizHawk.Client.ApiHawk;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common.Base_Implementations; using BizHawk.Emulation.Common.Base_Implementations;
using BizHawk.Emulation.Cores.Nintendo.SNES9X; using BizHawk.Emulation.Cores.Nintendo.SNES9X;
using BizHawk.Emulation.Cores.Consoles.SNK; using BizHawk.Emulation.Cores.Consoles.SNK;
@ -1045,7 +1046,7 @@ namespace BizHawk.Client.EmuHawk
private string ScreenshotPrefix() private string ScreenshotPrefix()
{ {
var screenPath = Config.PathEntries.ScreenshotAbsolutePathFor(Game.System); var screenPath = Config.PathEntries.ScreenshotAbsolutePathFor(Game.System);
var name = PathManager.FilesystemSafeName(Game); var name = Game.Name.FilesystemSafeName();
return Path.Combine(screenPath, name); return Path.Combine(screenPath, name);
} }
@ -3241,7 +3242,7 @@ namespace BizHawk.Client.EmuHawk
using var sfd = new SaveFileDialog(); using var sfd = new SaveFileDialog();
if (Game != null) if (Game != null)
{ {
sfd.FileName = $"{PathManager.FilesystemSafeName(Game)}.{ext}"; // don't use Path.ChangeExtension, it might wreck game names with dots in them sfd.FileName = $"{Game.Name.FilesystemSafeName()}.{ext}"; // don't use Path.ChangeExtension, it might wreck game names with dots in them
sfd.InitialDirectory = Config.PathEntries.AvAbsolutePath(); sfd.InitialDirectory = Config.PathEntries.AvAbsolutePath();
} }
else else
@ -3467,7 +3468,7 @@ namespace BizHawk.Client.EmuHawk
public string SaveStatePrefix() public string SaveStatePrefix()
{ {
var name = PathManager.FilesystemSafeName(Game); var name = Game.Name.FilesystemSafeName();
// Neshawk and Quicknes have incompatible savestates, store the name to keep them separate // Neshawk and Quicknes have incompatible savestates, store the name to keep them separate
if (Emulator.SystemId == "NES") if (Emulator.SystemId == "NES")

View File

@ -8,6 +8,7 @@ using System.Windows.Forms;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -102,7 +103,7 @@ namespace BizHawk.Client.EmuHawk
using var sfd = new SaveFileDialog using var sfd = new SaveFileDialog
{ {
FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Palettes", FileName = $"{Global.Game.Name.FilesystemSafeName()}-Palettes",
InitialDirectory = path, InitialDirectory = path,
Filter = FilesystemFilterSet.Screenshots.ToString(), Filter = FilesystemFilterSet.Screenshots.ToString(),
RestoreDirectory = true RestoreDirectory = true

View File

@ -9,6 +9,7 @@ using System.Windows.Forms;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
@ -167,7 +168,7 @@ namespace BizHawk.Client.EmuHawk
// Pull out matching names // Pull out matching names
for (var i = 0; i < _movieList.Count; i++) for (var i = 0; i < _movieList.Count; i++)
{ {
if (PathManager.FilesystemSafeName(_game) == _movieList[i].GameName) if (_game.Name.FilesystemSafeName() == _movieList[i].GameName)
{ {
indices.Add(i); indices.Add(i);
} }

View File

@ -6,6 +6,7 @@ using System.Linq;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.Common.MovieConversionExtensions; using BizHawk.Client.Common.MovieConversionExtensions;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -197,7 +198,7 @@ namespace BizHawk.Client.EmuHawk
private void RecordMovie_Load(object sender, EventArgs e) private void RecordMovie_Load(object sender, EventArgs e)
{ {
RecordBox.Text = PathManager.FilesystemSafeName(_game); RecordBox.Text = _game.Name.FilesystemSafeName();
StartFromCombo.SelectedIndex = 0; StartFromCombo.SelectedIndex = 0;
DefaultAuthorCheckBox.Checked = _config.UseDefaultAuthor; DefaultAuthorCheckBox.Checked = _config.UseDefaultAuthor;
if (_config.UseDefaultAuthor) if (_config.UseDefaultAuthor)

View File

@ -6,6 +6,7 @@ using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Common.PathExtensions;
// TODO - select which memorydomains go out to the CDL file. will this cause a problem when re-importing it? // TODO - select which memorydomains go out to the CDL file. will this cause a problem when re-importing it?
// perhaps missing domains shouldn't fail a check // perhaps missing domains shouldn't fail a check
@ -493,7 +494,7 @@ namespace BizHawk.Client.EmuHawk
try try
{ {
_autoloading = true; _autoloading = true;
var autoResumeFile = $"{PathManager.FilesystemSafeName(Global.Game)}.cdl"; var autoResumeFile = $"{Global.Game.Name.FilesystemSafeName()}.cdl";
var autoResumeDir = Config.PathEntries.LogAbsolutePath(); var autoResumeDir = Config.PathEntries.LogAbsolutePath();
var autoResumePath = Path.Combine(autoResumeDir, autoResumeFile); var autoResumePath = Path.Combine(autoResumeDir, autoResumeFile);
if (File.Exists(autoResumePath)) if (File.Exists(autoResumePath))

View File

@ -12,6 +12,7 @@ using BizHawk.Common;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;
using BizHawk.Common.StringExtensions; using BizHawk.Common.StringExtensions;
using BizHawk.Common.IOExtensions; using BizHawk.Common.IOExtensions;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
@ -969,7 +970,7 @@ namespace BizHawk.Client.EmuHawk
, FileName = , FileName =
_domain.Name == "File on Disk" _domain.Name == "File on Disk"
? RomName ? RomName
: PathManager.FilesystemSafeName(Global.Game) : Global.Game.Name.FilesystemSafeName()
}; };
var result = sfd.ShowHawkDialog(); var result = sfd.ShowHawkDialog();
@ -982,7 +983,7 @@ namespace BizHawk.Client.EmuHawk
{ {
FileName = _domain.Name == "File on Disk" FileName = _domain.Name == "File on Disk"
? $"{Path.GetFileNameWithoutExtension(RomName)}.txt" ? $"{Path.GetFileNameWithoutExtension(RomName)}.txt"
: PathManager.FilesystemSafeName(Global.Game), : Global.Game.Name.FilesystemSafeName(),
Filter = new FilesystemFilterSet(FilesystemFilter.TextFiles).ToString(), Filter = new FilesystemFilterSet(FilesystemFilter.TextFiles).ToString(),
InitialDirectory = RomDirectory, InitialDirectory = RomDirectory,
RestoreDirectory = true RestoreDirectory = true

View File

@ -11,6 +11,7 @@ using System.Windows.Forms;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
@ -569,7 +570,7 @@ namespace BizHawk.Client.EmuHawk
} }
else if (Global.Game != null) else if (Global.Game != null)
{ {
sfd.FileName = PathManager.FilesystemSafeName(Global.Game); sfd.FileName = Global.Game.Name.FilesystemSafeName();
sfd.InitialDirectory = Config.PathEntries.LuaAbsolutePath(); sfd.InitialDirectory = Config.PathEntries.LuaAbsolutePath();
} }
else else

View File

@ -6,6 +6,7 @@ using System.IO;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -279,7 +280,7 @@ namespace BizHawk.Client.EmuHawk
{ {
return Config.PathEntries.AbsolutePathFor(Path.Combine( return Config.PathEntries.AbsolutePathFor(Path.Combine(
Config.PathEntries["Global", "Macros"].Path, Config.PathEntries["Global", "Macros"].Path,
PathManager.FilesystemSafeName(Global.Game)), null); Global.Game.Name.FilesystemSafeName()), null);
} }
#endregion #endregion

View File

@ -10,6 +10,7 @@ using System.Xml.Linq;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Cores.Sega.MasterSystem; using BizHawk.Emulation.Cores.Sega.MasterSystem;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
@ -239,7 +240,7 @@ namespace BizHawk.Client.EmuHawk
filename = NameBox.Text; filename = NameBox.Text;
if (string.IsNullOrWhiteSpace(filename)) if (string.IsNullOrWhiteSpace(filename))
{ {
filename = Path.ChangeExtension(PathManager.FilesystemSafeName(Global.Game), ".xml"); filename = Path.ChangeExtension(Global.Game.Name.FilesystemSafeName(), ".xml");
} }
initialDirectory = Path.GetDirectoryName(filename); initialDirectory = Path.GetDirectoryName(filename);
@ -267,7 +268,7 @@ namespace BizHawk.Client.EmuHawk
if (OSTailoredCode.IsUnixHost) if (OSTailoredCode.IsUnixHost)
{ {
#if true #if true
return PathManager.IsSubfolder(toPath, fromPath) return fromPath.IsSubfolderOf(toPath)
? "./" + OSTailoredCode.SimpleSubshell("realpath", $"--relative-to=\"{toPath}\" \"{fromPath}\"", $"invalid path {fromPath} or missing realpath binary") ? "./" + OSTailoredCode.SimpleSubshell("realpath", $"--relative-to=\"{toPath}\" \"{fromPath}\"", $"invalid path {fromPath} or missing realpath binary")
: fromPath; : fromPath;
#else // written for Unix port but may be useful for .NET Core #else // written for Unix port but may be useful for .NET Core

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -68,7 +69,7 @@ namespace BizHawk.Client.EmuHawk
{ {
using var sfd = new SaveFileDialog using var sfd = new SaveFileDialog
{ {
FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Nametables", FileName = $"{Global.Game.Name.FilesystemSafeName()}-Nametables",
InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"), InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"),
Filter = FilesystemFilterSet.Screenshots.ToString(), Filter = FilesystemFilterSet.Screenshots.ToString(),
RestoreDirectory = true RestoreDirectory = true

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -74,7 +75,7 @@ namespace BizHawk.Client.EmuHawk
{ {
var sfd = new SaveFileDialog var sfd = new SaveFileDialog
{ {
FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Palettes", FileName = $"{Global.Game.Name.FilesystemSafeName()}-Palettes",
InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"), InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"),
Filter = FilesystemFilterSet.Screenshots.ToString(), Filter = FilesystemFilterSet.Screenshots.ToString(),
RestoreDirectory = true RestoreDirectory = true

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -36,7 +37,7 @@ namespace BizHawk.Client.EmuHawk
{ {
var sfd = new SaveFileDialog var sfd = new SaveFileDialog
{ {
FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Patterns", FileName = $"{Global.Game.Name.FilesystemSafeName()}-Patterns",
InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"), InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"),
Filter = FilesystemFilterSet.Screenshots.ToString(), Filter = FilesystemFilterSet.Screenshots.ToString(),
RestoreDirectory = true RestoreDirectory = true

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common.PathExtensions;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -38,7 +39,7 @@ namespace BizHawk.Client.EmuHawk
{ {
var sfd = new SaveFileDialog var sfd = new SaveFileDialog
{ {
FileName = $"{PathManager.FilesystemSafeName(Global.Game)}-Sprites", FileName = $"{Global.Game.Name.FilesystemSafeName()}-Sprites",
InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"), InitialDirectory = Global.Config.PathEntries.ScreenshotAbsolutePathFor("NES"),
Filter = FilesystemFilterSet.Screenshots.ToString(), Filter = FilesystemFilterSet.Screenshots.ToString(),
RestoreDirectory = true RestoreDirectory = true

View File

@ -11,6 +11,7 @@ using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.Common.MovieConversionExtensions; using BizHawk.Client.Common.MovieConversionExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions; using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Cores.Nintendo.N64; using BizHawk.Emulation.Cores.Nintendo.N64;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
@ -866,7 +867,7 @@ namespace BizHawk.Client.EmuHawk
{ {
return Path.Combine( return Path.Combine(
Global.Config.PathEntries.MovieAbsolutePath(), Global.Config.PathEntries.MovieAbsolutePath(),
$"{PathManager.FilesystemSafeName(Global.Game)}.{TasMovie.Extension}"); $"{Global.Game.Name.FilesystemSafeName()}.{TasMovie.Extension}");
} }
private void SaveTas() private void SaveTas()

View File

@ -1,11 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing;
using System.IO; using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using System.Drawing; using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -26,7 +26,7 @@ namespace BizHawk.Client.EmuHawk
{ {
FileName = !string.IsNullOrWhiteSpace(currentFile) FileName = !string.IsNullOrWhiteSpace(currentFile)
? Path.GetFileName(currentFile) ? Path.GetFileName(currentFile)
: $"{PathManager.FilesystemSafeName(Global.Game)}.{fileExt}", : $"{Global.Game.Name.FilesystemSafeName()}.{fileExt}",
InitialDirectory = path, InitialDirectory = path,
Filter = new FilesystemFilterSet(new FilesystemFilter(fileType, new[] { fileExt })).ToString(), Filter = new FilesystemFilterSet(new FilesystemFilter(fileType, new[] { fileExt })).ToString(),
RestoreDirectory = true RestoreDirectory = true
@ -52,7 +52,7 @@ namespace BizHawk.Client.EmuHawk
{ {
FileName = !string.IsNullOrWhiteSpace(currentFile) FileName = !string.IsNullOrWhiteSpace(currentFile)
? Path.GetFileName(currentFile) ? Path.GetFileName(currentFile)
: $"{PathManager.FilesystemSafeName(Global.Game)}.{fileExt}", : $"{Global.Game.Name.FilesystemSafeName()}.{fileExt}",
InitialDirectory = path, InitialDirectory = path,
Filter = new FilesystemFilterSet(new FilesystemFilter(fileType, new[] { fileExt })).ToString(), Filter = new FilesystemFilterSet(new FilesystemFilter(fileType, new[] { fileExt })).ToString(),
RestoreDirectory = true, RestoreDirectory = true,

View File

@ -12,6 +12,7 @@ using BizHawk.Client.ApiHawk;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.CoreExtensions; using BizHawk.Client.EmuHawk.CoreExtensions;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Common.ReflectionExtensions; using BizHawk.Common.ReflectionExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
@ -873,7 +874,7 @@ namespace BizHawk.Client.EmuHawk
f.Directory.Create(); f.Directory.Create();
} }
return Path.Combine(path, $"{PathManager.FilesystemSafeName(Global.Game)}.cht"); return Path.Combine(path, $"{Global.Game.Name.FilesystemSafeName()}.cht");
} }
public void UpdateCheatRelatedTools(object sender, CheatCollection.CheatListEventArgs e) public void UpdateCheatRelatedTools(object sender, CheatCollection.CheatListEventArgs e)

View File

@ -6,8 +6,9 @@ using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Client.Common; using BizHawk.Client.Common;
using BizHawk.Common.PathExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk namespace BizHawk.Client.EmuHawk
{ {
@ -284,12 +285,12 @@ namespace BizHawk.Client.EmuHawk
using var sfd = new SaveFileDialog(); using var sfd = new SaveFileDialog();
if (LogFile == null) if (LogFile == null)
{ {
sfd.FileName = PathManager.FilesystemSafeName(Global.Game) + _extension; sfd.FileName = Global.Game.Name.FilesystemSafeName() + _extension;
sfd.InitialDirectory = Config.PathEntries.LogAbsolutePath(); sfd.InitialDirectory = Config.PathEntries.LogAbsolutePath();
} }
else if (!string.IsNullOrWhiteSpace(LogFile.FullName)) else if (!string.IsNullOrWhiteSpace(LogFile.FullName))
{ {
sfd.FileName = PathManager.FilesystemSafeName(Global.Game); sfd.FileName = Global.Game.Name.FilesystemSafeName();
sfd.InitialDirectory = Path.GetDirectoryName(LogFile.FullName); sfd.InitialDirectory = Path.GetDirectoryName(LogFile.FullName);
} }
else else
@ -457,7 +458,7 @@ namespace BizHawk.Client.EmuHawk
{ {
FileBox.Visible = true; FileBox.Visible = true;
BrowseBox.Visible = true; BrowseBox.Visible = true;
var name = PathManager.FilesystemSafeName(Global.Game); var name = Global.Game.Name.FilesystemSafeName();
var filename = Path.Combine(Config.PathEntries.LogAbsolutePath(), name) + _extension; var filename = Path.Combine(Config.PathEntries.LogAbsolutePath(), name) + _extension;
LogFile = new FileInfo(filename); LogFile = new FileInfo(filename);
if (LogFile.Directory != null && !LogFile.Directory.Exists) if (LogFile.Directory != null && !LogFile.Directory.Exists)

View File

@ -0,0 +1,98 @@
using System;
using System.Linq;
using System.IO;
namespace BizHawk.Common.PathExtensions
{
public static class PathExtensions
{
public static string RemoveInvalidFileSystemChars(this string name)
{
var newStr = name;
var chars = Path.GetInvalidFileNameChars();
return chars.Aggregate(newStr, (current, c) => current.Replace(c.ToString(), ""));
}
/// <summary>
/// Decides if a path is non-empty, not . and not .\
/// </summary>
public static bool PathIsSet(this string path)
{
return !string.IsNullOrWhiteSpace(path) && path != "." && path != ".\\";
}
/// <remarks>Algorithm for Windows taken from https://stackoverflow.com/a/7710620/7467292</remarks>
public static bool IsSubfolderOf(this string childPath, string parentPath)
{
if (OSTailoredCode.IsUnixHost)
{
#if true
return OSTailoredCode.SimpleSubshell("realpath", $"-L \"{childPath}\"", $"invalid path {childPath} or missing realpath binary")
.StartsWith(OSTailoredCode.SimpleSubshell("realpath", $"-L \"{parentPath}\"", $"invalid path {parentPath} or missing realpath binary"));
#else // written for Unix port but may be useful for Windows when moving to .NET Core
var parentUriPath = new Uri(parentPath.TrimEnd('.')).AbsolutePath.TrimEnd('/');
try
{
for (var childUri = new DirectoryInfo(childPath).Parent; childUri != null; childUri = childUri?.Parent)
{
if (new Uri(childUri.FullName).AbsolutePath.TrimEnd('/') == parentUriPath) return true;
}
}
catch
{
// ignored
}
return false;
#endif
}
var parentUri = new Uri(parentPath);
for (var childUri = new DirectoryInfo(childPath).Parent; childUri != null; childUri = childUri?.Parent)
{
if (new Uri(childUri.FullName) == parentUri) return true;
}
return false;
}
public static string MakeRelativeTo(this string absolutePath, string basePath)
{
if (absolutePath.IsSubfolderOf(basePath))
{
return absolutePath.Replace(basePath, ".");
}
return absolutePath;
}
public static string FilesystemSafeName(this string? name)
{
name ??= "";
var filesystemSafeName = name
.Replace("|", "+")
.Replace(":", " -") // Path.GetFileName scraps everything to the left of a colon unfortunately, so we need this hack here
.Replace("\"", "") // Ivan IronMan Stewart's Super Off-Road has quotes in game name
.Replace("/", "+"); // Mario Bros / Duck hunt has a slash in the name which GetDirectoryName and GetFileName treat as if it were a folder
// zero 06-nov-2015 - regarding the below, i changed my mind. for libretro i want subdirectories here.
var filesystemDir = Path.GetDirectoryName(filesystemSafeName);
filesystemSafeName = Path.GetFileName(filesystemSafeName);
filesystemSafeName = filesystemSafeName.RemoveInvalidFileSystemChars();
// zero 22-jul-2012 - i don't think this is used the same way it used to. game.Name shouldn't be a path, so this stuff is illogical.
// if game.Name is a path, then someone should have made it not-a-path already.
// return Path.Combine(Path.GetDirectoryName(filesystemSafeName), Path.GetFileNameWithoutExtension(filesystemSafeName));
// adelikat:
// This hack is to prevent annoying things like Super Mario Bros..bk2
if (filesystemSafeName.EndsWith("."))
{
filesystemSafeName = filesystemSafeName.Remove(filesystemSafeName.Length - 1, 1);
}
return Path.Combine(filesystemDir, filesystemSafeName);
}
}
}