game display name

This commit is contained in:
4sval 2023-03-21 01:00:14 +01:00
parent 928834fd4b
commit c530275d84
11 changed files with 85 additions and 75 deletions

@ -1 +1 @@
Subproject commit 4a3efdafa7321e98d0ca1c29d3c3d2140980ab9f
Subproject commit ba77931bb2ff50610a05fbabb30180c80f8ab06b

View File

@ -14,10 +14,18 @@
Width="{Binding Source={x:Static SystemParameters.MaximizedPrimaryScreenWidth}, Converter={converters:RatioConverter}, ConverterParameter='0.75'}">
<adonisControls:AdonisWindow.Style>
<Style TargetType="adonisControls:AdonisWindow" BasedOn="{StaticResource {x:Type adonisControls:AdonisWindow}}" >
<Setter Property="Title" Value="FModel" />
<Setter Property="Title" Value="{Binding DataContext.InitialWindowTitle, RelativeSource={RelativeSource Self}}" />
<Style.Triggers>
<DataTrigger Binding="{Binding DataContext.TitleExtra, RelativeSource={RelativeSource Self}, Converter={x:Static converters:IsNullToBoolReversedConverter.Instance}}" Value="True">
<Setter Property="Title" Value="{Binding DataContext.TitleExtra, RelativeSource={RelativeSource Self}, StringFormat={}FModel {0}}" />
<Setter Property="Title">
<Setter.Value>
<MultiBinding StringFormat="{}{0} - {1} {2}">
<Binding Path="DataContext.InitialWindowTitle" RelativeSource="{RelativeSource Self}" />
<Binding Path="DataContext.GameDisplayName" RelativeSource="{RelativeSource Self}" />
<Binding Path="DataContext.TitleExtra" RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>

View File

@ -63,7 +63,7 @@ public partial class MainWindow
await _applicationView.CUE4Parse.Initialize();
await _applicationView.AesManager.InitAes();
await _applicationView.AesManager.UpdateProvider(true);
await _applicationView.UpdateProvider(true);
#if !DEBUG
await _applicationView.CUE4Parse.InitInformation();
#endif
@ -73,15 +73,12 @@ public partial class MainWindow
await _applicationView.InitOodle();
if (UserSettings.Default.DiscordRpc == EDiscordRpc.Always)
_discordHandler.Initialize(_applicationView.CUE4Parse.Provider.GameName);
_discordHandler.Initialize(_applicationView.GameDisplayName);
#if DEBUG
await _threadWorkerView.Begin(cancellationToken =>
_applicationView.CUE4Parse.Extract(cancellationToken,
"ShooterGame/Content/Characters/BountyHunter/S0/Ability_4/1P/Models/AB_BountyHunter_S0_4_TrailCreature_Skelmesh.uasset"));
await _threadWorkerView.Begin(cancellationToken =>
_applicationView.CUE4Parse.Extract(cancellationToken,
"ShooterGame/Content/Characters/BountyHunter/S0/Ability_4/1P/Anims/FP_BountyHunter_S0_4_Aim_S.uasset"));
// await _threadWorkerView.Begin(cancellationToken =>
// _applicationView.CUE4Parse.Extract(cancellationToken,
// "Discovery/Content/Discovery/Items/Charms/Charm_Skateboard_01/SM_Charm_Skateboard_01_A.uasset"));
#endif
}

View File

@ -48,7 +48,7 @@ namespace FModel.Services
public void UpdatePresence(CUE4ParseViewModel viewModel) =>
UpdatePresence(
$"{viewModel.Provider.GameName} - {viewModel.Provider.MountedVfs.Count}/{viewModel.Provider.MountedVfs.Count + viewModel.Provider.UnloadedVfs.Count} Packages",
$"{viewModel.Provider.GameDisplayName} - {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)

View File

@ -103,17 +103,11 @@ public class AesManagerViewModel : ViewModel
}
}
public async Task UpdateProvider(bool isLaunch)
public void SetAesKeys()
{
if (!isLaunch && !HasChange) return;
_cue4Parse.ClearProvider();
await _cue4Parse.LoadVfs(AesKeys);
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;
Log.Information("{@Json}", UserSettings.Default);
}

