Skip to content

Commit 14a511e

Browse files
Merge pull request #88 from isaki/pmp_group_filename_fix
Changes to PMP safe filenames.
2 parents c240324 + 584021f commit 14a511e

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

xivModdingFramework/Helpers/IOUtil.cs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,14 @@
4040
using System.Management;
4141
using Newtonsoft.Json;
4242
using Newtonsoft.Json.Linq;
43+
using System.Text;
4344

4445
namespace xivModdingFramework.Helpers
4546
{
4647
public static class IOUtil
4748
{
49+
private static readonly HashSet<char> _InvalidFileNameChars = new(Path.GetInvalidFileNameChars());
50+
4851
/// <summary>
4952
/// Compresses raw byte data.
5053
/// </summary>
@@ -729,16 +732,32 @@ public static bool IsDirectory(string path)
729732

730733
public static string MakePathSafe(string fileName, bool makeLowercase = true)
731734
{
732-
foreach (var c in Path.GetInvalidFileNameChars())
733-
{
734-
fileName = fileName.Replace(c, '-');
735-
}
736-
if (makeLowercase)
735+
return IOUtil.MakePathSafe(fileName, '-', makeLowercase);
736+
}
737+
738+
public static string MakePathSafe(string fileName, char rep, bool makeLowercase = true)
739+
{
740+
// This approach walks the string once, and hash lookups are O(1).
741+
StringBuilder ret = new(fileName.Length);
742+
foreach (var c in fileName)
737743
{
738-
fileName = fileName.ToLower();
744+
if (_InvalidFileNameChars.Contains(c))
745+
{
746+
ret.Append(rep);
747+
}
748+
else if (makeLowercase)
749+
{
750+
ret.Append(Char.ToLower(c));
751+
}
752+
else
753+
{
754+
ret.Append(c);
755+
}
739756
}
740-
return fileName.Trim();
757+
758+
return ret.ToString().Trim();
741759
}
760+
742761
public static void CopyFolder(string sourcePath, string targetPath)
743762
{
744763
sourcePath = MakeLongPath(sourcePath);
@@ -962,6 +981,5 @@ await Task.Run(async () =>
962981
Trace.WriteLine(ex);
963982
}
964983
}
965-
966984
}
967985
}

xivModdingFramework/Mods/FileTypes/PMP.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ namespace xivModdingFramework.Mods.FileTypes.PMP
4343
public static class PMP
4444
{
4545
public const int _WriteFileVersion = 3;
46+
47+
private const char _PMPSafeNameReplacement = '_';
48+
4649
private static bool _ImportActive = false;
4750
private static string _Source = null;
4851

@@ -837,7 +840,7 @@ public static async Task WritePmp(PMPJson pmp, string workingDirectory, string z
837840

838841
for(int i = 0; i < pmp.Groups.Count; i++)
839842
{
840-
var gName = IOUtil.MakePathSafe(pmp.Groups[i].Name.ToLower());
843+
var gName = PMP.MakePMPPathSafe(pmp.Groups[i].Name);
841844
var groupPath = Path.Combine(workingDirectory, "group_" + (i+1).ToString("D3") + "_" + gName + ".json");
842845
var groupString = JsonConvert.SerializeObject(pmp.Groups[i], Formatting.Indented);
843846
File.WriteAllText(groupPath, groupString);
@@ -1283,9 +1286,18 @@ await Task.Run(async () =>
12831286
return (seenMetadata.Values.ToList(), seenRgsps.Values.ToList(), otherManipulations);
12841287
}
12851288

1286-
}
1289+
private static string MakePMPPathSafe(string fileName)
1290+
{
1291+
// This method enforces the naming scheme that penumbra expects for its json components.
1292+
if (fileName == ".")
1293+
return new(_PMPSafeNameReplacement, 1);
12871294

1295+
if (fileName == "..")
1296+
return new(_PMPSafeNameReplacement, 2);
12881297

1298+
return IOUtil.MakePathSafe(fileName.Normalize(NormalizationForm.FormKC), _PMPSafeNameReplacement, true);
1299+
}
1300+
}
12891301

12901302
#region Penumbra Simple JSON Classes
12911303
public class PMPJson

0 commit comments

Comments
 (0)