diff --git a/FModel/App.config b/FModel/App.config index 7caf235c..c897b019 100644 --- a/FModel/App.config +++ b/FModel/App.config @@ -182,6 +182,12 @@ } } + + + + + 0 + diff --git a/FModel/FModel.csproj b/FModel/FModel.csproj index 2b5f257e..3b15145c 100644 --- a/FModel/FModel.csproj +++ b/FModel/FModel.csproj @@ -242,6 +242,8 @@ + + diff --git a/FModel/Methods/AESManager/DynamicKeysChecker.cs b/FModel/Methods/AESManager/DynamicKeysChecker.cs index 75d4635d..50bdfab1 100644 --- a/FModel/Methods/AESManager/DynamicKeysChecker.cs +++ b/FModel/Methods/AESManager/DynamicKeysChecker.cs @@ -30,7 +30,7 @@ namespace FModel.Methods.AESManager if (PAKEntries.PAKEntriesList != null && PAKEntries.PAKEntriesList.Any()) { - string KeysFromBen = EndpointsUtility.GetKeysFromBen(); + string KeysFromBen = EndpointsUtility.GetKeysFromBen(reload); if (!string.IsNullOrEmpty(KeysFromBen)) { Dictionary KeysDict = JsonConvert.DeserializeObject>(KeysFromBen); diff --git a/FModel/Methods/Assets/AssetTranslations.cs b/FModel/Methods/Assets/AssetTranslations.cs index f1953a46..ac60a0e2 100644 --- a/FModel/Methods/Assets/AssetTranslations.cs +++ b/FModel/Methods/Assets/AssetTranslations.cs @@ -1,3 +1,4 @@ +using FModel.Methods.Auth; using FModel.Methods.Utilities; using PakReader; using System; @@ -144,16 +145,20 @@ namespace FModel.Methods.Assets public static void SetHotfixedLocResDict() { - string pdd = Path.GetFullPath(Path.Combine(FProp.Default.FPak_Path, @"..\..\PersistentDownloadDir\EMS\")); - if (File.Exists(pdd + "a22d837b6a2b46349421259c0a5411bf")) + if (!FProp.Default.ELauncherToken.StartsWith("eg1~") || AuthFlow.IsLauncherTokenExpired()) + AuthFlow.SetOAuthLauncherToken(); + + if (!AuthFlow.IsLauncherTokenExpired() && FProp.Default.ELauncherToken.StartsWith("eg1~")) { - DebugHelper.WriteLine(".PAKs: Populating hotfixed string dictionary at " + pdd + "a22d837b6a2b46349421259c0a5411bf"); - HotfixLocResDict = new Dictionary>>>(); - using (StreamReader sr = new StreamReader(File.Open(pdd + "a22d837b6a2b46349421259c0a5411bf", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))) + string response = Requests.GetLauncherEndpoint("https://fortnite-public-service-prod11.ol.epicgames.com/fortnite/api/cloudstorage/system/a22d837b6a2b46349421259c0a5411bf"); + if (!string.IsNullOrEmpty(response)) { - while (!sr.EndOfStream) + string[] lines = response.Split('\n'); + DebugHelper.WriteLine(".PAKs: Populating hotfixed string dictionary"); + HotfixLocResDict = new Dictionary>>>(); + + foreach (string line in lines) { - string line = sr.ReadLine(); if (line.StartsWith("+TextReplacements=(Category=Game,")) { string txtNamespace = GetValueFromParam(line, "Namespace=\"", "\","); @@ -188,11 +193,9 @@ namespace FModel.Methods.Assets } } } + DebugHelper.WriteLine(".PAKs: Populated hotfixed string dictionary"); } - DebugHelper.WriteLine(".PAKs: Populated hotfixed string dictionary"); } - else - DebugHelper.WriteLine(".PAKs: No such file or directory " + pdd + "a22d837b6a2b46349421259c0a5411bf"); } private static string GetValueFromParam(string fullLine, string startWith, string endWith) diff --git a/FModel/Methods/Auth/AuthFlow.cs b/FModel/Methods/Auth/AuthFlow.cs new file mode 100644 index 00000000..8bf7c3a0 --- /dev/null +++ b/FModel/Methods/Auth/AuthFlow.cs @@ -0,0 +1,40 @@ +using Newtonsoft.Json; +using RestSharp; +using System; + +namespace FModel.Methods.Auth +{ + static class AuthFlow + { + private const string _EPIC_OAUTH_URL = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token"; + + public static void SetOAuthLauncherToken() + { + var oauthClient = new RestClient(_EPIC_OAUTH_URL); + var oauthRes = oauthClient.Execute( + new RestRequest(Method.POST) + .AddHeader("Content-Type", "application/x-www-form-urlencoded") + .AddHeader("Authorization", "basic MzQ0NmNkNzI2OTRjNGE0NDg1ZDgxYjc3YWRiYjIxNDE6OTIwOWQ0YTVlMjVhNDU3ZmI5YjA3NDg5ZDMxM2I0MWE=") + .AddParameter("grant_type", "client_credentials") + .AddParameter("token_type", "eg1")); + + var response = JsonConvert.DeserializeObject(oauthRes.Content); + var launcher_access_token = response["access_token"]; + var launcher_expires_in = response["expires_in"]; + + Properties.Settings.Default.ELauncherToken = launcher_access_token; + Properties.Settings.Default.ELauncherExpiration = DateTimeOffset.Now.AddSeconds(Convert.ToDouble(launcher_expires_in)).ToUnixTimeMilliseconds(); + Properties.Settings.Default.Save(); + } + + public static bool IsLauncherTokenExpired() + { + long currentTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + if ((currentTime - 60000) >= Properties.Settings.Default.ELauncherExpiration) + { + return true; + } + return false; + } + } +} diff --git a/FModel/Methods/Auth/Requests.cs b/FModel/Methods/Auth/Requests.cs new file mode 100644 index 00000000..c88240df --- /dev/null +++ b/FModel/Methods/Auth/Requests.cs @@ -0,0 +1,20 @@ +using RestSharp; + +namespace FModel.Methods.Auth +{ + static class Requests + { + public static string GetLauncherEndpoint(string url) + { + var client = new RestClient(url); + var request = new RestRequest(Method.GET) + .AddHeader("Authorization", "bearer " + Properties.Settings.Default.ELauncherToken); + + IRestResponse reqRes = client.Execute(request); + if (reqRes.StatusCode == System.Net.HttpStatusCode.OK) + return reqRes.Content; + + return string.Empty; + } + } +} diff --git a/FModel/Methods/Utilities/EndpointsUtility.cs b/FModel/Methods/Utilities/EndpointsUtility.cs index 6af4da91..f7c02779 100644 --- a/FModel/Methods/Utilities/EndpointsUtility.cs +++ b/FModel/Methods/Utilities/EndpointsUtility.cs @@ -76,14 +76,14 @@ namespace FModel.Methods.Utilities } } - public static string GetKeysFromBen() + public static string GetKeysFromBen(bool reload) { if (DLLImport.IsInternetAvailable()) { string EndpointContent = GetEndpoint(BENBOT_AES); if (!string.IsNullOrEmpty(EndpointContent)) { - if (string.IsNullOrEmpty(FProp.Default.FPak_MainAES)) + if (string.IsNullOrEmpty(FProp.Default.FPak_MainAES) || reload) { JToken mainKeyToken = JObject.Parse(EndpointContent).SelectToken("mainKey"); if (mainKeyToken != null) diff --git a/FModel/Properties/Settings.Designer.cs b/FModel/Properties/Settings.Designer.cs index 404639b9..a8fb7d1c 100644 --- a/FModel/Properties/Settings.Designer.cs +++ b/FModel/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace FModel.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.2.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -400,5 +400,29 @@ namespace FModel.Properties { this["FUM_AssetsType"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ELauncherToken { + get { + return ((string)(this["ELauncherToken"])); + } + set { + this["ELauncherToken"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("0")] + public long ELauncherExpiration { + get { + return ((long)(this["ELauncherExpiration"])); + } + set { + this["ELauncherExpiration"] = value; + } + } } } diff --git a/FModel/Properties/Settings.settings b/FModel/Properties/Settings.settings index bfa3cdf9..7ad200b9 100644 --- a/FModel/Properties/Settings.settings +++ b/FModel/Properties/Settings.settings @@ -174,5 +174,11 @@ } } + + + + + 0 + \ No newline at end of file