View File

@ -25,7 +25,7 @@ public class ApplicationViewModel : ViewModel
public EBuildKind Build
{
get => _build;
private set
private init
{
SetProperty(ref _build, value);
RaisePropertyChanged(nameof(TitleExtra));
@ -36,7 +36,7 @@ public class ApplicationViewModel : ViewModel
public FStatus Status
{
get => _status;
set => SetProperty(ref _status, value);
private init => SetProperty(ref _status, value);
}
public RightClickMenuCommand RightClickMenuCommand => _rightClickMenuCommand ??= new RightClickMenuCommand(this);
@ -46,9 +46,10 @@ public class ApplicationViewModel : ViewModel
public CopyCommand CopyCommand => _copyCommand ??= new CopyCommand(this);
private CopyCommand _copyCommand;
public string InitialWindowTitle => $"FModel {UserSettings.Default.UpdateMode}";
public string GameDisplayName => CUE4Parse.Provider.GameDisplayName ?? "Unknown";
public string TitleExtra =>
$"{UserSettings.Default.UpdateMode} - {CUE4Parse.Game.GetDescription()} (" + // FModel {UpdateMode} - {FGame} ({UE}) ({Build})
$"{(CUE4Parse.Game == FGame.Unknown && UserSettings.Default.ManualGames.TryGetValue(UserSettings.Default.GameDirectory, out var settings) ? settings.OverridedGame : UserSettings.Default.OverridedGame[CUE4Parse.Game])})" +
$"({(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 LoadingModesViewModel LoadingModes { get; }
@ -79,6 +80,7 @@ public class ApplicationViewModel : ViewModel
//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);
@ -103,6 +105,21 @@ public class ApplicationViewModel : ViewModel
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();
// ConsoleVariables - a.StripAdditiveRefPose=1
AesManager.SetAesKeys();
});
RaisePropertyChanged(nameof(GameDisplayName));
}
public void RestartWithWarning()
{
MessageBox.Show("It looks like you just changed something.\nFModel will restart to apply your changes.", "Uh oh, a restart is needed", MessageBoxButton.OK, MessageBoxImage.Warning);

View File

@ -298,41 +298,38 @@ public class CUE4ParseViewModel : ViewModel
/// load virtual files system from GameDirectory
/// </summary>
/// <returns></returns>
public async Task LoadVfs(IEnumerable<FileItem> aesKeys)
public void LoadVfs(CancellationToken token, IEnumerable<FileItem> aesKeys)
{
await _threadWorkerView.Begin(cancellationToken =>
GameDirectory.DeactivateAll();
// load files using UnloadedVfs to include non-encrypted vfs
foreach (var key in aesKeys)
{
GameDirectory.DeactivateAll();
token.ThrowIfCancellationRequested(); // cancel if needed
// load files using UnloadedVfs to include non-encrypted vfs
foreach (var key in aesKeys)
var k = key.Key.Trim();
if (k.Length != 66) k = Constants.ZERO_64_CHAR;
Provider.SubmitKey(key.Guid, new FAesKey(k));
}
// files in MountedVfs will be enabled
foreach (var file in GameDirectory.DirectoryFiles)
{
token.ThrowIfCancellationRequested();
if (Provider.MountedVfs.FirstOrDefault(x => x.Name == file.Name) is not { } vfs)
{
cancellationToken.ThrowIfCancellationRequested(); // cancel if needed
if (Provider.UnloadedVfs.FirstOrDefault(x => x.Name == file.Name) is IoStoreReader store)
file.FileCount = (int) store.Info.TocEntryCount - 1;
var k = key.Key.Trim();
if (k.Length != 66) k = Constants.ZERO_64_CHAR;
Provider.SubmitKey(key.Guid, new FAesKey(k));
continue;
}
// files in MountedVfs will be enabled
foreach (var file in GameDirectory.DirectoryFiles)
{
cancellationToken.ThrowIfCancellationRequested();
if (Provider.MountedVfs.FirstOrDefault(x => x.Name == file.Name) is not { } vfs)
{
if (Provider.UnloadedVfs.FirstOrDefault(x => x.Name == file.Name) is IoStoreReader store)
file.FileCount = (int) store.Info.TocEntryCount - 1;
file.IsEnabled = true;
file.MountPoint = vfs.MountPoint;
file.FileCount = vfs.FileCount;
}
continue;
}
file.IsEnabled = true;
file.MountPoint = vfs.MountPoint;
file.FileCount = vfs.FileCount;
}
Game = Helper.IAmThePanda(Provider.GameName) ? FGame.PandaGame : Provider.GameName.ToEnum(Game);
});
Game = Helper.IAmThePanda(Provider.GameName) ? FGame.PandaGame : Provider.GameName.ToEnum(Game);
}
public void ClearProvider()

