This commit is contained in:
Krowe Moh 2026-05-01 18:28:33 -06:00 committed by GitHub
commit 01544fabc9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 213 additions and 9 deletions

View File

@ -394,6 +394,13 @@ namespace FModel.Settings
set => SetProperty(ref _addAudio, value);
}
private Hotkey _removeAudio = new(Key.X);
public Hotkey RemoveAudio
{
get => _removeAudio;
set => SetProperty(ref _removeAudio, value);
}
private Hotkey _playPauseAudio = new(Key.K);
public Hotkey PlayPauseAudio
{

View File

@ -239,6 +239,20 @@ public class AudioPlayerViewModel : ViewModel, ISource, IDisposable
});
}
public void Unload()
{
Application.Current.Dispatcher.Invoke(() =>
{
_waveSource = null;
PlayedFile = new AudioFile(-1, "No audio file");
Spectrum = null;
RaiseSourceEvent(ESourceEventType.Clearing);
ClearSoundOut();
});
}
public void AddToPlaylist(byte[] data, string filePath)
{
Application.Current.Dispatcher.Invoke(() =>
@ -270,11 +284,30 @@ public class AudioPlayerViewModel : ViewModel, ISource, IDisposable
if (_audioFiles.Count < 1) return;
Application.Current.Dispatcher.Invoke(() =>
{
var removedPlaying = false;
if (PlayedFile.Id == SelectedAudioFile.Id)
{
removedPlaying = true;
Stop();
}
_audioFiles.RemoveAt(SelectedAudioFile.Id);
for (var i = 0; i < _audioFiles.Count; i++)
{
_audioFiles[i].Id = i;
}
if (_audioFiles.Count < 1)
{
Unload();
return;
}
SelectedAudioFile = _audioFiles[SelectedAudioFile.Id];
if (!removedPlaying) return;
Load();
Play();
});
}
@ -526,6 +559,11 @@ public class AudioPlayerViewModel : ViewModel, ISource, IDisposable
_soundOut.Volume = UserSettings.Default.AudioPlayerVolume / 100;
}
private void ClearSoundOut()
{
_soundOut = null;
}
private IEnumerable<MMDevice> EnumerateDevices()
{
using var deviceEnumerator = new MMDeviceEnumerator();

View File

@ -43,6 +43,7 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
if (param.Length == 0) return;
var folders = param.OfType<TreeItem>().ToArray();
var searchMenu = param[0] is GameFile;
var assets = param
.Select(static item => item switch
{
@ -138,6 +139,20 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
_ => (entry, bulk, update) => contextViewModel.CUE4Parse.Extract(cancellationToken, entry, false, bulk),
};
if (searchMenu)
{
var update = assets.Length > 1;
foreach (var entry in assets)
{
Thread.Yield();
cancellationToken.ThrowIfCancellationRequested();
fileAction(entry, bulktype, update);
}
if (assets.Length > 50) LogExport(contextViewModel, filetype);
return;
}
foreach (var group in assetsGroups)
{
var directory = group.Key;
@ -190,4 +205,18 @@ public class RightClickMenuCommand : ViewModelCommand<ApplicationViewModel>
Interlocked.Exchange(ref contextViewModel.CUE4Parse.ExportedCount, 0);
Interlocked.Exchange(ref contextViewModel.CUE4Parse.FailedExportCount, 0);
}
private void LogExport(ApplicationViewModel contextViewModel, string fileType)
{
if (contextViewModel.CUE4Parse.ExportedCount > 0)
{
FLogger.Append(ELog.Information, () =>
{
FLogger.Text($"Successfully exported {contextViewModel.CUE4Parse.ExportedCount} {fileType}, Failed to export {contextViewModel.CUE4Parse.FailedExportCount} {fileType} in other folders.", Constants.WHITE, true);
});
}
Interlocked.Exchange(ref contextViewModel.CUE4Parse.ExportedCount, 0);
Interlocked.Exchange(ref contextViewModel.CUE4Parse.FailedExportCount, 0);
}
}

View File

@ -31,9 +31,15 @@ public class TabCommand : ViewModelCommand<TabItem>
case "Close_Other_Tabs":
_applicationView.CUE4Parse.TabControl.RemoveOtherTabs(tabViewModel);
break;
case "Assets_Show_Metadata":
_applicationView.CUE4Parse.ShowMetadata(tabViewModel.Entry);
break;
case "Find_References":
_applicationView.CUE4Parse.FindReferences(tabViewModel.Entry);
break;
case "Assets_Decompile":
_applicationView.CUE4Parse.Decompile(tabViewModel.Entry);
break;
case "Save_Data":
await _threadWorkerView.Begin(_ => _applicationView.CUE4Parse.ExportData(tabViewModel.Entry));
break;
@ -77,9 +83,21 @@ public class TabCommand : ViewModelCommand<TabItem>
}.Show();
});
break;
case "Copy_Asset_Path":
case "File_Path":
Clipboard.SetText(tabViewModel.Entry.Path);
break;
case "File_Name":
Clipboard.SetText(tabViewModel.Entry.Name);
break;
case "Directory_Path":
Clipboard.SetText(tabViewModel.Entry.Directory);
break;
case "File_Path_No_Extension":
Clipboard.SetText(tabViewModel.Entry.PathWithoutExtension);
break;
case "File_Name_No_Extension":
Clipboard.SetText(tabViewModel.Entry.NameWithoutExtension);
break;
}
}
}

