diff --git a/FModel/Creator/Texts/Text.cs b/FModel/Creator/Texts/Text.cs index 2fd5f69f..bb5e8a30 100644 --- a/FModel/Creator/Texts/Text.cs +++ b/FModel/Creator/Texts/Text.cs @@ -157,6 +157,9 @@ namespace FModel.Creator.Texts { _NAME_TEXT_SIZE = 45; string text = icon.DisplayName; + + if (string.IsNullOrEmpty(text)) return; + SKTextAlign side = SKTextAlign.Center; int x = icon.Width / 2; int y = _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE; @@ -223,11 +226,12 @@ namespace FModel.Creator.Texts public static void DrawDescription(SKCanvas c, IBase icon) { - if (!string.IsNullOrEmpty(icon.Description)) return; - - int maxLine = 4; _BOTTOM_TEXT_SIZE = 15; string text = icon.Description; + + if (string.IsNullOrEmpty(text)) return; + + int maxLine = 4; ETextSide side = ETextSide.Center; switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign) { @@ -262,6 +266,8 @@ namespace FModel.Creator.Texts public static void DrawToBottom(SKCanvas c, BaseIcon icon, ETextSide side, string text) { + if (string.IsNullOrEmpty(text)) return; + SKPaint shortDescriptionPaint = new SKPaint { IsAntialias = true, diff --git a/FModel/Grabber/Manifests/ManifestGrabber.cs b/FModel/Grabber/Manifests/ManifestGrabber.cs index c2cf3a01..8d8fd593 100644 --- a/FModel/Grabber/Manifests/ManifestGrabber.cs +++ b/FModel/Grabber/Manifests/ManifestGrabber.cs @@ -1,5 +1,7 @@ using EpicManifestParser.Objects; + using FModel.Utils; + using System; using System.Threading.Tasks; @@ -11,7 +13,8 @@ namespace FModel.Grabber.Manifests { if (IsExpired()) { - OAuth auth = await Endpoints.GetOAuthInfo(); + OAuth auth = await Endpoints.GetOAuthInfo().ConfigureAwait(false); + if (auth != null) { Properties.Settings.Default.AccessToken = auth.AccessToken; @@ -20,19 +23,14 @@ namespace FModel.Grabber.Manifests } } - string ret = await Endpoints.GetStringEndpoint("https://launcher-public-service-prod06.ol.epicgames.com/launcher/api/public/assets/v2/platform/Windows/namespace/fn/catalogItem/4fe75bbc5a674f4f9b356b5c90567da5/app/Fortnite/label/Live", Properties.Settings.Default.AccessToken); - if (!string.IsNullOrEmpty(ret)) return new ManifestInfo(ret); - else return null; + string ret = await Endpoints.GetStringEndpoint("https://launcher-public-service-prod06.ol.epicgames.com/launcher/api/public/assets/v2/platform/Windows/namespace/fn/catalogItem/4fe75bbc5a674f4f9b356b5c90567da5/app/Fortnite/label/Live", Properties.Settings.Default.AccessToken).ConfigureAwait(false); + return string.IsNullOrEmpty(ret) ? null : new ManifestInfo(ret); } private static bool IsExpired() { long currentTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); - if ((currentTime - 60000) >= Properties.Settings.Default.LauncherExpiration) - { - return true; - } - return false; + return currentTime - 60000 >= Properties.Settings.Default.LauncherExpiration; } } } \ No newline at end of file diff --git a/FModel/Grabber/Paks/PaksGrabber.cs b/FModel/Grabber/Paks/PaksGrabber.cs index 42f44b99..cda5e027 100644 --- a/FModel/Grabber/Paks/PaksGrabber.cs +++ b/FModel/Grabber/Paks/PaksGrabber.cs @@ -1,18 +1,21 @@ -using FModel.Logger; -using FModel.Utils; -using FModel.ViewModels.MenuItem; -using FModel.Windows.Launcher; -using PakReader.Pak; -using System; +using System; using System.Collections.ObjectModel; using System.IO; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; + using EpicManifestParser.Objects; -using System.Text.RegularExpressions; + using FModel.Grabber.Manifests; +using FModel.Logger; +using FModel.Utils; +using FModel.ViewModels.MenuItem; +using FModel.Windows.Launcher; + +using PakReader.Pak; namespace FModel.Grabber.Paks { @@ -44,7 +47,20 @@ namespace FModel.Grabber.Paks if (Properties.Settings.Default.PakPath.EndsWith(".manifest")) { ManifestInfo manifestInfo = await ManifestGrabber.TryGetLatestManifestInfo().ConfigureAwait(false); - byte[] manifestData = await manifestInfo.DownloadManifestDataAsync().ConfigureAwait(false); + DirectoryInfo chunksDir = Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.OutputPath, "PakChunks")); + string manifestPath = Path.Combine(chunksDir.FullName, manifestInfo.Filename); + byte[] manifestData; + + if (File.Exists(manifestPath)) + { + manifestData = await File.ReadAllBytesAsync(manifestPath); + } + else + { + manifestData = await manifestInfo.DownloadManifestDataAsync().ConfigureAwait(false); + await File.WriteAllBytesAsync(manifestPath, manifestData).ConfigureAwait(false); + } + Manifest manifest = new Manifest(manifestData, new ManifestOptions { ChunkBaseUri = new Uri("http://download.epicgames.com/Builds/Fortnite/CloudDir/ChunksV3/", UriKind.Absolute), diff --git a/FModel/PakReader/ReaderExtensions.cs b/FModel/PakReader/ReaderExtensions.cs index a486e2ee..80d27b0d 100644 --- a/FModel/PakReader/ReaderExtensions.cs +++ b/FModel/PakReader/ReaderExtensions.cs @@ -1,18 +1,19 @@ using System; using System.IO; using System.Runtime.CompilerServices; -using System.Text; namespace PakReader { static class ReaderExtensions { - public static string ReadFString(this BinaryReader reader) + public static unsafe string ReadFString(this BinaryReader reader) { - // > 0 for ANSICHAR, < 0 for UCS2CHAR serialization var SaveNum = reader.ReadInt32(); - bool LoadUCS2Char = SaveNum < 0; - if (LoadUCS2Char) + + if (SaveNum == 0) return null; + + // > 0 for ANSICHAR, < 0 for UCS2CHAR serialization + if (SaveNum < 0) { // If SaveNum cannot be negated due to integer overflow, Ar is corrupted. if (SaveNum == int.MinValue) @@ -21,27 +22,22 @@ namespace PakReader } SaveNum = -SaveNum; - } - if (SaveNum == 0) return null; + var dataBytes = reader.ReadBytes(SaveNum * sizeof(char)); - // 1 byte is removed because of null terminator (\0) - if (LoadUCS2Char) - { - ushort[] data = new ushort[SaveNum]; - for (int i = 0; i < SaveNum; i++) + fixed (byte* pData = dataBytes) { - data[i] = reader.ReadUInt16(); - } - unsafe - { - fixed (ushort* dataPtr = &data[0]) - return new string((char*)dataPtr, 0, data.Length - 1); + return new string((char*)pData, 0, SaveNum - 1); // 1 byte is removed because of null terminator (\0) } } else { - return Encoding.UTF8.GetString(reader.ReadBytes(SaveNum).AsSpan(..^1)); + var dataBytes = reader.ReadBytes(SaveNum); + + fixed (byte* pData = dataBytes) + { + return new string((sbyte*)pData, 0, SaveNum - 1); // 1 byte is removed because of null terminator (\0) + } } }