Skip to content

Commit 541a4ce

Browse files
committed
Changes to TTMP format to include new fields
- Url & MinimumFrameworkVersion at the modpack level - IsDefault at the mod level
1 parent 974b252 commit 541a4ce

File tree

8 files changed

+155
-0
lines changed

8 files changed

+155
-0
lines changed

xivModdingFramework/Helpers/Constants.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System;
44
using System.Collections.Generic;
55
using System.Text;
6+
using System.Text.RegularExpressions;
67

78
namespace xivModdingFramework.Helpers
89
{
@@ -14,5 +15,11 @@ public static class Constants
1415
/// </summary>
1516
public static readonly char[] Alphabet = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
1617
public static string BinaryOffsetMarker = "::";
18+
19+
20+
21+
// This commedically long regex validates URL strings.
22+
// Came from - https://mathiasbynens.be/demo/url-regex (@scottgonzales version)
23+
public static readonly Regex UrlValidationRegex = new Regex("#([a-z]([a-z]|\\d|\\+|-|\\.)*):(\\/\\/(((([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:)*@)?((\\[(|(v[\\da-f]{1,}\\.(([a-z]|\\d|-|\\.|_|~)|[!\\$&'\\(\\)\\*\\+,;=]|:)+))\\])|((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5]))|(([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=])*)(:\\d*)?)(\\/(([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*|(\\/((([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)?)|((([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)+(\\/(([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)*)*)|((([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)){0})(\\?((([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|[\\xE000-\\xF8FF]|\\/|\\?)*)?(\\#((([a-z]|\\d|-|\\.|_|~|[\\x00A0-\\xD7FF\\xF900-\\xFDCF\\xFDF0-\\xFFEF])|(%[\\da-f]{2})|[!\\$&'\\(\\)\\*\\+,;=]|:|@)|\\/|\\?)*)?#iS");
1724
}
1825
}

xivModdingFramework/Helpers/IOUtil.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,5 +252,46 @@ public static XivDataFile GetDataFileFromPath(string path)
252252

253253
throw new Exception("Could not resolve data file - Invalid internal FFXIV path.");
254254
}
255+
256+
/// <summary>
257+
/// Cleans a given string of unusual or potentially invalid characters for most use cases, particularly URLs.
258+
/// </summary>
259+
/// <param name="st"></param>
260+
/// <returns></returns>
261+
public static string CleanString(string st)
262+
{
263+
if(st == null)
264+
{
265+
return "";
266+
}
267+
268+
269+
const string invalids = "!\"#$%&'()*+,-./@:;<=>[\\]^_`{|}~";
270+
271+
st = st.Trim();
272+
foreach (var c in invalids)
273+
{
274+
st.Replace(c.ToString(), "");
275+
}
276+
277+
return st;
278+
}
279+
280+
/// <summary>
281+
/// Cleans up and validates a string to ensure it's a valid URL.
282+
/// If the given URL is totally invalid, NULL is returned.
283+
/// </summary>
284+
/// <param name="url"></param>
285+
/// <returns></returns>
286+
public static string ValidateUrl(string url)
287+
{
288+
url = CleanString(url);
289+
if (Constants.UrlValidationRegex.IsMatch(url))
290+
{
291+
return url;
292+
}
293+
return null;
294+
}
295+
255296
}
256297
}

xivModdingFramework/Mods/DataContainers/ModList.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17+
using System;
1718
using System.Collections.Generic;
19+
using System.Diagnostics.Contracts;
20+
using System.Security.Cryptography;
21+
using System.Text;
1822

1923
namespace xivModdingFramework.Mods.DataContainers
2024
{
@@ -91,6 +95,11 @@ public class Mod
9195
/// </remarks>
9296
public bool enabled { get; set; }
9397

98+
/// <summary>
99+
/// The minimum framework version necessary to operate on this mod safely.
100+
/// </summary>
101+
public string minimumFrameworkVersion = "1.0.0.0";
102+
94103
/// <summary>
95104
/// The modPack associated with this mod
96105
/// </summary>
@@ -132,10 +141,30 @@ public class Data
132141
/// When importing a previously modified texture, this value is used to determine whether the modified data will be overwritten
133142
/// </remarks>
134143
public int modSize { get; set; }
144+
135145
}
136146