View File

@ -134,11 +134,27 @@ public class GameSelectorViewModel : ViewModel
}
}
var crashReportClientExe = Path.Combine(projectDir, "..", "Engine", "Binaries", "Win64", "CrashReportClient.exe");
if (File.Exists(crashReportClientExe) && TryGetUeVersionFromExe(crashReportClientExe, out ueVersion))
var projectEngineBinariesDir = Path.Combine(projectDir, "..", "Engine", "Binaries", "Win64");
if (Directory.Exists(projectEngineBinariesDir))
{
Log.Information("Detected UE version {UeVersion} from \"{Exe}\"", ueVersion, crashReportClientExe);
return true;
var crashReportClientExe = Path.Combine(projectEngineBinariesDir, "CrashReportClient.exe");
if (File.Exists(crashReportClientExe) && TryGetUeVersionFromExe(crashReportClientExe, out ueVersion))
{
Log.Information("Detected UE version {UeVersion} from \"{Exe}\"", ueVersion, crashReportClientExe);
return true;
}
if (Directory.GetFiles(projectEngineBinariesDir, "*-Win64-Shipping.exe") is { Length: > 0 } shipping)
{
foreach (var exe in shipping)
{
if (TryGetUeVersionFromExe(exe, out ueVersion))
{
Log.Information("Detected UE version {UeVersion} from \"{Exe}\"", ueVersion, exe);
return true;
}
}
}
}
ueVersion = EGame.GAME_UE4_LATEST;

View File

