diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj
index b0c1dd5a..c803bf70 100644
--- a/FModel/FModel.csproj
+++ b/FModel/FModel.csproj
@@ -111,6 +111,7 @@
+
diff --git a/FModel/Options.Designer.cs b/FModel/Options.Designer.cs
index 3bf76ed1..a36e3210 100644
--- a/FModel/Options.Designer.cs
+++ b/FModel/Options.Designer.cs
@@ -244,9 +244,9 @@
this.checkBox8.AutoSize = true;
this.checkBox8.Location = new System.Drawing.Point(6, 79);
this.checkBox8.Name = "checkBox8";
- this.checkBox8.Size = new System.Drawing.Size(177, 17);
+ this.checkBox8.Size = new System.Drawing.Size(233, 17);
this.checkBox8.TabIndex = 26;
- this.checkBox8.Text = "Use Featured Image If Available";
+ this.checkBox8.Text = "Use Characters\' Featured Image If Available";
this.checkBox8.UseVisualStyleBackColor = true;
this.checkBox8.CheckedChanged += new System.EventHandler(this.checkBox8_CheckedChanged);
//
diff --git a/FModel/PAKWindow.cs b/FModel/PAKWindow.cs
index b2224695..8a202203 100644
--- a/FModel/PAKWindow.cs
+++ b/FModel/PAKWindow.cs
@@ -2,6 +2,7 @@
using FModel.Parser.Featured;
using FModel.Challenges;
using FModel.Quest;
+using FModel.RenderMat;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
@@ -166,9 +167,6 @@ namespace FModel
Properties.Settings.Default.ExtractAndSerialize = true; //SERIALIZE BY DEFAULT
docPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).ToString() + "\\FModel";
- if (!Directory.Exists(docPath))
- Directory.CreateDirectory(docPath);
-
if (string.IsNullOrEmpty(Properties.Settings.Default.ExtractOutput))
{
Properties.Settings.Default.ExtractOutput = docPath;
@@ -179,6 +177,9 @@ namespace FModel
docPath = Properties.Settings.Default.ExtractOutput;
}
+ if (!Directory.Exists(docPath))
+ Directory.CreateDirectory(docPath);
+
if (!Directory.Exists(Properties.Settings.Default.FortnitePAKs))
{
loadAllPAKsToolStripMenuItem.Enabled = false;
@@ -1915,7 +1916,117 @@ namespace FModel
}
try
{
- if (filesPath2 != null)
+ if (filesPath2 != null && filesPath2.Contains("MI_UI_FeaturedRenderSwitch_"))
+ {
+ AppendText("✔ ", Color.Green);
+ AppendText(textureFile, Color.DarkRed);
+ AppendText(" successfully extracted to ", Color.Black);
+ AppendText(filesPath2.Substring(0, filesPath2.LastIndexOf('.')), Color.SteelBlue, true);
+ try
+ {
+ await Task.Run(() =>
+ {
+ jwpmProcess("serialize \"" + filesPath2.Substring(0, filesPath2.LastIndexOf('.')) + "\"");
+ });
+ var filesJSON3 = Directory.GetFiles(docPath, textureFile + ".json", SearchOption.AllDirectories).FirstOrDefault();
+ var json3 = JToken.Parse(File.ReadAllText(filesJSON3)).ToString();
+ File.Delete(filesJSON3);
+ AppendText("✔ ", Color.Green);
+ AppendText(textureFile, Color.DarkRed);
+ AppendText(" successfully serialized", Color.Black, true);
+
+ var RenderParser = RenderSwitchMaterial.FromJson(json3);
+ for (int i2 = 0; i2 < RenderParser.Length; i2++)
+ {
+ if (RenderParser[i2].TextureParameterValues.FirstOrDefault().ParameterValue != null)
+ {
+ string textureFile2 = RenderParser[i2].TextureParameterValues.FirstOrDefault().ParameterValue;
+ AppendText("✔ ", Color.Green);
+ AppendText(textureFile2, Color.DarkRed);
+ AppendText(" detected as a ", Color.Black);
+ AppendText("Texture2D file", Color.SteelBlue, true);
+
+ var filesPath3 = Directory.GetFiles(docPath + "\\Extracted", textureFile2 + ".*", SearchOption.AllDirectories).FirstOrDefault();
+ if (!File.Exists(filesPath3))
+ {
+ if (currentGUID != "0-0-0-0")
+ {
+ await Task.Run(() =>
+ {
+ jwpmProcess("extract \"" + Properties.Settings.Default.FortnitePAKs + "\\" + currentPAK + "\" \"" + textureFile2 + "\" \"" + docPath + "\"");
+ });
+ filesPath3 = Directory.GetFiles(docPath + "\\Extracted", textureFile2 + ".*", SearchOption.AllDirectories).FirstOrDefault();
+ }
+ else
+ {
+ if (isAllPAKs == false)
+ {
+ await Task.Run(() =>
+ {
+ jwpmProcess("extract \"" + Properties.Settings.Default.FortnitePAKs + "\\pakchunk0_s7-WindowsClient.pak" + "\" \"" + textureFile2 + "\" \"" + docPath + "\"");
+ });
+ }
+ if (isAllPAKs == true)
+ {
+ await Task.Run(() => {
+ try
+ {
+ jwpmProcess("extract \"" + Properties.Settings.Default.FortnitePAKs + "\\" + AllPAKsDict[textureFile2] + "\" \"" + textureFile2 + "\" \"" + docPath + "\"");
+ }
+ catch (KeyNotFoundException ex)
+ {
+ Console.ForegroundColor = ConsoleColor.Red;
+ Console.Write("[ERROR] ");
+ Console.ForegroundColor = ConsoleColor.White;
+ Console.Write(ex.Message);
+ }
+ });
+ }
+ filesPath3 = Directory.GetFiles(docPath + "\\Extracted", textureFile2 + ".*", SearchOption.AllDirectories).FirstOrDefault();
+ }
+ }
+ try
+ {
+ if (filesPath3 != null)
+ {
+ AppendText("✔ ", Color.Green);
+ AppendText(textureFile2, Color.DarkRed);
+ AppendText(" successfully extracted to ", Color.Black);
+ AppendText(filesPath3.Substring(0, filesPath3.LastIndexOf('.')), Color.SteelBlue, true);
+
+ itemIconPath = filesPath3.Substring(0, filesPath3.LastIndexOf('.')) + ".png";
+ if (!File.Exists(itemIconPath))
+ {
+ await Task.Run(() =>
+ {
+ jwpmProcess("texture \"" + filesPath3.Substring(0, filesPath3.LastIndexOf('.')) + "\"");
+ });
+ itemIconPath = filesPath3.Substring(0, filesPath3.LastIndexOf('.')) + ".png";
+ }
+
+ AppendText("✔ ", Color.Green);
+ AppendText(textureFile2, Color.DarkRed);
+ AppendText(" successfully converted to a PNG image with path ", Color.Black);
+ AppendText(itemIconPath, Color.SteelBlue, true);
+ }
+ }
+ catch (IndexOutOfRangeException)
+ {
+ AppendText("[IndexOutOfRangeException] ", Color.Red);
+ AppendText("Can't extract ", Color.Black);
+ AppendText(textureFile2, Color.SteelBlue);
+ AppendText(" in ", Color.Black);
+ AppendText("pakchunk0_s7-WindowsClient.pak", Color.DarkRed, true);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+ else if (filesPath2 != null && !filesPath2.Contains("MI_UI_FeaturedRenderSwitch_"))
{
AppendText("✔ ", Color.Green);
AppendText(textureFile, Color.DarkRed);
diff --git a/FModel/Parser/RenderSwitchMaterial.cs b/FModel/Parser/RenderSwitchMaterial.cs
new file mode 100644
index 00000000..befb3989
--- /dev/null
+++ b/FModel/Parser/RenderSwitchMaterial.cs
@@ -0,0 +1,106 @@
+//
+//
+// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
+//
+// using FModel.RenderMat;
+//
+// var renderSwitchMaterial = RenderSwitchMaterial.FromJson(jsonString);
+
+namespace FModel.RenderMat
+{
+ using System;
+ using System.Collections.Generic;
+
+ using System.Globalization;
+ using Newtonsoft.Json;
+ using Newtonsoft.Json.Converters;
+
+ public partial class RenderSwitchMaterial
+ {
+ [JsonProperty("export_type")]
+ public string ExportType { get; set; }
+
+ [JsonProperty("Parent")]
+ public string Parent { get; set; }
+
+ [JsonProperty("ScalarParameterValues")]
+ public ScalarParameterValue[] ScalarParameterValues { get; set; }
+
+ [JsonProperty("TextureParameterValues")]
+ public TextureParameterValue[] TextureParameterValues { get; set; }
+
+ [JsonProperty("BasePropertyOverrides")]
+ public BasePropertyOverrides BasePropertyOverrides { get; set; }
+ }
+
+ public partial class BasePropertyOverrides
+ {
+ [JsonProperty("BlendMode")]
+ public string BlendMode { get; set; }
+
+ [JsonProperty("ShadingModel")]
+ public string ShadingModel { get; set; }
+
+ [JsonProperty("OpacityMaskClipValue")]
+ public double OpacityMaskClipValue { get; set; }
+ }
+
+ public partial class ScalarParameterValue
+ {
+ [JsonProperty("ParameterInfo")]
+ public ParameterInfo ParameterInfo { get; set; }
+
+ [JsonProperty("ParameterValue")]
+ public long ParameterValue { get; set; }
+
+ [JsonProperty("ExpressionGUID")]
+ public string ExpressionGuid { get; set; }
+ }
+
+ public partial class ParameterInfo
+ {
+ [JsonProperty("Name")]
+ public string Name { get; set; }
+
+ [JsonProperty("Association")]
+ public string Association { get; set; }
+
+ [JsonProperty("Index")]
+ public long Index { get; set; }
+ }
+
+ public partial class TextureParameterValue
+ {
+ [JsonProperty("ParameterInfo")]
+ public ParameterInfo ParameterInfo { get; set; }
+
+ [JsonProperty("ParameterValue")]
+ public string ParameterValue { get; set; }
+
+ [JsonProperty("ExpressionGUID")]
+ public string ExpressionGuid { get; set; }
+ }
+
+ public partial class RenderSwitchMaterial
+ {
+ public static RenderSwitchMaterial[] FromJson(string json) => JsonConvert.DeserializeObject(json, FModel.RenderMat.Converter.Settings);
+ }
+
+ public static class Serialize
+ {
+ public static string ToJson(this RenderSwitchMaterial[] self) => JsonConvert.SerializeObject(self, FModel.RenderMat.Converter.Settings);
+ }
+
+ internal static class Converter
+ {
+ public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
+ {
+ MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
+ DateParseHandling = DateParseHandling.None,
+ Converters =
+ {
+ new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
+ },
+ };
+ }
+}
diff --git a/README.md b/README.md
index 25f02cee..e0c12b5a 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,7 @@ I'd highly suggest you to use [UModel](https://github.com/gildor2/UModel) instea
- [x] Quest viewer or something
- [x] Load all paks
- [ ] Shop loader ?
+- [ ] Update mode (auto extraction and icon creation of every useful thing)
- [x] Load only difference between 2 paks version
- [x] Custom watermark option on icons
- [x] Choose between extracted filename or displayName for icons file name