diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index 863bcfda..efd8db0c 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -149,6 +149,8 @@ + + diff --git a/FModel/MainWindow.cs b/FModel/MainWindow.cs index 7955bfb9..112120d6 100644 --- a/FModel/MainWindow.cs +++ b/FModel/MainWindow.cs @@ -376,8 +376,10 @@ namespace FModel private void CreatePakList(ToolStripItemClickedEventArgs selectedPak = null, bool loadAllPaKs = false, bool getDiff = false, bool updateMode = false) { ThePak.AllpaksDictionary = new Dictionary(); - RegisterSettings.updateModeDictionary = new Dictionary(); ThePak.PaksMountPoint = new Dictionary(); + ThePak.PaksExtractorDictionary = new Dictionary(); + ThePak.PaksFileArrayDictionary = new Dictionary(); + RegisterSettings.updateModeDictionary = new Dictionary(); PakHelper.PakAsTxt = null; if (selectedPak != null) @@ -569,7 +571,6 @@ namespace FModel private async void loadOneToolStripMenuItem_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) { await Task.Run(() => { - JohnWick.myArray = null; Invoke(new Action(() => { scintilla1.Text = ""; @@ -584,7 +585,6 @@ namespace FModel } private async void loadAllToolStripMenuItem_Click(object sender, EventArgs e) { - JohnWick.myArray = null; Invoke(new Action(() => { scintilla1.Text = ""; @@ -975,6 +975,9 @@ namespace FModel case "FortChallengeBundleItemDefinition": CreateBundleChallengesIcon(AssetArray[0], theAssetExtractedPath); break; + case "FortSchematicItemDefinition": + CreateSchematicIcon(AssetArray[0]); + break; case "Texture2D": ConvertTexture2D(); break; @@ -1146,6 +1149,59 @@ namespace FModel BundleDesign.toDrawOn.Dispose(); //actually this is the most useful thing in this method } + private void CreateSchematicIcon(JToken theItem) + { + SchematicIconDesign.toDrawOn = SchematicIconDesign.createGraphic(522, 822); + JToken craftedItem = SchematicItemInfos.getSchematicRecipeResult(theItem); + Rarity.DrawRarity(craftedItem, SchematicIconDesign.toDrawOn); + + ItemIcon.ItemIconPath = string.Empty; + ItemIcon.GetItemIcon(craftedItem, Settings.Default.loadFeaturedImage); + if (File.Exists(ItemIcon.ItemIconPath)) + { + Image itemIcon; + using (var bmpTemp = new Bitmap(ItemIcon.ItemIconPath)) + { + itemIcon = new Bitmap(bmpTemp); + } + SchematicIconDesign.toDrawOn.DrawImage(ImageUtilities.ResizeImage(itemIcon, 512, 512), new Point(5, 5)); + } + else + { + Image itemIcon = Resources.unknown512; + SchematicIconDesign.toDrawOn.DrawImage(itemIcon, new Point(0, 0)); + } + + if (Settings.Default.rarityNew) + { + GraphicsPath p = new GraphicsPath(); + p.StartFigure(); + p.AddLine(4, 438, 517, 383); + p.AddLine(517, 383, 517, 383 + 134); + p.AddLine(4, 383 + 134, 4, 383 + 134); + p.AddLine(4, 383 + 134, 4, 438); + p.CloseFigure(); + SchematicIconDesign.toDrawOn.FillPath(new SolidBrush(Color.FromArgb(70, 0, 0, 50)), p); + } + else { SchematicIconDesign.toDrawOn.FillRectangle(new SolidBrush(Color.FromArgb(70, 0, 0, 50)), new Rectangle(5, 383, 512, 134)); } + + DrawText.DrawTexts(craftedItem, SchematicIconDesign.toDrawOn, ""); + + if (autoSaveImagesToolStripMenuItem.Checked || Checking.UmWorking) + { + SchematicIconDesign.schematicBitmap.Save(App.DefaultOutputPath + "\\Icons\\" + ThePak.CurrentUsedItem + ".png", ImageFormat.Png); + + if (File.Exists(App.DefaultOutputPath + "\\Icons\\" + ThePak.CurrentUsedItem + ".png")) + { + new UpdateMyConsole(ThePak.CurrentUsedItem, Color.DarkRed).AppendToConsole(); + new UpdateMyConsole(" successfully saved", Color.Black, true).AppendToConsole(); + } + } + + pictureBox1.Image = SchematicIconDesign.schematicBitmap; + SchematicIconDesign.toDrawOn.Dispose(); + } + /// /// because the filename is usually the same for each language, John Wick extract all of them /// but then i have to manually get the right path from the treeview diff --git a/FModel/Methods/IconGenerator/SchematicGenerator/SchematicIconDesign.cs b/FModel/Methods/IconGenerator/SchematicGenerator/SchematicIconDesign.cs new file mode 100644 index 00000000..d1158ef3 --- /dev/null +++ b/FModel/Methods/IconGenerator/SchematicGenerator/SchematicIconDesign.cs @@ -0,0 +1,21 @@ +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Text; + +namespace FModel +{ + static class SchematicIconDesign + { + public static Graphics toDrawOn { get; set; } + public static Bitmap schematicBitmap { get; set; } + + public static Graphics createGraphic(int x, int y) + { + schematicBitmap = new Bitmap(x, y); + Graphics g = Graphics.FromImage(schematicBitmap); + g.TextRenderingHint = TextRenderingHint.AntiAlias; + g.SmoothingMode = SmoothingMode.HighQuality; + return g; + } + } +} diff --git a/FModel/Methods/IconGenerator/SchematicGenerator/SchematicItemInfos.cs b/FModel/Methods/IconGenerator/SchematicGenerator/SchematicItemInfos.cs new file mode 100644 index 00000000..e70698b6 --- /dev/null +++ b/FModel/Methods/IconGenerator/SchematicGenerator/SchematicItemInfos.cs @@ -0,0 +1,82 @@ +using csharp_wick; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Linq; + +namespace FModel +{ + class SchematicItemInfos + { + public static JToken getSchematicRecipeResult(JToken schematicAsset) + { + JToken toReturn = null; + + JToken craftingRecipe = schematicAsset["CraftingRecipe"]; + if (craftingRecipe != null) + { + JToken dataTable = craftingRecipe["DataTable"]; + if (dataTable != null) + { + string dataTableFilePath = JohnWick.ExtractAsset(ThePak.AllpaksDictionary[dataTable.Value()], dataTable.Value()); + if (!string.IsNullOrEmpty(dataTableFilePath)) + { + if (dataTableFilePath.Contains(".uasset") || dataTableFilePath.Contains(".uexp") || dataTableFilePath.Contains(".ubulk")) + { + JohnWick.MyAsset = new PakAsset(dataTableFilePath.Substring(0, dataTableFilePath.LastIndexOf('.'))); + try + { + if (JohnWick.MyAsset.GetSerialized() != null) + { + dynamic AssetData = JsonConvert.DeserializeObject(JohnWick.MyAsset.GetSerialized()); + JArray AssetArray = JArray.FromObject(AssetData); + + JToken weaponRowName = ((JObject)AssetArray[0]).GetValue(craftingRecipe["RowName"].Value(), StringComparison.OrdinalIgnoreCase); + if (weaponRowName != null) + { + JToken recipeResults = weaponRowName["RecipeResults"]; + if (recipeResults != null) + { + JToken primaryAssetName = recipeResults[0]["ItemPrimaryAssetId"]["PrimaryAssetName"]; + if (primaryAssetName != null) + { + string primaryAssetNameInDict = ThePak.AllpaksDictionary.Where(x => string.Equals(x.Key, primaryAssetName.Value(), StringComparison.CurrentCultureIgnoreCase)).Select(d => d.Key).FirstOrDefault(); + string primaryAssetTableFilePath = JohnWick.ExtractAsset(ThePak.AllpaksDictionary[primaryAssetNameInDict], primaryAssetNameInDict); + if (!string.IsNullOrEmpty(primaryAssetTableFilePath)) + { + if (primaryAssetTableFilePath.Contains(".uasset") || primaryAssetTableFilePath.Contains(".uexp") || primaryAssetTableFilePath.Contains(".ubulk")) + { + JohnWick.MyAsset = new PakAsset(primaryAssetTableFilePath.Substring(0, primaryAssetTableFilePath.LastIndexOf('.'))); + try + { + if (JohnWick.MyAsset.GetSerialized() != null) + { + dynamic primaryAssetData = JsonConvert.DeserializeObject(JohnWick.MyAsset.GetSerialized()); + JArray primaryAssetArray = JArray.FromObject(primaryAssetData); + toReturn = primaryAssetArray[0]; + } + } + catch (JsonSerializationException) + { + //do not crash when JsonSerialization does weird stuff + } + } + } + } + } + } + } + } + catch (JsonSerializationException) + { + //do not crash when JsonSerialization does weird stuff + } + } + } + } + } + + return toReturn; + } + } +} diff --git a/FModel/Methods/JohnWick/JohnWick.cs b/FModel/Methods/JohnWick/JohnWick.cs index bf2aa300..451225c5 100644 --- a/FModel/Methods/JohnWick/JohnWick.cs +++ b/FModel/Methods/JohnWick/JohnWick.cs @@ -11,9 +11,6 @@ namespace FModel static class JohnWick { public static PakAsset MyAsset; - private static PakExtractor _myExtractor; - public static string[] myArray { get; set; } - private static string currentPakToCheck { get; set; } /// /// Normal pak file: using AllpaksDictionary, it tells you the pak name depending on currentItem. Using this pak name and PaksMountPoint we get the mount point @@ -58,26 +55,22 @@ namespace FModel } else { myKey = Settings.Default.AESKey; } - if (currentPak != currentPakToCheck || myArray == null) - { - _myExtractor = new PakExtractor(Settings.Default.PAKsPath + "\\" + currentPak, myKey); - myArray = _myExtractor.GetFileList().ToArray(); - } + PakExtractor pakExtractor = ThePak.PaksExtractorDictionary[currentPak]; + string[] pakFiles = ThePak.PaksFileArrayDictionary[pakExtractor]; - string[] results = currentItem.Contains(".") ? Array.FindAll(myArray, s => s.Contains("/" + currentItem)) : Array.FindAll(myArray, s => s.Contains("/" + currentItem + ".")); + string[] results = currentItem.Contains(".") ? Array.FindAll(pakFiles, s => s.Contains("/" + currentItem)) : Array.FindAll(pakFiles, s => s.Contains("/" + currentItem + ".")); string AssetPath = string.Empty; for (int i = 0; i < results.Length; i++) { - int index = Array.IndexOf(myArray, results[i]); + int index = Array.IndexOf(pakFiles, results[i]); uint y = (uint)index; - byte[] b = _myExtractor.GetData(y); + byte[] b = pakExtractor.GetData(y); AssetPath = WriteFile(currentItem, results[i], b).Replace("/", "\\"); } - currentPakToCheck = currentPak; return AssetPath; } diff --git a/FModel/Methods/PakHelper/PakHelper.cs b/FModel/Methods/PakHelper/PakHelper.cs index 7869ed32..759bc59d 100644 --- a/FModel/Methods/PakHelper/PakHelper.cs +++ b/FModel/Methods/PakHelper/PakHelper.cs @@ -48,9 +48,10 @@ namespace FModel if (CurrentUsedPakLines != null) { bMainKeyWorking = true; + ThePak.PaksExtractorDictionary.Add(ThePak.mainPaksList[i].thePak, _extractor); + ThePak.PaksFileArrayDictionary.Add(_extractor, CurrentUsedPakLines); RegisterInDict(ThePak.mainPaksList[i].thePak, CurrentUsedPakLines, theSinglePak, loadAllPaKs); } - _extractor.Dispose(); } if (bMainKeyWorking) { LoadLocRes.LoadMySelectedLocRes(Settings.Default.IconLanguage); } @@ -75,9 +76,10 @@ namespace FModel string[] CurrentUsedPakLines = _extractor.GetFileList().ToArray(); if (CurrentUsedPakLines != null) { + ThePak.PaksExtractorDictionary.Add(ThePak.dynamicPaksList[i].thePak, _extractor); + ThePak.PaksFileArrayDictionary.Add(_extractor, CurrentUsedPakLines); RegisterInDict(ThePak.dynamicPaksList[i].thePak, CurrentUsedPakLines, theSinglePak, loadAllPaKs); } - _extractor.Dispose(); } } diff --git a/FModel/Methods/VarApp.cs b/FModel/Methods/VarApp.cs index 46403ff2..eaef3e5b 100644 --- a/FModel/Methods/VarApp.cs +++ b/FModel/Methods/VarApp.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json.Linq; +using csharp_wick; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Drawing; @@ -48,8 +49,10 @@ namespace FModel public static List dynamicPaksList { get; set; } public static string CurrentUsedItem { get; set; } - public static Dictionary PaksMountPoint { get; set; } public static Dictionary AllpaksDictionary { get; set; } + public static Dictionary PaksExtractorDictionary { get; set; } + public static Dictionary PaksFileArrayDictionary { get; set; } + public static Dictionary PaksMountPoint { get; set; } /// /// read the GUID of a the param, it's basically just reading some bytes at the end of a pak file, but it's useful to tell if the pak is dynamically encrypted