FModel 3.1.1.2

This commit is contained in:
iAmAsval 2020-09-10 15:53:59 +02:00
parent 08f50cdf10
commit 6c66243044
14 changed files with 182 additions and 29 deletions

View File

@ -44,16 +44,18 @@ namespace FModel.Creator.Bases
Stats = new List<Statistic>();
}
/// <summary>
/// used to get low res icons ONLY
/// </summary>
/// <param name="export"></param>
/// <param name="assetName"></param>
public BaseIcon(IUExport export, string assetName) : this()
public BaseIcon(IUExport export, string assetName, bool forceHR) : this()
{
if (export.GetExport<ObjectProperty>("Series") is ObjectProperty series)
Serie.GetRarity(this, series);
else if (Properties.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)
Rarity.GetHardCodedRarity(this, rarity);
if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is ObjectProperty itemDef)
LargeSmallImage.GetPreviewImage(this, itemDef, assetName, false);
else if (export.GetExport<SoftObjectProperty>("SmallPreviewImage", "SmallImage") is SoftObjectProperty previewImage)
LargeSmallImage.GetPreviewImage(this, itemDef, assetName, forceHR);
else if (export.GetExport<SoftObjectProperty>(forceHR ? "LargePreviewImage" : "SmallPreviewImage", forceHR ? "ItemDisplayAsset" : "SmallImage") is SoftObjectProperty previewImage)
LargeSmallImage.GetPreviewImage(this, previewImage);
}

View File

@ -0,0 +1,112 @@
using FModel.Creator.Rarities;
using FModel.Creator.Texts;
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
namespace FModel.Creator.Bases
{
public class BaseItemAccess
{
private readonly SKPaint descriptionPaint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = Text.TypeFaces.DescriptionTypeface,
TextSize = 13,
Color = SKColors.White,
};
public BaseIcon Item;
public string SItem;
public SKBitmap Lock;
public SKBitmap Unlock;
public string DisplayName;
public string Description;
public string UnlockDescription;
public int Size = 512; // keep it 512 (or a multiple of 512) if you don't want blurry icons
public BaseItemAccess()
{
Item = new BaseIcon();
SItem = "";
Lock = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Locks/T-Icon-Lock-128").Resize(24, 24);
Unlock = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Locks/T-Icon-Unlocked-128").Resize(24, 24);
DisplayName = "";
Description = "";
UnlockDescription = "";
}
public BaseItemAccess(IUExport export) : this()
{
if (export.GetExport<ObjectProperty>("access_item") is ObjectProperty accessItem)
{
SItem = accessItem.Value.Resource.ObjectName.String;
PakPackage p = Utils.GetPropertyPakPackage(accessItem.Value.Resource.OuterIndex.Resource.ObjectName.String);
if (p.HasExport() && !p.Equals(default))
{
var d = p.GetExport<UObject>();
if (d != null)
{
Item = new BaseIcon(d, SItem + ".uasset", true);
}
}
}
if (export.GetExport<TextProperty>("DisplayName") is TextProperty displayName)
DisplayName = Text.GetTextPropertyBase(displayName);
if (export.GetExport<TextProperty>("Description") is TextProperty description)
Description = Text.GetTextPropertyBase(description);
if (export.GetExport<TextProperty>("UnlockDescription") is TextProperty unlockDescription)
UnlockDescription = Text.GetTextPropertyBase(unlockDescription);
}
public void Draw(SKCanvas c)
{
Rarity.DrawRarity(c, Item);
int size = 45;
int left = Size / 2;
SKPaint namePaint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = Text.TypeFaces.DisplayNameTypeface,
TextSize = size,
Color = SKColors.White,
TextAlign = SKTextAlign.Center,
};
while (namePaint.MeasureText(DisplayName) > (Size - (Item.Margin * 2)))
{
namePaint.TextSize = size -= 2;
}
c.DrawText(DisplayName, left, Item.Margin * 8 + size, namePaint);
int topBase = Item.Margin + size * 2;
c.DrawBitmap(Lock, new SKRect(50, topBase, 50 + Lock.Width, topBase + Lock.Height),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
Helper.DrawMultilineText(c, UnlockDescription, Size, Item.Margin, ETextSide.Left,
new SKRect(70 + Lock.Width, topBase + 10, Size - 50, 256), descriptionPaint, out topBase);
c.DrawBitmap(Unlock, new SKRect(50, topBase, 50 + Unlock.Width, topBase + Unlock.Height),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
Helper.DrawMultilineText(c, Description, Size, Item.Margin, ETextSide.Left,
new SKRect(70 + Unlock.Width, topBase + 10, Size - 50, 256), descriptionPaint, out topBase);
int h = Size - Item.Margin - topBase;
c.DrawBitmap(Item.IconImage ?? Item.FallbackImage, new SKRect(left - h / 2, topBase, left + h / 2, Size - Item.Margin),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
c.DrawText(SItem, Size - (Item.Margin * 2.5f), Size - (Item.Margin * 2.5f), new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = Text.TypeFaces.DefaultTypeface,
TextSize = 15,
Color = SKColors.White,
TextAlign = SKTextAlign.Right,
});
}
}
}