View File

@ -96,28 +96,26 @@ public class MenuCommand : ViewModelCommand<ApplicationViewModel>
}
}
private static void SetFoldersIsExpanded(AssetsFolderViewModel root, bool isExpanded, CancellationToken cancellationToken)
private void SetFoldersIsExpanded(AssetsFolderViewModel root, bool expand, CancellationToken cancellationToken)
{
LinkedList<TreeItem> nodes = new();
var nodes = new LinkedList<TreeItem>();
foreach (TreeItem folder in root.Folders)
{
nodes.AddLast(folder);
}
LinkedListNode<TreeItem> current = nodes.First;
var current = nodes.First;
while (current != null)
{
TreeItem folder = current.Value;
var folder = current.Value;
// Collapse top-down (reduce layout updates)
if (!isExpanded)
if (!expand && folder.IsExpanded)
{
folder.IsExpanded = isExpanded;
folder.IsExpanded = false;
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
}
foreach (TreeItem child in folder.Folders)
foreach (var child in folder.Folders)
{
nodes.AddLast(child);
}
@ -125,15 +123,14 @@ public class MenuCommand : ViewModelCommand<ApplicationViewModel>
current = current.Next;
}
if (!expand) return;
// Expand bottom-up (reduce layout updates)
if (isExpanded)
for (var node = nodes.Last; node != null; node = node.Previous)
{
for (LinkedListNode<TreeItem> node = nodes.Last; node != null; node = node.Previous)
{
node.Value.IsExpanded = isExpanded;
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
}
node.Value.IsExpanded = true;
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
}
}
}

View File

@ -29,7 +29,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Extract_New_Tab":
foreach (var asset in assetItems)
{
Thread.Sleep(10);
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, true);
}
@ -37,7 +37,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Export_Data":
foreach (var asset in assetItems)
{
Thread.Sleep(10);
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.ExportData(asset.FullPath);
}
@ -45,7 +45,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Save_Properties":
foreach (var asset in assetItems)
{
Thread.Sleep(10);
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Properties);
}
@ -53,7 +53,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Save_Textures":
foreach (var asset in assetItems)
{
Thread.Sleep(10);
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Textures);
}
@ -61,7 +61,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Save_Models":
foreach (var asset in assetItems)
{
Thread.Sleep(10);
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Meshes | EBulkType.Auto);
}
@ -69,7 +69,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
case "Assets_Save_Animations":
foreach (var asset in assetItems)
{
Thread.Sleep(10);
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
contextViewModel.CUE4Parse.Extract(cancellationToken, asset.FullPath, false, EBulkType.Animations | EBulkType.Auto);
}

View File

@ -29,6 +29,6 @@ public partial class AesManager
private async void OnClosing(object sender, CancelEventArgs e)
{
await _applicationView.AesManager.UpdateProvider(false);
await _applicationView.UpdateProvider(false);
}
}
}

View File

@ -15,7 +15,7 @@ FModel is actively maintained and developed by a dedicated community of contribu
### Installation:
For installation, follow the instructions from [here](https://github.com/4sval/FModel/wiki/Installing-FModel)
### Support:
### Sponsorship:
<p>
<a href="https://www.jetbrains.com/">
<img src="https://cdn.fmodel.app/i/svg/jetbrains.svg" width="256px">