mirror of
https://github.com/4sval/FModel.git
synced 2026-03-21 17:24:26 -05:00
game display name
This commit is contained in:
parent
928834fd4b
commit
c530275d84
|
|
@ -1 +1 @@
|
|||
Subproject commit 4a3efdafa7321e98d0ca1c29d3c3d2140980ab9f
|
||||
Subproject commit ba77931bb2ff50610a05fbabb30180c80f8ab06b
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user