added basic Spellbreak icon creation

This commit is contained in:
iAmAsval
2020-09-20 21:13:03 +02:00
parent e591cb0818
commit 643a02d879
22 changed files with 281 additions and 68 deletions

View File

@@ -0,0 +1,71 @@
using FModel.Creator.Rarities;
using FModel.Creator.Texts;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System;
using System.Windows;
namespace FModel.Creator.Bases
{
public class BaseGCosmetic : IBase
{
public SKBitmap FallbackImage;
public SKBitmap IconImage;
public SKColor[] RarityBackgroundColors;
public SKColor[] RarityBorderColor;
public string DisplayName;
public string Description;
public int Width = 512; // keep it 512 (or a multiple of 512) if you don't want blurry icons
public int Height = 512;
public int Margin = 2;
public BaseGCosmetic(string exportType)
{
FallbackImage = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_Placeholder_Item_Image.png")).Stream);
IconImage = FallbackImage;
RarityBackgroundColors = new SKColor[2] { SKColor.Parse("FFFFFF"), SKColor.Parse("636363") };
RarityBorderColor = new SKColor[2] { SKColor.Parse("D0D0D0"), SKColor.Parse("FFFFFF") };
DisplayName = "";
Description = "";
Width = exportType switch
{
"GCosmeticCard" => 1024,
_ => 512
};
Height = exportType switch
{
"GCosmeticCard" => 200,
_ => 512
};
}
public BaseGCosmetic(IUExport export, string exportType) : this(exportType)
{
// rarity
Rarity.GetInGameRarity(this, export.GetExport<EnumProperty>("Rarity"));
// image
if (export.GetExport<SoftObjectProperty>("IconTexture") is SoftObjectProperty previewImage)
this.IconImage = Utils.GetSoftObjectTexture(previewImage);
else if (export.GetExport<ObjectProperty>("IconTexture") is ObjectProperty iconTexture)
this.IconImage = Utils.GetObjectTexture(iconTexture);
// text
if (export.GetExport<TextProperty>("DisplayName", "Title") is TextProperty displayName)
DisplayName = Text.GetTextPropertyBase(displayName);
if (export.GetExport<TextProperty>("Description") is TextProperty description)
Description = Text.GetTextPropertyBase(description);
}
SKBitmap IBase.FallbackImage => FallbackImage;
SKBitmap IBase.IconImage => IconImage;
SKColor[] IBase.RarityBackgroundColors => RarityBackgroundColors;
SKColor[] IBase.RarityBorderColor => RarityBorderColor;
string IBase.DisplayName => DisplayName;
string IBase.Description => Description;
int IBase.Width => Width;
int IBase.Height => Height;
int IBase.Margin => Margin;
}
}

View File

@@ -12,7 +12,7 @@ using System.Windows;
namespace FModel.Creator.Bases
{
public class BaseIcon
public class BaseIcon : IBase
{
public SKBitmap FallbackImage;
public SKBitmap IconImage;
@@ -126,5 +126,15 @@ namespace FModel.Creator.Bases
AdditionalSize = 48 * Stats.Count;
}
SKBitmap IBase.FallbackImage => FallbackImage;
SKBitmap IBase.IconImage => IconImage;
SKColor[] IBase.RarityBackgroundColors => RarityBackgroundColors;
SKColor[] IBase.RarityBorderColor => RarityBorderColor;
string IBase.DisplayName => DisplayName;
string IBase.Description => Description;
int IBase.Width => Size;
int IBase.Height => Size + AdditionalSize;
int IBase.Margin => Margin;
}
}

View File

@@ -0,0 +1,17 @@
using SkiaSharp;
namespace FModel.Creator.Bases
{
interface IBase
{
SKBitmap FallbackImage { get; }
SKBitmap IconImage { get; }
SKColor[] RarityBackgroundColors { get; }
SKColor[] RarityBorderColor { get; }
string DisplayName { get; }
string Description { get; }
int Width { get; }
int Height { get; }
int Margin { get; }
}
}

