FModel 2.4.0

This commit is contained in:
Asval 2019-06-18 00:13:16 +02:00
parent 7203caf3db
commit 19d86e8127
17 changed files with 194 additions and 161 deletions

View File

@ -136,7 +136,6 @@
<Compile Include="Methods\DLLImport.cs" />
<Compile Include="Methods\IconGenerator\DrawText.cs" />
<Compile Include="Methods\IconGenerator\Translations\LoadLocRes.cs" />
<Compile Include="Methods\IconGenerator\Translations\AssetNameMap.cs" />
<Compile Include="Methods\IconGenerator\Translations\SearchResource.cs" />
<Compile Include="Methods\ImagesMerger\ImagesMerger.cs" />
<Compile Include="Methods\Serializer\AssetReader.cs" />
@ -242,10 +241,10 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="oo2core_5_win64.dll">
<Content Include="csharp_wick.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="csharp_wick.dll">
<Content Include="oo2core_5_win64.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="DLLs\csharp-wick.dll" />

View File

@ -118,6 +118,11 @@ namespace FModel.Forms
Properties.Settings.Default.IconLanguage = comboBox1.SelectedItem.ToString();
Properties.Settings.Default.Save(); //SAVE
if (ThePak.AllpaksDictionary != null)
{
LoadLocRes.LoadMySelectedLocRes(Properties.Settings.Default.IconLanguage);
}
Close();
}

View File