@ -426,7 +426,7 @@ public class TabItem : ViewModel
{
Interlocked.Increment(ref ApplicationService.ApplicationView.CUE4Parse.ExportedCount);
Log.Information("{FileName} successfully saved", fileName);
if (updateUi)
if (updateUi && ApplicationService.ApplicationView.CUE4Parse.ExportedCount < 50)
{
FLogger.Append(ELog.Information, () =>
{

View File

@ -75,6 +75,8 @@ public partial class AudioPlayer
_applicationView.AudioPlayer.Previous();
else if (UserSettings.Default.NextAudio.IsTriggered(e.Key))
_applicationView.AudioPlayer.Next();
else if (UserSettings.Default.RemoveAudio.IsTriggered(e.Key))
_applicationView.AudioPlayer.Remove();
}
private void OnAudioFileMouseDoubleClick(object sender, MouseButtonEventArgs e)

View File

@ -4,7 +4,8 @@ namespace FModel.Views.Resources.Controls.Aup;
public enum ESourceEventType
{
Loading
Loading,
Clearing
}
public class SourceEventArgs : EventArgs
@ -15,4 +16,4 @@ public class SourceEventArgs : EventArgs
{
Event = e;
}
}
}

View File

@ -910,6 +910,26 @@
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem Header="Show Metadata" Command="{Binding TabCommand}" CommandParameter="Assets_Show_Metadata">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<Canvas Width="24" Height="24">
<Path Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource InfoIcon}" />
</Canvas>
</Viewbox>
</MenuItem.Icon>
<MenuItem.IsEnabled>
<Binding Path="PlacementTarget.SelectedItems" RelativeSource="{RelativeSource AncestorType=ContextMenu}">
<Binding.Converter>
<converters:AnyItemMeetsConditionConverter>
<converters:AnyItemMeetsConditionConverter.Conditions>
<converters:ItemIsUePackageCondition />
</converters:AnyItemMeetsConditionConverter.Conditions>
</converters:AnyItemMeetsConditionConverter>
</Binding.Converter>
</Binding>
</MenuItem.IsEnabled>
</MenuItem>
<MenuItem Header="Find References" Command="{Binding TabCommand}" CommandParameter="Find_References">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
@ -931,6 +951,35 @@
</Binding>
</MenuItem.IsEnabled>
</MenuItem>
<MenuItem Header="Decompile Blueprint" Command="{Binding TabCommand}" CommandParameter="Assets_Decompile">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<Canvas Width="24" Height="24">
<Path Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource CppIcon}" />
</Canvas>
</Viewbox>
</MenuItem.Icon>
<MenuItem.Style>
<Style TargetType="{x:Type MenuItem}" BasedOn="{StaticResource {x:Type MenuItem}}">
<Style.Triggers>
<DataTrigger Binding="{Binding ShowDecompileOption, Source={x:Static settings:UserSettings.Default}}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</MenuItem.Style>
<MenuItem.IsEnabled>
<Binding Path="PlacementTarget.SelectedItems" RelativeSource="{RelativeSource AncestorType=ContextMenu}">
<Binding.Converter>
<converters:AnyItemMeetsConditionConverter>
<converters:AnyItemMeetsConditionConverter.Conditions>
<converters:ItemActionCondition Action="Code" />
</converters:AnyItemMeetsConditionConverter.Conditions>
</converters:AnyItemMeetsConditionConverter>
</Binding.Converter>
</Binding>
</MenuItem.IsEnabled>
</MenuItem>
<Separator />
<MenuItem Command="{Binding TabCommand}" CommandParameter="Save_Data">
<MenuItem.Header>
@ -1010,7 +1059,7 @@
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Copy Package Path" Command="{Binding TabCommand}" CommandParameter="Copy_Asset_Path">
<MenuItem Header="Copy">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<Canvas Width="24" Height="24">
@ -1018,6 +1067,16 @@
</Canvas>
</Viewbox>
</MenuItem.Icon>
<MenuItem Header="Package Path" Command="{Binding TabCommand}" CommandParameter="File_Path">
</MenuItem>
<MenuItem Header="Package Name" Command="{Binding TabCommand}" CommandParameter="File_Name">
</MenuItem>
<MenuItem Header="Directory Path" Command="{Binding TabCommand}" CommandParameter="Directory_Path">
</MenuItem>
<MenuItem Header="Package Path w/o Extension" Command="{Binding TabCommand}" CommandParameter="File_Path_No_Extension">
</MenuItem>
<MenuItem Header="Package Name w/o Extension" Command="{Binding TabCommand}" CommandParameter="File_Name_No_Extension">
</MenuItem>
</MenuItem>
</ContextMenu>
</Setter.Value>

View File

@ -161,6 +161,21 @@
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Show Metadata" Command="{Binding DataContext.mainApplication.RightClickMenuCommand}">
<MenuItem.CommandParameter>
<MultiBinding Converter="{x:Static converters:MultiParameterConverter.Instance}">
<Binding Source="Assets_Show_Metadata" />
<Binding Path="SelectedItems" />
</MultiBinding>
</MenuItem.CommandParameter>
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<Canvas Width="24" Height="24">
<Path Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource InfoIcon}" />
</Canvas>
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Find References" Click="OnFindRefs">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
@ -529,6 +544,21 @@
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Show Metadata" Command="{Binding DataContext.mainApplication.RightClickMenuCommand}">
<MenuItem.CommandParameter>
<MultiBinding Converter="{x:Static converters:MultiParameterConverter.Instance}">
<Binding Source="Assets_Show_Metadata" />
<Binding Path="SelectedItems" />
</MultiBinding>
</MenuItem.CommandParameter>
<MenuItem.Icon>
<Viewbox Width="16" Height="16">
<Canvas Width="24" Height="24">
<Path Fill="{DynamicResource {x:Static adonisUi:Brushes.ForegroundBrush}}" Data="{StaticResource InfoIcon}" />
</Canvas>
</Viewbox>
</MenuItem.Icon>
</MenuItem>
<MenuItem Header="Find References" Click="OnFindRefs">
<MenuItem.Icon>
<Viewbox Width="16" Height="16">

View File

@ -563,6 +563,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@ -609,6 +610,9 @@
<TextBlock Grid.Row="12" Grid.Column="0" Text="Next Audio" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="12" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding NextAudio, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
<TextBlock Grid.Row="13" Grid.Column="0" Text="Remove Selected Audio" VerticalAlignment="Center" Margin="0 0 0 5" />
<controls:HotkeyTextBox Grid.Row="13" Grid.Column="2" Style="{StaticResource TextBoxDefaultStyle}" Margin="0 0 0 5"
HotKey="{Binding RemoveAudio, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="unluacTemplate">