137147
public class ModPack
138148
{
149+
150+
/// <summary>
151+
/// Generates a hash identifier from this mod's name and author information,
152+
/// in lowercase. For identifying new versions of same mods, potentially.
153+
/// </summary>
154+
/// <returns></returns>
155+
public byte[] GetHash()
156+
{
157+
using (SHA256 sha = SHA256.Create())
158+
{
159+
var n = name.ToLower();
160+
var a = author.ToLower();
161+
var key = n + a;
162+
var keyBytes= Encoding.Unicode.GetBytes(key);
163+
var hash = sha.ComputeHash(keyBytes);
164+
return hash;
165+
}
166+
}
167+
139168
/// <summary>
140169
/// The name of the modpack
141170
/// </summary>
@@ -150,5 +179,10 @@ public class ModPack
150179
/// The modpack version
151180
/// </summary>
152181
public string version { get; set; }
182+
183+
/// <summary>
184+
/// The URL the author associated with this modpack.
185+
/// </summary>
186+
public string url { get; set; }
153187
}
154188
}

xivModdingFramework/Mods/DataContainers/ModOption.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,14 @@ public class ModData
7979
/// </summary>
8080
public string FullPath { get; set; }
8181

82+
/// <summary>
83+
/// Whether or not this item is a default SE file.
84+
/// These files are still included in full, for the sake
85+
/// of backwards compatability, but in the future may have
86+
/// handling to simply disable existing mods, rather than copy over.
87+
/// </summary>
88+
public bool IsDefault = false;
89+
8290
/// <summary>
8391
/// The raw mod data
8492
/// </summary>

xivModdingFramework/Mods/DataContainers/ModPackData.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ public class ModPackData
4141
/// </summary>
4242
public string Description { get; set; }
4343

44+
/// <summary>
45+
/// Author's supplied URL for the modpack.
46+
/// </summary>
47+
public string Url { get; set; }
48+
4449
/// <summary>
4550
/// A list of pages containing a list of mod groups for that particular page
4651
/// </summary>

xivModdingFramework/Mods/DataContainers/ModPackJson.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
using System.Collections.Generic;
18+
using System.Security.Cryptography;
19+
using System.Text;
1820

