mirror of
https://github.com/4sval/FModel.git
synced 2026-04-18 23:57:42 -05:00
commit
e5d7315d41
|
|
@ -1 +1 @@
|
|||
Subproject commit adb0529c1770d41c84fa73f47ad918cd7d5ece4c
|
||||
Subproject commit 70d417009d729260486d905eb5d10f45c78cfec7
|
||||
|
|
@ -52,7 +52,7 @@ namespace FModel
|
|||
Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, ".data"));
|
||||
|
||||
Log.Logger = new LoggerConfiguration().WriteTo.Console(theme: AnsiConsoleTheme.Literate).WriteTo.File(
|
||||
path: Path.Combine(UserSettings.Default.OutputDirectory, "Logs", $"FModel-Log-{DateTime.Now:yyyy-MM-dd}.txt"),
|
||||
Path.Combine(UserSettings.Default.OutputDirectory, "Logs", $"FModel-Log-{DateTime.Now:yyyy-MM-dd}.txt"),
|
||||
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [FModel] [{Level:u3}] {Message:lj}{NewLine}{Exception}").CreateLogger();
|
||||
|
||||
Log.Information("Version {Version}", Constants.APP_VERSION);
|
||||
|
|
@ -80,6 +80,7 @@ namespace FModel
|
|||
Icon = MessageBoxImage.Error,
|
||||
Buttons = new[]
|
||||
{
|
||||
MessageBoxButtons.Custom("Reset Settings", EErrorKind.ResetSettings),
|
||||
MessageBoxButtons.Custom("Restart", EErrorKind.Restart),
|
||||
MessageBoxButtons.Custom("OK", EErrorKind.Ignore)
|
||||
},
|
||||
|
|
@ -89,6 +90,9 @@ namespace FModel
|
|||
MessageBox.Show(messageBox);
|
||||
if (messageBox.Result == MessageBoxResult.Custom && (EErrorKind) messageBox.ButtonPressed.Id != EErrorKind.Ignore)
|
||||
{
|
||||
if ((EErrorKind) messageBox.ButtonPressed.Id == EErrorKind.ResetSettings)
|
||||
UserSettings.Delete();
|
||||
|
||||
ApplicationService.ApplicationView.Restart();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ namespace FModel.Creator.Bases.BB
|
|||
|
||||
public override void ParseForInfo()
|
||||
{
|
||||
if (Object.TryGetValue(out FSoftObjectPath iconTextureAssetData, "IconTextureAssetData"))
|
||||
if (Object.TryGetValue(out FSoftObjectPath iconTextureAssetData, "IconTextureAssetData", "UnlockPortraitGuideImage"))
|
||||
Preview = Utils.GetBitmap(iconTextureAssetData);
|
||||
|
||||
if (Object.TryGetValue(out FText displayName, "DisplayName"))
|
||||
if (Object.TryGetValue(out FText displayName, "DisplayName", "RegionDisplayName", "ZoneName"))
|
||||
DisplayName = displayName.Text;
|
||||
if (Object.TryGetValue(out FText description, "Description"))
|
||||
if (Object.TryGetValue(out FText description, "Description", "RegionShortName", "ZoneDescription"))
|
||||
Description = description.Text;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,18 +46,32 @@ namespace FModel.Creator.Bases.FN
|
|||
Preview = Utils.GetBitmap(s);
|
||||
else if (Object.TryGetValue(out FPackageIndex otherPreview, "SmallPreviewImage", "ToastIcon", "access_item"))
|
||||
Preview = Utils.GetBitmap(otherPreview);
|
||||
else if (Object.TryGetValue(out UMaterialInstanceConstant materialInstancePreview, "EventCalloutImage"))
|
||||
Preview = Utils.GetBitmap(materialInstancePreview);
|
||||
else if (Object.TryGetValue(out FStructFallback brush, "IconBrush") && brush.TryGetValue(out UTexture2D res, "ResourceObject"))
|
||||
Preview = Utils.GetBitmap(res);
|
||||
|
||||
// text
|
||||
if (Object.TryGetValue(out FText displayName, "DisplayName", "DefaultHeaderText", "UIDisplayName", "EntryName"))
|
||||
if (Object.TryGetValue(out FText displayName, "DisplayName", "DefaultHeaderText", "UIDisplayName", "EntryName", "EventCalloutTitle"))
|
||||
DisplayName = displayName.Text;
|
||||
if (Object.TryGetValue(out FText description, "Description", "GeneralDescription", "DefaultBodyText", "UIDescription", "UIDisplayDescription", "EntryDescription"))
|
||||
if (Object.TryGetValue(out FText description, "Description", "GeneralDescription", "DefaultBodyText", "UIDescription", "UIDisplayDescription", "EntryDescription", "EventCalloutDescription"))
|
||||
Description = description.Text;
|
||||
else if (Object.TryGetValue(out FText[] descriptions, "Description"))
|
||||
Description = string.Join('\n', descriptions.Select(x => x.Text));
|
||||
if (Object.TryGetValue(out FText shortDescription, "ShortDescription", "UIDisplaySubName"))
|
||||
ShortDescription = shortDescription.Text;
|
||||
else if (Object.ExportType.Equals("AthenaItemWrapDefinition", StringComparison.OrdinalIgnoreCase))
|
||||
ShortDescription = "Wrap";
|
||||
ShortDescription = Utils.GetLocalizedResource("Fort.Cosmetics", "ItemWrapShortDescription", "Wrap");
|
||||
|
||||
// Only works on non-cataba designs
|
||||
if (Object.TryGetValue(out FStructFallback eventArrowColor, "EventArrowColor") &&
|
||||
eventArrowColor.TryGetValue(out FLinearColor specifiedArrowColor, "SpecifiedColor") &&
|
||||
Object.TryGetValue(out FStructFallback eventArrowShadowColor, "EventArrowShadowColor") &&
|
||||
eventArrowShadowColor.TryGetValue(out FLinearColor specifiedShadowColor, "SpecifiedColor"))
|
||||
{
|
||||
Background = new[] {SKColor.Parse(specifiedArrowColor.Hex), SKColor.Parse(specifiedShadowColor.Hex)};
|
||||
Border = new[] {SKColor.Parse(specifiedShadowColor.Hex), SKColor.Parse(specifiedArrowColor.Hex)};
|
||||
}
|
||||
|
||||
Description = Utils.RemoveHtmlTags(Description);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ namespace FModel.Creator.Bases.FN
|
|||
|
||||
public override void ParseForInfo()
|
||||
{
|
||||
if (!(Object is UMaterialInstanceConstant material)) return;
|
||||
if (Object is not UMaterialInstanceConstant material) return;
|
||||
|
||||
foreach (var textureParameter in material.TextureParameterValues) // get texture from base material
|
||||
{
|
||||
if (!(textureParameter.ParameterValue is UTexture2D texture) || Preview != null) continue;
|
||||
if (textureParameter.ParameterValue is not UTexture2D texture || Preview != null) continue;
|
||||
switch (textureParameter.ParameterInfo.Name.Text)
|
||||
{
|
||||
case "SeriesTexture":
|
||||
|
|
|
|||
50
FModel/Creator/Bases/SB/BaseGameModeInfo.cs
Normal file
50
FModel/Creator/Bases/SB/BaseGameModeInfo.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
using CUE4Parse.UE4.Assets.Exports;
|
||||
using CUE4Parse.UE4.Assets.Exports.Material;
|
||||
using CUE4Parse.UE4.Assets.Exports.Texture;
|
||||
using CUE4Parse.UE4.Objects.Core.i18N;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace FModel.Creator.Bases.SB
|
||||
{
|
||||
public class BaseGameModeInfo : UCreator
|
||||
{
|
||||
private SKBitmap _icon;
|
||||
|
||||
public BaseGameModeInfo(UObject uObject, EIconStyle style) : base(uObject, style)
|
||||
{
|
||||
Width = 738;
|
||||
Height = 1024;
|
||||
}
|
||||
|
||||
public override void ParseForInfo()
|
||||
{
|
||||
if (Object.TryGetValue(out FText displayName, "DisplayName"))
|
||||
DisplayName = displayName.Text;
|
||||
if (Object.TryGetValue(out FText description, "Description"))
|
||||
Description = description.Text;
|
||||
if (Object.TryGetValue(out UMaterialInstanceConstant portrait, "Portrait"))
|
||||
Preview = Utils.GetBitmap(portrait);
|
||||
if (Object.TryGetValue(out UTexture2D icon, "Icon"))
|
||||
_icon = Utils.GetBitmap(icon).Resize(25);
|
||||
}
|
||||
|
||||
public override SKImage Draw()
|
||||
{
|
||||
using var ret = new SKBitmap(Width, Height, SKColorType.Rgba8888, SKAlphaType.Premul);
|
||||
using var c = new SKCanvas(ret);
|
||||
|
||||
DrawPreview(c);
|
||||
DrawTextBackground(c);
|
||||
DrawDisplayName(c);
|
||||
DrawIcon(c);
|
||||
|
||||
return SKImage.FromBitmap(ret);
|
||||
}
|
||||
|
||||
private void DrawIcon(SKCanvas c)
|
||||
{
|
||||
if (_icon == null) return;
|
||||
c.DrawBitmap(_icon, new SKPoint(5, 5), ImagePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,8 +24,8 @@ namespace FModel.Creator.Bases.SB
|
|||
{
|
||||
Background = new[] {SKColor.Parse("FFFFFF"), SKColor.Parse("636363")};
|
||||
Border = new[] {SKColor.Parse("D0D0D0"), SKColor.Parse("FFFFFF")};
|
||||
Width = Object.ExportType.StartsWith("BP_Cosmetic_Card") ? 1536 : 512;
|
||||
Height = Object.ExportType.StartsWith("BP_Cosmetic_Card") ? 450 : 512;
|
||||
Width = Object.ExportType.StartsWith("GCosmeticCard") ? 1536 : 512;
|
||||
Height = Object.ExportType.StartsWith("GCosmeticCard") ? 450 : 512;
|
||||
}
|
||||
|
||||
public override void ParseForInfo()
|
||||
|
|
@ -33,12 +33,12 @@ namespace FModel.Creator.Bases.SB
|
|||
if (Object.TryGetValue(out FName rarity, "Rarity"))
|
||||
GetRarity(rarity);
|
||||
|
||||
if (Object.TryGetValue(out FSoftObjectPath preview, "IconTexture"))
|
||||
if (Object.TryGetValue(out FSoftObjectPath preview, "IconTexture", "OfferTexture", "PortraitTexture"))
|
||||
Preview = Utils.GetBitmap(preview);
|
||||
else if (Object.TryGetValue(out FPackageIndex icon, "IconTexture"))
|
||||
else if (Object.TryGetValue(out FPackageIndex icon, "IconTexture", "OfferTexture", "PortraitTexture"))
|
||||
Preview = Utils.GetBitmap(icon);
|
||||
|
||||
if (Object.TryGetValue(out FText displayName, "DisplayName", "Title"))
|
||||
if (Object.TryGetValue(out FText displayName, "DisplayName", "Title", "Name"))
|
||||
DisplayName = displayName.Text;
|
||||
if (Object.TryGetValue(out FText description, "Description"))
|
||||
Description = description.Text;
|
||||
|
|
|
|||
|
|
@ -227,4 +227,4 @@ namespace FModel.Creator.Bases
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@ namespace FModel.Creator
|
|||
case "FortCurrencyItemDefinition":
|
||||
case "FortResourceItemDefinition":
|
||||
case "FortBackpackItemDefinition":
|
||||
case "FortEventQuestMapDataAsset":
|
||||
case "FortCodeTokenItemDefinition":
|
||||
case "FortSchematicItemDefinition":
|
||||
case "FortWorldMultiItemDefinition":
|
||||
|
|
@ -163,21 +164,59 @@ namespace FModel.Creator
|
|||
return true;
|
||||
// Battle Breakers
|
||||
case "WExpGenericAccountItemDefinition":
|
||||
case "WExpGearAccountItemDefinition":
|
||||
case "WExpHQWorkerLodgesDefinition":
|
||||
case "WExpPersonalEventDefinition":
|
||||
case "WExpUpgradePotionDefinition":
|
||||
case "WExpAccountRewardDefinition":
|
||||
case "WExpHQBlacksmithDefinition":
|
||||
case "WExpHQSecretShopDefinition":
|
||||
case "WExpHQMonsterPitDefinition":
|
||||
case "WExpHQHeroTowerDefinition":
|
||||
case "WExpVoucherItemDefinition":
|
||||
case "WExpTreasureMapDefinition":
|
||||
case "WExpHammerChestDefinition":
|
||||
case "WExpHQWorkshopDefinition":
|
||||
case "WExpUnlockableDefinition":
|
||||
case "WExpHQSmelterDefinition":
|
||||
case "WExpContainerDefinition":
|
||||
case "WExpCharacterDefinition":
|
||||
case "WExpHQMarketDefinition":
|
||||
case "WExpGiftboxDefinition":
|
||||
case "WExpStandInDefinition":
|
||||
case "WExpRegionDefinition":
|
||||
case "WExpHQMineDefinition":
|
||||
case "WExpXpBookDefinition":
|
||||
case "WExpTokenDefinition":
|
||||
case "WExpItemDefinition":
|
||||
case "WExpZoneDefinition":
|
||||
creator = new BaseBreakersIcon(_object, EIconStyle.Default);
|
||||
return true;
|
||||
// Spellbreak
|
||||
case "GQuest":
|
||||
case "GAccolade":
|
||||
case "GCosmeticCard":
|
||||
case "GCosmeticSkin":
|
||||
case "GTargetedTeleportActiveSkill":
|
||||
case "GChronomasterV2ActiveSkill":
|
||||
case "GShadowstepActiveSkill":
|
||||
case "GGatewayActiveSkill":
|
||||
case "GStealthActiveSkill":
|
||||
case "GFeatherActiveSkill":
|
||||
case "GCosmeticDropTrail":
|
||||
case "GFlightActiveSkill":
|
||||
case "GCosmeticRunTrail":
|
||||
case "GCosmeticArtifact":
|
||||
case "GCosmeticTriumph":
|
||||
case "GWolfsbloodSkill":
|
||||
case "GDashActiveSkill":
|
||||
case "GCharacterPerk":
|
||||
case "GCosmeticTitle":
|
||||
case "GCosmeticBadge":
|
||||
case "GRMTStoreOffer":
|
||||
case "GCosmeticEmote":
|
||||
case "GCosmeticTriumph":
|
||||
case "GCosmeticRunTrail":
|
||||
case "GCosmeticArtifact":
|
||||
case "GCosmeticDropTrail":
|
||||
case "GCosmeticCard":
|
||||
case "GCosmeticSkin":
|
||||
case "GStoreOffer":
|
||||
case "GAccolade":
|
||||
case "GRuneItem":
|
||||
case "GQuest":
|
||||
creator = new BaseSpellIcon(_object, EIconStyle.Default);
|
||||
return true;
|
||||
case "GLeagueTier":
|
||||
|
|
@ -186,6 +225,10 @@ namespace FModel.Creator
|
|||
case "GLeagueDivision":
|
||||
creator = new BaseDivision(_object, EIconStyle.Default);
|
||||
return true;
|
||||
// TODO: Draw this properly
|
||||
// case "GGameModeInfo":
|
||||
// creator = new BaseGameModeInfo(_object, EIconStyle.Default);
|
||||
// return true;
|
||||
default:
|
||||
creator = null;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,14 @@ namespace FModel.Creator
|
|||
private const string _BURBANK_SMALL_BLACK = "burbanksmall-black";
|
||||
private const string _BURBANK_SMALL_BOLD = "burbanksmall-bold";
|
||||
|
||||
// Spellbreak
|
||||
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";
|
||||
|
||||
// WorldExplorers
|
||||
private const string _BATTLE_BREAKERS_BASE_PATH = "/Game/UMG/Fonts/Faces/";
|
||||
private const string _HEMIHEAD426 = "HemiHead426";
|
||||
|
|
@ -198,7 +206,23 @@ namespace FModel.Creator
|
|||
case FGame.Dungeons:
|
||||
break;
|
||||
case FGame.g3:
|
||||
{
|
||||
if (viewModel.Provider.TrySaveAsset(_SPELLBREAK_BASE_PATH + _QUADRAT_BOLD + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
DisplayName = SKTypeface.FromStream(m);
|
||||
}
|
||||
else DisplayName = Default;
|
||||
|
||||
if (viewModel.Provider.TrySaveAsset(_SPELLBREAK_BASE_PATH + _MONTSERRAT_SEMIBOLD + _EXT, out data))
|
||||
{
|
||||
var m = new MemoryStream(data) {Position = 0};
|
||||
Description = SKTypeface.FromStream(m);
|
||||
}
|
||||
else Description = Default;
|
||||
|
||||
break;
|
||||
}
|
||||
case FGame.StateOfDecay2:
|
||||
break;
|
||||
case FGame.Prospect:
|
||||
|
|
|
|||
|
|
@ -107,12 +107,14 @@ namespace FModel.Creator
|
|||
if (material == null) return null;
|
||||
foreach (var textureParameter in material.TextureParameterValues)
|
||||
{
|
||||
if (!(textureParameter.ParameterValue is UTexture2D texture)) continue;
|
||||
if (textureParameter.ParameterValue is not UTexture2D texture) continue;
|
||||
switch (textureParameter.ParameterInfo.Name.Text)
|
||||
{
|
||||
case "MainTex":
|
||||
case "TextureA":
|
||||
case "TextureB":
|
||||
case "OfferImage":
|
||||
case "KeyArtTexture":
|
||||
{
|
||||
return GetBitmap(texture);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ namespace FModel
|
|||
|
||||
public enum EErrorKind
|
||||
{
|
||||
Close,
|
||||
Ignore,
|
||||
Restart
|
||||
Restart,
|
||||
ResetSettings
|
||||
}
|
||||
|
||||
public enum SettingsOut
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>FModel.ico</ApplicationIcon>
|
||||
<Version>4.0.0</Version>
|
||||
<AssemblyVersion>4.0.0.0</AssemblyVersion>
|
||||
<FileVersion>4.0.0.0</FileVersion>
|
||||
<AssemblyVersion>4.0.0.1</AssemblyVersion>
|
||||
<FileVersion>4.0.0.1</FileVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsPublishable>true</IsPublishable>
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ namespace FModel.Framework
|
|||
|
||||
private void ObserveAll()
|
||||
{
|
||||
foreach (T item in Items)
|
||||
foreach (var item in Items)
|
||||
item.PropertyChanged += ChildPropertyChanged;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ namespace FModel.Settings
|
|||
File.WriteAllText(FilePath, JsonConvert.SerializeObject(Default, Formatting.Indented));
|
||||
}
|
||||
|
||||
public static void Delete()
|
||||
{
|
||||
if (File.Exists(FilePath)) File.Delete(FilePath);
|
||||
}
|
||||
|
||||
private string _outputDirectory;
|
||||
public string OutputDirectory
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FModel.ViewModels.ApiEndpoints.Models;
|
||||
|
|
@ -16,7 +15,7 @@ namespace FModel.ViewModels.ApiEndpoints
|
|||
|
||||
public async Task<AesResponse> GetAesKeysAsync(CancellationToken token)
|
||||
{
|
||||
var request = new RestRequest("https://benbotfn.tk/api/v2/aes", Method.GET)
|
||||
var request = new RestRequest("https://benbot.app/api/v2/aes", Method.GET)
|
||||
{
|
||||
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
|
||||
};
|
||||
|
|
@ -32,7 +31,7 @@ namespace FModel.ViewModels.ApiEndpoints
|
|||
|
||||
public async Task<MappingsResponse[]> GetMappingsAsync(CancellationToken token)
|
||||
{
|
||||
var request = new RestRequest("https://benbotfn.tk/api/v1/mappings", Method.GET)
|
||||
var request = new RestRequest("https://benbot.app/api/v1/mappings", Method.GET)
|
||||
{
|
||||
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -53,17 +53,17 @@ namespace FModel.ViewModels.ApiEndpoints
|
|||
return _infos ?? GetInfosAsync(token, updateMode).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public async Task<Backup[]> GetBackupsAsync(CancellationToken token, FGame game)
|
||||
public async Task<Backup[]> GetBackupsAsync(CancellationToken token, string gameName)
|
||||
{
|
||||
var request = new RestRequest($"https://api.fmodel.app/v1/backups/{game}", Method.GET);
|
||||
var request = new RestRequest($"https://api.fmodel.app/v1/backups/{gameName}", Method.GET);
|
||||
var response = await _client.ExecuteAsync<Backup[]>(request, token).ConfigureAwait(false);
|
||||
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, request.Resource);
|
||||
return response.Data;
|
||||
}
|
||||
|
||||
public Backup[] GetBackups(CancellationToken token, FGame game)
|
||||
public Backup[] GetBackups(CancellationToken token, string gameName)
|
||||
{
|
||||
return _backups ??= GetBackupsAsync(token, game).GetAwaiter().GetResult();
|
||||
return _backups ??= GetBackupsAsync(token, gameName).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public async Task<CommunityDesign> GetDesignAsync(string designName)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ namespace FModel.ViewModels
|
|||
private ThreadWorkerViewModel _threadWorkerView => ApplicationService.ThreadWorkerView;
|
||||
private ApiEndpointViewModel _apiEndpointView => ApplicationService.ApiEndpointView;
|
||||
private ApplicationViewModel _applicationView => ApplicationService.ApplicationView;
|
||||
private readonly FGame _game;
|
||||
private readonly string _gameName;
|
||||
|
||||
private Backup _selectedBackup;
|
||||
public Backup SelectedBackup
|
||||
|
|
@ -35,9 +35,9 @@ namespace FModel.ViewModels
|
|||
public ObservableCollection<Backup> Backups { get; }
|
||||
public ICollectionView BackupsView { get; }
|
||||
|
||||
public BackupManagerViewModel(FGame game)
|
||||
public BackupManagerViewModel(string gameName)
|
||||
{
|
||||
_game = game;
|
||||
_gameName = gameName;
|
||||
Backups = new ObservableCollection<Backup>();
|
||||
BackupsView = new ListCollectionView(Backups) {SortDescriptions = {new SortDescription("FileName", ListSortDirection.Ascending)}};
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ namespace FModel.ViewModels
|
|||
{
|
||||
await _threadWorkerView.Begin(cancellationToken =>
|
||||
{
|
||||
var backups = _apiEndpointView.FModelApi.GetBackups(cancellationToken, _game);
|
||||
var backups = _apiEndpointView.FModelApi.GetBackups(cancellationToken, _gameName);
|
||||
if (backups == null) return;
|
||||
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
|
|
@ -62,7 +62,7 @@ namespace FModel.ViewModels
|
|||
await _threadWorkerView.Begin(_ =>
|
||||
{
|
||||
var backupFolder = Path.Combine(UserSettings.Default.OutputDirectory, "Backups");
|
||||
var fileName = $"{_game}_{DateTime.Now:MMddyyyy}.fbkp";
|
||||
var fileName = $"{_gameName}_{DateTime.Now:MMddyyyy}.fbkp";
|
||||
var fullPath = Path.Combine(backupFolder, fileName);
|
||||
|
||||
using var fileStream = new FileStream(fullPath, FileMode.Create);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ using CUE4Parse.UE4.Assets.Exports.Sound;
|
|||
using CUE4Parse.UE4.Assets.Exports.Texture;
|
||||
using CUE4Parse.UE4.Assets.Exports.Wwise;
|
||||
using CUE4Parse.UE4.Localization;
|
||||
using CUE4Parse.UE4.Oodle.Objects;
|
||||
using CUE4Parse.UE4.Wwise;
|
||||
using CUE4Parse_Conversion.Materials;
|
||||
using CUE4Parse_Conversion.Sounds;
|
||||
|
|
@ -460,6 +461,17 @@ namespace FModel.ViewModels
|
|||
|
||||
break;
|
||||
}
|
||||
case "udic":
|
||||
{
|
||||
TabControl.SelectedTab.Image = null;
|
||||
if (Provider.TryCreateReader(fullPath, out var archive))
|
||||
{
|
||||
var header = new FDictionaryHeader(archive);
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(header, Formatting.Indented), bulkSave);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case "png":
|
||||
case "jpg":
|
||||
{
|
||||
|
|
@ -475,7 +487,6 @@ namespace FModel.ViewModels
|
|||
FLogger.AppendWarning();
|
||||
FLogger.AppendText($"Export '{fullPath.SubstringAfterLast('/')}' and change its extension if you want it to be an installable font file", Constants.WHITE, true);
|
||||
break;
|
||||
case "udic":
|
||||
case "ushaderbytecode":
|
||||
TabControl.SelectedTab.Image = null;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ namespace FModel.ViewModels.Commands
|
|||
|
||||
public override void Execute(CustomDirectoriesViewModel contextViewModel, object parameter)
|
||||
{
|
||||
if (parameter is not CustomDirectory customDir) return;
|
||||
if (parameter is not CustomDirectory customDir)
|
||||
customDir = new CustomDirectory();
|
||||
|
||||
Helper.OpenWindow<AdonisWindow>("Custom Directory", () =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ namespace FModel.ViewModels.Commands
|
|||
Helper.OpenWindow<AdonisWindow>("AES Manager", () => new AesManager().Show());
|
||||
break;
|
||||
case "Directory_Backup":
|
||||
Helper.OpenWindow<AdonisWindow>("Backup Manager", () => new BackupManager(contextViewModel.CUE4Parse.Game).Show());
|
||||
Helper.OpenWindow<AdonisWindow>("Backup Manager", () => new BackupManager(contextViewModel.CUE4Parse.Provider.GameName).Show());
|
||||
break;
|
||||
case "Views_AudioPlayer":
|
||||
Helper.OpenWindow<AdonisWindow>("Audio Player", () => new AudioPlayer().Show());
|
||||
|
|
|
|||
|
|
@ -105,8 +105,7 @@ namespace FModel.ViewModels
|
|||
Icon = new Image {Source = new BitmapImage(new Uri("/FModel;component/Resources/add_directory.png", UriKind.Relative))},
|
||||
HorizontalContentAlignment = HorizontalAlignment.Left,
|
||||
VerticalContentAlignment = VerticalAlignment.Center,
|
||||
Command = AddEditDirectoryCommand,
|
||||
CommandParameter = new CustomDirectory()
|
||||
Command = AddEditDirectoryCommand
|
||||
};
|
||||
yield return new Separator();
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,13 @@ namespace FModel.ViewModels
|
|||
get => _showCities;
|
||||
set => SetProperty(ref _showCities, value, nameof(ShowCities));
|
||||
}
|
||||
|
||||
private bool _showLandmarks;
|
||||
public bool ShowLandmarks
|
||||
{
|
||||
get => _showLandmarks;
|
||||
set => SetProperty(ref _showLandmarks, value, nameof(ShowLandmarks));
|
||||
}
|
||||
|
||||
private bool _showPatrolPaths;
|
||||
public bool ShowPatrolPaths
|
||||
|
|
@ -49,6 +56,13 @@ namespace FModel.ViewModels
|
|||
get => _citiesImage;
|
||||
set => SetProperty(ref _citiesImage, value);
|
||||
}
|
||||
|
||||
private BitmapImage _landmarksImage;
|
||||
public BitmapImage LandmarksImage
|
||||
{
|
||||
get => _landmarksImage;
|
||||
set => SetProperty(ref _landmarksImage, value);
|
||||
}
|
||||
|
||||
private BitmapImage _patrolPathImage;
|
||||
public BitmapImage PatrolPathImage
|
||||
|
|
@ -81,6 +95,8 @@ namespace FModel.ViewModels
|
|||
c.DrawBitmap(_mapBitmap, 0, 0);
|
||||
if (ShowCities)
|
||||
c.DrawBitmap(_citiesBitmap, 0, 0);
|
||||
if (ShowLandmarks)
|
||||
c.DrawBitmap(_landmarksBitmap, 0, 0);
|
||||
if (ShowPatrolPaths)
|
||||
c.DrawBitmap(_patrolPathBitmap, 0, 0);
|
||||
|
||||
|
|
@ -98,7 +114,12 @@ namespace FModel.ViewModels
|
|||
{
|
||||
switch (propertyName)
|
||||
{
|
||||
case nameof(ShowCities) when _citiesBitmap == null && _mapBitmap != null:
|
||||
case nameof(ShowCities) when _citiesBitmap == null && _landmarksBitmap == null && _mapBitmap != null:
|
||||
{
|
||||
await LoadCities();
|
||||
break;
|
||||
}
|
||||
case nameof(ShowLandmarks) when _landmarksBitmap == null && _citiesBitmap == null && _mapBitmap != null:
|
||||
{
|
||||
await LoadCities();
|
||||
break;
|
||||
|
|
@ -127,6 +148,7 @@ namespace FModel.ViewModels
|
|||
private const int WorldRadius = 135000;
|
||||
private SKBitmap _mapBitmap;
|
||||
private SKBitmap _citiesBitmap;
|
||||
private SKBitmap _landmarksBitmap;
|
||||
private SKBitmap _patrolPathBitmap;
|
||||
private readonly SKBitmap _pinBitmap =
|
||||
SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/pin.png"))?.Stream);
|
||||
|
|
@ -141,7 +163,7 @@ namespace FModel.ViewModels
|
|||
private readonly SKPaint _pathPaint = new()
|
||||
{
|
||||
IsAntialias = true, FilterQuality = SKFilterQuality.High, IsStroke = true,
|
||||
Style = SKPaintStyle.Stroke, StrokeWidth = 5, Color = SKColors.Red,
|
||||
Style = SKPaintStyle.Stroke, StrokeWidth = 10, Color = SKColors.Red,
|
||||
ImageFilter = SKImageFilter.CreateDropShadow(4, 4, 8, 8, SKColors.Black)
|
||||
};
|
||||
|
||||
|
|
@ -173,27 +195,38 @@ namespace FModel.ViewModels
|
|||
await _threadWorkerView.Begin(_ =>
|
||||
{
|
||||
_citiesBitmap = new SKBitmap(_mapBitmap.Width, _mapBitmap.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
|
||||
using var c = new SKCanvas(_citiesBitmap);
|
||||
_landmarksBitmap = new SKBitmap(_mapBitmap.Width, _mapBitmap.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
|
||||
using var cities = new SKCanvas(_citiesBitmap);
|
||||
using var landmarks = new SKCanvas(_landmarksBitmap);
|
||||
if (Utils.TryLoadObject("FortniteGame/Content/Quests/QuestIndicatorData", out UObject indicatorData) &&
|
||||
indicatorData.TryGetValue(out FStructFallback[] challengeMapPoiData, "ChallengeMapPoiData"))
|
||||
{
|
||||
foreach (var poiData in challengeMapPoiData)
|
||||
{
|
||||
if (!poiData.TryGetValue(out FSoftObjectPath discoveryQuest, "DiscoveryQuest") ||
|
||||
!poiData.TryGetValue(out FText text, "Text") ||
|
||||
!poiData.TryGetValue(out FVector worldLocation, "WorldLocation") ||
|
||||
discoveryQuest.AssetPathName.Text.Contains("Landmarks")) continue;
|
||||
!poiData.TryGetValue(out FText text, "Text") || string.IsNullOrEmpty(text.Text) ||
|
||||
!poiData.TryGetValue(out FVector worldLocation, "WorldLocation")) continue;
|
||||
|
||||
var shaper = new CustomSKShaper(_imagePaint.Typeface);
|
||||
var shapedText = shaper.Shape(text.Text, _imagePaint);
|
||||
|
||||
var vector = GetMapPosition(worldLocation);
|
||||
c.DrawPoint(vector.X, vector.Y, _pathPaint);
|
||||
c.DrawBitmap(_cityPinBitmap, vector.X - 50, vector.Y - 90, _imagePaint);
|
||||
c.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _imagePaint);
|
||||
|
||||
if (discoveryQuest.AssetPathName.Text.Contains("landmarks", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
landmarks.DrawPoint(vector.X, vector.Y, _pathPaint);
|
||||
landmarks.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _imagePaint);
|
||||
}
|
||||
else
|
||||
{
|
||||
cities.DrawPoint(vector.X, vector.Y, _pathPaint);
|
||||
cities.DrawBitmap(_cityPinBitmap, vector.X - 50, vector.Y - 90, _imagePaint);
|
||||
cities.DrawShapedText(shaper, text.Text, vector.X - shapedText.Points[^1].X / 2, vector.Y - 12.5F, _imagePaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CitiesImage = GetImageSource(_citiesBitmap);
|
||||
LandmarksImage = GetImageSource(_landmarksBitmap);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
<TextBlock Text="				" FontSize="25" FontWeight="700" Height="2" Foreground="Transparent" HorizontalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<TextBlock FontSize="12" Foreground="#727272" TextWrapping="Wrap" Margin="0 0 0 30"
|
||||
Text="Maiky ♥, HYPEX ♥, VenomLeaks ♥, JayKey ♥, Fevers ♥, Netu ♥, TheGameVlog ♥, Quentin ♥, Mikey, kyle, Yanteh, Shiina, SexyNutella, Alexander, Jinx, Tector, s0ll, imatrix, LamZykoss, Frenzy Leaks, LlamaLeaks, XTigerHyperX, FunGames, WeLoveFortnite." />
|
||||
Text="Maiky ♥, HYPEX ♥, VenomLeaks ♥, JayKey ♥, Fevers ♥, Netu ♥, TheGameVlog ♥, Quentin ♥, Laggy ♥, s0ll ♥, RazTracker, Mikey, kyle, Yanteh, Shiina, SexyNutella, Alexander, Jinx, Tector, imatrix, LamZykoss, Frenzy Leaks, LlamaLeaks, XTigerHyperX, FunGames, WeLoveFortnite." />
|
||||
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<TextBlock Text="Powered by" FontSize="15" FontWeight="700" Foreground="#9DA3DD" FontStretch="Expanded" />
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ namespace FModel.Views
|
|||
{
|
||||
private readonly BackupManagerViewModel _viewModel;
|
||||
|
||||
public BackupManager(FGame game)
|
||||
public BackupManager(string gameName)
|
||||
{
|
||||
DataContext = _viewModel = new BackupManagerViewModel(game);
|
||||
DataContext = _viewModel = new BackupManagerViewModel(gameName);
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Header" VerticalAlignment="Center" />
|
||||
<TextBox Grid.Row="0" Grid.Column="2" Text="{Binding Header, Mode=TwoWay}" />
|
||||
<TextBox x:Name="WpfSuckMyDick" Grid.Row="0" Grid.Column="2" Text="{Binding Header, Mode=TwoWay}" />
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Directory" VerticalAlignment="Center" />
|
||||
<TextBox Grid.Row="2" Grid.Column="2" Text="{Binding DirectoryPath, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ namespace FModel.Views
|
|||
{
|
||||
DataContext = customDir;
|
||||
InitializeComponent();
|
||||
|
||||
Activate();
|
||||
WpfSuckMyDick.Focus();
|
||||
WpfSuckMyDick.SelectAll();
|
||||
}
|
||||
|
||||
private void OnClick(object sender, RoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -54,11 +54,11 @@
|
|||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Images Per Row" VerticalAlignment="Center" Margin="0 0 10 0" />
|
||||
<Slider x:Name="SizeSlider" Grid.Row="0" Grid.Column="1" TickPlacement="None" AutoToolTipPlacement="BottomRight"
|
||||
IsMoveToPointEnabled="True" Minimum="2" Maximum="20" TickFrequency="1" Thumb.DragCompleted="DrawPreview"/>
|
||||
IsMoveToPointEnabled="True" Minimum="2" Maximum="20" TickFrequency="1" MouseUp="Click_DrawPreview" Thumb.DragCompleted="DrawPreview"/>
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Margin Between Images" VerticalAlignment="Center" Margin="0 0 10 0" />
|
||||
<Slider Grid.Row="2" Grid.Column="1" Value="{Binding ImageMergerMargin, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}"
|
||||
TickPlacement="None" AutoToolTipPlacement="BottomRight" IsMoveToPointEnabled="True" Minimum="0" Maximum="50" TickFrequency="1"
|
||||
Thumb.DragCompleted="DrawPreview" />
|
||||
MouseUp="Click_DrawPreview" Thumb.DragCompleted="DrawPreview" />
|
||||
</Grid>
|
||||
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||
<Button x:Name="AddButton" Content="Add" MinWidth="80" Padding="1,3,1,3" Click="OnImageAdd"/>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.Threading.Tasks;
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media.Imaging;
|
||||
using AdonisUI.Controls;
|
||||
using FModel.Extensions;
|
||||
|
|
@ -30,6 +31,11 @@ namespace FModel.Views
|
|||
if (ImagePreview.Source != null)
|
||||
await DrawPreview().ConfigureAwait(false);
|
||||
}
|
||||
private async void Click_DrawPreview(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (ImagePreview.Source != null)
|
||||
await DrawPreview().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task DrawPreview()
|
||||
{
|
||||
|
|
@ -267,5 +273,6 @@ namespace FModel.Views
|
|||
}
|
||||
|
||||
private void OnCopyImage(object sender, RoutedEventArgs e) => Clipboard.SetImage((BitmapSource) ImagePreview.Source);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,8 @@
|
|||
<StackPanel Grid.Column="0" VerticalAlignment="Center" Margin="50">
|
||||
<CheckBox Content="Show Cities" IsEnabled="{Binding IsReady}" IsChecked="{Binding MapViewer.ShowCities, Mode=TwoWay}"
|
||||
Margin="0 0 0 10" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
|
||||
<CheckBox Content="Show Landmarks" IsEnabled="{Binding IsReady}" IsChecked="{Binding MapViewer.ShowLandmarks, Mode=TwoWay}"
|
||||
Margin="0 0 0 10" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
|
||||
<CheckBox Content="Show Patrol Paths" IsEnabled="{Binding IsReady}" IsChecked="{Binding MapViewer.ShowPatrolPaths, Mode=TwoWay}"
|
||||
Margin="0 0 0 10" Style="{DynamicResource {x:Static adonisUi:Styles.ToggleSwitch}}" />
|
||||
<Button Content="Save Image" IsEnabled="{Binding IsReady}" Click="OnClick" />
|
||||
|
|
@ -43,6 +45,8 @@
|
|||
Visibility="{Binding IsReady, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<Image UseLayoutRounding="True" Source="{Binding MapViewer.CitiesImage}" HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Visibility="{Binding MapViewer.ShowCities, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<Image UseLayoutRounding="True" Source="{Binding MapViewer.LandmarksImage}" HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Visibility="{Binding MapViewer.ShowLandmarks, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<Image UseLayoutRounding="True" Source="{Binding MapViewer.PatrolPathImage}" HorizontalAlignment="Right" VerticalAlignment="Center"
|
||||
Visibility="{Binding MapViewer.ShowPatrolPaths, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user