mirror of
https://github.com/4sval/FModel.git
synced 2026-03-24 18:54:42 -05:00
Merge pull request #401 from 4sval/feature/settingsv2
feature/settingsv2
This commit is contained in:
commit
b337ab7abd
|
|
@ -1 +1 @@
|
|||
Subproject commit 2666e11af8aa93222a07ac8513f5257af51304ce
|
||||
Subproject commit 91354a050d10aa7bc8e2e8a5cc0a839406929758
|
||||
|
|
@ -41,6 +41,8 @@ public partial class App
|
|||
{
|
||||
UserSettings.Default = JsonConvert.DeserializeObject<UserSettings>(
|
||||
File.ReadAllText(UserSettings.FilePath), JsonNetSerializer.SerializerSettings);
|
||||
|
||||
/*if (UserSettings.Default.ShowChangelog) */MigrateV1Games();
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
@ -141,6 +143,17 @@ public partial class App
|
|||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void MigrateV1Games()
|
||||
{
|
||||
foreach ((var gameDir, var setting) in UserSettings.Default.ManualGames)
|
||||
{
|
||||
if (!Directory.Exists(gameDir)) continue;
|
||||
UserSettings.Default.PerDirectory[gameDir] =
|
||||
DirectorySettings.Default(setting.GameName, setting.GameDirectory, true, setting.OverridedGame, setting.AesKeys?.MainKey);
|
||||
}
|
||||
UserSettings.Default.ManualGames.Clear();
|
||||
}
|
||||
|
||||
private string GetOperatingSystemProductName()
|
||||
{
|
||||
var productName = string.Empty;
|
||||
|
|
|
|||
|
|
@ -203,69 +203,6 @@ public class CreatorPackage : IDisposable
|
|||
case "QuestData":
|
||||
creator = new Bases.MV.BaseQuest(_object, _style);
|
||||
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 "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 "GCosmeticCard":
|
||||
case "GCosmeticSkin":
|
||||
case "GStoreOffer":
|
||||
case "GAccolade":
|
||||
case "GRuneItem":
|
||||
case "GQuest":
|
||||
creator = new BaseSpellIcon(_object, EIconStyle.Default);
|
||||
return true;
|
||||
case "GLeagueTier":
|
||||
creator = new BaseLeague(_object, EIconStyle.Default);
|
||||
return true;
|
||||
case "GLeagueDivision":
|
||||
creator = new BaseDivision(_object, EIconStyle.Default);
|
||||
return true;
|
||||
default:
|
||||
creator = null;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -49,23 +49,6 @@ public class Typefaces
|
|||
private const string _XIANGHEHEI_SC_PRO_BLACK = "XiangHeHei_SC/MXiangHeHeiSCPro-Black";
|
||||
private const string _XIANGHEHEI_SC_PRO_HEAVY = "XiangHeHei_SC/MXiangHeHeiSCPro-Heavy";
|
||||
|
||||
// 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";
|
||||
private const string _NOTO_SANS_JP_REGULAR = "NotoSansJP-Regular";
|
||||
private const string _LATO_BLACK = "Lato-Black";
|
||||
private const string _LATO_BLACK_ITALIC = "Lato-BlackItalic";
|
||||
private const string _LATO_LIGHT = "Lato-Light";
|
||||
private const string _LATO_MEDIUM = "Lato-Medium";
|
||||
|
||||
private readonly CUE4ParseViewModel _viewModel;
|
||||
|
||||
public readonly SKTypeface Default; // used as a fallback font for all untranslated strings (item source, ...)
|
||||
|
|
@ -85,9 +68,9 @@ public class Typefaces
|
|||
|
||||
Default = SKTypeface.FromStream(Application.GetResourceStream(_BURBANK_BIG_CONDENSED_BOLD)?.Stream);
|
||||
|
||||
switch (viewModel.Game)
|
||||
switch (viewModel.Provider.InternalGameName.ToUpperInvariant())
|
||||
{
|
||||
case FGame.FortniteGame:
|
||||
case "FORTNITEGAME":
|
||||
{
|
||||
DisplayName = OnTheFly(_FORTNITE_BASE_PATH +
|
||||
language switch
|
||||
|
|
@ -172,36 +155,7 @@ public class Typefaces
|
|||
} + _EXT);
|
||||
break;
|
||||
}
|
||||
case FGame.WorldExplorers:
|
||||
{
|
||||
DisplayName = OnTheFly(_BATTLE_BREAKERS_BASE_PATH +
|
||||
language switch
|
||||
{
|
||||
ELanguage.Korean => _NOTO_SANS_KR_REGULAR,
|
||||
ELanguage.Russian => _LATO_BLACK,
|
||||
ELanguage.Japanese => _NOTO_SANS_JP_REGULAR,
|
||||
ELanguage.Chinese => _NOTO_SANS_SC_REGULAR,
|
||||
_ => _HEMIHEAD426
|
||||
} + _EXT);
|
||||
|
||||
Description = OnTheFly(_BATTLE_BREAKERS_BASE_PATH +
|
||||
language switch
|
||||
{
|
||||
ELanguage.Korean => _NOTO_SANS_KR_REGULAR,
|
||||
ELanguage.Russian => _LATO_BLACK,
|
||||
ELanguage.Japanese => _NOTO_SANS_JP_REGULAR,
|
||||
ELanguage.Chinese => _NOTO_SANS_SC_REGULAR,
|
||||
_ => _HEMIHEAD426
|
||||
} + _EXT);
|
||||
break;
|
||||
}
|
||||
case FGame.g3:
|
||||
{
|
||||
DisplayName = OnTheFly(_SPELLBREAK_BASE_PATH + _QUADRAT_BOLD + _EXT);
|
||||
Description = OnTheFly(_SPELLBREAK_BASE_PATH + _MONTSERRAT_SEMIBOLD + _EXT);
|
||||
break;
|
||||
}
|
||||
case FGame.MultiVersus:
|
||||
case "MULTIVERSUS":
|
||||
{
|
||||
DisplayName = OnTheFly(_PANDAGAME_BASE_PATH + language switch
|
||||
{
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ public static class Utils
|
|||
public static SKBitmap GetB64Bitmap(string b64) => SKBitmap.Decode(new MemoryStream(Convert.FromBase64String(b64)) { Position = 0 });
|
||||
public static SKBitmap GetBitmap(FSoftObjectPath softObjectPath) => GetBitmap(softObjectPath.AssetPathName.Text);
|
||||
public static SKBitmap GetBitmap(string fullPath) => TryLoadObject(fullPath, out UTexture2D texture) ? GetBitmap(texture) : null;
|
||||
public static SKBitmap GetBitmap(UTexture2D texture) => texture.IsVirtual ? null : texture.Decode(UserSettings.Default.OverridedPlatform);
|
||||
public static SKBitmap GetBitmap(UTexture2D texture) => texture.IsVirtual ? null : texture.Decode(UserSettings.Default.CurrentDir.TexturePlatform);
|
||||
public static SKBitmap GetBitmap(byte[] data) => SKBitmap.Decode(data);
|
||||
|
||||
public static SKBitmap ResizeWithRatio(this SKBitmap me, double width, double height)
|
||||
|
|
|
|||
|
|
@ -52,56 +52,6 @@ public enum EDiscordRpc
|
|||
Never
|
||||
}
|
||||
|
||||
public enum FGame
|
||||
{
|
||||
[Description("Unknown")]
|
||||
Unknown,
|
||||
[Description("Fortnite")]
|
||||
FortniteGame,
|
||||
[Description("Valorant")]
|
||||
ShooterGame,
|
||||
[Description("Dead By Daylight")]
|
||||
DeadByDaylight,
|
||||
[Description("Borderlands 3")]
|
||||
OakGame,
|
||||
[Description("Minecraft Dungeons")]
|
||||
Dungeons,
|
||||
[Description("Battle Breakers")]
|
||||
WorldExplorers,
|
||||
[Description("Spellbreak")]
|
||||
g3,
|
||||
[Description("State Of Decay 2")]
|
||||
StateOfDecay2,
|
||||
[Description("The Cycle")]
|
||||
Prospect,
|
||||
[Description("The Outer Worlds")]
|
||||
Indiana,
|
||||
[Description("Rogue Company")]
|
||||
RogueCompany,
|
||||
[Description("Star Wars: Jedi Fallen Order")]
|
||||
SwGame,
|
||||
[Description("Core")]
|
||||
Platform,
|
||||
[Description("Days Gone")]
|
||||
BendGame,
|
||||
[Description("PLAYERUNKNOWN'S BATTLEGROUNDS")]
|
||||
TslGame,
|
||||
[Description("Splitgate")]
|
||||
PortalWars,
|
||||
[Description("GTA: The Trilogy - Definitive Edition")]
|
||||
Gameface,
|
||||
[Description("Sea of Thieves")]
|
||||
Athena,
|
||||
[Description("DEPRECATED")]
|
||||
PandaGame,
|
||||
[Description("MultiVersus")]
|
||||
MultiVersus,
|
||||
[Description("Tower of Fantasy")]
|
||||
Hotta,
|
||||
[Description("eFootball 2023")]
|
||||
eFootball
|
||||
}
|
||||
|
||||
public enum ELoadingMode
|
||||
{
|
||||
[Description("Single")]
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@
|
|||
</Viewbox>
|
||||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Directories" ItemsSource="{Binding CustomDirectories.Directories}" IsEnabled="{Binding Status.IsReady}">
|
||||
<MenuItem Header="Favorite Directories" ItemsSource="{Binding CustomDirectories.Directories}" IsEnabled="{Binding Status.IsReady}">
|
||||
<MenuItem.Icon>
|
||||
<Viewbox Width="16" Height="16">
|
||||
<Canvas Width="24" Height="24">
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
<Style TargetType="MenuItem" BasedOn="{StaticResource {x:Type MenuItem}}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
|
||||
<DataTrigger Binding="{Binding CUE4Parse.InternalGameName, Converter={x:Static converters:CaseInsensitiveStringEqualsConverter.Instance}, ConverterParameter='FortniteGame'}" Value="True">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
|
|
@ -396,7 +396,7 @@
|
|||
</MenuItem.Icon>
|
||||
</MenuItem>
|
||||
<Separator />
|
||||
<MenuItem Header="Save Directory" Click="OnSaveDirectoryClick">
|
||||
<MenuItem Header="Favorite Directory" Click="OnFavoriteDirectoryClick">
|
||||
<MenuItem.Icon>
|
||||
<Viewbox Width="16" Height="16">
|
||||
<Canvas Width="24" Height="24">
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ public partial class MainWindow
|
|||
|
||||
private void OnClosing(object sender, CancelEventArgs e)
|
||||
{
|
||||
_applicationView.CustomDirectories.Save();
|
||||
_discordHandler.Dispose();
|
||||
}
|
||||
|
||||
|
|
@ -56,8 +55,8 @@ public partial class MainWindow
|
|||
case EAesReload.Always:
|
||||
await _applicationView.CUE4Parse.RefreshAes();
|
||||
break;
|
||||
case EAesReload.OncePerDay when UserSettings.Default.LastAesReload != DateTime.Today:
|
||||
UserSettings.Default.LastAesReload = DateTime.Today;
|
||||
case EAesReload.OncePerDay when UserSettings.Default.CurrentDir.LastAesReload != DateTime.Today:
|
||||
UserSettings.Default.CurrentDir.LastAesReload = DateTime.Today;
|
||||
await _applicationView.CUE4Parse.RefreshAes();
|
||||
break;
|
||||
}
|
||||
|
|
@ -228,13 +227,13 @@ public partial class MainWindow
|
|||
}
|
||||
}
|
||||
|
||||
private void OnSaveDirectoryClick(object sender, RoutedEventArgs e)
|
||||
private void OnFavoriteDirectoryClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (AssetsFolderName.SelectedItem is not TreeItem folder) return;
|
||||
|
||||
_applicationView.CustomDirectories.Add(new CustomDirectory(folder.Header, folder.PathAtThisPoint));
|
||||
FLogger.Append(ELog.Information, () =>
|
||||
FLogger.Text($"Successfully saved '{folder.PathAtThisPoint}' as a new custom directory", Constants.WHITE, true));
|
||||
FLogger.Text($"Successfully saved '{folder.PathAtThisPoint}' as a new favorite directory", Constants.WHITE, true));
|
||||
}
|
||||
|
||||
private void OnCopyDirectoryPathClick(object sender, RoutedEventArgs e)
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ namespace FModel.Services
|
|||
|
||||
public void UpdatePresence(CUE4ParseViewModel viewModel) =>
|
||||
UpdatePresence(
|
||||
$"{viewModel.Provider.GameDisplayName ?? viewModel.Provider.GameName} - {viewModel.Provider.MountedVfs.Count}/{viewModel.Provider.MountedVfs.Count + viewModel.Provider.UnloadedVfs.Count} Packages",
|
||||
$"{viewModel.Provider.GameDisplayName ?? viewModel.Provider.InternalGameName} - {viewModel.Provider.MountedVfs.Count}/{viewModel.Provider.MountedVfs.Count + viewModel.Provider.UnloadedVfs.Count} Packages",
|
||||
$"Mode: {UserSettings.Default.LoadingMode.GetDescription()} - {viewModel.SearchVm.ResultsCount:### ### ###} Loaded Assets".Trim());
|
||||
|
||||
public void UpdatePresence(string details, string state)
|
||||
|
|
|
|||
65
FModel/Settings/CustomDirectory.cs
Normal file
65
FModel/Settings/CustomDirectory.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
using System.Collections.Generic;
|
||||
using FModel.Framework;
|
||||
|
||||
namespace FModel.Settings;
|
||||
|
||||
public class CustomDirectory : ViewModel
|
||||
{
|
||||
public static IList<CustomDirectory> Default(string gameName)
|
||||
{
|
||||
switch (gameName)
|
||||
{
|
||||
case "Fortnite":
|
||||
case "Fortnite [LIVE]":
|
||||
return new List<CustomDirectory>
|
||||
{
|
||||
new("Cosmetics", "FortniteGame/Content/Athena/Items/Cosmetics/"),
|
||||
new("Emotes [AUDIO]", "FortniteGame/Content/Athena/Sounds/Emotes/"),
|
||||
new("Music Packs [AUDIO]", "FortniteGame/Content/Athena/Sounds/MusicPacks/"),
|
||||
new("Weapons", "FortniteGame/Content/Athena/Items/Weapons/"),
|
||||
new("Strings", "FortniteGame/Content/Localization/")
|
||||
};
|
||||
case "VALORANT":
|
||||
case "VALORANT [LIVE]":
|
||||
return new List<CustomDirectory>
|
||||
{
|
||||
new("Audio", "ShooterGame/Content/WwiseAudio/Media/"),
|
||||
new("Characters", "ShooterGame/Content/Characters/"),
|
||||
new("Gun Buddies", "ShooterGame/Content/Equippables/Buddies/"),
|
||||
new("Cards and Sprays", "ShooterGame/Content/Personalization/"),
|
||||
new("Shop Backgrounds", "ShooterGame/Content/UI/OutOfGame/MainMenu/Store/Shared/Textures/"),
|
||||
new("Weapon Renders", "ShooterGame/Content/UI/Screens/OutOfGame/MainMenu/Collection/Assets/Large/")
|
||||
};
|
||||
default:
|
||||
return new List<CustomDirectory>();
|
||||
}
|
||||
}
|
||||
|
||||
private string _header;
|
||||
public string Header
|
||||
{
|
||||
get => _header;
|
||||
set => SetProperty(ref _header, value);
|
||||
}
|
||||
|
||||
private string _directoryPath;
|
||||
public string DirectoryPath
|
||||
{
|
||||
get => _directoryPath;
|
||||
set => SetProperty(ref _directoryPath, value);
|
||||
}
|
||||
|
||||
public CustomDirectory()
|
||||
{
|
||||
Header = string.Empty;
|
||||
DirectoryPath = string.Empty;
|
||||
}
|
||||
|
||||
public CustomDirectory(string header, string path)
|
||||
{
|
||||
Header = header;
|
||||
DirectoryPath = path;
|
||||
}
|
||||
|
||||
public override string ToString() => Header;
|
||||
}
|
||||
120
FModel/Settings/DirectorySettings.cs
Normal file
120
FModel/Settings/DirectorySettings.cs
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using CUE4Parse.UE4.Assets.Exports.Texture;
|
||||
using CUE4Parse.UE4.Versions;
|
||||
using FModel.Framework;
|
||||
using FModel.ViewModels.ApiEndpoints.Models;
|
||||
|
||||
namespace FModel.Settings;
|
||||
|
||||
public class DirectorySettings : ViewModel, ICloneable
|
||||
{
|
||||
public static DirectorySettings Default(
|
||||
string gameName, string gameDir, bool manual = false, EGame ue = EGame.GAME_UE4_LATEST, string aes = "")
|
||||
{
|
||||
UserSettings.Default.PerDirectory.TryGetValue(gameDir, out var old);
|
||||
return new DirectorySettings
|
||||
{
|
||||
GameName = gameName,
|
||||
GameDirectory = gameDir,
|
||||
IsManual = manual,
|
||||
UeVersion = old?.UeVersion ?? ue,
|
||||
TexturePlatform = old?.TexturePlatform ?? ETexturePlatform.DesktopMobile,
|
||||
Versioning = old?.Versioning ?? new VersioningSettings(),
|
||||
Endpoints = old?.Endpoints ?? EndpointSettings.Default(gameName),
|
||||
Directories = old?.Directories ?? CustomDirectory.Default(gameName),
|
||||
AesKeys = old?.AesKeys ?? new AesResponse { MainKey = aes, DynamicKeys = null },
|
||||
LastAesReload = old?.LastAesReload ?? DateTime.Today.AddDays(-1)
|
||||
};
|
||||
}
|
||||
|
||||
private string _gameName;
|
||||
public string GameName
|
||||
{
|
||||
get => _gameName;
|
||||
set => SetProperty(ref _gameName, value);
|
||||
}
|
||||
|
||||
private string _gameDirectory;
|
||||
public string GameDirectory
|
||||
{
|
||||
get => _gameDirectory;
|
||||
set => SetProperty(ref _gameDirectory, value);
|
||||
}
|
||||
|
||||
private bool _isManual;
|
||||
public bool IsManual
|
||||
{
|
||||
get => _isManual;
|
||||
set => SetProperty(ref _isManual, value);
|
||||
}
|
||||
|
||||
private EGame _ueVersion;
|
||||
public EGame UeVersion
|
||||
{
|
||||
get => _ueVersion;
|
||||
set => SetProperty(ref _ueVersion, value);
|
||||
}
|
||||
|
||||
private ETexturePlatform _texturePlatform;
|
||||
public ETexturePlatform TexturePlatform
|
||||
{
|
||||
get => _texturePlatform;
|
||||
set => SetProperty(ref _texturePlatform, value);
|
||||
}
|
||||
|
||||
private VersioningSettings _versioning;
|
||||
public VersioningSettings Versioning
|
||||
{
|
||||
get => _versioning;
|
||||
set => SetProperty(ref _versioning, value);
|
||||
}
|
||||
|
||||
private EndpointSettings[] _endpoints;
|
||||
public EndpointSettings[] Endpoints
|
||||
{
|
||||
get => _endpoints;
|
||||
set => SetProperty(ref _endpoints, value);
|
||||
}
|
||||
|
||||
private IList<CustomDirectory> _directories;
|
||||
public IList<CustomDirectory> Directories
|
||||
{
|
||||
get => _directories;
|
||||
set => SetProperty(ref _directories, value);
|
||||
}
|
||||
|
||||
private AesResponse _aesKeys;
|
||||
public AesResponse AesKeys
|
||||
{
|
||||
get => _aesKeys;
|
||||
set => SetProperty(ref _aesKeys, value);
|
||||
}
|
||||
|
||||
private DateTime _lastAesReload;
|
||||
public DateTime LastAesReload
|
||||
{
|
||||
get => _lastAesReload;
|
||||
set => SetProperty(ref _lastAesReload, value);
|
||||
}
|
||||
|
||||
private bool Equals(DirectorySettings other)
|
||||
{
|
||||
return GameDirectory == other.GameDirectory && UeVersion == other.UeVersion;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is DirectorySettings other && Equals(other);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(GameDirectory, (int) UeVersion);
|
||||
}
|
||||
|
||||
public object Clone()
|
||||
{
|
||||
return this.MemberwiseClone();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,29 @@
|
|||
using System.Linq;
|
||||
using FModel.Framework;
|
||||
using FModel.ViewModels.ApiEndpoints;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace FModel.Framework;
|
||||
namespace FModel.Settings;
|
||||
|
||||
public class FEndpoint : ViewModel
|
||||
public class EndpointSettings : ViewModel
|
||||
{
|
||||
public static EndpointSettings[] Default(string gameName)
|
||||
{
|
||||
switch (gameName)
|
||||
{
|
||||
case "Fortnite":
|
||||
case "Fortnite [LIVE]":
|
||||
return new EndpointSettings[]
|
||||
{
|
||||
new("https://fortnitecentral.genxgames.gg/api/v1/aes", "$.['mainKey','dynamicKeys']"),
|
||||
new("https://fortnitecentral.genxgames.gg/api/v1/mappings", "$.[?(@.meta.compressionMethod=='Oodle')].['url','fileName']")
|
||||
};
|
||||
default:
|
||||
return new EndpointSettings[] { new(), new() };
|
||||
}
|
||||
}
|
||||
|
||||
private string _url;
|
||||
public string Url
|
||||
{
|
||||
|
|
@ -51,8 +68,8 @@ public class FEndpoint : ViewModel
|
|||
"Your endpoint configuration is valid! Please, avoid any unnecessary modifications!" :
|
||||
"Your endpoint configuration DOES NOT seem to be valid yet! Please, test it out!";
|
||||
|
||||
public FEndpoint() {}
|
||||
public FEndpoint(string url, string path)
|
||||
public EndpointSettings() {}
|
||||
public EndpointSettings(string url, string path)
|
||||
{
|
||||
Url = url;
|
||||
Path = path;
|
||||
|
|
@ -3,8 +3,6 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using CUE4Parse.UE4.Assets.Exports.Texture;
|
||||
using CUE4Parse.UE4.Objects.Core.Serialization;
|
||||
using CUE4Parse.UE4.Versions;
|
||||
using CUE4Parse_Conversion.Meshes;
|
||||
using CUE4Parse_Conversion.Textures;
|
||||
|
|
@ -33,6 +31,7 @@ namespace FModel.Settings
|
|||
|
||||
public static void Save()
|
||||
{
|
||||
Default.PerDirectory[Default.CurrentDir.GameDirectory] = Default.CurrentDir;
|
||||
File.WriteAllText(FilePath, JsonConvert.SerializeObject(Default, Formatting.Indented));
|
||||
}
|
||||
|
||||
|
|
@ -41,13 +40,9 @@ namespace FModel.Settings
|
|||
if (File.Exists(FilePath)) File.Delete(FilePath);
|
||||
}
|
||||
|
||||
public static bool IsEndpointValid(FGame game, EEndpointType type, out FEndpoint endpoint)
|
||||
public static bool IsEndpointValid(EEndpointType type, out EndpointSettings endpoint)
|
||||
{
|
||||
endpoint = null;
|
||||
if (!Default.CustomEndpoints.TryGetValue(game, out var endpoints))
|
||||
return false;
|
||||
|
||||
endpoint = endpoints[(int) type];
|
||||
endpoint = Default.CurrentDir.Endpoints[(int) type];
|
||||
return endpoint.Overwrite || endpoint.IsValid;
|
||||
}
|
||||
|
||||
|
|
@ -100,7 +95,7 @@ namespace FModel.Settings
|
|||
set => SetProperty(ref _modelDirectory, value);
|
||||
}
|
||||
|
||||
private string _gameDirectory;
|
||||
private string _gameDirectory = string.Empty;
|
||||
public string GameDirectory
|
||||
{
|
||||
get => _gameDirectory;
|
||||
|
|
@ -135,13 +130,6 @@ namespace FModel.Settings
|
|||
set => SetProperty(ref _avalonImageSize, value);
|
||||
}
|
||||
|
||||
private IDictionary<FGame, AesResponse> _aesKeys = new Dictionary<FGame, AesResponse>();
|
||||
public IDictionary<FGame, AesResponse> AesKeys
|
||||
{
|
||||
get => _aesKeys;
|
||||
set => SetProperty(ref _aesKeys, value);
|
||||
}
|
||||
|
||||
private string _audioDeviceId;
|
||||
public string AudioDeviceId
|
||||
{
|
||||
|
|
@ -156,7 +144,7 @@ namespace FModel.Settings
|
|||
set => SetProperty(ref _audioPlayerVolume, value);
|
||||
}
|
||||
|
||||
private ELoadingMode _loadingMode = ELoadingMode.Multiple;
|
||||
private ELoadingMode _loadingMode = ELoadingMode.All;
|
||||
public ELoadingMode LoadingMode
|
||||
{
|
||||
get => _loadingMode;
|
||||
|
|
@ -233,9 +221,19 @@ namespace FModel.Settings
|
|||
set => SetProperty(ref _readScriptData, value);
|
||||
}
|
||||
|
||||
// <gameDirectory as string, settings>
|
||||
// can't refactor to use this data layout for everything
|
||||
// because it will wipe old user settings that relies on FGame
|
||||
private IDictionary<string, DirectorySettings> _perDirectory = new Dictionary<string, DirectorySettings>();
|
||||
public IDictionary<string, DirectorySettings> PerDirectory
|
||||
{
|
||||
get => _perDirectory;
|
||||
set => SetProperty(ref _perDirectory, value);
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public DirectorySettings CurrentDir { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TO DELETEEEEEEEEEEEEE
|
||||
/// </summary>
|
||||
private IDictionary<string, GameSelectorViewModel.DetectedGame> _manualGames = new Dictionary<string, GameSelectorViewModel.DetectedGame>();
|
||||
public IDictionary<string, GameSelectorViewModel.DetectedGame> ManualGames
|
||||
{
|
||||
|
|
@ -243,291 +241,6 @@ namespace FModel.Settings
|
|||
set => SetProperty(ref _manualGames, value);
|
||||
}
|
||||
|
||||
private ETexturePlatform _overridedPlatform = ETexturePlatform.DesktopMobile;
|
||||
public ETexturePlatform OverridedPlatform
|
||||
{
|
||||
get => _overridedPlatform;
|
||||
set => SetProperty(ref _overridedPlatform, value);
|
||||
}
|
||||
|
||||
private IDictionary<FGame, string> _presets = new Dictionary<FGame, string>
|
||||
{
|
||||
{FGame.Unknown, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.FortniteGame, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.ShooterGame, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.DeadByDaylight, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.OakGame, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.Dungeons, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.WorldExplorers, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.g3, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.StateOfDecay2, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.Prospect, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.Indiana, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.RogueCompany, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.SwGame, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.Platform, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.BendGame, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.TslGame, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.PortalWars, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.Gameface, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.Athena, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.MultiVersus, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.Hotta, Constants._NO_PRESET_TRIGGER},
|
||||
{FGame.eFootball, Constants._NO_PRESET_TRIGGER}
|
||||
};
|
||||
public IDictionary<FGame, string> Presets
|
||||
{
|
||||
get => _presets;
|
||||
set => SetProperty(ref _presets, value);
|
||||
}
|
||||
|
||||
private IDictionary<FGame, EGame> _overridedGame = new Dictionary<FGame, EGame>
|
||||
{
|
||||
{FGame.Unknown, EGame.GAME_UE4_LATEST},
|
||||
{FGame.FortniteGame, EGame.GAME_UE5_2},
|
||||
{FGame.ShooterGame, EGame.GAME_Valorant},
|
||||
{FGame.DeadByDaylight, EGame.GAME_UE4_27},
|
||||
{FGame.OakGame, EGame.GAME_Borderlands3},
|
||||
{FGame.Dungeons, EGame.GAME_UE4_22},
|
||||
{FGame.WorldExplorers, EGame.GAME_UE4_24},
|
||||
{FGame.g3, EGame.GAME_UE4_22},
|
||||
{FGame.StateOfDecay2, EGame.GAME_StateOfDecay2},
|
||||
{FGame.Prospect, EGame.GAME_Splitgate},
|
||||
{FGame.Indiana, EGame.GAME_UE4_21},
|
||||
{FGame.RogueCompany, EGame.GAME_RogueCompany},
|
||||
{FGame.SwGame, EGame.GAME_UE4_LATEST},
|
||||
{FGame.Platform, EGame.GAME_UE4_26},
|
||||
{FGame.BendGame, EGame.GAME_UE4_11},
|
||||
{FGame.TslGame, EGame.GAME_PlayerUnknownsBattlegrounds},
|
||||
{FGame.PortalWars, EGame.GAME_UE4_27},
|
||||
{FGame.Gameface, EGame.GAME_GTATheTrilogyDefinitiveEdition},
|
||||
{FGame.Athena, EGame.GAME_SeaOfThieves},
|
||||
{FGame.MultiVersus, EGame.GAME_UE4_26},
|
||||
{FGame.Hotta, EGame.GAME_TowerOfFantasy},
|
||||
{FGame.eFootball, EGame.GAME_UE4_26}
|
||||
};
|
||||
public IDictionary<FGame, EGame> OverridedGame
|
||||
{
|
||||
get => _overridedGame;
|
||||
set => SetProperty(ref _overridedGame, value);
|
||||
}
|
||||
|
||||
private IDictionary<FGame, List<FCustomVersion>> _overridedCustomVersions = new Dictionary<FGame, List<FCustomVersion>>
|
||||
{
|
||||
{FGame.Unknown, null},
|
||||
{FGame.FortniteGame, null},
|
||||
{FGame.ShooterGame, null},
|
||||
{FGame.DeadByDaylight, null},
|
||||
{FGame.OakGame, null},
|
||||
{FGame.Dungeons, null},
|
||||
{FGame.WorldExplorers, null},
|
||||
{FGame.g3, null},
|
||||
{FGame.StateOfDecay2, null},
|
||||
{FGame.Prospect, null},
|
||||
{FGame.Indiana, null},
|
||||
{FGame.RogueCompany, null},
|
||||
{FGame.SwGame, null},
|
||||
{FGame.Platform, null},
|
||||
{FGame.BendGame, null},
|
||||
{FGame.TslGame, null},
|
||||
{FGame.PortalWars, null},
|
||||
{FGame.Gameface, null},
|
||||
{FGame.Athena, null},
|
||||
{FGame.MultiVersus, null},
|
||||
{FGame.Hotta, null},
|
||||
{FGame.eFootball, null}
|
||||
};
|
||||
public IDictionary<FGame, List<FCustomVersion>> OverridedCustomVersions
|
||||
{
|
||||
get => _overridedCustomVersions;
|
||||
set => SetProperty(ref _overridedCustomVersions, value);
|
||||
}
|
||||
|
||||
private IDictionary<FGame, Dictionary<string, bool>> _overridedOptions = new Dictionary<FGame, Dictionary<string, bool>>
|
||||
{
|
||||
{FGame.Unknown, null},
|
||||
{FGame.FortniteGame, null},
|
||||
{FGame.ShooterGame, null},
|
||||
{FGame.DeadByDaylight, null},
|
||||
{FGame.OakGame, null},
|
||||
{FGame.Dungeons, null},
|
||||
{FGame.WorldExplorers, null},
|
||||
{FGame.g3, null},
|
||||
{FGame.StateOfDecay2, null},
|
||||
{FGame.Prospect, null},
|
||||
{FGame.Indiana, null},
|
||||
{FGame.RogueCompany, null},
|
||||
{FGame.SwGame, null},
|
||||
{FGame.Platform, null},
|
||||
{FGame.BendGame, null},
|
||||
{FGame.TslGame, null},
|
||||
{FGame.PortalWars, null},
|
||||
{FGame.Gameface, null},
|
||||
{FGame.Athena, null},
|
||||
{FGame.MultiVersus, null},
|
||||
{FGame.Hotta, null},
|
||||
{FGame.eFootball, null}
|
||||
};
|
||||
|
||||
private IDictionary<FGame, Dictionary<string, KeyValuePair<string, string>>> _overridedMapStructTypes = new Dictionary<FGame, Dictionary<string, KeyValuePair<string, string>>>
|
||||
{
|
||||
{FGame.Unknown, null},
|
||||
{FGame.FortniteGame, null},
|
||||
{FGame.ShooterGame, null},
|
||||
{FGame.DeadByDaylight, null},
|
||||
{FGame.OakGame, null},
|
||||
{FGame.Dungeons, null},
|
||||
{FGame.WorldExplorers, null},
|
||||
{FGame.g3, null},
|
||||
{FGame.StateOfDecay2, null},
|
||||
{FGame.Prospect, null},
|
||||
{FGame.Indiana, null},
|
||||
{FGame.RogueCompany, null},
|
||||
{FGame.SwGame, null},
|
||||
{FGame.Platform, null},
|
||||
{FGame.BendGame, null},
|
||||
{FGame.TslGame, null},
|
||||
{FGame.PortalWars, null},
|
||||
{FGame.Gameface, null},
|
||||
{FGame.Athena, null},
|
||||
{FGame.MultiVersus, null},
|
||||
{FGame.Hotta, null},
|
||||
{FGame.eFootball, null}
|
||||
};
|
||||
public IDictionary<FGame, Dictionary<string, bool>> OverridedOptions
|
||||
{
|
||||
get => _overridedOptions;
|
||||
set => SetProperty(ref _overridedOptions, value);
|
||||
}
|
||||
|
||||
public IDictionary<FGame, Dictionary<string, KeyValuePair<string, string>>> OverridedMapStructTypes
|
||||
{
|
||||
get => _overridedMapStructTypes;
|
||||
set => SetProperty(ref _overridedMapStructTypes, value);
|
||||
}
|
||||
|
||||
private IDictionary<FGame, FEndpoint[]> _customEndpoints = new Dictionary<FGame, FEndpoint[]>
|
||||
{
|
||||
{FGame.Unknown, new FEndpoint[]{new (), new ()}},
|
||||
{
|
||||
FGame.FortniteGame, new []
|
||||
{
|
||||
new FEndpoint("https://fortnitecentral.genxgames.gg/api/v1/aes", "$.['mainKey','dynamicKeys']"),
|
||||
new FEndpoint("https://fortnitecentral.genxgames.gg/api/v1/mappings", "$.[?(@.meta.compressionMethod=='Oodle')].['url','fileName']") // && @.meta.platform=='Windows'
|
||||
}
|
||||
},
|
||||
{FGame.ShooterGame, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.DeadByDaylight, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.OakGame, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.Dungeons, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.WorldExplorers, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.g3, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.StateOfDecay2, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.Prospect, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.Indiana, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.RogueCompany, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.SwGame, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.Platform, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.BendGame, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.TslGame, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.PortalWars, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.Gameface, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.Athena, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.MultiVersus, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.Hotta, new FEndpoint[]{new (), new ()}},
|
||||
{FGame.eFootball, new FEndpoint[]{new (), new ()}}
|
||||
};
|
||||
public IDictionary<FGame, FEndpoint[]> CustomEndpoints
|
||||
{
|
||||
get => _customEndpoints;
|
||||
set => SetProperty(ref _customEndpoints, value);
|
||||
}
|
||||
|
||||
private IDictionary<FGame, IList<CustomDirectory>> _customDirectories = new Dictionary<FGame, IList<CustomDirectory>>
|
||||
{
|
||||
{FGame.Unknown, new List<CustomDirectory>()},
|
||||
{
|
||||
FGame.FortniteGame, new List<CustomDirectory>
|
||||
{
|
||||
new("Cosmetics", "FortniteGame/Content/Athena/Items/Cosmetics/"),
|
||||
new("Emotes [AUDIO]", "FortniteGame/Content/Athena/Sounds/Emotes/"),
|
||||
new("Music Packs [AUDIO]", "FortniteGame/Content/Athena/Sounds/MusicPacks/"),
|
||||
new("Weapons", "FortniteGame/Content/Athena/Items/Weapons/"),
|
||||
new("Strings", "FortniteGame/Content/Localization/")
|
||||
}
|
||||
},
|
||||
{
|
||||
FGame.ShooterGame, new List<CustomDirectory>
|
||||
{
|
||||
new("Audio", "ShooterGame/Content/WwiseAudio/Media/"),
|
||||
new("Characters", "ShooterGame/Content/Characters/"),
|
||||
new("Gun Buddies", "ShooterGame/Content/Equippables/Buddies/"),
|
||||
new("Cards and Sprays", "ShooterGame/Content/Personalization/"),
|
||||
new("Shop Backgrounds", "ShooterGame/Content/UI/OutOfGame/MainMenu/Store/Shared/Textures/"),
|
||||
new("Weapon Renders", "ShooterGame/Content/UI/Screens/OutOfGame/MainMenu/Collection/Assets/Large/")
|
||||
}
|
||||
},
|
||||
{
|
||||
FGame.DeadByDaylight, new List<CustomDirectory>
|
||||
{
|
||||
new("Audio", "DeadByDaylight/Content/WwiseAudio/Windows/"),
|
||||
new("Characters", "DeadByDaylight/Content/Characters/"),
|
||||
new("Icons", "DeadByDaylight/Content/UI/UMGAssets/Icons/"),
|
||||
new("Strings", "DeadByDaylight/Content/Localization/")
|
||||
}
|
||||
},
|
||||
{FGame.OakGame, new List<CustomDirectory>()},
|
||||
{
|
||||
FGame.Dungeons, new List<CustomDirectory>
|
||||
{
|
||||
new("Levels", "Dungeons/Content/data/Lovika/Levels"),
|
||||
new("Friendlies", "Dungeons/Content/Actor/Characters/Friendlies"),
|
||||
new("Skins", "Dungeons/Content/Actor/Characters/Player/Master/Skins"),
|
||||
new("Strings", "Dungeons/Content/Localization/")
|
||||
}
|
||||
},
|
||||
{
|
||||
FGame.WorldExplorers, new List<CustomDirectory>
|
||||
{
|
||||
new("Loot", "WorldExplorers/Content/Loot/"),
|
||||
new("Strings", "WorldExplorers/Content/Localization/")
|
||||
}
|
||||
},
|
||||
{
|
||||
FGame.g3, new List<CustomDirectory>
|
||||
{
|
||||
new("Cosmetics", "g3/Content/Blueprints/Cosmetics/"),
|
||||
new("Strings", "g3/Content/Localization/")
|
||||
}
|
||||
},
|
||||
{FGame.StateOfDecay2, new List<CustomDirectory>()},
|
||||
{FGame.Prospect, new List<CustomDirectory>()},
|
||||
{FGame.Indiana, new List<CustomDirectory>()},
|
||||
{FGame.RogueCompany, new List<CustomDirectory>()},
|
||||
{FGame.SwGame, new List<CustomDirectory>()},
|
||||
{FGame.Platform, new List<CustomDirectory>()},
|
||||
{FGame.BendGame, new List<CustomDirectory>()},
|
||||
{FGame.TslGame, new List<CustomDirectory>()},
|
||||
{FGame.PortalWars, new List<CustomDirectory>()},
|
||||
{FGame.Gameface, new List<CustomDirectory>()},
|
||||
{FGame.Athena, new List<CustomDirectory>()},
|
||||
{FGame.MultiVersus, new List<CustomDirectory>()},
|
||||
{FGame.Hotta, new List<CustomDirectory>()},
|
||||
{FGame.eFootball, new List<CustomDirectory>()}
|
||||
};
|
||||
public IDictionary<FGame, IList<CustomDirectory>> CustomDirectories
|
||||
{
|
||||
get => _customDirectories;
|
||||
set => SetProperty(ref _customDirectories, value);
|
||||
}
|
||||
|
||||
private DateTime _lastAesReload = DateTime.Today.AddDays(-1);
|
||||
public DateTime LastAesReload
|
||||
{
|
||||
get => _lastAesReload;
|
||||
set => SetProperty(ref _lastAesReload, value);
|
||||
}
|
||||
|
||||
private AuthResponse _lastAuthResponse = new() {AccessToken = "", ExpiresAt = DateTime.Now};
|
||||
public AuthResponse LastAuthResponse
|
||||
{
|
||||
|
|
|
|||
31
FModel/Settings/VersioningSettings.cs
Normal file
31
FModel/Settings/VersioningSettings.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using System.Collections.Generic;
|
||||
using CUE4Parse.UE4.Objects.Core.Serialization;
|
||||
using FModel.Framework;
|
||||
|
||||
namespace FModel.Settings;
|
||||
|
||||
public class VersioningSettings : ViewModel
|
||||
{
|
||||
private IList<FCustomVersion> _customVersions;
|
||||
public IList<FCustomVersion> CustomVersions
|
||||
{
|
||||
get => _customVersions;
|
||||
set => SetProperty(ref _customVersions, value);
|
||||
}
|
||||
|
||||
private IDictionary<string, bool> _options;
|
||||
public IDictionary<string, bool> Options
|
||||
{
|
||||
get => _options;
|
||||
set => SetProperty(ref _options, value);
|
||||
}
|
||||
|
||||
private IDictionary<string, KeyValuePair<string, string>> _mapStructTypes;
|
||||
public IDictionary<string, KeyValuePair<string, string>> MapStructTypes
|
||||
{
|
||||
get => _mapStructTypes;
|
||||
set => SetProperty(ref _mapStructTypes, value);
|
||||
}
|
||||
|
||||
public VersioningSettings() {}
|
||||
}
|
||||
|
|
@ -35,22 +35,7 @@ public class AesManagerViewModel : ViewModel
|
|||
{
|
||||
await _threadWorkerView.Begin(_ =>
|
||||
{
|
||||
if (_cue4Parse.Game == FGame.Unknown &&
|
||||
UserSettings.Default.ManualGames.TryGetValue(UserSettings.Default.GameDirectory, out var settings))
|
||||
{
|
||||
_keysFromSettings = settings.AesKeys;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserSettings.Default.AesKeys.TryGetValue(_cue4Parse.Game, out _keysFromSettings);
|
||||
}
|
||||
|
||||
_keysFromSettings ??= new AesResponse
|
||||
{
|
||||
MainKey = string.Empty,
|
||||
DynamicKeys = null
|
||||
};
|
||||
|
||||
_keysFromSettings = UserSettings.Default.CurrentDir.AesKeys;
|
||||
_mainKey.Key = Helper.FixKey(_keysFromSettings.MainKey);
|
||||
AesKeys = new FullyObservableCollection<FileItem>(EnumerateAesKeys());
|
||||
AesKeys.ItemPropertyChanged += AesKeysOnItemPropertyChanged;
|
||||
|
|
@ -105,9 +90,7 @@ public class AesManagerViewModel : ViewModel
|
|||
|
||||
public void SetAesKeys()
|
||||
{
|
||||
if (_cue4Parse.Game == FGame.Unknown && UserSettings.Default.ManualGames.ContainsKey(UserSettings.Default.GameDirectory))
|
||||
UserSettings.Default.ManualGames[UserSettings.Default.GameDirectory].AesKeys = _keysFromSettings;
|
||||
else UserSettings.Default.AesKeys[_cue4Parse.Game] = _keysFromSettings;
|
||||
UserSettings.Default.CurrentDir.AesKeys = _keysFromSettings;
|
||||
// Log.Information("{@Json}", UserSettings.Default);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -48,9 +48,7 @@ public class ApplicationViewModel : ViewModel
|
|||
|
||||
public string InitialWindowTitle => $"FModel {UserSettings.Default.UpdateMode}";
|
||||
public string GameDisplayName => CUE4Parse.Provider.GameDisplayName ?? "Unknown";
|
||||
public string TitleExtra =>
|
||||
$"({(CUE4Parse.Game == FGame.Unknown && UserSettings.Default.ManualGames.TryGetValue(UserSettings.Default.GameDirectory, out var settings) ? settings.OverridedGame : UserSettings.Default.OverridedGame[CUE4Parse.Game])})" +
|
||||
$"{(Build != EBuildKind.Release ? $" ({Build})" : "")}";
|
||||
public string TitleExtra => $"({UserSettings.Default.CurrentDir.UeVersion}){(Build != EBuildKind.Release ? $" ({Build})" : "")}";
|
||||
|
||||
public LoadingModesViewModel LoadingModes { get; }
|
||||
public CustomDirectoriesViewModel CustomDirectories { get; }
|
||||
|
|
@ -73,50 +71,42 @@ public class ApplicationViewModel : ViewModel
|
|||
#endif
|
||||
LoadingModes = new LoadingModesViewModel();
|
||||
|
||||
AvoidEmptyGameDirectoryAndSetEGame(false);
|
||||
if (UserSettings.Default.GameDirectory is null)
|
||||
UserSettings.Default.CurrentDir = AvoidEmptyGameDirectory(false);
|
||||
if (UserSettings.Default.CurrentDir is null)
|
||||
{
|
||||
//If no game is selected, many things will break before a shutdown request is processed in the normal way.
|
||||
//A hard exit is preferable to an unhandled expection in this case
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
CUE4Parse = new CUE4ParseViewModel(UserSettings.Default.GameDirectory);
|
||||
CustomDirectories = new CustomDirectoriesViewModel(CUE4Parse.Game, UserSettings.Default.GameDirectory);
|
||||
SettingsView = new SettingsViewModel(CUE4Parse.Game);
|
||||
CUE4Parse = new CUE4ParseViewModel();
|
||||
CustomDirectories = new CustomDirectoriesViewModel();
|
||||
SettingsView = new SettingsViewModel();
|
||||
AesManager = new AesManagerViewModel(CUE4Parse);
|
||||
MapViewer = new MapViewerViewModel(CUE4Parse);
|
||||
AudioPlayer = new AudioPlayerViewModel();
|
||||
|
||||
Status.SetStatus(EStatusKind.Ready);
|
||||
}
|
||||
|
||||
public void AvoidEmptyGameDirectoryAndSetEGame(bool bAlreadyLaunched)
|
||||
public DirectorySettings AvoidEmptyGameDirectory(bool bAlreadyLaunched)
|
||||
{
|
||||
var gameDirectory = UserSettings.Default.GameDirectory;
|
||||
if (!string.IsNullOrEmpty(gameDirectory) && !bAlreadyLaunched) return;
|
||||
if (!bAlreadyLaunched && UserSettings.Default.PerDirectory.TryGetValue(gameDirectory, out var currentDir))
|
||||
return currentDir;
|
||||
|
||||
var gameLauncherViewModel = new GameSelectorViewModel(gameDirectory);
|
||||
var result = new DirectorySelector(gameLauncherViewModel).ShowDialog();
|
||||
if (!result.HasValue || !result.Value) return;
|
||||
if (!result.HasValue || !result.Value) return null;
|
||||
|
||||
UserSettings.Default.GameDirectory = gameLauncherViewModel.SelectedDetectedGame.GameDirectory;
|
||||
if (!bAlreadyLaunched || gameDirectory == gameLauncherViewModel.SelectedDetectedGame.GameDirectory) return;
|
||||
UserSettings.Default.GameDirectory = gameLauncherViewModel.SelectedDirectory.GameDirectory;
|
||||
if (!bAlreadyLaunched || UserSettings.Default.CurrentDir.Equals(gameLauncherViewModel.SelectedDirectory))
|
||||
return gameLauncherViewModel.SelectedDirectory;
|
||||
|
||||
// UserSettings.Save(); // ??? change key then change game, key saved correctly what?
|
||||
UserSettings.Default.CurrentDir = gameLauncherViewModel.SelectedDirectory;
|
||||
RestartWithWarning();
|
||||
}
|
||||
|
||||
public async Task UpdateProvider(bool isLaunch)
|
||||
{
|
||||
if (!isLaunch && !AesManager.HasChange) return;
|
||||
|
||||
CUE4Parse.ClearProvider();
|
||||
await ApplicationService.ThreadWorkerView.Begin(cancellationToken =>
|
||||
{
|
||||
CUE4Parse.LoadVfs(cancellationToken, AesManager.AesKeys);
|
||||
CUE4Parse.Provider.LoadIniConfigs();
|
||||
AesManager.SetAesKeys();
|
||||
});
|
||||
RaisePropertyChanged(nameof(GameDisplayName));
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RestartWithWarning()
|
||||
|
|
@ -161,6 +151,20 @@ public class ApplicationViewModel : ViewModel
|
|||
Application.Current.Shutdown();
|
||||
}
|
||||
|
||||
public async Task UpdateProvider(bool isLaunch)
|
||||
{
|
||||
if (!isLaunch && !AesManager.HasChange) return;
|
||||
|
||||
CUE4Parse.ClearProvider();
|
||||
await ApplicationService.ThreadWorkerView.Begin(cancellationToken =>
|
||||
{
|
||||
CUE4Parse.LoadVfs(cancellationToken, AesManager.AesKeys);
|
||||
CUE4Parse.Provider.LoadIniConfigs();
|
||||
AesManager.SetAesKeys();
|
||||
});
|
||||
RaisePropertyChanged(nameof(GameDisplayName));
|
||||
}
|
||||
|
||||
public async Task InitVgmStream()
|
||||
{
|
||||
var vgmZipFilePath = Path.Combine(UserSettings.Default.OutputDirectory, ".data", "vgmstream-win.zip");
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ public class CUE4ParseViewModel : ViewModel
|
|||
private readonly Regex _fnLive = new(@"^FortniteGame(/|\\)Content(/|\\)Paks(/|\\)",
|
||||
RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||
|
||||
private FGame _game;
|
||||
public FGame Game
|
||||
private string _internalGameName;
|
||||
public string InternalGameName
|
||||
{
|
||||
get => _game;
|
||||
set => SetProperty(ref _game, value);
|
||||
get => _internalGameName;
|
||||
set => SetProperty(ref _internalGameName, value);
|
||||
}
|
||||
|
||||
private bool _modelIsOverwritingMaterial;
|
||||
|
|
@ -123,80 +123,48 @@ public class CUE4ParseViewModel : ViewModel
|
|||
public TabControlViewModel TabControl { get; }
|
||||
public ConfigIni BuildInfo { get; }
|
||||
|
||||
public CUE4ParseViewModel(string gameDirectory)
|
||||
public CUE4ParseViewModel()
|
||||
{
|
||||
var currentDir = UserSettings.Default.CurrentDir;
|
||||
var gameDirectory = currentDir.GameDirectory;
|
||||
var versionContainer = new VersionContainer(
|
||||
game: currentDir.UeVersion, platform: currentDir.TexturePlatform,
|
||||
customVersions: new FCustomVersionContainer(currentDir.Versioning.CustomVersions),
|
||||
optionOverrides: currentDir.Versioning.Options,
|
||||
mapStructTypesOverrides: currentDir.Versioning.MapStructTypes);
|
||||
|
||||
switch (gameDirectory)
|
||||
{
|
||||
case Constants._FN_LIVE_TRIGGER:
|
||||
{
|
||||
Game = FGame.FortniteGame;
|
||||
Provider = new StreamedFileProvider("FortniteLive", true,
|
||||
new VersionContainer(
|
||||
UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform,
|
||||
customVersions: new FCustomVersionContainer(UserSettings.Default.OverridedCustomVersions[Game]),
|
||||
optionOverrides: UserSettings.Default.OverridedOptions[Game]));
|
||||
InternalGameName = "FortniteGame";
|
||||
Provider = new StreamedFileProvider("FortniteLive", true, versionContainer);
|
||||
break;
|
||||
}
|
||||
case Constants._VAL_LIVE_TRIGGER:
|
||||
{
|
||||
Game = FGame.ShooterGame;
|
||||
Provider = new StreamedFileProvider("ValorantLive", true,
|
||||
new VersionContainer(
|
||||
UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform,
|
||||
customVersions: new FCustomVersionContainer(UserSettings.Default.OverridedCustomVersions[Game]),
|
||||
optionOverrides: UserSettings.Default.OverridedOptions[Game]));
|
||||
InternalGameName = "ShooterGame";
|
||||
Provider = new StreamedFileProvider("ValorantLive", true, versionContainer);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
var parent = gameDirectory.SubstringBeforeLast("\\Content").SubstringAfterLast("\\");
|
||||
if (gameDirectory.Contains("eFootball")) parent = gameDirectory.SubstringBeforeLast("\\pak").SubstringAfterLast("\\");
|
||||
Game = parent.ToEnum(FGame.Unknown);
|
||||
var versions = new VersionContainer(UserSettings.Default.OverridedGame[Game], UserSettings.Default.OverridedPlatform,
|
||||
customVersions: new FCustomVersionContainer(UserSettings.Default.OverridedCustomVersions[Game]),
|
||||
optionOverrides: UserSettings.Default.OverridedOptions[Game],
|
||||
mapStructTypesOverrides: UserSettings.Default.OverridedMapStructTypes[Game]);
|
||||
|
||||
switch (Game)
|
||||
InternalGameName = gameDirectory.SubstringBeforeLast(gameDirectory.Contains("eFootball") ? "\\pak" : "\\Content").SubstringAfterLast("\\");
|
||||
Provider = InternalGameName switch
|
||||
{
|
||||
case FGame.StateOfDecay2:
|
||||
{
|
||||
Provider = new DefaultFileProvider(new DirectoryInfo(gameDirectory), new List<DirectoryInfo>
|
||||
{
|
||||
new(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\StateOfDecay2\\Saved\\Paks"),
|
||||
new(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\StateOfDecay2\\Saved\\DisabledPaks")
|
||||
},
|
||||
SearchOption.AllDirectories, true, versions);
|
||||
break;
|
||||
}
|
||||
case FGame.FortniteGame:
|
||||
Provider = new DefaultFileProvider(new DirectoryInfo(gameDirectory), new List<DirectoryInfo>
|
||||
{
|
||||
new(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\FortniteGame\\Saved\\PersistentDownloadDir\\InstalledBundles"),
|
||||
},
|
||||
SearchOption.AllDirectories, true, versions);
|
||||
break;
|
||||
case FGame.eFootball:
|
||||
Provider = new DefaultFileProvider(new DirectoryInfo(gameDirectory), new List<DirectoryInfo>
|
||||
{
|
||||
new(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\KONAMI\\eFootball\\ST\\Download")
|
||||
},
|
||||
SearchOption.AllDirectories, true, versions);
|
||||
break;
|
||||
case FGame.Unknown when UserSettings.Default.ManualGames.TryGetValue(gameDirectory, out var settings):
|
||||
{
|
||||
versions = new VersionContainer(settings.OverridedGame, UserSettings.Default.OverridedPlatform,
|
||||
customVersions: new FCustomVersionContainer(settings.OverridedCustomVersions),
|
||||
optionOverrides: settings.OverridedOptions,
|
||||
mapStructTypesOverrides: settings.OverridedMapStructTypes);
|
||||
goto default;
|
||||
}
|
||||
default:
|
||||
{
|
||||
Provider = new DefaultFileProvider(gameDirectory, SearchOption.AllDirectories, true, versions);
|
||||
break;
|
||||
}
|
||||
}
|
||||
"StateOfDecay2" => new DefaultFileProvider(new DirectoryInfo(gameDirectory),
|
||||
new List<DirectoryInfo>
|
||||
{
|
||||
new(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\StateOfDecay2\\Saved\\Paks"),
|
||||
new(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\StateOfDecay2\\Saved\\DisabledPaks")
|
||||
}, SearchOption.AllDirectories, true, versionContainer),
|
||||
"eFootball" => new DefaultFileProvider(new DirectoryInfo(gameDirectory),
|
||||
new List<DirectoryInfo>
|
||||
{
|
||||
new(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\KONAMI\\eFootball\\ST\\Download")
|
||||
}, SearchOption.AllDirectories, true, versionContainer),
|
||||
_ => new DefaultFileProvider(gameDirectory, SearchOption.AllDirectories, true, versionContainer)
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -336,7 +304,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
file.FileCount = vfs.FileCount;
|
||||
}
|
||||
|
||||
Game = Provider.GameName.ToEnum(Game);
|
||||
InternalGameName = Provider.InternalGameName;
|
||||
}
|
||||
|
||||
public void ClearProvider()
|
||||
|
|
@ -354,7 +322,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
{
|
||||
// game directory dependent, we don't have the provider game name yet since we don't have aes keys
|
||||
// except when this comes from the AES Manager
|
||||
if (!UserSettings.IsEndpointValid(Game, EEndpointType.Aes, out var endpoint))
|
||||
if (!UserSettings.IsEndpointValid(EEndpointType.Aes, out var endpoint))
|
||||
return;
|
||||
|
||||
await _threadWorkerView.Begin(cancellationToken =>
|
||||
|
|
@ -362,7 +330,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
var aes = _apiEndpointView.DynamicApi.GetAesKeys(cancellationToken, endpoint.Url, endpoint.Path);
|
||||
if (aes is not { IsValid: true }) return;
|
||||
|
||||
UserSettings.Default.AesKeys[Game] = aes;
|
||||
UserSettings.Default.CurrentDir.AesKeys = aes;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -370,7 +338,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
{
|
||||
await _threadWorkerView.Begin(cancellationToken =>
|
||||
{
|
||||
var info = _apiEndpointView.FModelApi.GetNews(cancellationToken, Provider.GameName);
|
||||
var info = _apiEndpointView.FModelApi.GetNews(cancellationToken, Provider.InternalGameName);
|
||||
if (info == null) return;
|
||||
|
||||
FLogger.Append(ELog.None, () =>
|
||||
|
|
@ -385,7 +353,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
|
||||
public Task InitMappings()
|
||||
{
|
||||
if (!UserSettings.IsEndpointValid(Game, EEndpointType.Mapping, out var endpoint))
|
||||
if (!UserSettings.IsEndpointValid(EEndpointType.Mapping, out var endpoint))
|
||||
{
|
||||
Provider.MappingsContainer = null;
|
||||
return Task.CompletedTask;
|
||||
|
|
@ -458,10 +426,8 @@ public class CUE4ParseViewModel : ViewModel
|
|||
FLogger.Text("Additive animations have their reference pose stripped, which will lead to inaccurate preview and export", Constants.WHITE, true));
|
||||
continue;
|
||||
case "r.StaticMesh.KeepMobileMinLODSettingOnDesktop":
|
||||
Provider.Versions["StaticMesh.KeepMobileMinLODSettingOnDesktop"] = boolValue;
|
||||
continue;
|
||||
case "r.SkeletalMesh.KeepMobileMinLODSettingOnDesktop":
|
||||
Provider.Versions["SkeletalMesh.KeepMobileMinLODSettingOnDesktop"] = boolValue;
|
||||
Provider.Versions[it.Key[2..]] = boolValue;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
@ -487,7 +453,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
|
||||
public Task VerifyContentBuildManifest()
|
||||
{
|
||||
if (Provider is not DefaultFileProvider || !Provider.GameName.Equals("FortniteGame", StringComparison.OrdinalIgnoreCase))
|
||||
if (Provider is not DefaultFileProvider || !Provider.InternalGameName.Equals("FortniteGame", StringComparison.OrdinalIgnoreCase))
|
||||
return Task.CompletedTask;
|
||||
|
||||
var persistentDownloadDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "FortniteGame/Saved/PersistentDownloadDir");
|
||||
|
|
@ -579,7 +545,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
}
|
||||
private Task LoadHotfixedLocalizedResources()
|
||||
{
|
||||
if (!Provider.GameName.Equals("fortnitegame", StringComparison.OrdinalIgnoreCase) || HotfixedResourcesDone) return Task.CompletedTask;
|
||||
if (!Provider.InternalGameName.Equals("fortnitegame", StringComparison.OrdinalIgnoreCase) || HotfixedResourcesDone) return Task.CompletedTask;
|
||||
return Task.Run(() =>
|
||||
{
|
||||
var hotfixes = ApplicationService.ApiEndpointView.CentralApi.GetHotfixes(default, Provider.GetLanguageCode(UserSettings.Default.AssetLanguage));
|
||||
|
|
@ -606,7 +572,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
if (_virtualPathCount > 0) return Task.CompletedTask;
|
||||
return Task.Run(() =>
|
||||
{
|
||||
_virtualPathCount = Provider.LoadVirtualPaths(UserSettings.Default.OverridedGame[Game].GetVersion());
|
||||
_virtualPathCount = Provider.LoadVirtualPaths(UserSettings.Default.CurrentDir.UeVersion.GetVersion());
|
||||
if (_virtualPathCount > 0)
|
||||
{
|
||||
FLogger.Append(ELog.Information, () =>
|
||||
|
|
@ -927,7 +893,8 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case UStaticMesh when isNone && UserSettings.Default.PreviewStaticMeshes:
|
||||
case USkeletalMesh when isNone && UserSettings.Default.PreviewSkeletalMeshes:
|
||||
case UMaterialInstance when isNone && UserSettings.Default.PreviewMaterials && !ModelIsOverwritingMaterial &&
|
||||
!(Game == FGame.FortniteGame && export.Owner != null && (export.Owner.Name.EndsWith($"/MI_OfferImages/{export.Name}", StringComparison.OrdinalIgnoreCase) ||
|
||||
!(Provider.InternalGameName.Equals("FortniteGame", StringComparison.OrdinalIgnoreCase) && export.Owner != null &&
|
||||
(export.Owner.Name.EndsWith($"/MI_OfferImages/{export.Name}", StringComparison.OrdinalIgnoreCase) ||
|
||||
export.Owner.Name.EndsWith($"/RenderSwitch_Materials/{export.Name}", StringComparison.OrdinalIgnoreCase) ||
|
||||
export.Owner.Name.EndsWith($"/MI_BPTile/{export.Name}", StringComparison.OrdinalIgnoreCase))):
|
||||
{
|
||||
|
|
@ -1012,7 +979,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
MaterialFormat = UserSettings.Default.MaterialExportFormat,
|
||||
TextureFormat = UserSettings.Default.TextureExportFormat,
|
||||
SocketFormat = UserSettings.Default.SocketExportFormat,
|
||||
Platform = UserSettings.Default.OverridedPlatform,
|
||||
Platform = UserSettings.Default.CurrentDir.TexturePlatform,
|
||||
ExportMorphTargets = UserSettings.Default.SaveMorphTargets
|
||||
};
|
||||
var toSave = new Exporter(export, exportOptions);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
using AdonisUI.Controls;
|
||||
using FModel.Framework;
|
||||
using FModel.Settings;
|
||||
using FModel.Views;
|
||||
|
||||
namespace FModel.ViewModels.Commands;
|
||||
|
|
@ -31,4 +32,4 @@ public class AddEditDirectoryCommand : ViewModelCommand<CustomDirectoriesViewMod
|
|||
contextViewModel.Add(customDir);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using FModel.Framework;
|
||||
using FModel.Settings;
|
||||
|
||||
namespace FModel.ViewModels.Commands;
|
||||
|
||||
|
|
@ -17,4 +18,4 @@ public class DeleteDirectoryCommand : ViewModelCommand<CustomDirectoriesViewMode
|
|||
|
||||
contextViewModel.Delete(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,13 +23,13 @@ public class MenuCommand : ViewModelCommand<ApplicationViewModel>
|
|||
switch (parameter)
|
||||
{
|
||||
case "Directory_Selector":
|
||||
contextViewModel.AvoidEmptyGameDirectoryAndSetEGame(true);
|
||||
contextViewModel.AvoidEmptyGameDirectory(true);
|
||||
break;
|
||||
case "Directory_AES":
|
||||
Helper.OpenWindow<AdonisWindow>("AES Manager", () => new AesManager().Show());
|
||||
break;
|
||||
case "Directory_Backup":
|
||||
Helper.OpenWindow<AdonisWindow>("Backup Manager", () => new BackupManager(contextViewModel.CUE4Parse.Provider.GameName).Show());
|
||||
Helper.OpenWindow<AdonisWindow>("Backup Manager", () => new BackupManager(contextViewModel.CUE4Parse.Provider.InternalGameName).Show());
|
||||
break;
|
||||
case "Directory_ArchivesInfo":
|
||||
contextViewModel.CUE4Parse.TabControl.AddTab("Archives Info");
|
||||
|
|
@ -51,10 +51,6 @@ public class MenuCommand : ViewModelCommand<ApplicationViewModel>
|
|||
case "Settings":
|
||||
Helper.OpenWindow<AdonisWindow>("Settings", () => new SettingsView().Show());
|
||||
break;
|
||||
case "ModelSettings":
|
||||
UserSettings.Default.LastOpenedSettingTab = contextViewModel.CUE4Parse.Game == FGame.FortniteGame ? 2 : 1;
|
||||
Helper.OpenWindow<AdonisWindow>("Settings", () => new SettingsView().Show());
|
||||
break;
|
||||
case "Help_About":
|
||||
Helper.OpenWindow<AdonisWindow>("About", () => new About().Show());
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -11,37 +11,6 @@ using FModel.ViewModels.Commands;
|
|||
|
||||
namespace FModel.ViewModels;
|
||||
|
||||
public class CustomDirectory : ViewModel
|
||||
{
|
||||
private string _header;
|
||||
public string Header
|
||||
{
|
||||
get => _header;
|
||||
set => SetProperty(ref _header, value);
|
||||
}
|
||||
|
||||
private string _directoryPath;
|
||||
public string DirectoryPath
|
||||
{
|
||||
get => _directoryPath;
|
||||
set => SetProperty(ref _directoryPath, value);
|
||||
}
|
||||
|
||||
public CustomDirectory()
|
||||
{
|
||||
Header = string.Empty;
|
||||
DirectoryPath = string.Empty;
|
||||
}
|
||||
|
||||
public CustomDirectory(string header, string path)
|
||||
{
|
||||
Header = header;
|
||||
DirectoryPath = path;
|
||||
}
|
||||
|
||||
public override string ToString() => Header;
|
||||
}
|
||||
|
||||
public class CustomDirectoriesViewModel : ViewModel
|
||||
{
|
||||
private GoToCommand _goToCommand;
|
||||
|
|
@ -54,13 +23,8 @@ public class CustomDirectoriesViewModel : ViewModel
|
|||
private readonly ObservableCollection<Control> _directories;
|
||||
public ReadOnlyObservableCollection<Control> Directories { get; }
|
||||
|
||||
private readonly FGame _game;
|
||||
private readonly string _gameDirectoryAtLaunch;
|
||||
|
||||
public CustomDirectoriesViewModel(FGame game, string directory)
|
||||
public CustomDirectoriesViewModel()
|
||||
{
|
||||
_game = game;
|
||||
_gameDirectoryAtLaunch = directory;
|
||||
_directories = new ObservableCollection<Control>(EnumerateDirectories());
|
||||
Directories = new ReadOnlyObservableCollection<Control>(_directories);
|
||||
}
|
||||
|
|
@ -74,6 +38,7 @@ public class CustomDirectoriesViewModel : ViewModel
|
|||
public void Add(CustomDirectory dir)
|
||||
{
|
||||
_directories.Add(new MenuItem { Header = dir.Header, Tag = dir.DirectoryPath, ItemsSource = EnumerateCommands(dir) });
|
||||
Save();
|
||||
}
|
||||
|
||||
public void Edit(int index, CustomDirectory newDir)
|
||||
|
|
@ -82,25 +47,25 @@ public class CustomDirectoriesViewModel : ViewModel
|
|||
|
||||
dir.Header = newDir.Header;
|
||||
dir.Tag = newDir.DirectoryPath;
|
||||
Save();
|
||||
}
|
||||
|
||||
public void Delete(int index)
|
||||
{
|
||||
_directories.RemoveAt(index);
|
||||
Save();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
var cd = new List<CustomDirectory>();
|
||||
var directories = new List<CustomDirectory>();
|
||||
for (var i = 2; i < _directories.Count; i++)
|
||||
{
|
||||
if (_directories[i] is not MenuItem m) continue;
|
||||
cd.Add(new CustomDirectory(m.Header.ToString(), m.Tag.ToString()));
|
||||
directories.Add(new CustomDirectory(m.Header.ToString(), m.Tag.ToString()));
|
||||
}
|
||||
|
||||
if (_game == FGame.Unknown && UserSettings.Default.ManualGames.ContainsKey(_gameDirectoryAtLaunch))
|
||||
UserSettings.Default.ManualGames[_gameDirectoryAtLaunch].CustomDirectories = cd;
|
||||
else UserSettings.Default.CustomDirectories[_game] = cd;
|
||||
UserSettings.Default.CurrentDir.Directories = directories;
|
||||
}
|
||||
|
||||
private IEnumerable<Control> EnumerateDirectories()
|
||||
|
|
@ -115,12 +80,7 @@ public class CustomDirectoriesViewModel : ViewModel
|
|||
};
|
||||
yield return new Separator();
|
||||
|
||||
IList<CustomDirectory> cd;
|
||||
if (_game == FGame.Unknown && UserSettings.Default.ManualGames.TryGetValue(_gameDirectoryAtLaunch, out var settings))
|
||||
cd = settings.CustomDirectories;
|
||||
else cd = UserSettings.Default.CustomDirectories[_game];
|
||||
|
||||
foreach (var setting in cd)
|
||||
foreach (var setting in UserSettings.Default.CurrentDir.Directories)
|
||||
{
|
||||
if (setting.DirectoryPath.EndsWith('/'))
|
||||
setting.DirectoryPath = setting.DirectoryPath[..^1];
|
||||
|
|
@ -167,4 +127,4 @@ public class CustomDirectoriesViewModel : ViewModel
|
|||
CommandParameter = dir
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,114 +22,93 @@ public class GameSelectorViewModel : ViewModel
|
|||
{
|
||||
public string GameName { get; set; }
|
||||
public string GameDirectory { get; set; }
|
||||
public EGame OverridedGame { get; set; }
|
||||
public bool IsManual { get; set; }
|
||||
|
||||
// the followings are only used when game is manually added
|
||||
public AesResponse AesKeys { get; set; }
|
||||
public EGame OverridedGame { get; set; }
|
||||
public List<FCustomVersion> OverridedCustomVersions { get; set; }
|
||||
public Dictionary<string, bool> OverridedOptions { get; set; }
|
||||
public Dictionary<string, KeyValuePair<string, string>> OverridedMapStructTypes { get; set; }
|
||||
public IList<CustomDirectory> CustomDirectories { get; set; }
|
||||
}
|
||||
|
||||
private DetectedGame _selectedDetectedGame;
|
||||
public DetectedGame SelectedDetectedGame
|
||||
private DirectorySettings _selectedDirectory;
|
||||
public DirectorySettings SelectedDirectory
|
||||
{
|
||||
get => _selectedDetectedGame;
|
||||
set => SetProperty(ref _selectedDetectedGame, value);
|
||||
get => _selectedDirectory;
|
||||
set => SetProperty(ref _selectedDirectory, value);
|
||||
}
|
||||
|
||||
private readonly ObservableCollection<DetectedGame> _autoDetectedGames;
|
||||
public ReadOnlyObservableCollection<DetectedGame> AutoDetectedGames { get; }
|
||||
private readonly ObservableCollection<DirectorySettings> _detectedDirectories;
|
||||
public ReadOnlyObservableCollection<DirectorySettings> DetectedDirectories { get; }
|
||||
public ReadOnlyObservableCollection<EGame> UeVersions { get; }
|
||||
|
||||
public GameSelectorViewModel(string gameDirectory)
|
||||
{
|
||||
_autoDetectedGames = new ObservableCollection<DetectedGame>(EnumerateDetectedGames().Where(x => x != null));
|
||||
foreach (var game in UserSettings.Default.ManualGames.Values)
|
||||
_detectedDirectories = new ObservableCollection<DirectorySettings>(EnumerateDetectedGames().Where(x => x != null));
|
||||
foreach (var dir in UserSettings.Default.PerDirectory.Values.Where(x => x.IsManual))
|
||||
{
|
||||
_autoDetectedGames.Add(game);
|
||||
_detectedDirectories.Add((DirectorySettings) dir.Clone());
|
||||
}
|
||||
|
||||
AutoDetectedGames = new ReadOnlyObservableCollection<DetectedGame>(_autoDetectedGames);
|
||||
DetectedDirectories = new ReadOnlyObservableCollection<DirectorySettings>(_detectedDirectories);
|
||||
|
||||
if (AutoDetectedGames.FirstOrDefault(x => x.GameDirectory == gameDirectory) is { } detectedGame)
|
||||
SelectedDetectedGame = detectedGame;
|
||||
if (DetectedDirectories.FirstOrDefault(x => x.GameDirectory == gameDirectory) is { } detectedGame)
|
||||
SelectedDirectory = detectedGame;
|
||||
else if (!string.IsNullOrEmpty(gameDirectory))
|
||||
AddUnknownGame(gameDirectory);
|
||||
AddUndetectedDir(gameDirectory);
|
||||
else
|
||||
SelectedDetectedGame = AutoDetectedGames.FirstOrDefault();
|
||||
SelectedDirectory = DetectedDirectories.FirstOrDefault();
|
||||
|
||||
UeVersions = new ReadOnlyObservableCollection<EGame>(new ObservableCollection<EGame>(EnumerateUeGames()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// dedicated to manual games
|
||||
/// </summary>
|
||||
public void AddUnknownGame(string gameName, string gameDirectory)
|
||||
public void AddUndetectedDir(string gameDirectory) => AddUndetectedDir(gameDirectory.SubstringAfterLast('\\'), gameDirectory);
|
||||
public void AddUndetectedDir(string gameName, string gameDirectory)
|
||||
{
|
||||
var game = new DetectedGame
|
||||
{
|
||||
GameName = gameName,
|
||||
GameDirectory = gameDirectory,
|
||||
IsManual = true,
|
||||
AesKeys = null,
|
||||
OverridedGame = EGame.GAME_UE4_LATEST,
|
||||
OverridedCustomVersions = null,
|
||||
OverridedOptions = null,
|
||||
OverridedMapStructTypes = null,
|
||||
CustomDirectories = new List<CustomDirectory>()
|
||||
};
|
||||
|
||||
UserSettings.Default.ManualGames[gameDirectory] = game;
|
||||
_autoDetectedGames.Add(game);
|
||||
SelectedDetectedGame = AutoDetectedGames.Last();
|
||||
}
|
||||
|
||||
public void AddUnknownGame(string gameDirectory)
|
||||
{
|
||||
_autoDetectedGames.Add(new DetectedGame { GameName = gameDirectory.SubstringAfterLast('\\'), GameDirectory = gameDirectory });
|
||||
SelectedDetectedGame = AutoDetectedGames.Last();
|
||||
var setting = DirectorySettings.Default(gameName, gameDirectory, true);
|
||||
UserSettings.Default.PerDirectory[gameDirectory] = setting;
|
||||
_detectedDirectories.Add(setting);
|
||||
SelectedDirectory = DetectedDirectories.Last();
|
||||
}
|
||||
|
||||
public void DeleteSelectedGame()
|
||||
{
|
||||
UserSettings.Default.ManualGames.Remove(SelectedDetectedGame.GameDirectory); // should not be a problem
|
||||
_autoDetectedGames.Remove(SelectedDetectedGame);
|
||||
SelectedDetectedGame = AutoDetectedGames.Last();
|
||||
UserSettings.Default.PerDirectory.Remove(SelectedDirectory.GameDirectory); // should not be a problem
|
||||
_detectedDirectories.Remove(SelectedDirectory);
|
||||
SelectedDirectory = DetectedDirectories.Last();
|
||||
}
|
||||
|
||||
private IEnumerable<DetectedGame> EnumerateDetectedGames()
|
||||
private IEnumerable<EGame> EnumerateUeGames() => Enum.GetValues<EGame>();
|
||||
private IEnumerable<DirectorySettings> EnumerateDetectedGames()
|
||||
{
|
||||
yield return GetUnrealEngineGame("Fortnite", "\\FortniteGame\\Content\\Paks");
|
||||
yield return new DetectedGame { GameName = "Fortnite [LIVE]", GameDirectory = Constants._FN_LIVE_TRIGGER };
|
||||
yield return GetUnrealEngineGame("Pewee", "\\RogueCompany\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("Rosemallow", "\\Indiana\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("Catnip", "\\OakGame\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("AzaleaAlpha", "\\Prospect\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("WorldExplorersLive", "\\WorldExplorers\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("Newt", "\\g3\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("shoebill", "\\SwGame\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("Snoek", "\\StateOfDecay2\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("a99769d95d8f400baad1f67ab5dfe508", "\\Core\\Platform\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("Nebula", "\\BendGame\\Content");
|
||||
yield return GetUnrealEngineGame("711c5e95dc094ca58e5f16bd48e751d6", "\\MultiVersus\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("9361c8c6d2f34b42b5f2f61093eedf48", "\\TslGame\\Content\\Paks");
|
||||
yield return GetRiotGame("VALORANT", "ShooterGame\\Content\\Paks");
|
||||
yield return new DetectedGame { GameName = "Valorant [LIVE]", GameDirectory = Constants._VAL_LIVE_TRIGGER };
|
||||
yield return GetMojangGame("MinecraftDungeons", "\\dungeons\\dungeons\\Dungeons\\Content\\Paks");
|
||||
yield return GetSteamGame(381210, "\\DeadByDaylight\\Content\\Paks"); // Dead By Daylight
|
||||
yield return GetSteamGame(578080, "\\TslGame\\Content\\Paks"); // PUBG
|
||||
yield return GetSteamGame(1172380, "\\SwGame\\Content\\Paks"); // STAR WARS Jedi: Fallen Order™
|
||||
yield return GetSteamGame(677620, "\\PortalWars\\Content\\Paks"); // Splitgate
|
||||
yield return GetSteamGame(1172620, "\\Athena\\Content\\Paks"); // Sea of Thieves
|
||||
yield return GetSteamGame(1665460, "\\pak"); // eFootball 2023
|
||||
yield return GetRockstarGamesGame("GTA III - Definitive Edition", "\\Gameface\\Content\\Paks");
|
||||
yield return GetRockstarGamesGame("GTA San Andreas - Definitive Edition", "\\Gameface\\Content\\Paks");
|
||||
yield return GetRockstarGamesGame("GTA Vice City - Definitive Edition", "\\Gameface\\Content\\Paks");
|
||||
yield return GetLevelInfiniteGame("tof_launcher", "\\Hotta\\Content\\Paks");
|
||||
yield return GetUnrealEngineGame("Fortnite", "\\FortniteGame\\Content\\Paks", EGame.GAME_UE5_3);
|
||||
yield return DirectorySettings.Default("Fortnite [LIVE]", Constants._FN_LIVE_TRIGGER, ue: EGame.GAME_UE5_3);
|
||||
yield return GetUnrealEngineGame("Pewee", "\\RogueCompany\\Content\\Paks", EGame.GAME_RogueCompany);
|
||||
yield return GetUnrealEngineGame("Rosemallow", "\\Indiana\\Content\\Paks", EGame.GAME_UE4_21);
|
||||
yield return GetUnrealEngineGame("Catnip", "\\OakGame\\Content\\Paks", EGame.GAME_Borderlands3);
|
||||
yield return GetUnrealEngineGame("AzaleaAlpha", "\\Prospect\\Content\\Paks", EGame.GAME_UE4_27);
|
||||
yield return GetUnrealEngineGame("shoebill", "\\SwGame\\Content\\Paks", EGame.GAME_StarWarsJediFallenOrder);
|
||||
yield return GetUnrealEngineGame("Snoek", "\\StateOfDecay2\\Content\\Paks", EGame.GAME_StateOfDecay2);
|
||||
yield return GetUnrealEngineGame("711c5e95dc094ca58e5f16bd48e751d6", "\\MultiVersus\\Content\\Paks", EGame.GAME_UE4_26);
|
||||
yield return GetUnrealEngineGame("9361c8c6d2f34b42b5f2f61093eedf48", "\\TslGame\\Content\\Paks", EGame.GAME_PlayerUnknownsBattlegrounds);
|
||||
yield return GetRiotGame("VALORANT", "ShooterGame\\Content\\Paks", EGame.GAME_Valorant);
|
||||
yield return DirectorySettings.Default("VALORANT [LIVE]", Constants._VAL_LIVE_TRIGGER, ue: EGame.GAME_Valorant);
|
||||
yield return GetSteamGame(381210, "\\DeadByDaylight\\Content\\Paks", EGame.GAME_UE4_27); // Dead By Daylight
|
||||
yield return GetSteamGame(578080, "\\TslGame\\Content\\Paks", EGame.GAME_PlayerUnknownsBattlegrounds); // PUBG
|
||||
yield return GetSteamGame(1172380, "\\SwGame\\Content\\Paks", EGame.GAME_StarWarsJediFallenOrder); // STAR WARS Jedi: Fallen Order™
|
||||
yield return GetSteamGame(677620, "\\PortalWars\\Content\\Paks", EGame.GAME_Splitgate); // Splitgate
|
||||
yield return GetSteamGame(1172620, "\\Athena\\Content\\Paks", EGame.GAME_SeaOfThieves); // Sea of Thieves
|
||||
yield return GetSteamGame(1665460, "\\pak", EGame.GAME_UE4_26); // eFootball 2023
|
||||
yield return GetRockstarGamesGame("GTA III - Definitive Edition", "\\Gameface\\Content\\Paks", EGame.GAME_GTATheTrilogyDefinitiveEdition);
|
||||
yield return GetRockstarGamesGame("GTA San Andreas - Definitive Edition", "\\Gameface\\Content\\Paks", EGame.GAME_GTATheTrilogyDefinitiveEdition);
|
||||
yield return GetRockstarGamesGame("GTA Vice City - Definitive Edition", "\\Gameface\\Content\\Paks", EGame.GAME_GTATheTrilogyDefinitiveEdition);
|
||||
yield return GetLevelInfiniteGame("tof_launcher", "\\Hotta\\Content\\Paks", EGame.GAME_TowerOfFantasy);
|
||||
}
|
||||
|
||||
private LauncherInstalled _launcherInstalled;
|
||||
private DetectedGame GetUnrealEngineGame(string gameName, string pakDirectory)
|
||||
private DirectorySettings GetUnrealEngineGame(string gameName, string pakDirectory, EGame ueVersion)
|
||||
{
|
||||
_launcherInstalled ??= GetDriveLauncherInstalls<LauncherInstalled>("ProgramData\\Epic\\UnrealEngineLauncher\\LauncherInstalled.dat");
|
||||
if (_launcherInstalled?.InstallationList != null)
|
||||
|
|
@ -140,7 +119,7 @@ public class GameSelectorViewModel : ViewModel
|
|||
if (installationList.AppName.Equals(gameName, StringComparison.OrdinalIgnoreCase) && Directory.Exists(gameDir))
|
||||
{
|
||||
Log.Debug("Found {GameName} in LauncherInstalled.dat", gameName);
|
||||
return new DetectedGame { GameName = installationList.AppName, GameDirectory = gameDir };
|
||||
return DirectorySettings.Default(installationList.AppName, gameDir, ue: ueVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -149,7 +128,7 @@ public class GameSelectorViewModel : ViewModel
|
|||
}
|
||||
|
||||
private RiotClientInstalls _riotClientInstalls;
|
||||
private DetectedGame GetRiotGame(string gameName, string pakDirectory)
|
||||
private DirectorySettings GetRiotGame(string gameName, string pakDirectory, EGame ueVersion)
|
||||
{
|
||||
_riotClientInstalls ??= GetDriveLauncherInstalls<RiotClientInstalls>("ProgramData\\Riot Games\\RiotClientInstalls.json");
|
||||
if (_riotClientInstalls is { AssociatedClient: { } })
|
||||
|
|
@ -160,7 +139,7 @@ public class GameSelectorViewModel : ViewModel
|
|||
if (key.Contains(gameName, StringComparison.OrdinalIgnoreCase) && Directory.Exists(gameDir))
|
||||
{
|
||||
Log.Debug("Found {GameName} in RiotClientInstalls.json", gameName);
|
||||
return new DetectedGame { GameName = gameName, GameDirectory = gameDir };
|
||||
return DirectorySettings.Default(gameName, gameDir, ue: ueVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,36 +147,19 @@ public class GameSelectorViewModel : ViewModel
|
|||
return null;
|
||||
}
|
||||
|
||||
private LauncherSettings _launcherSettings;
|
||||
private DetectedGame GetMojangGame(string gameName, string pakDirectory)
|
||||
{
|
||||
_launcherSettings ??= GetDataLauncherInstalls<LauncherSettings>("\\.minecraft\\launcher_settings.json");
|
||||
if (_launcherSettings is { ProductLibraryDir: { } })
|
||||
{
|
||||
var gameDir = $"{_launcherSettings.ProductLibraryDir}{pakDirectory}";
|
||||
if (Directory.Exists(gameDir))
|
||||
{
|
||||
Log.Debug("Found {GameName} in launcher_settings.json", gameName);
|
||||
return new DetectedGame { GameName = gameName, GameDirectory = gameDir };
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DetectedGame GetSteamGame(int id, string pakDirectory)
|
||||
private DirectorySettings GetSteamGame(int id, string pakDirectory, EGame ueVersion)
|
||||
{
|
||||
var steamInfo = SteamDetection.GetSteamGameById(id);
|
||||
if (steamInfo is not null)
|
||||
{
|
||||
Log.Debug("Found {GameName} in steam manifests", steamInfo.Name);
|
||||
return new DetectedGame { GameName = steamInfo.Name, GameDirectory = $"{steamInfo.GameRoot}{pakDirectory}" };
|
||||
return DirectorySettings.Default(steamInfo.Name, $"{steamInfo.GameRoot}{pakDirectory}", ue: ueVersion);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DetectedGame GetRockstarGamesGame(string key, string pakDirectory)
|
||||
private DirectorySettings GetRockstarGamesGame(string key, string pakDirectory, EGame ueVersion)
|
||||
{
|
||||
var installLocation = string.Empty;
|
||||
try
|
||||
|
|
@ -213,13 +175,13 @@ public class GameSelectorViewModel : ViewModel
|
|||
if (Directory.Exists(gameDir))
|
||||
{
|
||||
Log.Debug("Found {GameName} in the registry", key);
|
||||
return new DetectedGame { GameName = key, GameDirectory = gameDir };
|
||||
return DirectorySettings.Default(key, gameDir, ue: ueVersion);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private DetectedGame GetLevelInfiniteGame(string key, string pakDirectory)
|
||||
private DirectorySettings GetLevelInfiniteGame(string key, string pakDirectory, EGame ueVersion)
|
||||
{
|
||||
var installLocation = string.Empty;
|
||||
var displayName = string.Empty;
|
||||
|
|
@ -238,7 +200,7 @@ public class GameSelectorViewModel : ViewModel
|
|||
if (Directory.Exists(gameDir))
|
||||
{
|
||||
Log.Debug("Found {GameName} in the registry", key);
|
||||
return new DetectedGame { GameName = displayName, GameDirectory = gameDir };
|
||||
return DirectorySettings.Default(displayName, gameDir, ue: ueVersion);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
@ -258,19 +220,6 @@ public class GameSelectorViewModel : ViewModel
|
|||
return default;
|
||||
}
|
||||
|
||||
private T GetDataLauncherInstalls<T>(string jsonFile)
|
||||
{
|
||||
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
var launcher = $"{appData}{jsonFile}";
|
||||
if (File.Exists(launcher))
|
||||
{
|
||||
Log.Debug("\"{Launcher}\" found in \"{AppData}\"", launcher, appData);
|
||||
return JsonConvert.DeserializeObject<T>(File.ReadAllText(launcher));
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
#pragma warning disable 649
|
||||
private class LauncherInstalled
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,26 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Threading.Tasks;
|
||||
using CUE4Parse.UE4.Assets.Exports.Texture;
|
||||
using CUE4Parse.UE4.Objects.Core.Misc;
|
||||
using CUE4Parse.UE4.Objects.Core.Serialization;
|
||||
using CUE4Parse.UE4.Versions;
|
||||
using CUE4Parse_Conversion.Meshes;
|
||||
using CUE4Parse_Conversion.Textures;
|
||||
using CUE4Parse.UE4.Assets.Exports.Material;
|
||||
using FModel.Extensions;
|
||||
using FModel.Framework;
|
||||
using FModel.Services;
|
||||
using FModel.Settings;
|
||||
using FModel.ViewModels.ApiEndpoints.Models;
|
||||
|
||||
namespace FModel.ViewModels;
|
||||
|
||||
public class SettingsViewModel : ViewModel
|
||||
{
|
||||
private ThreadWorkerViewModel _threadWorkerView => ApplicationService.ThreadWorkerView;
|
||||
private ApiEndpointViewModel _apiEndpointView => ApplicationService.ApiEndpointView;
|
||||
private readonly DiscordHandler _discordHandler = DiscordService.DiscordHandler;
|
||||
|
||||
private bool _useCustomOutputFolders;
|
||||
|
|
@ -37,17 +31,6 @@ public class SettingsViewModel : ViewModel
|
|||
set => SetProperty(ref _selectedUpdateMode, value);
|
||||
}
|
||||
|
||||
private string _selectedPreset;
|
||||
public string SelectedPreset
|
||||
{
|
||||
get => _selectedPreset;
|
||||
set
|
||||
{
|
||||
SetProperty(ref _selectedPreset, value);
|
||||
RaisePropertyChanged("EnableElements");
|
||||
}
|
||||
}
|
||||
|
||||
private ETexturePlatform _selectedUePlatform;
|
||||
public ETexturePlatform SelectedUePlatform
|
||||
{
|
||||
|
|
@ -62,36 +45,36 @@ public class SettingsViewModel : ViewModel
|
|||
set => SetProperty(ref _selectedUeGame, value);
|
||||
}
|
||||
|
||||
private List<FCustomVersion> _selectedCustomVersions;
|
||||
public List<FCustomVersion> SelectedCustomVersions
|
||||
private IList<FCustomVersion> _selectedCustomVersions;
|
||||
public IList<FCustomVersion> SelectedCustomVersions
|
||||
{
|
||||
get => _selectedCustomVersions;
|
||||
set => SetProperty(ref _selectedCustomVersions, value);
|
||||
}
|
||||
|
||||
private Dictionary<string, bool> _selectedOptions;
|
||||
public Dictionary<string, bool> SelectedOptions
|
||||
private IDictionary<string, bool> _selectedOptions;
|
||||
public IDictionary<string, bool> SelectedOptions
|
||||
{
|
||||
get => _selectedOptions;
|
||||
set => SetProperty(ref _selectedOptions, value);
|
||||
}
|
||||
|
||||
private Dictionary<string, KeyValuePair<string, string>> _selectedMapStructTypes;
|
||||
public Dictionary<string, KeyValuePair<string, string>> SelectedMapStructTypes
|
||||
private IDictionary<string, KeyValuePair<string, string>> _selectedMapStructTypes;
|
||||
public IDictionary<string, KeyValuePair<string, string>> SelectedMapStructTypes
|
||||
{
|
||||
get => _selectedMapStructTypes;
|
||||
set => SetProperty(ref _selectedMapStructTypes, value);
|
||||
}
|
||||
|
||||
private FEndpoint _aesEndpoint;
|
||||
public FEndpoint AesEndpoint
|
||||
private EndpointSettings _aesEndpoint;
|
||||
public EndpointSettings AesEndpoint
|
||||
{
|
||||
get => _aesEndpoint;
|
||||
set => SetProperty(ref _aesEndpoint, value);
|
||||
}
|
||||
|
||||
private FEndpoint _mappingEndpoint;
|
||||
public FEndpoint MappingEndpoint
|
||||
private EndpointSettings _mappingEndpoint;
|
||||
public EndpointSettings MappingEndpoint
|
||||
{
|
||||
get => _mappingEndpoint;
|
||||
set => SetProperty(ref _mappingEndpoint, value);
|
||||
|
|
@ -168,7 +151,6 @@ public class SettingsViewModel : ViewModel
|
|||
}
|
||||
|
||||
public ReadOnlyObservableCollection<EUpdateMode> UpdateModes { get; private set; }
|
||||
public ObservableCollection<string> Presets { get; private set; }
|
||||
public ReadOnlyObservableCollection<EGame> UeGames { get; private set; }
|
||||
public ReadOnlyObservableCollection<ELanguage> AssetLanguages { get; private set; }
|
||||
public ReadOnlyObservableCollection<EAesReload> AesReloads { get; private set; }
|
||||
|
|
@ -182,10 +164,6 @@ public class SettingsViewModel : ViewModel
|
|||
public ReadOnlyObservableCollection<ETextureFormat> TextureExportFormats { get; private set; }
|
||||
public ReadOnlyObservableCollection<ETexturePlatform> Platforms { get; private set; }
|
||||
|
||||
public bool EnableElements => SelectedPreset == Constants._NO_PRESET_TRIGGER;
|
||||
|
||||
private readonly FGame _game;
|
||||
private Game _gamePreset;
|
||||
private string _outputSnapshot;
|
||||
private string _rawDataSnapshot;
|
||||
private string _propertiesSnapshot;
|
||||
|
|
@ -194,12 +172,11 @@ public class SettingsViewModel : ViewModel
|
|||
private string _modelSnapshot;
|
||||
private string _gameSnapshot;
|
||||
private EUpdateMode _updateModeSnapshot;
|
||||
private string _presetSnapshot;
|
||||
private ETexturePlatform _uePlatformSnapshot;
|
||||
private EGame _ueGameSnapshot;
|
||||
private List<FCustomVersion> _customVersionsSnapshot;
|
||||
private Dictionary<string, bool> _optionsSnapshot;
|
||||
private Dictionary<string, KeyValuePair<string, string>> _mapStructTypesSnapshot;
|
||||
private IList<FCustomVersion> _customVersionsSnapshot;
|
||||
private IDictionary<string, bool> _optionsSnapshot;
|
||||
private IDictionary<string, KeyValuePair<string, string>> _mapStructTypesSnapshot;
|
||||
private ELanguage _assetLanguageSnapshot;
|
||||
private ECompressedAudio _compressedAudioSnapshot;
|
||||
private EIconStyle _cosmeticStyleSnapshot;
|
||||
|
|
@ -211,9 +188,9 @@ public class SettingsViewModel : ViewModel
|
|||
|
||||
private bool _mappingsUpdate = false;
|
||||
|
||||
public SettingsViewModel(FGame game)
|
||||
public SettingsViewModel()
|
||||
{
|
||||
_game = game;
|
||||
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
|
|
@ -226,33 +203,19 @@ public class SettingsViewModel : ViewModel
|
|||
_modelSnapshot = UserSettings.Default.ModelDirectory;
|
||||
_gameSnapshot = UserSettings.Default.GameDirectory;
|
||||
_updateModeSnapshot = UserSettings.Default.UpdateMode;
|
||||
_presetSnapshot = UserSettings.Default.Presets[_game];
|
||||
_uePlatformSnapshot = UserSettings.Default.OverridedPlatform;
|
||||
if (_game == FGame.Unknown && UserSettings.Default.ManualGames.TryGetValue(_gameSnapshot, out var settings))
|
||||
{
|
||||
_ueGameSnapshot = settings.OverridedGame;
|
||||
_customVersionsSnapshot = settings.OverridedCustomVersions;
|
||||
_optionsSnapshot = settings.OverridedOptions;
|
||||
_mapStructTypesSnapshot = settings.OverridedMapStructTypes;
|
||||
}
|
||||
else
|
||||
{
|
||||
_ueGameSnapshot = UserSettings.Default.OverridedGame[_game];
|
||||
_customVersionsSnapshot = UserSettings.Default.OverridedCustomVersions[_game];
|
||||
_optionsSnapshot = UserSettings.Default.OverridedOptions[_game];
|
||||
_mapStructTypesSnapshot = UserSettings.Default.OverridedMapStructTypes[_game];
|
||||
}
|
||||
_uePlatformSnapshot = UserSettings.Default.CurrentDir.TexturePlatform;
|
||||
_ueGameSnapshot = UserSettings.Default.CurrentDir.UeVersion;
|
||||
_customVersionsSnapshot = UserSettings.Default.CurrentDir.Versioning.CustomVersions;
|
||||
_optionsSnapshot = UserSettings.Default.CurrentDir.Versioning.Options;
|
||||
_mapStructTypesSnapshot = UserSettings.Default.CurrentDir.Versioning.MapStructTypes;
|
||||
|
||||
if (UserSettings.Default.CustomEndpoints.TryGetValue(_game, out var endpoints))
|
||||
AesEndpoint = UserSettings.Default.CurrentDir.Endpoints[0];
|
||||
MappingEndpoint = UserSettings.Default.CurrentDir.Endpoints[1];
|
||||
MappingEndpoint.PropertyChanged += (_, args) =>
|
||||
{
|
||||
AesEndpoint = endpoints[0];
|
||||
MappingEndpoint = endpoints[1];
|
||||
MappingEndpoint.PropertyChanged += (_, args) =>
|
||||
{
|
||||
if (!_mappingsUpdate)
|
||||
_mappingsUpdate = args.PropertyName is "Overwrite" or "FilePath";
|
||||
};
|
||||
}
|
||||
if (!_mappingsUpdate)
|
||||
_mappingsUpdate = args.PropertyName is "Overwrite" or "FilePath";
|
||||
};
|
||||
|
||||
_assetLanguageSnapshot = UserSettings.Default.AssetLanguage;
|
||||
_compressedAudioSnapshot = UserSettings.Default.CompressedAudioMode;
|
||||
|
|
@ -264,7 +227,6 @@ public class SettingsViewModel : ViewModel
|
|||
_textureExportFormatSnapshot = UserSettings.Default.TextureExportFormat;
|
||||
|
||||
SelectedUpdateMode = _updateModeSnapshot;
|
||||
SelectedPreset = _presetSnapshot;
|
||||
SelectedUePlatform = _uePlatformSnapshot;
|
||||
SelectedUeGame = _ueGameSnapshot;
|
||||
SelectedCustomVersions = _customVersionsSnapshot;
|
||||
|
|
@ -282,7 +244,6 @@ public class SettingsViewModel : ViewModel
|
|||
SelectedDiscordRpc = UserSettings.Default.DiscordRpc;
|
||||
|
||||
UpdateModes = new ReadOnlyObservableCollection<EUpdateMode>(new ObservableCollection<EUpdateMode>(EnumerateUpdateModes()));
|
||||
Presets = new ObservableCollection<string>(EnumeratePresets());
|
||||
UeGames = new ReadOnlyObservableCollection<EGame>(new ObservableCollection<EGame>(EnumerateUeGames()));
|
||||
AssetLanguages = new ReadOnlyObservableCollection<ELanguage>(new ObservableCollection<ELanguage>(EnumerateAssetLanguages()));
|
||||
AesReloads = new ReadOnlyObservableCollection<EAesReload>(new ObservableCollection<EAesReload>(EnumerateAesReloads()));
|
||||
|
|
@ -297,53 +258,6 @@ public class SettingsViewModel : ViewModel
|
|||
Platforms = new ReadOnlyObservableCollection<ETexturePlatform>(new ObservableCollection<ETexturePlatform>(EnumerateUePlatforms()));
|
||||
}
|
||||
|
||||
public async Task InitPresets(string gameName)
|
||||
{
|
||||
await _threadWorkerView.Begin(cancellationToken =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(gameName)) return;
|
||||
_gamePreset = _apiEndpointView.FModelApi.GetGames(cancellationToken, gameName);
|
||||
});
|
||||
|
||||
if (_gamePreset?.Versions == null) return;
|
||||
foreach (var version in _gamePreset.Versions.Keys)
|
||||
{
|
||||
Presets.Add(version);
|
||||
}
|
||||
}
|
||||
|
||||
public void SwitchPreset(string key)
|
||||
{
|
||||
if (_gamePreset?.Versions == null || !_gamePreset.Versions.TryGetValue(key, out var version)) return;
|
||||
SelectedUeGame = version.GameEnum.ToEnum(EGame.GAME_UE4_LATEST);
|
||||
|
||||
SelectedCustomVersions = new List<FCustomVersion>();
|
||||
foreach (var (guid, v) in version.CustomVersions)
|
||||
{
|
||||
SelectedCustomVersions.Add(new FCustomVersion { Key = new FGuid(guid), Version = v });
|
||||
}
|
||||
|
||||
SelectedOptions = new Dictionary<string, bool>();
|
||||
foreach (var (k, v) in version.Options)
|
||||
{
|
||||
SelectedOptions[k] = v;
|
||||
}
|
||||
|
||||
SelectedMapStructTypes = new Dictionary<string, KeyValuePair<string, string>>();
|
||||
foreach (var (k, v) in version.MapStructTypes)
|
||||
{
|
||||
SelectedMapStructTypes[k] = v;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetPreset()
|
||||
{
|
||||
SelectedUeGame = _ueGameSnapshot;
|
||||
SelectedCustomVersions = _customVersionsSnapshot;
|
||||
SelectedOptions = _optionsSnapshot;
|
||||
SelectedMapStructTypes = _mapStructTypesSnapshot;
|
||||
}
|
||||
|
||||
public bool Save(out List<SettingsOut> whatShouldIDo)
|
||||
{
|
||||
var restart = false;
|
||||
|
|
@ -369,22 +283,11 @@ public class SettingsViewModel : ViewModel
|
|||
restart = true;
|
||||
|
||||
UserSettings.Default.UpdateMode = SelectedUpdateMode;
|
||||
UserSettings.Default.Presets[_game] = SelectedPreset;
|
||||
UserSettings.Default.OverridedPlatform = SelectedUePlatform;
|
||||
if (_game == FGame.Unknown && UserSettings.Default.ManualGames.ContainsKey(UserSettings.Default.GameDirectory))
|
||||
{
|
||||
UserSettings.Default.ManualGames[UserSettings.Default.GameDirectory].OverridedGame = SelectedUeGame;
|
||||
UserSettings.Default.ManualGames[UserSettings.Default.GameDirectory].OverridedCustomVersions = SelectedCustomVersions;
|
||||
UserSettings.Default.ManualGames[UserSettings.Default.GameDirectory].OverridedOptions = SelectedOptions;
|
||||
UserSettings.Default.ManualGames[UserSettings.Default.GameDirectory].OverridedMapStructTypes = SelectedMapStructTypes;
|
||||
}
|
||||
else
|
||||
{
|
||||
UserSettings.Default.OverridedGame[_game] = SelectedUeGame;
|
||||
UserSettings.Default.OverridedCustomVersions[_game] = SelectedCustomVersions;
|
||||
UserSettings.Default.OverridedOptions[_game] = SelectedOptions;
|
||||
UserSettings.Default.OverridedMapStructTypes[_game] = SelectedMapStructTypes;
|
||||
}
|
||||
UserSettings.Default.CurrentDir.UeVersion = SelectedUeGame;
|
||||
UserSettings.Default.CurrentDir.TexturePlatform = SelectedUePlatform;
|
||||
UserSettings.Default.CurrentDir.Versioning.CustomVersions = SelectedCustomVersions;
|
||||
UserSettings.Default.CurrentDir.Versioning.Options = SelectedOptions;
|
||||
UserSettings.Default.CurrentDir.Versioning.MapStructTypes = SelectedMapStructTypes;
|
||||
|
||||
UserSettings.Default.AssetLanguage = SelectedAssetLanguage;
|
||||
UserSettings.Default.CompressedAudioMode = SelectedCompressedAudio;
|
||||
|
|
@ -404,10 +307,6 @@ public class SettingsViewModel : ViewModel
|
|||
}
|
||||
|
||||
private IEnumerable<EUpdateMode> EnumerateUpdateModes() => Enum.GetValues<EUpdateMode>();
|
||||
private IEnumerable<string> EnumeratePresets()
|
||||
{
|
||||
yield return Constants._NO_PRESET_TRIGGER;
|
||||
}
|
||||
private IEnumerable<EGame> EnumerateUeGames() => Enum.GetValues<EGame>();
|
||||
private IEnumerable<ELanguage> EnumerateAssetLanguages() => Enum.GetValues<ELanguage>();
|
||||
private IEnumerable<EAesReload> EnumerateAesReloads() => Enum.GetValues<EAesReload>();
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ public class TabItem : ViewModel
|
|||
}
|
||||
|
||||
public void AddImage(UTexture texture, bool save, bool updateUi)
|
||||
=> AddImage(texture.Name, texture.RenderNearestNeighbor, texture.Decode(UserSettings.Default.OverridedPlatform), save, updateUi);
|
||||
=> AddImage(texture.Name, texture.RenderNearestNeighbor, texture.Decode(UserSettings.Default.CurrentDir.TexturePlatform), save, updateUi);
|
||||
|
||||
public void AddImage(string name, bool rnn, SKBitmap[] img, bool save, bool updateUi)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,14 +80,8 @@
|
|||
<Button Grid.Column="1" MinWidth="78" Margin="0 0 12 0" IsDefault="True" IsCancel="False"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Bottom" Content="OK" Click="OnClick" />
|
||||
<Button Grid.Column="2" MinWidth="78" Margin="0 0 12 0" IsDefault="False" IsCancel="False"
|
||||
HorizontalAlignment="Right" VerticalAlignment="Bottom" Content="Refresh" Click="OnRefreshAes">
|
||||
<Button.Visibility>
|
||||
<!-- if aes custom endpoint is enabled, make this visible -->
|
||||
<MultiBinding Converter="{x:Static converters:EndpointToTypeConverter.Instance}">
|
||||
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:Views.AesManager}}" Path="DataContext" />
|
||||
<Binding Source="{x:Static local:EEndpointType.Aes}" />
|
||||
</MultiBinding>
|
||||
</Button.Visibility>
|
||||
HorizontalAlignment="Right" VerticalAlignment="Bottom" Content="Refresh" Click="OnRefreshAes"
|
||||
Visibility="{Binding Converter={x:Static converters:EndpointToTypeConverter.Instance}, ConverterParameter={x:Static local:EEndpointType.Aes}}">
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
using System.Windows;
|
||||
using FModel.ViewModels;
|
||||
using FModel.Settings;
|
||||
|
||||
namespace FModel.Views;
|
||||
|
||||
|
|
@ -9,7 +9,7 @@ public partial class CustomDir
|
|||
{
|
||||
DataContext = customDir;
|
||||
InitializeComponent();
|
||||
|
||||
|
||||
Activate();
|
||||
WpfSuckMyDick.Focus();
|
||||
WpfSuckMyDick.SelectAll();
|
||||
|
|
@ -20,4 +20,4 @@ public partial class CustomDir
|
|||
DialogResult = true;
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,36 +37,45 @@
|
|||
Padding="{adonisUi:Space 0}" Background="Transparent">
|
||||
<StackPanel>
|
||||
<Grid Margin="0 5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Text="Detected Game" VerticalAlignment="Center" />
|
||||
<ComboBox Grid.Column="2" ItemsSource="{Binding AutoDetectedGames}"
|
||||
VerticalAlignment="Center" SelectedItem="{Binding SelectedDetectedGame, Mode=TwoWay}">
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Detected Game" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<ComboBox Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding DetectedDirectories}" Margin="0 0 0 5"
|
||||
VerticalAlignment="Center" SelectedItem="{Binding SelectedDirectory, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding GameName, Converter={x:Static converters:StringToGameConverter.Instance}}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
</Grid>
|
||||
<Grid x:Name="Hello" Margin="0 0 0 5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBox Grid.Column="0" Text="{Binding SelectedDetectedGame.GameDirectory, Mode=TwoWay}" />
|
||||
<Button Grid.Column="2" Content="..." HorizontalAlignment="Right" Click="OnBrowseDirectories" />
|
||||
<Button Grid.Column="3" Style="{DynamicResource {x:Static adonisUi:Styles.AccentButton}}" Padding="0"
|
||||
Click="OnDeleteDirectory" Width="{Binding ActualWidth, ElementName=OkGuysButWhoFuckingAsked}"
|
||||
Visibility="{Binding SelectedDetectedGame.IsManual, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
ToolTip="Delete Game" Margin="5 0 0 0">
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="UE Versions" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<ComboBox Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="3" ItemsSource="{Binding UeVersions}" Margin="0 0 0 5"
|
||||
VerticalAlignment="Center" SelectedItem="{Binding SelectedDirectory.UeVersion, Mode=TwoWay}">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Text="{Binding Converter={x:Static converters:EnumToStringConverter.Instance}}" />
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="2" Grid.Column="0" Text="Directory" VerticalAlignment="Center" />
|
||||
<TextBox Grid.Row="2" Grid.Column="2" Text="{Binding SelectedDirectory.GameDirectory, Mode=TwoWay}" />
|
||||
<Button Grid.Row="2" Grid.Column="4" Content="..." HorizontalAlignment="Right" Click="OnBrowseDirectories" />
|
||||
<Button Grid.Row="2" Grid.Column="4" Style="{DynamicResource {x:Static adonisUi:Styles.AccentButton}}" Padding="0"
|
||||
Click="OnDeleteDirectory" Width="{Binding ActualWidth, ElementName=OkGuysButWhoFuckingAsked}" ToolTip="Delete Game"
|
||||
Visibility="{Binding SelectedDirectory.IsManual, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<Viewbox Width="16" Height="16" HorizontalAlignment="Center">
|
||||
<Canvas Width="24" Height="24">
|
||||
<Path Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource RemoveIcon}" />
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ public partial class DirectorySelector
|
|||
var folderBrowser = new VistaFolderBrowserDialog {ShowNewFolderButton = false};
|
||||
if (folderBrowser.ShowDialog() == true)
|
||||
{
|
||||
gameLauncherViewModel.AddUnknownGame(folderBrowser.SelectedPath);
|
||||
gameLauncherViewModel.AddUndetectedDir(folderBrowser.SelectedPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -44,12 +44,12 @@ public partial class DirectorySelector
|
|||
|
||||
private void OnAddDirectory(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not GameSelectorViewModel gameLauncherViewModel||
|
||||
if (DataContext is not GameSelectorViewModel gameLauncherViewModel ||
|
||||
string.IsNullOrEmpty(HelloMyNameIsGame.Text) ||
|
||||
string.IsNullOrEmpty(HelloGameMyNameIsDirectory.Text))
|
||||
return;
|
||||
|
||||
gameLauncherViewModel.AddUnknownGame(HelloMyNameIsGame.Text, HelloGameMyNameIsDirectory.Text);
|
||||
gameLauncherViewModel.AddUndetectedDir(HelloMyNameIsGame.Text, HelloGameMyNameIsDirectory.Text);
|
||||
HelloMyNameIsGame.Clear();
|
||||
HelloGameMyNameIsDirectory.Clear();
|
||||
}
|
||||
|
|
@ -61,4 +61,4 @@ public partial class DirectorySelector
|
|||
|
||||
gameLauncherViewModel.DeleteSelectedGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
</Grid.RowDefinitions>
|
||||
|
||||
<avalonEdit:TextEditor x:Name="MyAvalonEditor" Grid.Row="0" Background="{DynamicResource {x:Static adonisUi:Brushes.Layer3BackgroundBrush}}"
|
||||
FontFamily="Consolas" FontSize="8pt" IsReadOnly="True" ShowLineNumbers="True" Foreground="#DAE5F2" />
|
||||
FontFamily="Consolas" FontSize="8pt" ShowLineNumbers="True" Foreground="#DAE5F2" />
|
||||
|
||||
<Border Grid.Row="1"
|
||||
Background="{DynamicResource {x:Static adonisUi:Brushes.Layer1BackgroundBrush}}"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using CUE4Parse.UE4.Objects.Core.Misc;
|
||||
|
|
@ -13,7 +12,6 @@ namespace FModel.Views.Resources.Controls;
|
|||
|
||||
public partial class DictionaryEditor
|
||||
{
|
||||
private readonly bool _enableElements;
|
||||
private readonly List<FCustomVersion> _defaultCustomVersions;
|
||||
private readonly Dictionary<string, bool> _defaultOptions;
|
||||
private readonly Dictionary<string, KeyValuePair<string, string>> _defaultMapStructTypes;
|
||||
|
|
@ -22,9 +20,8 @@ public partial class DictionaryEditor
|
|||
public Dictionary<string, bool> Options { get; private set; }
|
||||
public Dictionary<string, KeyValuePair<string, string>> MapStructTypes { get; private set; }
|
||||
|
||||
public DictionaryEditor(string title, bool enableElements)
|
||||
public DictionaryEditor(string title)
|
||||
{
|
||||
_enableElements = enableElements;
|
||||
_defaultCustomVersions = new List<FCustomVersion> { new() { Key = new FGuid(), Version = 0 } };
|
||||
_defaultOptions = new Dictionary<string, bool> { { "key1", true }, { "key2", false } };
|
||||
_defaultMapStructTypes = new Dictionary<string, KeyValuePair<string, string>> { { "MapName", new KeyValuePair<string, string>("KeyType", "ValueType") } };
|
||||
|
|
@ -32,11 +29,10 @@ public partial class DictionaryEditor
|
|||
InitializeComponent();
|
||||
|
||||
Title = title;
|
||||
MyAvalonEditor.IsReadOnly = !_enableElements;
|
||||
MyAvalonEditor.SyntaxHighlighting = AvalonExtensions.HighlighterSelector("");
|
||||
}
|
||||
|
||||
public DictionaryEditor(List<FCustomVersion> customVersions, string title, bool enableElements) : this(title, enableElements)
|
||||
public DictionaryEditor(IList<FCustomVersion> customVersions, string title) : this(title)
|
||||
{
|
||||
MyAvalonEditor.Document = new TextDocument
|
||||
{
|
||||
|
|
@ -44,7 +40,7 @@ public partial class DictionaryEditor
|
|||
};
|
||||
}
|
||||
|
||||
public DictionaryEditor(Dictionary<string, bool> options, string title, bool enableElements) : this(title, enableElements)
|
||||
public DictionaryEditor(IDictionary<string, bool> options, string title) : this(title)
|
||||
{
|
||||
MyAvalonEditor.Document = new TextDocument
|
||||
{
|
||||
|
|
@ -52,7 +48,7 @@ public partial class DictionaryEditor
|
|||
};
|
||||
}
|
||||
|
||||
public DictionaryEditor(Dictionary<string, KeyValuePair<string, string>> options, string title, bool enableElements) : this(title, enableElements)
|
||||
public DictionaryEditor(IDictionary<string, KeyValuePair<string, string>> options, string title) : this(title)
|
||||
{
|
||||
MyAvalonEditor.Document = new TextDocument
|
||||
{
|
||||
|
|
@ -62,13 +58,6 @@ public partial class DictionaryEditor
|
|||
|
||||
private void OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!_enableElements)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
switch (Title)
|
||||
|
|
@ -104,9 +93,6 @@ public partial class DictionaryEditor
|
|||
|
||||
private void OnReset(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!_enableElements)
|
||||
return;
|
||||
|
||||
MyAvalonEditor.Document = Title switch
|
||||
{
|
||||
"Versioning Configuration (Custom Versions)" => new TextDocument
|
||||
|
|
@ -117,7 +103,7 @@ public partial class DictionaryEditor
|
|||
{
|
||||
Text = JsonConvert.SerializeObject(_defaultOptions, Formatting.Indented)
|
||||
},
|
||||
"MapStructTypes" => new TextDocument
|
||||
"Versioning Configuration (MapStructTypes)" => new TextDocument
|
||||
{
|
||||
Text = JsonConvert.SerializeObject(_defaultMapStructTypes, Formatting.Indented)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,12 +2,10 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using FModel.Extensions;
|
||||
using FModel.Framework;
|
||||
using FModel.Services;
|
||||
using FModel.Settings;
|
||||
using ICSharpCode.AvalonEdit.Document;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using RestSharp;
|
||||
|
||||
namespace FModel.Views.Resources.Controls;
|
||||
|
||||
|
|
@ -16,7 +14,7 @@ public partial class EndpointEditor
|
|||
private readonly EEndpointType _type;
|
||||
private bool _isTested;
|
||||
|
||||
public EndpointEditor(FEndpoint endpoint, string title, EEndpointType type)
|
||||
public EndpointEditor(EndpointSettings endpoint, string title, EEndpointType type)
|
||||
{
|
||||
DataContext = endpoint;
|
||||
_type = type;
|
||||
|
|
@ -52,13 +50,13 @@ public partial class EndpointEditor
|
|||
|
||||
private void OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DialogResult = _isTested && DataContext is FEndpoint { IsValid: true };
|
||||
DialogResult = _isTested && DataContext is EndpointSettings { IsValid: true };
|
||||
Close();
|
||||
}
|
||||
|
||||
private async void OnSend(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not FEndpoint endpoint) return;
|
||||
if (DataContext is not EndpointSettings endpoint) return;
|
||||
|
||||
var body = await ApplicationService.ApiEndpointView.DynamicApi.GetRequestBody(default, endpoint.Url).ConfigureAwait(false);
|
||||
Application.Current.Dispatcher.Invoke(delegate
|
||||
|
|
@ -70,7 +68,7 @@ public partial class EndpointEditor
|
|||
|
||||
private void OnTest(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is not FEndpoint endpoint) return;
|
||||
if (DataContext is not EndpointSettings endpoint) return;
|
||||
|
||||
endpoint.TryValidate(ApplicationService.ApiEndpointView.DynamicApi, _type, out var response);
|
||||
_isTested = true;
|
||||
|
|
@ -82,7 +80,7 @@ public partial class EndpointEditor
|
|||
private void OnTextChanged(object sender, TextChangedEventArgs e)
|
||||
{
|
||||
if (sender is not TextBox { IsLoaded: true } ||
|
||||
DataContext is not FEndpoint endpoint) return;
|
||||
DataContext is not EndpointSettings endpoint) return;
|
||||
endpoint.IsValid = false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,21 +3,18 @@ using System.Globalization;
|
|||
using System.Windows;
|
||||
using System.Windows.Data;
|
||||
using FModel.Settings;
|
||||
using FModel.ViewModels;
|
||||
|
||||
namespace FModel.Views.Resources.Converters;
|
||||
|
||||
public class EndpointToTypeConverter : IMultiValueConverter
|
||||
public class EndpointToTypeConverter : IValueConverter
|
||||
{
|
||||
public static readonly EndpointToTypeConverter Instance = new();
|
||||
|
||||
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (values[0] is not ApplicationViewModel viewModel ||
|
||||
values[1] is not EEndpointType type)
|
||||
return false;
|
||||
if (parameter is not EEndpointType type) throw new NotImplementedException();
|
||||
|
||||
var isValid = UserSettings.IsEndpointValid(viewModel.CUE4Parse.Game, type, out _);
|
||||
var isValid = UserSettings.IsEndpointValid(type, out _);
|
||||
return targetType switch
|
||||
{
|
||||
not null when targetType == typeof(Visibility) => isValid ? Visibility.Visible : Visibility.Collapsed,
|
||||
|
|
@ -25,7 +22,7 @@ public class EndpointToTypeConverter : IMultiValueConverter
|
|||
};
|
||||
}
|
||||
|
||||
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,31 +11,24 @@ public class StringToGameConverter : IValueConverter
|
|||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
var ret = value switch
|
||||
return value switch
|
||||
{
|
||||
"Newt" => FGame.g3,
|
||||
"Nebula" => FGame.BendGame,
|
||||
"Fortnite" => FGame.FortniteGame,
|
||||
"VALORANT" => FGame.ShooterGame,
|
||||
"Pewee" => FGame.RogueCompany,
|
||||
"Catnip" => FGame.OakGame,
|
||||
"AzaleaAlpha" => FGame.Prospect,
|
||||
"Snoek" => FGame.StateOfDecay2,
|
||||
"Rosemallow" => FGame.Indiana,
|
||||
"WorldExplorersLive" => FGame.WorldExplorers,
|
||||
"MinecraftDungeons" => FGame.Dungeons,
|
||||
"shoebill" => FGame.SwGame,
|
||||
"a99769d95d8f400baad1f67ab5dfe508" => FGame.Platform,
|
||||
"711c5e95dc094ca58e5f16bd48e751d6" => FGame.MultiVersus,
|
||||
"9361c8c6d2f34b42b5f2f61093eedf48" => FGame.TslGame,
|
||||
381210 => FGame.DeadByDaylight,
|
||||
578080 => FGame.TslGame,
|
||||
677620 => FGame.PortalWars,
|
||||
1172620 => FGame.Athena,
|
||||
1665460 => FGame.eFootball,
|
||||
_ => FGame.Unknown
|
||||
"Pewee" => "Rogue Company",
|
||||
"Rosemallow" => "The Outer Worlds",
|
||||
"Catnip" => "Borderlands 3",
|
||||
"AzaleaAlpha" => "The Cycle",
|
||||
"shoebill" => "Star Wars: Jedi Fallen Order",
|
||||
"Snoek" => "State Of Decay 2",
|
||||
"711c5e95dc094ca58e5f16bd48e751d6" => "MultiVersus",
|
||||
"9361c8c6d2f34b42b5f2f61093eedf48" => "PLAYERUNKNOWN'S BATTLEGROUNDS",
|
||||
381210 => "Dead By Daylight",
|
||||
578080 => "PLAYERUNKNOWN'S BATTLEGROUNDS",
|
||||
1172380 => "Star Wars: Jedi Fallen Order",
|
||||
677620 => "Splitgate",
|
||||
1172620 => "Sea of Thieves",
|
||||
1665460 => "eFootball 2023",
|
||||
_ => value
|
||||
};
|
||||
return ret == FGame.Unknown ? value : ret.GetDescription();
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
xmlns:adonisUi="clr-namespace:AdonisUI;assembly=AdonisUI"
|
||||
xmlns:adonisControls="clr-namespace:AdonisUI.Controls;assembly=AdonisUI"
|
||||
xmlns:adonisExtensions="clr-namespace:AdonisUI.Extensions;assembly=AdonisUI"
|
||||
WindowStartupLocation="CenterScreen" ResizeMode="NoResize" IconVisibility="Collapsed" SizeToContent="Height" Loaded="OnLoaded"
|
||||
WindowStartupLocation="CenterScreen" ResizeMode="NoResize" IconVisibility="Collapsed" SizeToContent="Height"
|
||||
MinHeight="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenHeight}, Converter={converters:RatioConverter}, ConverterParameter='0.10'}"
|
||||
Width="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenWidth}, Converter={converters:RatioConverter}, ConverterParameter='0.35'}">
|
||||
<adonisControls:AdonisWindow.Style>
|
||||
|
|
@ -42,7 +42,6 @@
|
|||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
|
|
@ -55,7 +54,7 @@
|
|||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="Output Directory *" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Directory where log files, backups and other do-not-delete files will be put in." />
|
||||
<TextBox x:Name="ImStockBro" Grid.Row="0" Grid.Column="2" Text="{Binding OutputDirectory, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0 0 0 5" />
|
||||
<TextBox x:Name="ImJackedBro" Grid.Row="0" Grid.Column="2" Text="{Binding OutputDirectory, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0 0 0 5" />
|
||||
<Button Grid.Row="0" Grid.Column="4" Content="..." HorizontalAlignment="Right" Click="OnBrowseOutput" Margin="0 0 0 5" />
|
||||
|
||||
<CheckBox Grid.Row="0" Grid.Column="6" Margin="5 0 0 5" ToolTip="Customize the directory of more output folders"
|
||||
|
|
@ -73,7 +72,7 @@
|
|||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="10" />
|
||||
<ColumnDefinition Width="{Binding ActualWidth, ElementName=ImStockBro}" />
|
||||
<ColumnDefinition Width="{Binding ActualWidth, ElementName=ImJackedBro}" />
|
||||
<ColumnDefinition Width="5" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
|
@ -131,14 +130,9 @@
|
|||
|
||||
<Separator Grid.Row="6" Grid.Column="0" Grid.ColumnSpan="7" Style="{StaticResource CustomSeparator}" Tag="ADVANCED"></Separator>
|
||||
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" Text="Presets" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Use a fine tuned preset for the game you're trying to load and its version" />
|
||||
<ComboBox Grid.Row="7" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.Presets}" SelectedItem="{Binding SettingsView.SelectedPreset, Mode=TwoWay}"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" SelectionChanged="OnSelectionChanged" Margin="0 0 0 5">
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" Text="UE Versions *" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Override the UE version to use when parsing packages" />
|
||||
<ComboBox Grid.Row="8" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.UeGames}" SelectedItem="{Binding SettingsView.SelectedUeGame, Mode=TwoWay}"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" IsEnabled="{Binding SettingsView.EnableElements}"
|
||||
<TextBlock Grid.Row="7" Grid.Column="0" Text="UE Versions *" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Override the UE version to use when parsing packages" />
|
||||
<ComboBox Grid.Row="7" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.UeGames}" SelectedItem="{Binding SettingsView.SelectedUeGame, Mode=TwoWay}"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
|
||||
Margin="0 0 0 5">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
|
|
@ -147,8 +141,8 @@
|
|||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" Text="Versioning Configuration *" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<Grid Grid.Row="9" Grid.Column="2" Grid.ColumnSpan="5" Margin="0 0 0 5">
|
||||
<TextBlock Grid.Row="8" Grid.Column="0" Text="Versioning Configuration *" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<Grid Grid.Row="8" Grid.Column="2" Grid.ColumnSpan="5" Margin="0 0 0 5">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="5" />
|
||||
|
|
@ -162,9 +156,9 @@
|
|||
<Button Grid.Column="4" Content="MapStructTypes" Click="OpenMapStructTypes" />
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" Text="Texture Platform *" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Override the game's platform to ensure texture compatibility" />
|
||||
<ComboBox Grid.Row="10" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.Platforms}" SelectedItem="{Binding SettingsView.SelectedUePlatform, Mode=TwoWay}"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" IsEnabled="{Binding SettingsView.EnableElements}"
|
||||
<TextBlock Grid.Row="9" Grid.Column="0" Text="Texture Platform *" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Override the game's platform to ensure texture compatibility" />
|
||||
<ComboBox Grid.Row="9" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.Platforms}" SelectedItem="{Binding SettingsView.SelectedUePlatform, Mode=TwoWay}"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
|
||||
Margin="0 0 0 5">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
|
|
@ -173,8 +167,8 @@
|
|||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" Text="Compressed Audio" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="What to do when encountering a compressed audio file" />
|
||||
<ComboBox Grid.Row="11" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.CompressedAudios}" SelectedItem="{Binding SettingsView.SelectedCompressedAudio, Mode=TwoWay}"
|
||||
<TextBlock Grid.Row="10" Grid.Column="0" Text="Compressed Audio" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="What to do when encountering a compressed audio file" />
|
||||
<ComboBox Grid.Row="10" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.CompressedAudios}" SelectedItem="{Binding SettingsView.SelectedCompressedAudio, Mode=TwoWay}"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
|
|
@ -183,8 +177,8 @@
|
|||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="12" Grid.Column="0" Text="Endpoint Configuration" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<Grid Grid.Row="12" Grid.Column="2" Grid.ColumnSpan="5" Margin="0 0 0 5"
|
||||
<TextBlock Grid.Row="11" Grid.Column="0" Text="Endpoint Configuration" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<Grid Grid.Row="11" Grid.Column="2" Grid.ColumnSpan="5" Margin="0 0 0 5"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
|
|
@ -196,10 +190,10 @@
|
|||
<Button Grid.Column="2" Content="Mapping" Click="OpenMappingEndpoint" />
|
||||
</Grid>
|
||||
|
||||
<TextBlock Grid.Row="13" Grid.Column="0" Text="AES Reload at Launch" VerticalAlignment="Center" Margin="0 0 0 5"
|
||||
<TextBlock Grid.Row="12" Grid.Column="0" Text="AES Reload at Launch" VerticalAlignment="Center" Margin="0 0 0 5"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
|
||||
Visibility="{Binding SettingsView.AesEndpoint.IsValid, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<ComboBox Grid.Row="13" Grid.Column="2" Grid.ColumnSpan="5" Margin="0 0 0 5"
|
||||
<ComboBox Grid.Row="12" Grid.Column="2" Grid.ColumnSpan="5" Margin="0 0 0 5"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
|
||||
ItemsSource="{Binding SettingsView.AesReloads}" SelectedItem="{Binding SettingsView.SelectedAesReload, Mode=TwoWay}"
|
||||
Visibility="{Binding SettingsView.AesEndpoint.IsValid, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
|
|
@ -210,27 +204,27 @@
|
|||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<TextBlock Grid.Row="14" Grid.Column="0" Text="Serialize Script Bytecode" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<CheckBox Grid.Row="14" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
|
||||
<TextBlock Grid.Row="13" Grid.Column="0" Text="Serialize Script Bytecode" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<CheckBox Grid.Row="13" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
|
||||
IsChecked="{Binding ReadScriptData, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 5 0 10"/>
|
||||
|
||||
<TextBlock Grid.Row="15" Grid.Column="0" Text="Keep Directory Structure" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Auto-save packages following their game directory" />
|
||||
<CheckBox Grid.Row="15" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
|
||||
<TextBlock Grid.Row="14" Grid.Column="0" Text="Keep Directory Structure" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Auto-save packages following their game directory" />
|
||||
<CheckBox Grid.Row="14" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
|
||||
IsChecked="{Binding KeepDirectoryStructure, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 5 0 10"/>
|
||||
|
||||
<TextBlock Grid.Row="16" Grid.Column="0" Text="Local Mapping File" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<CheckBox Grid.Row="16" Grid.Column="2" Margin="0 5 0 10"
|
||||
<TextBlock Grid.Row="15" Grid.Column="0" Text="Local Mapping File" VerticalAlignment="Center" Margin="0 0 0 5" />
|
||||
<CheckBox Grid.Row="15" Grid.Column="2" Margin="0 5 0 10"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
|
||||
Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
|
||||
IsChecked="{Binding SettingsView.MappingEndpoint.Overwrite, Mode=TwoWay}" />
|
||||
|
||||
<TextBlock Grid.Row="17" Grid.Column="0" Text="Mapping File Path" VerticalAlignment="Center" Margin="0 0 0 5"
|
||||
<TextBlock Grid.Row="16" Grid.Column="0" Text="Mapping File Path" VerticalAlignment="Center" Margin="0 0 0 5"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
|
||||
Visibility="{Binding SettingsView.MappingEndpoint.Overwrite, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<TextBox Grid.Row="17" Grid.Column="2" Grid.ColumnSpan="3" Margin="0 0 0 5" Text="{Binding SettingsView.MappingEndpoint.FilePath, Mode=TwoWay}"
|
||||
<TextBox Grid.Row="16" Grid.Column="2" Grid.ColumnSpan="3" Margin="0 0 0 5" Text="{Binding SettingsView.MappingEndpoint.FilePath, Mode=TwoWay}"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
|
||||
Visibility="{Binding SettingsView.MappingEndpoint.Overwrite, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
<Button Grid.Row="17" Grid.Column="6" Content="..." HorizontalAlignment="Right" Click="OnBrowseMappings" Margin="0 0 0 5"
|
||||
<Button Grid.Row="16" Grid.Column="6" Content="..." HorizontalAlignment="Right" Click="OnBrowseMappings" Margin="0 0 0 5"
|
||||
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
|
||||
Visibility="{Binding SettingsView.MappingEndpoint.Overwrite, Converter={StaticResource BoolToVisibilityConverter}}" />
|
||||
</Grid>
|
||||
|
|
@ -524,7 +518,7 @@
|
|||
<Style TargetType="TreeViewItem" BasedOn="{StaticResource TreeViewItemStyle}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
|
||||
<DataTrigger Binding="{Binding CUE4Parse.InternalGameName, Converter={x:Static converters:CaseInsensitiveStringEqualsConverter.Instance}, ConverterParameter='FortniteGame'}" Value="True">
|
||||
<Setter Property="Visibility" Value="Visible" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
|
|
|
|||
|
|
@ -30,11 +30,6 @@ public partial class SettingsView
|
|||
}
|
||||
}
|
||||
|
||||
private async void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
await _applicationView.SettingsView.InitPresets(_applicationView.CUE4Parse.Provider.GameName);
|
||||
}
|
||||
|
||||
private async void OnClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var restart = _applicationView.SettingsView.Save(out var whatShouldIDo);
|
||||
|
|
@ -154,19 +149,9 @@ public partial class SettingsView
|
|||
}
|
||||
}
|
||||
|
||||
private void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
if (sender is not ComboBox { SelectedItem: string s }) return;
|
||||
if (s == Constants._NO_PRESET_TRIGGER) _applicationView.SettingsView.ResetPreset();
|
||||
else _applicationView.SettingsView.SwitchPreset(s);
|
||||
}
|
||||
|
||||
private void OpenCustomVersions(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var editor = new DictionaryEditor(
|
||||
_applicationView.SettingsView.SelectedCustomVersions,
|
||||
"Versioning Configuration (Custom Versions)",
|
||||
_applicationView.SettingsView.EnableElements);
|
||||
var editor = new DictionaryEditor(_applicationView.SettingsView.SelectedCustomVersions, "Versioning Configuration (Custom Versions)");
|
||||
var result = editor.ShowDialog();
|
||||
if (!result.HasValue || !result.Value)
|
||||
return;
|
||||
|
|
@ -176,10 +161,7 @@ public partial class SettingsView
|
|||
|
||||
private void OpenOptions(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var editor = new DictionaryEditor(
|
||||
_applicationView.SettingsView.SelectedOptions,
|
||||
"Versioning Configuration (Options)",
|
||||
_applicationView.SettingsView.EnableElements);
|
||||
var editor = new DictionaryEditor(_applicationView.SettingsView.SelectedOptions, "Versioning Configuration (Options)");
|
||||
var result = editor.ShowDialog();
|
||||
if (!result.HasValue || !result.Value)
|
||||
return;
|
||||
|
|
@ -189,10 +171,7 @@ public partial class SettingsView
|
|||
|
||||
private void OpenMapStructTypes(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var editor = new DictionaryEditor(
|
||||
_applicationView.SettingsView.SelectedMapStructTypes,
|
||||
"MapStructTypes",
|
||||
_applicationView.SettingsView.EnableElements);
|
||||
var editor = new DictionaryEditor(_applicationView.SettingsView.SelectedMapStructTypes, "Versioning Configuration (MapStructTypes)");
|
||||
var result = editor.ShowDialog();
|
||||
if (!result.HasValue || !result.Value)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@ public class Options
|
|||
["tl_next"] = new ("tl_next"),
|
||||
};
|
||||
|
||||
_platform = UserSettings.Default.OverridedPlatform;
|
||||
_game = Services.ApplicationService.ApplicationView.CUE4Parse.Provider.GameName.ToUpper();
|
||||
_platform = UserSettings.Default.CurrentDir.TexturePlatform;
|
||||
_game = Services.ApplicationService.ApplicationView.CUE4Parse.Provider.InternalGameName.ToUpper();
|
||||
|
||||
SelectModel(Guid.Empty);
|
||||
}
|
||||
|
|
@ -231,7 +231,7 @@ public class Options
|
|||
MaterialFormat = UserSettings.Default.MaterialExportFormat,
|
||||
TextureFormat = UserSettings.Default.TextureExportFormat,
|
||||
SocketFormat = UserSettings.Default.SocketExportFormat,
|
||||
Platform = UserSettings.Default.OverridedPlatform,
|
||||
Platform = _platform,
|
||||
ExportMorphTargets = UserSettings.Default.SaveMorphTargets
|
||||
};
|
||||
var toSave = new Exporter(export, exportOptions);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user