mirror of
https://github.com/4sval/FModel.git
synced 2026-03-22 01:34:37 -05:00
added playlist images support
This commit is contained in:
parent
b18b38255b
commit
f5fa499905
|
|
@ -1,15 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Windows;
|
||||
|
||||
using FModel.Creator.Icons;
|
||||
using FModel.Creator.Rarities;
|
||||
using FModel.Creator.Stats;
|
||||
using FModel.Creator.Texts;
|
||||
using FModel.Properties;
|
||||
using FModel.Utils;
|
||||
|
||||
using Fortnite_API.Objects;
|
||||
using Fortnite_API.Objects.V1;
|
||||
|
||||
using PakReader.Pak;
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
|
||||
namespace FModel.Creator.Bases
|
||||
{
|
||||
|
|
@ -25,19 +33,19 @@ namespace FModel.Creator.Bases
|
|||
public string Description;
|
||||
public string ShortDescription;
|
||||
public string CosmeticSource;
|
||||
public int Size = 512; // keep it 512 (or a multiple of 512) if you don't want blurry icons
|
||||
public int AdditionalSize = 0; // must be increased if there are weapon stats, hero abilities or more to draw/show
|
||||
public int Size = 512; // keep it 512 (or a multiple of 512) if you don't want blurry icons
|
||||
public int AdditionalSize; // must be increased if there are weapon stats, hero abilities or more to draw/show
|
||||
public int Margin = 2;
|
||||
public List<Statistic> Stats;
|
||||
|
||||
public BaseIcon()
|
||||
{
|
||||
FallbackImage = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_Placeholder_Item_Image.png")).Stream);
|
||||
FallbackImage = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_Placeholder_Item_Image.png"))?.Stream);
|
||||
IconImage = FallbackImage;
|
||||
RarityBackgroundImage = null;
|
||||
UserFacingFlags = null;
|
||||
RarityBackgroundColors = new SKColor[2] { SKColor.Parse("5EBC36"), SKColor.Parse("305C15") };
|
||||
RarityBorderColor = new SKColor[2] { SKColor.Parse("74EF52"), SKColor.Parse("74EF52") };
|
||||
RarityBackgroundColors = new[] { SKColor.Parse("5EBC36"), SKColor.Parse("305C15") };
|
||||
RarityBorderColor = new[] { SKColor.Parse("74EF52"), SKColor.Parse("74EF52") };
|
||||
DisplayName = "";
|
||||
Description = "";
|
||||
ShortDescription = "";
|
||||
|
|
@ -47,18 +55,18 @@ namespace FModel.Creator.Bases
|
|||
|
||||
public BaseIcon(IUExport export, string assetName, bool forceHR) : this()
|
||||
{
|
||||
if (export.GetExport<ObjectProperty>("Series") is ObjectProperty series)
|
||||
if (export.GetExport<ObjectProperty>("Series") is { } series)
|
||||
Serie.GetRarity(this, series);
|
||||
else if (Properties.Settings.Default.UseGameColors) // override default green
|
||||
else if (Settings.Default.UseGameColors) // override default green
|
||||
Rarity.GetInGameRarity(this, export.GetExport<EnumProperty>("Rarity")); // uncommon will be triggered by Rarity being null
|
||||
else if (export.GetExport<EnumProperty>("Rarity") is EnumProperty rarity)
|
||||
else if (export.GetExport<EnumProperty>("Rarity") is { } rarity)
|
||||
Rarity.GetHardCodedRarity(this, rarity);
|
||||
|
||||
if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is ObjectProperty itemDef)
|
||||
if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is { } itemDef)
|
||||
LargeSmallImage.GetPreviewImage(this, itemDef, assetName, forceHR);
|
||||
else if (export.GetExport<SoftObjectProperty>(forceHR ? "LargePreviewImage" : "SmallPreviewImage", forceHR ? "ItemDisplayAsset" : "SmallImage") is SoftObjectProperty previewImage)
|
||||
else if (export.GetExport<SoftObjectProperty>(forceHR ? "LargePreviewImage" : "SmallPreviewImage", forceHR ? "ItemDisplayAsset" : "SmallImage") is { } previewImage)
|
||||
LargeSmallImage.GetPreviewImage(this, previewImage);
|
||||
else if (export.GetExport<ObjectProperty>("access_item") is ObjectProperty accessItem)
|
||||
else if (export.GetExport<ObjectProperty>("access_item") is { } accessItem)
|
||||
{
|
||||
PakPackage p = Utils.GetPropertyPakPackage(accessItem.Value.Resource.OuterIndex.Resource.ObjectName.String);
|
||||
if (p.HasExport() && !p.Equals(default))
|
||||
|
|
@ -71,7 +79,7 @@ namespace FModel.Creator.Bases
|
|||
}
|
||||
}
|
||||
|
||||
if (export.GetExport<TextProperty>("DisplayName", "DefaultHeaderText", "UIDisplayName") is TextProperty displayName)
|
||||
if (export.GetExport<TextProperty>("DisplayName", "DefaultHeaderText", "UIDisplayName") is { } displayName)
|
||||
DisplayName = Text.GetTextPropertyBase(displayName);
|
||||
}
|
||||
|
||||
|
|
@ -90,58 +98,58 @@ namespace FModel.Creator.Bases
|
|||
public BaseIcon(IUExport export, string exportType, ref string assetName) : this()
|
||||
{
|
||||
// rarity
|
||||
if (export.GetExport<ObjectProperty>("Series") is ObjectProperty series)
|
||||
if (export.GetExport<ObjectProperty>("Series") is { } series)
|
||||
Serie.GetRarity(this, series);
|
||||
else if (Properties.Settings.Default.UseGameColors) // override default green
|
||||
else if (Settings.Default.UseGameColors) // override default green
|
||||
Rarity.GetInGameRarity(this, export.GetExport<EnumProperty>("Rarity")); // uncommon will be triggered by Rarity being null
|
||||
else if (export.GetExport<EnumProperty>("Rarity") is EnumProperty rarity)
|
||||
else if (export.GetExport<EnumProperty>("Rarity") is { } rarity)
|
||||
Rarity.GetHardCodedRarity(this, rarity);
|
||||
|
||||
// image
|
||||
if (Properties.Settings.Default.UseItemShopIcon &&
|
||||
if (Settings.Default.UseItemShopIcon &&
|
||||
DisplayAssetImage.GetDisplayAssetImage(this, export.GetExport<SoftObjectProperty>("DisplayAssetPath"), ref assetName))
|
||||
{ } // ^^^^ will return false if image not found, if so, we try to get the normal icon
|
||||
else if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is ObjectProperty itemDef)
|
||||
else if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is { } itemDef)
|
||||
LargeSmallImage.GetPreviewImage(this, itemDef, assetName);
|
||||
else if (export.GetExport<SoftObjectProperty>("LargePreviewImage", "SmallPreviewImage", "ItemDisplayAsset") is SoftObjectProperty previewImage)
|
||||
else if (export.GetExport<SoftObjectProperty>("LargePreviewImage", "SmallPreviewImage", "ItemDisplayAsset") is { } previewImage)
|
||||
LargeSmallImage.GetPreviewImage(this, previewImage);
|
||||
else if (export.GetExport<ObjectProperty>("SmallPreviewImage") is ObjectProperty smallPreviewImage)
|
||||
this.IconImage = Utils.GetObjectTexture(smallPreviewImage);
|
||||
else if (export.GetExport<StructProperty>("IconBrush") is StructProperty iconBrush) // abilities
|
||||
else if (export.GetExport<ObjectProperty>("SmallPreviewImage") is { } smallPreviewImage)
|
||||
IconImage = Utils.GetObjectTexture(smallPreviewImage);
|
||||
else if (export.GetExport<StructProperty>("IconBrush") is { } iconBrush) // abilities
|
||||
LargeSmallImage.GetPreviewImage(this, iconBrush);
|
||||
|
||||
// text
|
||||
if (export.GetExport<TextProperty>("DisplayName", "DefaultHeaderText", "UIDisplayName") is TextProperty displayName)
|
||||
if (export.GetExport<TextProperty>("DisplayName", "DefaultHeaderText", "UIDisplayName") is { } displayName)
|
||||
DisplayName = Text.GetTextPropertyBase(displayName);
|
||||
if (export.GetExport<TextProperty>("Description", "DefaultBodyText", "UIDescription") is TextProperty description)
|
||||
if (export.GetExport<TextProperty>("Description", "DefaultBodyText", "UIDescription") is { } description)
|
||||
Description = Text.GetTextPropertyBase(description);
|
||||
else if (export.GetExport<ArrayProperty>("Description") is ArrayProperty arrayDescription) // abilities
|
||||
else if (export.GetExport<ArrayProperty>("Description") is { } arrayDescription) // abilities
|
||||
Description = Text.GetTextPropertyBase(arrayDescription);
|
||||
if (export.GetExport<StructProperty>("MaxStackSize") is StructProperty maxStackSize)
|
||||
if (export.GetExport<StructProperty>("MaxStackSize") is { } maxStackSize)
|
||||
ShortDescription = Text.GetMaxStackSize(maxStackSize);
|
||||
else if (export.GetExport<StructProperty>("XpRewardAmount") is StructProperty xpRewardAmount)
|
||||
else if (export.GetExport<StructProperty>("XpRewardAmount") is { } xpRewardAmount)
|
||||
ShortDescription = Text.GetXpRewardAmount(xpRewardAmount);
|
||||
else if (export.GetExport<TextProperty>("ShortDescription", "UIDisplaySubName") is TextProperty shortDescription)
|
||||
else if (export.GetExport<TextProperty>("ShortDescription", "UIDisplaySubName") is { } shortDescription)
|
||||
ShortDescription = Text.GetTextPropertyBase(shortDescription);
|
||||
else if (exportType.Equals("AthenaItemWrapDefinition")) // if no ShortDescription it's most likely a wrap
|
||||
ShortDescription = Localizations.GetLocalization("Fort.Cosmetics", "ItemWrapShortDescription", "Wrap");
|
||||
|
||||
// gameplaytags
|
||||
if (export.GetExport<StructProperty>("GameplayTags") is StructProperty gameplayTags)
|
||||
if (export.GetExport<StructProperty>("GameplayTags") is { } gameplayTags)
|
||||
GameplayTag.GetGameplayTags(this, gameplayTags, exportType);
|
||||
else if (export.GetExport<ObjectProperty>("cosmetic_item") is ObjectProperty cosmeticItem) // variants
|
||||
else if (export.GetExport<ObjectProperty>("cosmetic_item") is { } cosmeticItem) // variants
|
||||
CosmeticSource = cosmeticItem.Value.Resource.ObjectName.String;
|
||||
|
||||
if (Properties.Settings.Default.DrawStats && export.GetExport<SoftObjectProperty>("AmmoData") is SoftObjectProperty ammoData)
|
||||
if (Settings.Default.DrawStats && export.GetExport<SoftObjectProperty>("AmmoData") is { } ammoData)
|
||||
Statistics.GetAmmoData(this, ammoData);
|
||||
if (Properties.Settings.Default.DrawStats && export.GetExport<StructProperty>("WeaponStatHandle") is StructProperty weaponStatHandle &&
|
||||
if (Settings.Default.DrawStats && export.GetExport<StructProperty>("WeaponStatHandle") is { } weaponStatHandle &&
|
||||
(exportType.Equals("FortWeaponMeleeItemDefinition") ||
|
||||
(export.GetExport<SoftObjectProperty>("StatList") is SoftObjectProperty statList &&
|
||||
(export.GetExport<SoftObjectProperty>("StatList") is { } statList &&
|
||||
!statList.Value.AssetPathName.String.StartsWith("/Game/UI/Tooltips/NoTooltipStats"))))
|
||||
{
|
||||
Statistics.GetWeaponStats(this, weaponStatHandle);
|
||||
}
|
||||
if (Properties.Settings.Default.DrawStats && export.GetExport<ObjectProperty>("HeroGameplayDefinition") is ObjectProperty heroGameplayDefinition)
|
||||
if (Settings.Default.DrawStats && export.GetExport<ObjectProperty>("HeroGameplayDefinition") is { } heroGameplayDefinition)
|
||||
Statistics.GetHeroStats(this, heroGameplayDefinition);
|
||||
|
||||
/* Please do not add Schematics support because it takes way too much memory */
|
||||
|
|
|
|||
61
FModel/Creator/Bases/BasePlaylist.cs
Normal file
61
FModel/Creator/Bases/BasePlaylist.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
|
||||
using FModel.Creator.Texts;
|
||||
using FModel.Utils;
|
||||
|
||||
using Fortnite_API.Objects;
|
||||
using Fortnite_API.Objects.V1;
|
||||
|
||||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
|
||||
using SkiaSharp;
|
||||
|
||||
namespace FModel.Creator.Bases
|
||||
{
|
||||
public class BasePlaylist : IBase
|
||||
{
|
||||
public SKBitmap FallbackImage { get; }
|
||||
public SKBitmap IconImage { get; }
|
||||
public SKColor[] RarityBackgroundColors { get; }
|
||||
public SKColor[] RarityBorderColor { get; }
|
||||
public string DisplayName { get; }
|
||||
public string Description { get; }
|
||||
public int Width { get; }
|
||||
public int Height { get; }
|
||||
public int Margin { get; } = 2;
|
||||
|
||||
public BasePlaylist(IUExport export)
|
||||
{
|
||||
FallbackImage = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_Placeholder_Item_Image.png"))?.Stream);
|
||||
IconImage = FallbackImage;
|
||||
RarityBackgroundColors = new[] { SKColor.Parse("5EBC36"), SKColor.Parse("305C15") };
|
||||
RarityBorderColor = new[] { SKColor.Parse("74EF52"), SKColor.Parse("74EF52") };
|
||||
|
||||
if (export.GetExport<TextProperty>("UIDisplayName", "DisplayName") is { } displayName)
|
||||
DisplayName = Text.GetTextPropertyBase(displayName);
|
||||
if (export.GetExport<TextProperty>("UIDescription", "Description") is { } description)
|
||||
Description = Text.GetTextPropertyBase(description);
|
||||
|
||||
Width = Height = 512;
|
||||
|
||||
if (export.GetExport<NameProperty>("PlaylistName") is { } playlistName && !playlistName.Value.IsNone)
|
||||
{
|
||||
ApiResponse<PlaylistV1> playlist = Endpoints.FortniteAPI.V1.Playlists.Get(playlistName.Value.String);
|
||||
|
||||
if (playlist.IsSuccess && playlist.Data.Images.HasShowcase)
|
||||
{
|
||||
byte[] imageBytes = Endpoints.GetRawData(playlist.Data.Images.Showcase);
|
||||
|
||||
if (imageBytes != null)
|
||||
{
|
||||
IconImage = SKBitmap.Decode(imageBytes);
|
||||
Width = IconImage.Width;
|
||||
Height = IconImage.Height;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -52,7 +52,6 @@ namespace FModel.Creator
|
|||
case "FortAbilityKit":
|
||||
case "FortWorkerType":
|
||||
case "RewardGraphToken":
|
||||
case "FortPlaylistAthena":
|
||||
case "FortBannerTokenType":
|
||||
case "FortVariantTokenType":
|
||||
case "FortDecoItemDefinition":
|
||||
|
|
@ -142,6 +141,34 @@ namespace FModel.Creator
|
|||
}
|
||||
return true;
|
||||
}
|
||||
case "FortPlaylistAthena":
|
||||
{
|
||||
BasePlaylist icon = new BasePlaylist(exports[index]);
|
||||
using (var ret = new SKBitmap(icon.Width, icon.Height, SKColorType.Rgba8888, SKAlphaType.Premul))
|
||||
using (var c = new SKCanvas(ret))
|
||||
{
|
||||
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign != EIconDesign.NoBackground)
|
||||
{
|
||||
Rarity.DrawRarity(c, icon);
|
||||
}
|
||||
|
||||
LargeSmallImage.DrawPreviewImage(c, icon);
|
||||
|
||||
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign != EIconDesign.NoBackground)
|
||||
{
|
||||
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign != EIconDesign.NoText)
|
||||
{
|
||||
Text.DrawBackground(c, icon);
|
||||
Text.DrawDisplayName(c, icon);
|
||||
Text.DrawDescription(c, icon);
|
||||
}
|
||||
}
|
||||
|
||||
Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
|
||||
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case "AthenaSeasonItemDefinition":
|
||||
{
|
||||
BaseSeason icon = new BaseSeason(exports[index], assetFolder);
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@
|
|||
<PackageReference Include="DotNetZip" Version="1.13.8" />
|
||||
<PackageReference Include="EpicManifestParser" Version="1.2.0" />
|
||||
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.0.1" />
|
||||
<PackageReference Include="Fortnite-API-Wrapper" Version="2.1.0" />
|
||||
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.2.6" />
|
||||
<PackageReference Include="LZMA-SDK" Version="19.0.0" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.19041.1" />
|
||||
|
|
|
|||
|
|
@ -3,20 +3,41 @@ using Newtonsoft.Json;
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Fortnite_API;
|
||||
|
||||
namespace FModel.Utils
|
||||
{
|
||||
static class Endpoints
|
||||
{
|
||||
public static readonly FortniteApi FortniteAPI = new FortniteApi($"FModel/{Assembly.GetExecutingAssembly().GetName().Version}");
|
||||
public const string BENBOT_AES = "https://benbotfn.tk/api/v1/aes";
|
||||
public const string BENBOT_HOTFIXES = "https://benbotfn.tk/api/v1/hotfixes";
|
||||
public const string FMODEL_JSON = "https://dl.dropbox.com/s/sxyaqo6zu1drlea/FModel.json?dl=0";
|
||||
public const string OAUTH_URL = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token";
|
||||
private const string _BASIC_FN_TOKEN = "basic MzQ0NmNkNzI2OTRjNGE0NDg1ZDgxYjc3YWRiYjIxNDE6OTIwOWQ0YTVlMjVhNDU3ZmI5YjA3NDg5ZDMxM2I0MWE=";
|
||||
|
||||
public static async Task<string> GetStringEndpoint(string url) => await GetStringEndpoint(url, string.Empty);
|
||||
public static byte[] GetRawData(Uri uri) => GetRawDataAsync(uri).GetAwaiter().GetResult();
|
||||
public static async Task<byte[]> GetRawDataAsync(Uri uri)
|
||||
{
|
||||
using (HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(2) })
|
||||
{
|
||||
try
|
||||
{
|
||||
var data = await client.GetByteArrayAsync(uri).ConfigureAwait(false);
|
||||
return data;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Task<string> GetStringEndpoint(string url) => GetStringEndpoint(url, string.Empty);
|
||||
public static async Task<string> GetStringEndpoint(string url, string token)
|
||||
{
|
||||
DebugHelper.WriteLine("{0} {1} {2} {3}", "[FModel]", "[Endpoints]", "[GET]", url);
|
||||
|
|
@ -49,7 +70,7 @@ namespace FModel.Utils
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
public static async Task<T> GetJsonEndpoint<T>(string url) => await GetJsonEndpoint<T>(url, string.Empty);
|
||||
public static Task<T> GetJsonEndpoint<T>(string url) => GetJsonEndpoint<T>(url, string.Empty);
|
||||
public static async Task<T> GetJsonEndpoint<T>(string url, string query)
|
||||
{
|
||||
if (url.Equals(BENBOT_HOTFIXES) && !string.IsNullOrEmpty(query))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user