Skip to content

Commit c66d5c7

Browse files
committed
Beta v2.3.3.7b
1 parent 38bd635 commit c66d5c7

File tree

6 files changed

+158
-16
lines changed

6 files changed

+158
-16
lines changed

xivModdingFramework/General/CMP.cs

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Dynamic;
44
using System.IO;
5+
using System.Linq;
56
using System.Text;
67
using System.Text.RegularExpressions;
78
using System.Threading.Tasks;
@@ -44,6 +45,31 @@ internal static async Task ApplyRgspFile(string filePath, IndexFile index = null
4445
await SetScalingParameter(rgsp, index, modlist);
4546
}
4647

48+
/// <summary>
49+
/// Disables the .rgsp file for this race, if it exists, and restores the .cmp file for the race back to default.
50+
/// </summary>
51+
/// <param name="race"></param>
52+
/// <param name="gender"></param>
53+
/// <returns></returns>
54+
public static async Task DisableRgspMod(XivSubRace race, XivGender gender)
55+
{
56+
var path = GetRgspPath(race, gender);
57+
var _modding = new Modding(XivCache.GameInfo.GameDirectory);
58+
59+
60+
var modlist = await _modding.GetModListAsync();
61+
var mod = modlist.Mods.FirstOrDefault(x => x.fullPath == path);
62+
if (mod != null && mod.enabled)
63+
{
64+
await _modding.ToggleModStatus(path, false);
65+
} else
66+
{
67+
var def = await GetScalingParameter(race, gender, true);
68+
await SetScalingParameter(def);
69+
}
70+
71+
}
72+
4773
internal static async Task RestoreDefaultScaling(string rgspPath, IndexFile index = null, ModList modlist = null)
4874
{
4975
var match = RgspPathExtractFormat.Match(rgspPath);
@@ -55,6 +81,26 @@ internal static async Task RestoreDefaultScaling(string rgspPath, IndexFile inde
5581
await RestoreDefaultScaling(race, gender, index, modlist);
5682
}
5783

84+
internal static string GetModFileNameFromRgspPath(string path)
85+
{
86+
var match = RgspPathExtractFormat.Match(path);
87+
if (!match.Success) return null;
88+
89+
var race = (XivSubRace)Int32.Parse(match.Groups[1].Value);
90+
var gender = (XivGender)Int32.Parse(match.Groups[2].Value);
91+
92+
var name = race.GetDisplayName() + " - " + gender.ToString();
93+
return name;
94+
}
95+
96+
public static string GetRgspPath(XivSubRace race, XivGender gender)
97+
{
98+
var subraceId = (int)race;
99+
var genderId = (int)gender;
100+
var rgspFilePath = String.Format(RgspPathFormat, subraceId, genderId);
101+
return rgspFilePath;
102+
}
103+
58104
/// <summary>
59105
/// Restores the default settings back into the CMP file.
60106
/// Does NOT delete .rgsp entry.
@@ -78,17 +124,15 @@ internal static async Task RestoreDefaultScaling(XivSubRace race, XivGender gend
78124
/// <returns></returns>
79125
public static async Task SaveScalingParameter(RacialGenderScalingParameter rgsp, string sourceApplication, IndexFile index = null, ModList modlist = null)
80126
{
81-
var subraceId = (int) rgsp.Race;
82-
var genderId = (int)rgsp.Gender;
83127

84128
// Write the .rgsp file and let the DAT functions handle applying it.
85-
var rgspFilePath = String.Format(RgspPathFormat, subraceId, genderId);
129+
var rgspFilePath = GetRgspPath(rgsp.Race, rgsp.Gender);
86130

87131
var bytes = rgsp.GetBytes();
88132

89133

90134
var dummyItem = new XivGenericItemModel();
91-
dummyItem.Name = rgsp.Race.GetDisplayName();
135+
dummyItem.Name = rgsp.Race.GetDisplayName() + " - " + rgsp.Gender.ToString();
92136
dummyItem.SecondaryCategory = "Racial Scaling";
93137

94138
var _dat = new Dat(XivCache.GameInfo.GameDirectory);
@@ -104,6 +148,13 @@ public static async Task<RacialGenderScalingParameter> GetScalingParameter(XivS
104148
return cmp.GetScalingParameter(race, gender);
105149
}
106150

151+
/// <summary>
152+
/// Performs the base level alteration to the CMP file, without going through .rgsp files.
153+
/// </summary>
154+
/// <param name="data"></param>
155+
/// <param name="index"></param>
156+
/// <param name="modlist"></param>
157+
/// <returns></returns>
107158
private static async Task SetScalingParameter(RacialGenderScalingParameter data, IndexFile index = null, ModList modlist = null)
108159
{
109160
var cmp = await GetCharaMakeParameterSet(false, index, modlist);

xivModdingFramework/General/DataContainers/CharaMakeParameter.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ public RacialScalingParameter(byte[] data)
238238
/// </summary>
239239
public class RacialGenderScalingParameter
240240
{
241+
private const ushort Version = 2;
241242
public XivSubRace Race { get; private set; }
242243
public XivGender Gender { get; private set; }
243244

@@ -288,10 +289,25 @@ public RacialGenderScalingParameter(RacialScalingParameter rsp, XivSubRace race,
288289
public RacialGenderScalingParameter(byte[] data)
289290
{
290291
var offset = 0;
291-
Race = (XivSubRace) data[0];
292-
Gender = (XivGender) data[1];
292+
var byte0 = data[offset];
293+
294+
ushort version = 0;
295+
if(byte0 != 255)
296+
{
297+
version = 1;
298+
} else
299+
{
300+
offset++;
301+
302+
version = BitConverter.ToUInt16(data, offset);
303+
offset += 2;
304+
}
305+
306+
Race = (XivSubRace) data[offset];
307+
offset++;
308+
Gender = (XivGender) data[offset];
309+
offset++;
293310

294-
offset = 2;
295311
MinSize = BitConverter.ToSingle(data, offset);
296312
offset += 4;
297313
MaxSize = BitConverter.ToSingle(data, offset);
@@ -321,6 +337,9 @@ public byte[] GetBytes()
321337
{
322338
List<byte> data = new List<byte>();
323339

340+
data.Add((byte)255);
341+
data.AddRange(BitConverter.GetBytes(Version));
342+
324343
data.Add((byte)Race);
325344
data.Add((byte)Gender);
326345

xivModdingFramework/Mods/Modding.cs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,9 @@ public async Task<bool> ToggleModUnsafe(bool enable, Mod mod, bool includeIntern
385385

386386
// And write that metadata to the actual constituent files.
387387
await ItemMetadata.ApplyMetadata(meta, cachedIndex, cachedModlist);
388+
} else if(ext == ".rgsp")
389+
{
390+
await CMP.ApplyRgspFile(mod.fullPath, cachedIndex, cachedModlist);
388391
}
389392
}
390393
}
@@ -396,6 +399,18 @@ public async Task<bool> ToggleModUnsafe(bool enable, Mod mod, bool includeIntern
396399
if (cachedIndex != null)
397400
{
398401
cachedIndex.SetDataOffset(mod.fullPath, 0);
402+
403+
// This is a metadata entry being deleted, we'll need to restore the metadata entries back to default.
404+
if (mod.fullPath.EndsWith(".meta"))
405+
{
406+
var root = await XivCache.GetFirstRoot(mod.fullPath);
407+
await ItemMetadata.RestoreDefaultMetadata(root, cachedIndex, cachedModlist);
408+
}
409+
410+
if (mod.fullPath.EndsWith(".rgsp"))
411+
{
412+
await CMP.RestoreDefaultScaling(mod.fullPath, cachedIndex, cachedModlist);
413+
}
399414
}
400415
else
401416
{
@@ -685,8 +700,17 @@ public async Task CleanUpModlist(IProgress<(int Current, int Total, string Messa
685700
root = await XivCache.GetFirstRoot(mod.fullPath);
686701
if(root == null)
687702
{
688-
mod.name = Path.GetFileName(mod.fullPath);
689-
mod.category = "Raw Files";
703+
var cmpName = CMP.GetModFileNameFromRgspPath(mod.fullPath);
704+
if (cmpName != null)
705+
{
706+
mod.name = cmpName;
707+
mod.category = "Racial Scaling";
708+
}
709+
else
710+
{
711+
mod.name = Path.GetFileName(mod.fullPath);
712+
mod.category = "Raw Files";
713+
}
690714
continue;
691715
}
692716

xivModdingFramework/Mods/RootCloner.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ public static async Task<Dictionary<string, string>> CloneRoot(XivDependencyRoot
106106
if (String.IsNullOrEmpty(avfxStuff.Folder) || String.IsNullOrEmpty(avfxStuff.File)) continue;
107107

108108
var path = avfxStuff.Folder + "/" + avfxStuff.File;
109-
if (await _index.FileExists(path))
109+
if (index.FileExists(path))
110110
{
111111
originalVfxPaths.Add(path);
112112
}

xivModdingFramework/SqPack/FileTypes/Dat.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1553,11 +1553,31 @@ public async Task<uint> WriteToDat(byte[] importData, XivDataFile dataFile, long
15531553
var datPath = Path.Combine(_gameDirectory.FullName, $"{dataFile.GetDataFileName()}{DatExtension}{datNum}");
15541554

15551555
// Copy the data into the file.
1556-
using (var bw = new BinaryWriter(File.OpenWrite(datPath)))
1556+
BinaryWriter bw = null;
1557+
1558+
try
15571559
{
1558-
if(targetOffset >= 2048) {
1560+
try
1561+
{
1562+
bw = new BinaryWriter(File.OpenWrite(datPath));
1563+
}
1564+
catch
1565+
{
1566+
if(bw != null)
1567+
{
1568+
bw.Dispose();
1569+
}
1570+
1571+
// Wait just a bit and try again.
1572+
await Task.Delay(100);
1573+
bw = new BinaryWriter(File.OpenWrite(datPath));
1574+
}
1575+
1576+
if (targetOffset >= 2048)
1577+
{
15591578
bw.BaseStream.Seek(seekPointer, SeekOrigin.Begin);
1560-
} else
1579+
}
1580+
else
15611581
{
15621582
bw.BaseStream.Seek(0, SeekOrigin.End);
15631583
}
@@ -1579,6 +1599,13 @@ public async Task<uint> WriteToDat(byte[] importData, XivDataFile dataFile, long
15791599
bw.Write((byte)0);
15801600
}
15811601
}
1602+
finally
1603+
{
1604+
if (bw != null)
1605+
{
1606+
bw.Dispose();
1607+
}
1608+
}
15821609

15831610
var intFormat = (uint)(filePointer / 8);
15841611
uint datIdentifier = (uint)(datNum * 2);

xivModdingFramework/SqPack/FileTypes/Index.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -794,12 +794,33 @@ public async Task SaveIndexFile(IndexFile index, bool alreadySemaphoreLocked = f
794794
throw new Exception("Cannot write index files; files current in use.");
795795
}
796796

797-
using (var index1Stream = new BinaryWriter(File.OpenWrite(index1Path)))
797+
BinaryWriter index1Stream = null;
798+
BinaryWriter index2Stream = null;
799+
try
798800
{
799-
using (var index2Stream = new BinaryWriter(File.OpenWrite(index2Path)))
801+
try
802+
{
803+
index1Stream = new BinaryWriter(File.OpenWrite(index1Path));
804+
index2Stream = new BinaryWriter(File.OpenWrite(index2Path));
805+
}
806+
catch
800807
{
801-
index.Save(index1Stream, index2Stream);
808+
index1Stream?.Dispose();
809+
index2Stream?.Dispose();
810+
811+
// Set a minor delay and try again, in case the user has some sort of locking issue.
812+
await Task.Delay(200);
813+
814+
index1Stream = new BinaryWriter(File.OpenWrite(index1Path));
815+
index2Stream = new BinaryWriter(File.OpenWrite(index2Path));
802816
}
817+
818+
index.Save(index1Stream, index2Stream);
819+
}
820+
finally
821+
{
822+
index1Stream?.Dispose();
823+
index2Stream?.Dispose();
803824
}
804825

805826

0 commit comments

Comments
 (0)