1921
namespace xivModdingFramework.Mods.DataContainers
2022
{
@@ -45,6 +47,36 @@ public class ModPackJson
4547
/// </summary>
4648
public string Description { get; set; }
4749

50+
/// <summary>
51+
/// The modpack's weblink.
52+
/// </summary>
53+
public string Url { get; set; }
54+
55+
/// <summary>
56+
/// Minimum required version of the Framework to import this modpack file.
57+
/// The 1.0.0.0 here is purely a fallback default; it should be assigned to
58+
/// in the actual modpack generation.
59+
/// </summary>
60+
public string MinimumFrameworkVersion = "1.0.0.0";
61+
62+
/// <summary>
63+
/// Generates a hash identifier from this mod's name and author information,
64+
/// in lowercase. For identifying new versions of same mods, potentially.
65+
/// </summary>
66+
/// <returns></returns>
67+
public byte[] GetHash()
68+
{
69+
using (SHA256 sha = SHA256.Create())
70+
{
71+
var n = Name.ToLower();
72+
var a = Author.ToLower();
73+
var key = n + a;
74+
var keyBytes = Encoding.Unicode.GetBytes(key);
75+
var hash = sha.ComputeHash(keyBytes);
76+
return hash;
77+
}
78+
}
79+
4880
/// <summary>
4981
/// A list of pages containing a list of mod groups for that particular page
5082
/// </summary>
@@ -160,6 +192,16 @@ public class ModsJson
160192
/// </summary>
161193
public string DatFile { get; set; }
162194

195+
/// <summary>
196+
/// Indicates if this "Mod" is actually just a placeholder in a modpack,
197+
/// indicating that we want any existing mod on this file to be disabled.
198+
///
199+
/// Default mod entries include completely valid copies of their original
200+
/// SE item, for backwards compatability and in case some code imports
201+
/// them incorrectly or needs the information for calculations.
202+
/// </summary>
203+
public bool IsDefault { get; set; }
204+
163205
/// <summary>
164206
/// The Mod Pack Entry
165207
/// </summary>

xivModdingFramework/Mods/DataContainers/SimpleModPackData.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ public class SimpleModPackData
3636
/// </summary>
3737
public Version Version { get; set; }
3838

39+
/// <summary>
40+
/// The modpack Url
41+
/// </summary>
42+
public string Url = "";
43+
3944
/// <summary>
4045
/// The description for the mod pack
4146
/// </summary>
@@ -70,6 +75,11 @@ public class SimpleModData
7075
/// </summary>
7176
public long ModOffset { get; set; }
7277

78+
/// <summary>
79+
/// If the entry is SE Default data or not.
80+
/// </summary>
81+
public bool IsDefault = false;
82+
7383
/// <summary>
7484
/// The size of the mod data
7585
/// </summary>

xivModdingFramework/Mods/FileTypes/TTMP.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class TTMP
3434
{
3535
private readonly string _currentWizardTTMPVersion = "1.0w";
3636
private readonly string _currentSimpleTTMPVersion = "1.0s";
37+
private const string _minimumAssembly = "1.0.0.0";
38+
3739
private string _tempMPD, _tempMPL, _source;
3840
private readonly DirectoryInfo _modPackDirectory;
3941

@@ -61,10 +63,12 @@ public async Task<int> CreateWizardModPack(ModPackData modPackData, IProgress<do
6163
var modPackJson = new ModPackJson
6264
{
6365
TTMPVersion = _currentWizardTTMPVersion,
66+
MinimumFrameworkVersion = _minimumAssembly,
6467
Name = modPackData.Name,
6568
Author = modPackData.Author,
6669
Version = modPackData.Version.ToString(),
6770
Description = modPackData.Description,
71+
Url = modPackData.Url,
6872
ModPackPages = new List<ModPackPageJson>()
6973
};
7074

@@ -123,6 +127,7 @@ public async Task<int> CreateWizardModPack(ModPackData modPackData, IProgress<do
123127
Name = modOptionMod.Value.Name,
124128
Category = modOptionMod.Value.Category.GetEnDisplayName(),
125129
FullPath = modOptionMod.Key,
130+
IsDefault = modOptionMod.Value.IsDefault,
126131
ModSize = modOptionMod.Value.ModDataBytes.Length,
127132
ModOffset = binaryWriter.BaseStream.Position,
128133
DatFile = dataFile.GetDataFileName(),
@@ -201,6 +206,8 @@ public async Task<int> CreateSimpleModPack(SimpleModPackData modPackData, Direct
201206
Name = modPackData.Name,
202207
Author = modPackData.Author,
203208
Version = modPackData.Version.ToString(),
209+
MinimumFrameworkVersion = _minimumAssembly,
210+
Url = modPackData.Url,
204211
Description = modPackData.Description,
205212
SimpleModsList = new List<ModsJson>()
206213
};
@@ -218,6 +225,7 @@ public async Task<int> CreateSimpleModPack(SimpleModPackData modPackData, Direct
218225
FullPath = simpleModData.FullPath,
219226
ModSize = simpleModData.ModSize,
220227
DatFile = simpleModData.DatFile,
228+
IsDefault = simpleModData.IsDefault,
221229
ModOffset = binaryWriter.BaseStream.Position,
222230
ModPackEntry = new ModPack
223231
{

0 commit comments

Comments
 (0)