mirror of
https://github.com/4sval/FModel.git
synced 2026-04-17 06:56:46 -05:00
added "deleted cosmetics" support for valorant + fixed egl2
This commit is contained in:
parent
088d558aad
commit
9e60c55337
30
FModel/Creator/BaseValorant.cs
Normal file
30
FModel/Creator/BaseValorant.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using PakReader.Parsers.Class;
|
||||
using PakReader.Parsers.PropertyTagData;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace FModel.Creator
|
||||
{
|
||||
public class BaseValorant
|
||||
{
|
||||
public SKBitmap FallbackImage;
|
||||
public SKBitmap IconImage;
|
||||
public string DisplayName;
|
||||
public string Description;
|
||||
public int Size = 512; // keep it 512 (or a multiple of 512) if you don't want blurry icons
|
||||
|
||||
public BaseValorant()
|
||||
{
|
||||
FallbackImage = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_Placeholder_Item_Image.png")).Stream);
|
||||
IconImage = FallbackImage;
|
||||
DisplayName = "";
|
||||
Description = "";
|
||||
}
|
||||
|
||||
public BaseValorant(IUExport export, string assetFolder, ref string assetName) : this()
|
||||
{
|
||||
//if (export.GetExport<ArrayProperty>("ExplicitAssets") is ArrayProperty explicitAssets)
|
||||
}
|
||||
}
|
||||
}
|
||||
10
FModel/Creator/Characters/PrimaryAsset.cs
Normal file
10
FModel/Creator/Characters/PrimaryAsset.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace FModel.Creator.Characters
|
||||
{
|
||||
class PrimaryAsset
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ using FModel.ViewModels.ImageBox;
|
|||
using PakReader.Parsers.Class;
|
||||
using SkiaSharp;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace FModel.Creator
|
||||
{
|
||||
|
|
@ -201,5 +202,27 @@ namespace FModel.Creator
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool TryDrawValorantIcon(string assetPath, string exportType, IUExport export)
|
||||
{
|
||||
var d = new DirectoryInfo(assetPath);
|
||||
string assetName = d.Name;
|
||||
string assetFolder = d.Parent.Name;
|
||||
|
||||
//if (Regex.Match(exportType, $"{assetName.Substring(0, assetName.LastIndexOf("."))}_C", RegexOptions.IgnoreCase).Success)
|
||||
//{
|
||||
// BaseValorant icon = new BaseValorant(export, assetFolder, ref assetName);
|
||||
// using (var ret = new SKBitmap(icon.Size, icon.Size, SKColorType.Rgba8888, SKAlphaType.Premul))
|
||||
// using (var c = new SKCanvas(ret))
|
||||
// {
|
||||
|
||||
|
||||
// Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
|
||||
// ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,56 +46,59 @@ namespace FModel.Creator.Texts
|
|||
|
||||
public Typefaces()
|
||||
{
|
||||
DefaultTypeface = SKTypeface.FromStream(Application.GetResourceStream(_BURBANK_BIG_CONDENSED_BOLD).Stream);
|
||||
|
||||
ArraySegment<byte>[] t = Utils.GetPropertyArraySegmentByte(_BASE_PATH + _BURBANK_BIG_CONDENSED_BLACK);
|
||||
if (t != null && t.Length == 3)
|
||||
BundleDefaultTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
else BundleDefaultTypeface = DefaultTypeface;
|
||||
|
||||
string namePath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _ASIA_ERINM :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Russian ? _BURBANK_BIG_CONDENSED_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NIS_JYAU :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_TC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_SC_BLACK :
|
||||
string.Empty);
|
||||
if (!namePath.Equals(_BASE_PATH))
|
||||
if (Globals.Game.ActualGame == EGame.Fortnite)
|
||||
{
|
||||
t = Utils.GetPropertyArraySegmentByte(namePath);
|
||||
if (t != null && t.Length == 3)
|
||||
DisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
}
|
||||
else DisplayNameTypeface = DefaultTypeface;
|
||||
DefaultTypeface = SKTypeface.FromStream(Application.GetResourceStream(_BURBANK_BIG_CONDENSED_BOLD).Stream);
|
||||
|
||||
string descriptionPath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _NOTO_SANS_KR_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NOTO_SANS_JP_BOLD :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_TC_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_SC_REGULAR :
|
||||
_NOTO_SANS_REGULAR);
|
||||
t = Utils.GetPropertyArraySegmentByte(descriptionPath);
|
||||
if (t != null && t.Length == 3)
|
||||
DescriptionTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
else DescriptionTypeface = DefaultTypeface;
|
||||
|
||||
string bundleNamePath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _ASIA_ERINM :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Russian ? _BURBANK_BIG_CONDENSED_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NIS_JYAU :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_TC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_SC_BLACK :
|
||||
string.Empty);
|
||||
if (!bundleNamePath.Equals(_BASE_PATH))
|
||||
{
|
||||
t = Utils.GetPropertyArraySegmentByte(bundleNamePath);
|
||||
ArraySegment<byte>[] t = Utils.GetPropertyArraySegmentByte(_BASE_PATH + _BURBANK_BIG_CONDENSED_BLACK);
|
||||
if (t != null && t.Length == 3)
|
||||
BundleDisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
BundleDefaultTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
else BundleDefaultTypeface = DefaultTypeface;
|
||||
|
||||
string namePath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _ASIA_ERINM :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Russian ? _BURBANK_BIG_CONDENSED_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NIS_JYAU :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_TC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_SC_BLACK :
|
||||
string.Empty);
|
||||
if (!namePath.Equals(_BASE_PATH))
|
||||
{
|
||||
t = Utils.GetPropertyArraySegmentByte(namePath);
|
||||
if (t != null && t.Length == 3)
|
||||
DisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
}
|
||||
else DisplayNameTypeface = DefaultTypeface;
|
||||
|
||||
string descriptionPath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _NOTO_SANS_KR_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NOTO_SANS_JP_BOLD :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_TC_REGULAR :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_SC_REGULAR :
|
||||
_NOTO_SANS_REGULAR);
|
||||
t = Utils.GetPropertyArraySegmentByte(descriptionPath);
|
||||
if (t != null && t.Length == 3)
|
||||
DescriptionTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
else DescriptionTypeface = DefaultTypeface;
|
||||
|
||||
string bundleNamePath = _BASE_PATH + (
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _ASIA_ERINM :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Russian ? _BURBANK_BIG_CONDENSED_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NIS_JYAU :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_TC_BLACK :
|
||||
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_SC_BLACK :
|
||||
string.Empty);
|
||||
if (!bundleNamePath.Equals(_BASE_PATH))
|
||||
{
|
||||
t = Utils.GetPropertyArraySegmentByte(bundleNamePath);
|
||||
if (t != null && t.Length == 3)
|
||||
BundleDisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
|
||||
}
|
||||
else BundleDisplayNameTypeface = BundleDefaultTypeface;
|
||||
}
|
||||
else BundleDisplayNameTypeface = BundleDefaultTypeface;
|
||||
}
|
||||
|
||||
public bool NeedReload(bool forceReload) => forceReload ?
|
||||
|
|
|
|||
|
|
@ -23,12 +23,15 @@ namespace FModel.Grabber.Paks
|
|||
{
|
||||
if (string.IsNullOrEmpty(Properties.Settings.Default.PakPath))
|
||||
{
|
||||
var launcher = new FLauncher();
|
||||
if ((bool)launcher.ShowDialog())
|
||||
Application.Current.Dispatcher.Invoke(delegate
|
||||
{
|
||||
Properties.Settings.Default.PakPath = launcher.Path;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
var launcher = new FLauncher();
|
||||
if ((bool)launcher.ShowDialog())
|
||||
{
|
||||
Properties.Settings.Default.PakPath = launcher.Path;
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// define the current game thank to the pak path
|
||||
|
|
|
|||
|
|
@ -64,8 +64,12 @@ namespace PakReader.Pak
|
|||
}
|
||||
|
||||
public string GetFirstExportType() => ExportTypes[0];
|
||||
public string GetSecondExportType() => ExportTypes.Length > 1 ? ExportTypes[1] : GetFirstExportType();
|
||||
|
||||
public IUExport[] GetAllExports() => Exports;
|
||||
public IUExport GetFirstExport() => Exports[0];
|
||||
public IUExport GetSecondExport() => Exports.Length > 1 ? Exports[1] : GetFirstExport();
|
||||
|
||||
public T GetExport<T>() where T : IUExport
|
||||
{
|
||||
var exports = Exports;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace PakReader.Parsers.Objects
|
|||
internal UScriptStruct(PackageReader reader, FName structName) : this(reader, structName.String) { }
|
||||
internal UScriptStruct(PackageReader reader, string structName)
|
||||
{
|
||||
//System.Diagnostics.Debug.WriteLine(structName);
|
||||
Struct = structName switch
|
||||
{
|
||||
"LevelSequenceObjectReferenceMap" => new FLevelSequenceObjectReferenceMap(reader),
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ namespace PakReader.Parsers
|
|||
ObjectClassName = ImportMap[Export.ClassIndex.AsImport].ObjectName;
|
||||
else
|
||||
throw new FileLoadException("Can't get class name"); // Shouldn't reach this unless the laws of math have bent to MagmaReef's will
|
||||
if (ObjectClassName.String.Equals("BlueprintGeneratedClass")) continue;
|
||||
|
||||
var pos = Position = Export.SerialOffset - PackageFileSummary.TotalHeaderSize;
|
||||
ExportTypes[i] = ObjectClassName.String;
|
||||
|
|
@ -65,7 +66,7 @@ namespace PakReader.Parsers
|
|||
|
||||
if (pos + Export.SerialSize != Position)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[ExportType=${ObjectClassName.String}] Didn't read {Export.ObjectName} correctly (at {Position}, should be {pos + Export.SerialSize}, {pos + Export.SerialSize - Position} behind)");
|
||||
System.Diagnostics.Debug.WriteLine($"[ExportType={ObjectClassName.String}] Didn't read {Export.ObjectName} correctly (at {Position}, should be {pos + Export.SerialSize}, {pos + Export.SerialSize - Position} behind)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,7 +239,9 @@ namespace FModel.Utils
|
|||
}
|
||||
|
||||
// Creator Image
|
||||
if (TryDrawIcon(entry.Name, p.GetFirstExportType(), p.GetFirstExport()))
|
||||
if (Globals.Game.ActualGame == EGame.Valorant && TryDrawValorantIcon(entry.Name, p.GetSecondExportType(), p.GetSecondExport()))
|
||||
return p;
|
||||
else if (TryDrawIcon(entry.Name, p.GetFirstExportType(), p.GetFirstExport()))
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ namespace FModel.Utils
|
|||
|
||||
int stringLength = reader.ReadUInt16BE();
|
||||
string cacheDirectory = Encoding.UTF8.GetString(reader.ReadBytes(stringLength));
|
||||
if (Directory.Exists(cacheDirectory + "\\game\\FortniteGame\\Content\\Paks"))
|
||||
if (Directory.Exists(cacheDirectory + "\\fn\\FortniteGame\\Content\\Paks"))
|
||||
{
|
||||
return cacheDirectory + "\\game\\FortniteGame\\Content\\Paks";
|
||||
return cacheDirectory + "\\fn\\FortniteGame\\Content\\Paks";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ using FModel.Windows.CustomNotifier;
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace FModel.Utils
|
||||
{
|
||||
|
|
@ -105,5 +106,34 @@ namespace FModel.Utils
|
|||
if (bSave)
|
||||
Properties.Settings.Default.Save();
|
||||
}
|
||||
|
||||
public static string GetUniqueFilePath(string filePath)
|
||||
{
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
string folderPath = Path.GetDirectoryName(filePath);
|
||||
string fileName = Path.GetFileNameWithoutExtension(filePath);
|
||||
string fileExtension = Path.GetExtension(filePath);
|
||||
int number = 1;
|
||||
|
||||
Match regex = Regex.Match(fileName, @"^(.+) \((\d+)\)$");
|
||||
|
||||
if (regex.Success)
|
||||
{
|
||||
fileName = regex.Groups[1].Value;
|
||||
number = int.Parse(regex.Groups[2].Value);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
number++;
|
||||
string newFileName = $"{fileName} ({number}){fileExtension}";
|
||||
filePath = Path.Combine(folderPath, newFileName);
|
||||
}
|
||||
while (File.Exists(filePath));
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,12 +48,12 @@ namespace FModel.ViewModels.AvalonEdit
|
|||
{
|
||||
if (autoSave)
|
||||
{
|
||||
string path = Properties.Settings.Default.OutputPath + "\\JSONs\\" + Path.ChangeExtension(vm.OwerName, ".json");
|
||||
string path = Folders.GetUniqueFilePath(Properties.Settings.Default.OutputPath + "\\JSONs\\" + Path.ChangeExtension(vm.OwerName, ".json"));
|
||||
File.WriteAllText(path, vm.Document.Text);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[AvalonEditViewModel]", $"{vm.OwerName} successfully saved");
|
||||
FConsole.AppendText(string.Format(Properties.Resources.SaveSuccess, Path.ChangeExtension(vm.OwerName, ".json")), FColors.Green, true);
|
||||
FConsole.AppendText(string.Format(Properties.Resources.SaveSuccess, Path.GetFileName(path)), FColors.Green, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -322,7 +322,15 @@ namespace FModel.ViewModels.MenuItem
|
|||
break;
|
||||
}
|
||||
|
||||
var deleted = oldFiles.Where(kvp => !newFiles.TryGetValue(kvp.Key, out var _) && kvp.Key.StartsWith("/FortniteGame/Content/Athena/Items/Cosmetics/")).ToDictionary(x => x.Key, x => x.Value);
|
||||
string cosmeticsPath;
|
||||
if (Globals.Game.ActualGame == EGame.Fortnite)
|
||||
cosmeticsPath = $"/{Folders.GetGameName()}/Content/Athena/Items/Cosmetics/";
|
||||
else if (Globals.Game.ActualGame == EGame.Valorant)
|
||||
cosmeticsPath = $"/{Folders.GetGameName()}/Content/Labels/";
|
||||
else
|
||||
cosmeticsPath = "/gqdozqhndpioqgnq/"; // just corrupting it so it doesn't trigger all assets
|
||||
|
||||
var deleted = oldFiles.Where(kvp => !newFiles.TryGetValue(kvp.Key, out var _) && kvp.Key.StartsWith(cosmeticsPath)).ToDictionary(x => x.Key, x => x.Value);
|
||||
if (deleted.Count > 0)
|
||||
{
|
||||
FConsole.AppendText(Properties.Resources.RemovedRenamedCosmetics, FColors.Red, true);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user