View File

@@ -25,7 +25,7 @@ namespace FModel.Creator
string assetFolder = d.Parent.Name;
if (Text.TypeFaces.NeedReload(false)) Text.TypeFaces = new Typefaces(); // when opening bundle creator settings without loading paks first
int index = Globals.Game.ActualGame == EGame.Valorant ? 1 : 0;
int index = Globals.Game.ActualGame == EGame.Valorant || Globals.Game.ActualGame == EGame.Spellbreak ? 1 : 0;
string exportType = exportTypes.Length > index ? exportTypes[index].String : string.Empty;
switch (exportType)
{
@@ -290,6 +290,43 @@ namespace FModel.Creator
// }
// return false;
// }
case "GAccolade":
case "GCosmeticSkin":
case "GCosmeticCard":
case "GCosmeticTitle":
case "GCosmeticBadge":
case "GCosmeticEmote":
case "GCosmeticTriumph":
case "GCosmeticRunTrail":
case "GCosmeticArtifact":
case "GCosmeticDropTrail":
{
BaseGCosmetic icon = new BaseGCosmetic(exports[index], exportType);
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;
}
}
return false;
}

View File

@@ -54,8 +54,8 @@ namespace FModel.Creator.Icons
return false;
}
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),
public static void DrawPreviewImage(SKCanvas c, IBase icon) =>
c.DrawBitmap(icon.IconImage ?? icon.FallbackImage, new SKRect(icon.Margin, icon.Margin, icon.Width - icon.Margin, icon.Height - icon.Margin),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
}
}

View File