@ -372,6 +372,7 @@ namespace FModel
ThePak.CurrentUsedPak = null;
ThePak.CurrentUsedPakGuid = null;
}
LoadLocRes.LoadMySelectedLocRes(Settings.Default.IconLanguage);
UpdateConsole("Building tree, please wait...", Color.FromArgb(255, 244, 132, 66), "Loading");
}
private void TreeParsePath(TreeNodeCollection nodeList, string path) //https://social.msdn.microsoft.com/Forums/en-US/c75c1804-6933-40ba-b17a-0e36ae8bcbb5/how-to-create-a-tree-view-with-full-paths?forum=csharplanguage
@ -1266,7 +1267,7 @@ namespace FModel
DrawText.DrawTexts(theItem, g, specialMode);
UpdateConsole(theItem.DisplayName, Color.FromArgb(255, 66, 244, 66), "Success");
UpdateConsole(theItem.DisplayName.SourceString, Color.FromArgb(255, 66, 244, 66), "Success");
if (autoSaveImagesToolStripMenuItem.Checked || updateModeToolStripMenuItem.Checked)
{
bmp.Save(App.DefaultOutputPath + "\\Icons\\" + ThePak.CurrentUsedItem + ".png", ImageFormat.Png);
@ -1354,7 +1355,7 @@ namespace FModel
}
}
UpdateConsole(theItem.DisplayName, Color.FromArgb(255, 66, 244, 66), "Success");
UpdateConsole(theItem.DisplayName.SourceString, Color.FromArgb(255, 66, 244, 66), "Success");
if (autoSaveImagesToolStripMenuItem.Checked || updateModeToolStripMenuItem.Checked)
{
Invoke(new Action(() =>

View File

@ -154,13 +154,49 @@ namespace FModel
}
private static void drawCompletionText(string count)
{
string all = string.Empty;
string any = string.Empty;
switch (Settings.Default.IconLanguage)
{
case "English":
all = "Complete ALL CHALLENGES to earn the reward item";
any = "Complete ANY " + count + " CHALLENGES to earn the reward item";
goto default;
case "French":
all = "Terminez CHACUN DES DÉFIS pour gagner la récompense";
any = "Terminez " + count + " DES DÉFIS pour gagner la récompense";
goto default;
case "German":
all = "Schließe ALLE HERAUSFORDERUNGEN ab, um die Belohnung zu verdienen";
any = "Schließe " + count + " HERAUSFORDERUNGEN ab, um die Belohnung zu verdienen";
goto default;
case "Italian":
all = "Completa TUTTE LE SFIDE per ottenere l'oggetto in ricompensa";
any = "Completa " + count + " SFIDE QUALSIASI per ottenere l'oggetto ricompensa";
goto default;
case "Spanish":
all = "Completa LOS DESAFÍOS para conseguir el objeto de recompensa";
any = "Completa " + count + " DE LOS DESAFÍOS para conseguir el objeto de recompensa";
goto default;
default:
if (count == "-1")
{
toDrawOn.DrawString(all, new Font(FontUtilities.pfc.Families[1], 50), new SolidBrush(Color.White), new Point(100, theY + 22));
}
else
{
toDrawOn.DrawString(any, new Font(FontUtilities.pfc.Families[1], 50), new SolidBrush(Color.White), new Point(100, theY + 22));
}
break;
}
if (count == "-1")
{
toDrawOn.DrawString("Complete ALL CHALLENGES to earn the reward item", new Font(FontUtilities.pfc.Families[1], 50), new SolidBrush(Color.White), new Point(100, theY + 22));
toDrawOn.DrawString(all, new Font(FontUtilities.pfc.Families[1], 50), new SolidBrush(Color.White), new Point(100, theY + 22));
}
else
{
toDrawOn.DrawString("Complete ANY " + count + " CHALLENGES to earn the reward item", new Font(FontUtilities.pfc.Families[1], 50), new SolidBrush(Color.White), new Point(100, theY + 22));
toDrawOn.DrawString(any, new Font(FontUtilities.pfc.Families[1], 50), new SolidBrush(Color.White), new Point(100, theY + 22));
}
}
@ -170,8 +206,25 @@ namespace FModel
/// <param name="myBitmap"></param>
public static void drawWatermark(Bitmap myBitmap)
{
toDrawOn.FillRectangle(new SolidBrush(Color.FromArgb(100, 0, 0, 0)), new Rectangle(0, theY + 240, myBitmap.Width, 40));
toDrawOn.DrawString(myItem.DisplayName + " Generated using FModel & JohnWickParse - " + DateTime.Now.ToString("dd/MM/yyyy"), new Font(FontUtilities.pfc.Families[0], 20), new SolidBrush(Color.FromArgb(150, 255, 255, 255)), new Point(myBitmap.Width / 2, theY + 250), FontUtilities.centeredString);
if (LoadLocRes.myLocRes != null && Settings.Default.IconLanguage != "English")
{
string text = SearchResource.getTranslatedText(myItem.DisplayName.Key);
if (!string.IsNullOrEmpty(text))
{
toDrawOn.FillRectangle(new SolidBrush(Color.FromArgb(100, 0, 0, 0)), new Rectangle(0, theY + 240, myBitmap.Width, 40));
toDrawOn.DrawString(text + " Generated using FModel & JohnWickParse - " + DateTime.Now.ToString("dd/MM/yyyy"), new Font(FontUtilities.pfc.Families[0], 20), new SolidBrush(Color.FromArgb(150, 255, 255, 255)), new Point(myBitmap.Width / 2, theY + 250), FontUtilities.centeredString);
}
else
{
toDrawOn.FillRectangle(new SolidBrush(Color.FromArgb(100, 0, 0, 0)), new Rectangle(0, theY + 240, myBitmap.Width, 40));
toDrawOn.DrawString(myItem.DisplayName.SourceString + " Generated using FModel & JohnWickParse - " + DateTime.Now.ToString("dd/MM/yyyy"), new Font(FontUtilities.pfc.Families[0], 20), new SolidBrush(Color.FromArgb(150, 255, 255, 255)), new Point(myBitmap.Width / 2, theY + 250), FontUtilities.centeredString);
}
}
else
{
toDrawOn.FillRectangle(new SolidBrush(Color.FromArgb(100, 0, 0, 0)), new Rectangle(0, theY + 240, myBitmap.Width, 40));
toDrawOn.DrawString(myItem.DisplayName.SourceString + " Generated using FModel & JohnWickParse - " + DateTime.Now.ToString("dd/MM/yyyy"), new Font(FontUtilities.pfc.Families[0], 20), new SolidBrush(Color.FromArgb(150, 255, 255, 255)), new Point(myBitmap.Width / 2, theY + 250), FontUtilities.centeredString);
}
}
private static void drawForbyteReward()

View File

@ -34,7 +34,16 @@ namespace FModel
}
public static string getBundleDisplayName(ItemsIdParser theItem)
{
return theItem.DisplayName.ToUpper();
if (LoadLocRes.myLocRes != null && Properties.Settings.Default.IconLanguage != "English")
{
string text = SearchResource.getTranslatedText(theItem.DisplayName.Key);
if (!string.IsNullOrEmpty(text))
{
return text.ToUpper();
}
else { return theItem.DisplayName.SourceString.ToUpper(); }
}
else { return theItem.DisplayName.SourceString.ToUpper(); }
}
public static string getLastFolder(string pathToExtractedBundle)
{
@ -93,11 +102,18 @@ namespace FModel
long oldCount = 0;
for (int p = 0; p < questParser[x].Objectives.Length; p++)
{
string newQuest = questParser[x].Objectives[p].Description;
string newQuest;
if (LoadLocRes.myLocRes != null && Properties.Settings.Default.IconLanguage != "English")
{
newQuest = SearchResource.getTranslatedText(questParser[x].Objectives[p].Description.Key);
}
else { newQuest = questParser[x].Objectives[p].Description.SourceString; }
long newCount = questParser[x].Objectives[p].Count;
if (questParser[x].BAthenaMustCompleteInSingleMatch != false && questParser[x].ObjectiveCompletionCount > 0)
if (questParser[x].BAthenaMustCompleteInSingleMatch && questParser[x].ObjectiveCompletionCount > 0)
{
newCount = questParser[x].ObjectiveCompletionCount;
}
if (newQuest != oldQuest && newCount != oldCount)
{

View File

@ -84,7 +84,19 @@ namespace FModel
try
{
ShortDescription = theItem.ShortDescription;
switch (Settings.Default.IconLanguage)
{
case "French":
case "German":
case "Italian":
case "Spanish":
ShortDescription = SearchResource.getTranslatedText(theItem.ShortDescription.Key);
if (string.IsNullOrEmpty(ShortDescription)) { ShortDescription = theItem.ShortDescription.SourceString; }
break;
default:
ShortDescription = theItem.ShortDescription.SourceString;
break;
}
}
catch (Exception)
{
@ -219,7 +231,22 @@ namespace FModel
{
if (theItem.DisplayName != null)
{
myGraphic.DrawString(theItem.DisplayName, new Font(FontUtilities.pfc.Families[0], 35), new SolidBrush(Color.White), new Point(522 / 2, 395), FontUtilities.centeredString);
if (LoadLocRes.myLocRes != null && Settings.Default.IconLanguage != "English")
{
string text = SearchResource.getTranslatedText(theItem.DisplayName.Key);
if (!string.IsNullOrEmpty(text))
{
myGraphic.DrawString(text, new Font(FontUtilities.pfc.Families[0], 35), new SolidBrush(Color.White), new Point(522 / 2, 395), FontUtilities.centeredString);
}
else
{
myGraphic.DrawString(theItem.DisplayName.SourceString, new Font(FontUtilities.pfc.Families[0], 35), new SolidBrush(Color.White), new Point(522 / 2, 395), FontUtilities.centeredString);
}
}
else
{
myGraphic.DrawString(theItem.DisplayName.SourceString, new Font(FontUtilities.pfc.Families[0], 35), new SolidBrush(Color.White), new Point(522 / 2, 395), FontUtilities.centeredString);
}
}
}
@ -232,7 +259,22 @@ namespace FModel
{
if (theItem.Description != null)
{
myGraphic.DrawString(theItem.Description, new Font("Arial", 10), new SolidBrush(Color.White), new RectangleF(5, 441, 512, 49), FontUtilities.centeredStringLine);
if (LoadLocRes.myLocRes != null && Settings.Default.IconLanguage != "English")
{
string text = SearchResource.getTranslatedText(theItem.Description.Key);
if (!string.IsNullOrEmpty(text))
{
myGraphic.DrawString(text, new Font("Arial", 10), new SolidBrush(Color.White), new RectangleF(5, 441, 512, 49), FontUtilities.centeredStringLine);
}
else
{
myGraphic.DrawString(theItem.Description.SourceString, new Font("Arial", 10), new SolidBrush(Color.White), new RectangleF(5, 441, 512, 49), FontUtilities.centeredStringLine);
}
}
else
{
myGraphic.DrawString(theItem.Description.SourceString, new Font("Arial", 10), new SolidBrush(Color.White), new RectangleF(5, 441, 512, 49), FontUtilities.centeredStringLine);
}
}
}

View File

@ -1,109 +0,0 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace FModel
{
static class AssetNameMap
{
public static List<string> myNamespacesList { get; set; }
public static void searchStringsInUexp(string filepath)
{
myNamespacesList = new List<string>();
if (File.Exists(filepath))
{
List<string> weirdStrings = new List<string>();
List<string> listBeforeData = new List<string>();
bool previousByteWasValid = false;
byte[] bytes = File.ReadAllBytes(filepath);
string pattern = @"^[a-zA-Z0-9()'\-.&!+, ]";
Regex regex = new Regex(pattern);
foreach (byte b in bytes) // Iterate throught all the bytes of the file
{
string byteString = Encoding.UTF8.GetString(new[] { b }); // Generate string for single byte
bool valid = regex.IsMatch(byteString);
if (valid)
{
if (previousByteWasValid) weirdStrings[weirdStrings.Count - 1] += byteString;
else weirdStrings.Add(byteString);
}
previousByteWasValid = valid;
}
bool found = false;
foreach (string str in weirdStrings)
{
if (str.Length >= 2)
{
if (found) { myNamespacesList.Add(str); break; }
listBeforeData.Add(str);
if (str == "Outfit"
|| str == "Back Bling"
|| str == "Pet"
|| str == "Harvesting Tool"
|| str == "Glider"
|| str == "Contrail"
|| str == "Emote"
|| str == "Emoticon"
|| str == "Toy"
|| str == "Music")
{
int index = listBeforeData.IndexOf(str);
//Console.WriteLine("DName: " + listBeforeData[index - 3]);
//Console.WriteLine("Description: " + listBeforeData[index - 1]);
myNamespacesList.Add(listBeforeData[index - 3]);
myNamespacesList.Add(listBeforeData[index - 1]);
found = true;
}
}
}
}
}
public static void getNameMap(string filepath)
{
Console.Clear();
using (BinaryReader reader = new BinaryReader(File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.GetEncoding(1252)))
{
reader.ReadBytes(24);
int AssetLength = reader.ReadInt32();
//Console.WriteLine(AssetLength);
reader.ReadBytes(13);
int NamespaceCount = reader.ReadInt32();
long LocalizedStringArrayOffset = -1;
LocalizedStringArrayOffset = reader.ReadInt64();
if (LocalizedStringArrayOffset != -1)
{
long newOffset = LocalizedStringArrayOffset - 4;
reader.BaseStream.Seek(newOffset, SeekOrigin.Begin);
string[] LocalizedStringArray = new string[NamespaceCount];
for (int i = 0; i < LocalizedStringArray.Length; i++)
{
string tag = AssetReader.readCleanString(reader);
if (tag != "None") { LocalizedStringArray[i] = tag; Console.WriteLine(LocalizedStringArray[i]); }
}
}
}
}
}
}

View File

@ -27,7 +27,11 @@
private static string getMyLocRes(string selectedLanguage)
{
string oldKey = JohnWick.MyKey;
JohnWick.MyKey = Properties.Settings.Default.AESKey;
string locResPath = JohnWick.ExtractAsset(ThePak.AllpaksDictionary["Game_BR.locres"], "Game_BR.locres");
JohnWick.MyKey = oldKey;
return LocResSerializer.StringFinder(locResPath.Replace("zh-Hant", selectedLanguage));
}
}

View File

@ -6,17 +6,19 @@ namespace FModel
static class SearchResource
{
private static string parsedJsonToCheck { get; set; }
private static JObject jo { get; set; }
private static string oldLanguage = Properties.Settings.Default.IconLanguage;
public static string getTranslatedText(string theNamespace)
{
string toReturn = string.Empty;
string myParsedJson = string.Empty;
string newLanguage = Properties.Settings.Default.IconLanguage;
if (myParsedJson != parsedJsonToCheck)
if (parsedJsonToCheck == null || newLanguage != oldLanguage)
{
myParsedJson = JToken.Parse(LoadLocRes.myLocRes).ToString().TrimStart('[').TrimEnd(']');
parsedJsonToCheck = JToken.Parse(LoadLocRes.myLocRes).ToString().TrimStart('[').TrimEnd(']');
jo = JObject.Parse(parsedJsonToCheck);
}
JObject jo = JObject.Parse(myParsedJson);
foreach (JToken token in jo.FindTokens(theNamespace))
{
LocResParser LocResParse = LocResParser.FromJson(token.ToString());
@ -24,13 +26,9 @@ namespace FModel
{
toReturn = LocResParse.LocResText;
}
else if (LocResParse.WorkerSetBonusTraitPattern != null)
{
toReturn = LocResParse.WorkerSetBonusTraitPattern;
}
}
oldLanguage = newLanguage;
parsedJsonToCheck = myParsedJson;
return toReturn;
}
}

View File

@ -99,18 +99,6 @@ namespace FModel
}
currentPakToCheck = currentPak;
/*if (AssetPath.Contains("Athena\\Items\\") && File.Exists(AssetPath.Substring(0, AssetPath.LastIndexOf(".")) + ".uexp")) //TEST
{
try
{
AssetNameMap.searchStringsInUexp(AssetPath.Substring(0, AssetPath.LastIndexOf(".")) + ".uexp");
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}*/
return AssetPath;
}

View File

@ -27,15 +27,24 @@ namespace FModel.Parser.Banners
public string CategoryRowName { get; set; }
[JsonProperty("DisplayName")]
public string DisplayName { get; set; }
public FTextInfos DisplayName { get; set; }
[JsonProperty("DisplayDescription")]
public string DisplayDescription { get; set; }
public FTextInfos DisplayDescription { get; set; }
[JsonProperty("bFullUsageRights")]
public bool BFullUsageRights { get; set; }
}
public partial class FTextInfos
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("source_string")]
public string SourceString { get; set; }
}
public class Image
{
[JsonProperty("asset_path_name")]

View File

@ -19,7 +19,7 @@ namespace FModel.Parser.Challenges
public DisplayStyle DisplayStyle { get; set; }
[JsonProperty("DisplayName")]
public string DisplayName { get; set; }
public DisplayName DisplayName { get; set; }
[JsonProperty("SmallPreviewImage")]
public LargePreviewImage SmallPreviewImage { get; set; }
@ -28,6 +28,15 @@ namespace FModel.Parser.Challenges
public LargePreviewImage LargePreviewImage { get; set; }
}
public partial class DisplayName
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("source_string")]
public string SourceString { get; set; }
}
public class BundleCompletionReward
{
[JsonProperty("CompletionCount")]

View File

@ -28,13 +28,13 @@ namespace FModel.Parser.Items
public string Series { get; set; }
[JsonProperty("DisplayName")]
public string DisplayName { get; set; }
public FTextInfos DisplayName { get; set; }
[JsonProperty("ShortDescription")]
public string ShortDescription { get; set; }
public FTextInfos ShortDescription { get; set; }
[JsonProperty("Description")]
public string Description { get; set; }
public FTextInfos Description { get; set; }
[JsonProperty("GameplayTags")]
public GameplayTags GameplayTags { get; set; }
@ -67,6 +67,15 @@ namespace FModel.Parser.Items
public WeaponStatHandle WeaponStatHandle { get; set; }
}
public partial class FTextInfos
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("source_string")]
public string SourceString { get; set; }
}
public class GameplayTags
{
[JsonProperty("gameplay_tags")]

View File

@ -31,16 +31,16 @@ namespace FModel.Parser.Quests
public Objective[] Objectives { get; set; }
[JsonProperty("CompletionText")]
public string CompletionText { get; set; }
public FTextInfos CompletionText { get; set; }
[JsonProperty("GrantToProfileType")]
public string GrantToProfileType { get; set; }
[JsonProperty("DisplayName")]
public string DisplayName { get; set; }
public FTextInfos DisplayName { get; set; }
[JsonProperty("Description")]
public string Description { get; set; }
public FTextInfos Description { get; set; }
[JsonProperty("GameplayTags")]
public GameplayTags GameplayTags { get; set; }
@ -52,6 +52,15 @@ namespace FModel.Parser.Quests
public LargePreviewImage LargePreviewImage { get; set; }
}
public partial class FTextInfos
{
[JsonProperty("key")]
public string Key { get; set; }
[JsonProperty("source_string")]
public string SourceString { get; set; }
}
public class GameplayTags
{
[JsonProperty("gameplay_tags")]
@ -115,10 +124,10 @@ namespace FModel.Parser.Quests
public long LinkSquadIndex { get; set; }
[JsonProperty("Description")]
public string Description { get; set; }
public FTextInfos Description { get; set; }
[JsonProperty("HudShortDescription")]
public string HudShortDescription { get; set; }
public FTextInfos HudShortDescription { get; set; }
[JsonProperty("HudIcon")]
public LargePreviewImage HudIcon { get; set; }

View File

@ -33,7 +33,7 @@ using System.Runtime.InteropServices;
// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut
// en utilisant '*', comme indiqué ci-dessous :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.3.3.0")]
[assembly: AssemblyFileVersion("2.3.3.0")]
[assembly: AssemblyVersion("2.4.0.0")]
[assembly: AssemblyFileVersion("2.4.0.0")]
[assembly: NeutralResourcesLanguage("en")]

Binary file not shown.

View File

@ -10,12 +10,12 @@
### Prerequisites
[.NET Framework 4.7.1](https://dotnet.microsoft.com/download/dotnet-framework/net471)
### Download
[![](https://img.shields.io/badge/Release-Executable-orange.svg?logo=github)](https://github.com/iAmAsval/FModel/releases/tag/2.3.3)
[![](https://img.shields.io/badge/Release-Executable-orange.svg?logo=github)](https://github.com/iAmAsval/FModel/releases/tag/2.4.0)
### How does it works
**1.** Once you start the executable, you'll be asked to set your path to your Fortnite .PAK files. Meanwhile a `FModel` subfolder will be created in your `Documents` folder.
![](https://i.imgur.com/O2Vg3Bx.gif)
**2.** Restart the executable, enter the AES Key, click **Load** and select your .PAK file
**2.** Restart the executable, go to the AES Manager and add you AES Keys, click **Load** and select your .PAK file
- It will parse all Assets contained in the selected .PAK file with their respective path
**3.** Navigate through the tree to find the Asset you want
@ -84,10 +84,10 @@ I'd highly suggest you to use [UModel](https://github.com/gildor2/UModel) instea
## TODO
- [ ] Code refactoring
- [ ] Icons translation
- [ ] 2FA support
- [ ] Export Queue
- [ ] Nintendo Switch sound files
- [x] Translation support
- [x] AES Manager
- [x] Display support for .locres files
- [x] Nintendo Switch PAKs