View File

@ -128,7 +128,7 @@ namespace FModel.Creator.Bases
c.DrawText(ability.DisplayName, Width + Margin + xToAdd + 10, yaPos + Margin + textSize, namePaint);
Helper.DrawMultilineText(c, ability.Description, Width, Width + Margin + xToAdd + 10, ETextSide.Left,
new SKRect(Margin, textSize + yaPos + 27.5f, Width + AdditionalWidth - Margin, Height - 27.5f), descriptionPaint, out var _);
new SKRect(Width + Margin + xToAdd + 10, textSize + yaPos + 27.5f, Width + AdditionalWidth - Margin, Height - 27.5f), descriptionPaint, out var _);
if (ability.Icon != null)
c.DrawBitmap(ability.Icon, new SKRect(Width + Margin, yaPos, Width + Margin + ability.Icon.Width, yaPos + ability.Icon.Height),

View File

@ -40,7 +40,7 @@ namespace FModel.Creator.Bundles
var c = p.GetExport<UDataTable>();
if (c != null && c.TryGetCaseInsensitiveValue(parts[1], out var s) && s is UObject banner)
{
RewardIcon = new BaseIcon(banner, "BannerIcons.uasset").IconImage.Resize(64, 64);
RewardIcon = new BaseIcon(banner, "BannerIcons.uasset", false).IconImage.Resize(64, 64);
}
}
}
@ -84,7 +84,7 @@ namespace FModel.Creator.Bundles
break;
default:
IsCountShifted = false;
RewardIcon = new BaseIcon(d, itemDefinition.Value.AssetPathName.String.Substring(s1, s2) + ".uasset").IconImage.Resize(64, 64);
RewardIcon = new BaseIcon(d, itemDefinition.Value.AssetPathName.String.Substring(s1, s2) + ".uasset", false).IconImage.Resize(64, 64);
break;
}
}
@ -124,7 +124,7 @@ namespace FModel.Creator.Bundles
{
int i = path.LastIndexOf('/');
IsCountShifted = false;
RewardIcon = new BaseIcon(d, path.Substring(i > 0 ? i : 0) + ".uasset").IconImage.Resize(64, 64);
RewardIcon = new BaseIcon(d, path.Substring(i > 0 ? i : 0) + ".uasset", false).IconImage.Resize(64, 64);
}
}
break;

View File

@ -202,6 +202,19 @@ namespace FModel.Creator
}
return true;
}
case "FortItemAccessTokenType":
{
BaseItemAccess icon = new BaseItemAccess(exports[index]);
using (var ret = new SKBitmap(icon.Size, icon.Size, SKColorType.Rgba8888, SKAlphaType.Opaque))
using (var c = new SKCanvas(ret))
{
icon.Draw(c);
Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
}
return true;
}
case "MapUIData":
{
BaseMapUIData icon = new BaseMapUIData(exports[index]);

View File

@ -56,6 +56,6 @@ namespace FModel.Creator.Icons
public static void DrawPreviewImage(SKCanvas c, BaseIcon icon) =>
c.DrawBitmap(icon.IconImage ?? icon.FallbackImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
}
}

View File