@@ -66,6 +66,27 @@ namespace FModel.Creator.Rarities
else GetHardCodedRarity(icon, e);
}
public static void GetInGameRarity(BaseGCosmetic icon, EnumProperty e)
{
PakPackage p = Utils.GetPropertyPakPackage("/Game/UI/UIKit/DT_RarityColors");
if (p.HasExport() && !p.Equals(default))
{
var d = p.GetExport<UDataTable>();
if (d != null)
{
if (e != null && d.TryGetValue(e?.Value.String["EXRarity::".Length..], out object r) && r is UObject rarity &&
rarity.GetExport<ArrayProperty>("Colors") is ArrayProperty colors &&
colors.Value[0] is StructProperty s1 && s1.Value is FLinearColor color1 &&
colors.Value[1] is StructProperty s2 && s2.Value is FLinearColor color2 &&
colors.Value[2] is StructProperty s3 && s3.Value is FLinearColor color3)
{
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse(color1.Hex), SKColor.Parse(color3.Hex) };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse(color2.Hex), SKColor.Parse(color1.Hex) };
}
}
}
}
public static void GetHardCodedRarity(BaseIcon icon, EnumProperty e)
{
switch (e?.Value.String)
@@ -103,17 +124,17 @@ namespace FModel.Creator.Rarities
}
}
public static void DrawRarity(SKCanvas c, BaseIcon icon)
public static void DrawRarity(SKCanvas c, IBase icon)
{
// border
c.DrawRect(new SKRect(0, 0, icon.Size, icon.Size),
c.DrawRect(new SKRect(0, 0, icon.Width, icon.Height),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Shader = SKShader.CreateLinearGradient(
new SKPoint(icon.Size / 2, icon.Size),
new SKPoint(icon.Size, icon.Size / 4),
new SKPoint(icon.Width / 2, icon.Height),
new SKPoint(icon.Width, icon.Height / 4),
icon.RarityBorderColor,
SKShaderTileMode.Clamp)
});
@@ -122,12 +143,12 @@ namespace FModel.Creator.Rarities
{
case EIconDesign.Flat:
{
if (icon.RarityBackgroundImage != null)
c.DrawBitmap(icon.RarityBackgroundImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
if (icon is BaseIcon i && i.RarityBackgroundImage != null)
c.DrawBitmap(i.RarityBackgroundImage, new SKRect(icon.Margin, icon.Margin, icon.Width - icon.Margin, icon.Height - icon.Margin),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
else
{
c.DrawRect(new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
c.DrawRect(new SKRect(icon.Margin, icon.Margin, icon.Width - icon.Margin, icon.Height - icon.Margin),
new SKPaint
{
IsAntialias = true,
@@ -143,16 +164,16 @@ namespace FModel.Creator.Rarities
};
var pathTop = new SKPath { FillType = SKPathFillType.EvenOdd };
pathTop.MoveTo(icon.Margin, icon.Margin);
pathTop.LineTo(icon.Margin + (icon.Size / 17 * 10), icon.Margin);
pathTop.LineTo(icon.Margin, icon.Margin + (icon.Size / 17));
pathTop.LineTo(icon.Margin + (icon.Width / 17 * 10), icon.Margin);
pathTop.LineTo(icon.Margin, icon.Margin + (icon.Height / 17));
pathTop.Close();
c.DrawPath(pathTop, paint);
var pathBottom = new SKPath { FillType = SKPathFillType.EvenOdd };
pathBottom.MoveTo(icon.Margin, icon.Size - icon.Margin);
pathBottom.LineTo(icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 2.5f));
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 4.5f));
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin);
pathBottom.MoveTo(icon.Margin, icon.Height - icon.Margin);
pathBottom.LineTo(icon.Margin, icon.Height - icon.Margin - (icon.Height / 17 * 2.5f));
pathBottom.LineTo(icon.Width - icon.Margin, icon.Height - icon.Margin - (icon.Height / 17 * 4.5f));
pathBottom.LineTo(icon.Width - icon.Margin, icon.Height - icon.Margin);
pathBottom.Close();
c.DrawPath(pathBottom, paint);
}
@@ -160,18 +181,18 @@ namespace FModel.Creator.Rarities
}
default:
{
if (icon.RarityBackgroundImage != null)
c.DrawBitmap(icon.RarityBackgroundImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
if (icon is BaseIcon i && i.RarityBackgroundImage != null)
c.DrawBitmap(i.RarityBackgroundImage, new SKRect(icon.Margin, icon.Margin, icon.Width - icon.Margin, icon.Height - icon.Margin),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
else
c.DrawRect(new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
c.DrawRect(new SKRect(icon.Margin, icon.Margin, icon.Width - icon.Margin, icon.Height - icon.Margin),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Shader = SKShader.CreateRadialGradient(
new SKPoint(icon.Size / 2, icon.Size / 2),
icon.Size / 5 * 4,
new SKPoint(icon.Width / 2, icon.Height / 2),
icon.Width / 5 * 4,
icon.RarityBackgroundColors,
SKShaderTileMode.Clamp)
});

View File

@@ -14,8 +14,8 @@ namespace FModel.Creator.Texts
public float Width { get; set; }
}
public static void DrawCenteredMultilineText(SKCanvas canvas, string text, int maxLineCount, BaseIcon icon, ETextSide side, SKRect area, SKPaint paint)
=> DrawCenteredMultilineText(canvas, text, maxLineCount, icon.Size, icon.Margin, side, area, paint);
public static void DrawCenteredMultilineText(SKCanvas canvas, string text, int maxLineCount, IBase icon, ETextSide side, SKRect area, SKPaint paint)
=> DrawCenteredMultilineText(canvas, text, maxLineCount, icon.Width, icon.Margin, side, area, paint);
public static void DrawCenteredMultilineText(SKCanvas canvas, string text, int maxLineCount, int size, int margin, ETextSide side, SKRect area, SKPaint paint)
{
float lineHeight = paint.TextSize * 1.2f;

View File

@@ -87,17 +87,17 @@ namespace FModel.Creator.Texts
return string.Empty;
}
public static void DrawBackground(SKCanvas c, BaseIcon icon)
public static void DrawBackground(SKCanvas c, IBase icon)
{
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
{
case EIconDesign.Flat:
{
var pathBottom = new SKPath { FillType = SKPathFillType.EvenOdd };
pathBottom.MoveTo(icon.Margin, icon.Size - icon.Margin);
pathBottom.LineTo(icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 2.5f));
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 4.5f));
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin);
pathBottom.MoveTo(icon.Margin, icon.Height - icon.Margin);
pathBottom.LineTo(icon.Margin, icon.Height - icon.Margin - (icon.Height / 17 * 2.5f));
pathBottom.LineTo(icon.Width - icon.Margin, icon.Height - icon.Margin - (icon.Height / 17 * 4.5f));
pathBottom.LineTo(icon.Width - icon.Margin, icon.Height - icon.Margin);
pathBottom.Close();
c.DrawPath(pathBottom, new SKPaint
{
@@ -110,7 +110,7 @@ namespace FModel.Creator.Texts
default:
{
c.DrawRect(
new SKRect(icon.Margin, _STARTER_TEXT_POSITION, icon.Size - icon.Margin, icon.Size - icon.Margin),
new SKRect(icon.Margin, _STARTER_TEXT_POSITION, icon.Width - icon.Margin, icon.Height - icon.Margin),
new SKPaint
{
IsAntialias = true,
@@ -122,12 +122,12 @@ namespace FModel.Creator.Texts
}
}
public static void DrawDisplayName(SKCanvas c, BaseIcon icon)
public static void DrawDisplayName(SKCanvas c, IBase icon)
{
_NAME_TEXT_SIZE = 45;
string text = icon.DisplayName;
SKTextAlign side = SKTextAlign.Center;
int x = icon.Size / 2;
int x = icon.Width / 2;
int y = _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE;
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
{
@@ -141,7 +141,7 @@ namespace FModel.Creator.Texts
{
_NAME_TEXT_SIZE = 47;
side = SKTextAlign.Right;
x = icon.Size - icon.Margin * 2;
x = icon.Width - icon.Margin * 2;
break;
}
}
@@ -157,7 +157,7 @@ namespace FModel.Creator.Texts
};
// resize if too long
while (namePaint.MeasureText(text) > (icon.Size - (icon.Margin * 2)))
while (namePaint.MeasureText(text) > (icon.Width - (icon.Margin * 2)))
{
namePaint.TextSize = _NAME_TEXT_SIZE -= 2;
}
@@ -165,7 +165,7 @@ namespace FModel.Creator.Texts
c.DrawText(text, x, y, namePaint);
}
public static void DrawDescription(SKCanvas c, BaseIcon icon)
public static void DrawDescription(SKCanvas c, IBase icon)
{
int maxLine = 4;
_BOTTOM_TEXT_SIZE = 15;
@@ -198,7 +198,7 @@ namespace FModel.Creator.Texts
// wrap if too long
Helper.DrawCenteredMultilineText(c, text, maxLine, icon, side,
new SKRect(icon.Margin, _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE, icon.Size - icon.Margin, icon.Size - _BOTTOM_TEXT_SIZE),
new SKRect(icon.Margin, _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE, icon.Width - icon.Margin, icon.Height - _BOTTOM_TEXT_SIZE),
descriptionPaint);
}

View File

@@ -49,6 +49,13 @@ namespace FModel.Creator.Texts
private const string _DINNEXT_LTARABIC_LIGHT = "UI/Fonts/FinalFonts/LOCFonts/DIN_Next_Arabic/DINNextLTArabic-Light";
private const string _NOTOSANS_CJK_LIGHT = "UI/Fonts/FinalFonts/LOCFonts/CJK/NotoSansCJK-Light"; // chinese, japanese, korean
private const string _DINNEXT_W1G_BOLD = "UI/Fonts/FinalFonts/DINNextW1G-Bold";
private const string _SPELLBREAK_BASE_PATH = "/Game/UI/Fonts/";
private const string _MONTSERRAT_SEMIBOLD = "Montserrat-Semibold";
private const string _MONTSERRAT_SEMIBOLD_ITALIC = "Montserrat-SemiBoldItalic";
private const string _NANUM_GOTHIC = "NanumGothic";
private const string _QUADRAT_BOLD = "Quadrat_Bold";
private const string _SEGOE_BOLD_ITALIC = "Segoe_Bold_Italic";
#pragma warning restore IDE0051
public SKTypeface DefaultTypeface; // used as default font for all untranslated strings (item source, ...)
@@ -143,6 +150,18 @@ namespace FModel.Creator.Texts
BundleDefaultTypeface = SKTypeface.FromStream(t[2].AsStream());
else BundleDefaultTypeface = DefaultTypeface;
}
else if (Globals.Game.ActualGame == EGame.Spellbreak)
{
ArraySegment<byte>[] t = Utils.GetPropertyArraySegmentByte(_SPELLBREAK_BASE_PATH + _QUADRAT_BOLD);
if (t != null && t.Length == 3 && t[2].Array != null)
DisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
else DisplayNameTypeface = DefaultTypeface;
t = Utils.GetPropertyArraySegmentByte(_SPELLBREAK_BASE_PATH + _MONTSERRAT_SEMIBOLD);
if (t != null && t.Length == 3 && t[2].Array != null)
DescriptionTypeface = SKTypeface.FromStream(t[2].AsStream());
else DescriptionTypeface = DefaultTypeface;
}
}
public bool NeedReload(bool forceReload) => forceReload ?

View File

@@ -64,6 +64,10 @@ namespace FModel.Creator
s += "_1024";
else if (s.Equals("/Game/UI/Foundation/Textures/BattleRoyale/BattlePass/T-BattlePass-Season14-Tile") || s.Equals("/Game/UI/Foundation/Textures/BattleRoyale/BattlePass/T-BattlePassWithLevels-Season14-Tile"))
s += "_1";
else if (s.Equals("/Game/UI/Textures/assets/cosmetics/skins/headshot/Skin_Headshot_WolfsBlood_UIT"))
s = "/Game/UI/Textures/assets/cosmetics/skins/headshot/Skin_Headshot_Wolfsblood_UIT";
else if (s.Equals("/Game/UI/Textures/assets/cosmetics/skins/headshot/Skin_Headshot_Timeweaver_UIT"))
s = "/Game/UI/Textures/assets/cosmetics/skins/headshot/Skin_Headshot_TimeWeaver_UIT";
}
PakPackage p = GetPropertyPakPackage(s);

View File

@@ -89,6 +89,7 @@
<None Remove="Resources\power.png" />
<None Remove="Resources\progress-download.png" />
<None Remove="Resources\refresh.png" />
<None Remove="Resources\rotate-3d.png" />
<None Remove="Resources\settings.png" />
<None Remove="Resources\share-all.png" />
<None Remove="Resources\share.png" />
@@ -129,18 +130,18 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autoupdater.NET.Official" Version="1.6.2" />
<PackageReference Include="Autoupdater.NET.Official" Version="1.6.3" />
<PackageReference Include="AvalonEdit" Version="6.0.1" />
<PackageReference Include="CSCore" Version="1.2.1.2" />
<PackageReference Include="DiscordRichPresence" Version="1.0.150" />
<PackageReference Include="DotNetZip" Version="1.13.8" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.0.1" />
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.1.11" />
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.2.6" />
<PackageReference Include="LZMA-SDK" Version="19.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NVorbis" Version="0.10.1" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" />
<PackageReference Include="SkiaSharp" Version="2.80.1" />
<PackageReference Include="SkiaSharp" Version="2.80.2" />
<PackageReference Include="ToastNotifications" Version="2.5.1" />
<PackageReference Include="ToastNotifications.Messages" Version="2.5.1" />
<PackageReference Include="WriteableBitmapEx" Version="1.6.7" />
@@ -202,6 +203,7 @@
<Resource Include="Resources\power.png" />
<Resource Include="Resources\progress-download.png" />
<Resource Include="Resources\refresh.png" />
<Resource Include="Resources\rotate-3d.png" />
<Resource Include="Resources\settings.png" />
<Resource Include="Resources\share-all.png" />
<Resource Include="Resources\share.png" />

View File

@@ -71,6 +71,11 @@
<Image Source="Resources/cast-audio.png"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Mesh Viewer">
<MenuItem.Icon>
<Image Source="Resources/rotate-3d.png"/>
</MenuItem.Icon>
</MenuItem>
<Separator/>
<MenuItem x:Name="FModel_MI_Assets_GoTo" Header="{x:Static properties:Resources.Directories}">
<MenuItem.Icon>

View File

@@ -0,0 +1,29 @@
using System.Collections;
using System.Collections.Generic;
namespace PakReader.Parsers.Class
{
public sealed class UAkAudioEvent : IUExport
{
readonly Dictionary<string, object> Map;
internal UAkAudioEvent(PackageReader reader)
{
_ = new UObject(reader, true);
Map = new Dictionary<string, object>(1)
{
{ "MaxAttenuationRadius", reader.ReadFloat() }
};
}
public object this[string key] => Map[key];
public IEnumerable<string> Keys => Map.Keys;
public IEnumerable<object> Values => Map.Values;
public int Count => Map.Count;
public bool ContainsKey(string key) => Map.ContainsKey(key);
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => Map.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Map.GetEnumerator();
public bool TryGetValue(string key, out object value) => Map.TryGetValue(key, out value);
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
@@ -74,20 +73,5 @@ namespace PakReader.Parsers.Class
return false;
}
public bool TryGetValue(string key, out object value) => Dict.TryGetValue(key, out value);
public T Deserialize<T>()
{
var ret = ReflectionHelper.NewInstance<T>();
var map = ReflectionHelper.GetActionMap<T>();
foreach (var kv in Dict)
{
(var baseType, var typeGetter) = ReflectionHelper.GetPropertyInfo(kv.Value.GetType());
if (map.TryGetValue((kv.Key.ToLowerInvariant(), baseType), out Action<object, object> setter))
{
setter(ret, typeGetter(kv.Value));
}
}
return ret;
}
}
}

View File

@@ -32,7 +32,7 @@ namespace PakReader.Parsers.Objects
PakFileName = pakName;
string name = caseSensitive ? reader.ReadFString() : reader.ReadFString().ToLowerInvariant();
Name = name.StartsWith("/") ? name.Substring(1) : name;
Name = name.StartsWith("/") ? name[1..] : name;
var StartOffset = reader.BaseStream.Position;
@@ -229,16 +229,16 @@ namespace PakReader.Parsers.Objects
public FPakEntry Uexp = null;
public FPakEntry Ubulk = null;
public bool IsUE4Package() => Name.Substring(Name.LastIndexOf(".")).Equals(".uasset");
public bool IsLocres() => Name.Substring(Name.LastIndexOf(".")).Equals(".locres");
public bool IsUE4Map() => Name.Substring(Name.LastIndexOf(".")).Equals(".umap");
public bool IsUE4Font() => Name.Substring(Name.LastIndexOf(".")).Equals(".ufont");
public bool IsUE4Package() => Name[Name.LastIndexOf(".")..].Equals(".uasset");
public bool IsLocres() => Name[Name.LastIndexOf(".")..].Equals(".locres");
public bool IsUE4Map() => Name[Name.LastIndexOf(".")..].Equals(".umap");
public bool IsUE4Font() => Name[Name.LastIndexOf(".")..].Equals(".ufont");
public bool HasUexp() => Uexp != null;
public bool HasUbulk() => Ubulk != null;
public bool IsCompressed() => UncompressedSize != Size || CompressionMethodIndex != (int)ECompressionFlags.COMPRESS_None;
public string GetExtension() => Name.Substring(Name.LastIndexOf("."));
public string GetExtension() => Name[Name.LastIndexOf(".")..];
public string GetPathWithoutFile()
{
int stop = Name.LastIndexOf("/");

View File

@@ -75,7 +75,7 @@ namespace PakReader.Parsers
public override bool CanRead => throw new NotImplementedException();
public override bool CanSeek => throw new NotImplementedException();
public override bool CanWrite => throw new NotImplementedException();
public override long Length => throw new NotImplementedException();
public override long Length => _baseStream.Length;
public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
}
}

View File

@@ -57,6 +57,7 @@ namespace PakReader.Parsers
"FontFace" => new UFontFace(this, ubulk),
"SoundWave" => new USoundWave(this, ubulk, ExportMap.Sum(e => e.SerialSize) + PackageFileSummary.TotalHeaderSize),
"StringTable" => new UStringTable(this),
"AkAudioEvent" => new UAkAudioEvent(this),
_ => new UObject(this),
};

View File

@@ -2184,6 +2184,16 @@ namespace FModel.Properties {
}
}
/// <summary>
/// Recherche une ressource localisée de type System.Drawing.Bitmap.
/// </summary>
public static System.Drawing.Bitmap rotate_3d {
get {
object obj = ResourceManager.GetObject("rotate_3d", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Recherche une chaîne localisée semblable à Russian.
/// </summary>

View File

@@ -1081,4 +1081,7 @@ It's now the most used free software to leak on Fortnite.</value>
<data name="SkipThisVersion" xml:space="preserve">
<value>Skip this Version</value>
</data>
<data name="rotate_3d" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\rotate-3d.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -342,9 +342,9 @@ namespace FModel.Utils
public static void Filter(string filter, string item, out bool bSearch)
{
if (filter.StartsWith("!="))
bSearch = item.IndexOf(filter.Substring(2), StringComparison.CurrentCultureIgnoreCase) < 0;
bSearch = item.IndexOf(filter[2..], StringComparison.CurrentCultureIgnoreCase) < 0;
else if (filter.StartsWith("=="))
bSearch = item.IndexOf(filter.Substring(2), StringComparison.CurrentCulture) >= 0;
bSearch = item.IndexOf(filter[2..], StringComparison.CurrentCulture) >= 0;
else
bSearch = item.IndexOf(filter, StringComparison.CurrentCultureIgnoreCase) >= 0;
}
@@ -367,7 +367,7 @@ namespace FModel.Utils
if (data[i] == null)
continue;
string basePath = Properties.Settings.Default.OutputPath + "\\Exports\\" + mount.Substring(1);
string basePath = Properties.Settings.Default.OutputPath + "\\Exports\\" + mount[1..];
string fullPath = basePath + Path.ChangeExtension(entry.Name, ext[i]);
string name = Path.GetFileName(fullPath);
Directory.CreateDirectory(basePath + entry.GetPathWithoutFile());
@@ -394,7 +394,7 @@ namespace FModel.Utils
{
if (Globals.CachedPakFiles.TryGetValue(entry.PakFileName, out var r))
{
string basePath = Properties.Settings.Default.OutputPath + "\\Exports\\" + r.MountPoint.Substring(1);
string basePath = Properties.Settings.Default.OutputPath + "\\Exports\\" + r.MountPoint[1..];
string fullPath = basePath + entry.Name;
string name = Path.GetFileName(fullPath);
Directory.CreateDirectory(basePath + entry.GetPathWithoutFile());
@@ -440,7 +440,7 @@ namespace FModel.Utils
{
if (Globals.CachedPakFiles.TryGetValue(entry.PakFileName, out var r))
{
string toCopy = r.MountPoint.Substring(1);
string toCopy = r.MountPoint[1..];
if (mode == ECopy.Path)
toCopy += entry.Name;
else if (mode == ECopy.PathNoExt)

View File

@@ -80,7 +80,7 @@ namespace FModel.Utils
lzmaEncoder.Code(input, output, -1, -1, prg);
}
public static void Decompress(Stream input, Stream output, Action<long, long>? onProgress = null)
public static void Decompress(Stream input, Stream output, Action<long, long> onProgress = null)
{
var decoder = new Decoder();