@ -45,7 +45,7 @@ namespace FModel.Creator.Texts
public static void DrawMultilineText(SKCanvas canvas, string text, int size, int margin, ETextSide side, SKRect area, SKPaint paint, out int yPos)
{
float lineHeight = paint.TextSize * 1.2f;
Line[] lines = SplitLines(text, paint, area.Width - margin);
Line[] lines = SplitLines(text, paint, area.Width);
if (lines == null)
{
yPos = (int)area.Top;
@ -59,7 +59,7 @@ namespace FModel.Creator.Texts
{
ETextSide.Center => area.MidX - lines[i].Width / 2,
ETextSide.Right => size - margin - lines[i].Width,
ETextSide.Left => margin,
ETextSide.Left => area.Left,
_ => area.MidX - lines[i].Width / 2
};
canvas.DrawText(lines[i].Value.TrimEnd(), x, y, paint);

View File

@ -8,8 +8,8 @@
<StartupObject>FModel.App</StartupObject>
<Authors>Asval</Authors>
<Company></Company>
<AssemblyVersion>3.1.1.1</AssemblyVersion>
<FileVersion>3.1.1.1</FileVersion>
<AssemblyVersion>3.1.1.2</AssemblyVersion>
<FileVersion>3.1.1.2</FileVersion>
<PackageIcon>FModel.ico</PackageIcon>
<PackageIconUrl />
<PackageProjectUrl>https://github.com/iAmAsval/FModel</PackageProjectUrl>

View File

@ -67,35 +67,26 @@ namespace PakReader
}
}
// Read entries count
if (VersionNumber >= Version.Optimized_CRC32)
{
uint EntriesCount = reader.ReadUInt32();
}
reader.ReadUInt32(); // EntriesCount
// Read namespace count
uint NamespaceCount = reader.ReadUInt32();
for (uint i = 0; i < NamespaceCount; i++)
{
// Read namespace
if (VersionNumber >= Version.Optimized_CRC32)
{
reader.ReadUInt32(); // StrHash
}
string Namespace = reader.ReadFString();
string Namespace = reader.ReadFString();
uint KeyCount = reader.ReadUInt32();
Dictionary<string, string> Entries = new Dictionary<string, string>((int)KeyCount);
for (uint j = 0; j < KeyCount; j++)
{
// Read key
if (VersionNumber >= Version.Optimized_CRC32)
{
reader.ReadUInt32(); // StrHash
}
string Key = reader.ReadFString();
string Key = reader.ReadFString();
reader.ReadUInt32(); // SourceStringHash
string EntryLocalizedString;

View File

@ -45,6 +45,8 @@ namespace PakReader.Textures.BC
return ret;
}
//BC7 https://github.com/hglm/detex/blob/master/decompress-bptc.c
static int GetPixelLoc(int width, int x, int y, int bpp, int off) => (y * width + x) * bpp + off;
static byte GetZNormal(byte x, byte y)

View File

@ -812,4 +812,13 @@ Jetzt ist es die am häufigsten genutzte freie Software um mit Fortnite zu leake
<data name="WithPosition" xml:space="preserve">
<value>Position / Wert</value>
</data>
<data name="MaybeLater" xml:space="preserve">
<value>Vielleicht später</value>
</data>
<data name="NoKeyWarning" xml:space="preserve">
<value>Eine verschlüsselte .PAK-Datei wurde gefunden. Bitte gib einen funktionierenden AES-Schlüssel zum Entschlüsseln an</value>
</data>
<data name="SkipThisVersion" xml:space="preserve">
<value>Diese Version überspringen</value>
</data>
</root>

View File

@ -778,4 +778,13 @@ Col tempo sono state aggiunte nuove funzioni e molti altri utenti hanno comincia
<data name="WithPosition" xml:space="preserve">
<value>Posizione / Valore</value>
</data>
<data name="SkipThisVersion" xml:space="preserve">
<value>Ignora questa Versione</value>
</data>
<data name="NoKeyWarning" xml:space="preserve">
<value>È stato trovato un file .PAK criptato. Per decriptarlo, fornisci una chiave AES valida</value>
</data>
<data name="MaybeLater" xml:space="preserve">
<value>Magari più avanti</value>
</data>
</root>

View File

@ -771,4 +771,13 @@
<data name="WithPosition" xml:space="preserve">
<value>Должность / Значение</value>
</data>
<data name="MaybeLater" xml:space="preserve">
<value>Возможно позднее</value>
</data>
<data name="NoKeyWarning" xml:space="preserve">
<value>Найден зашифрованный .PAK файл. Для того чтобы расшифровать его, пожалуйста, укажите рабочий AES ключ</value>
</data>
<data name="SkipThisVersion" xml:space="preserve">
<value>Пропустить эту версию</value>
</data>
</root>

View File

@ -784,4 +784,10 @@
<data name="NoKeyWarning" xml:space="preserve">
<value>找到一个加密的.PAK文件。要解密文件请设置正确的AES加密密钥。</value>
</data>
<data name="MaybeLater" xml:space="preserve">
<value>也许以后</value>
</data>
<data name="SkipThisVersion" xml:space="preserve">
<value>跳过此版本</value>
</data>
</root>