Skip to content

Commit dbf618e

Browse files
committed
ui now deals with GameFile instead of a bad replica
that means loose files are now supported, or should be Export Raw Data shows the correct extension
1 parent 3d0bdf0 commit dbf618e

20 files changed

+246
-336
lines changed

FModel/Framework/FakeCUE4Parse.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using CUE4Parse.Compression;
3+
using CUE4Parse.FileProvider.Objects;
4+
using CUE4Parse.UE4.Readers;
5+
6+
namespace FModel.Framework;
7+
8+
public class FakeGameFile : GameFile
9+
{
10+
public FakeGameFile(string path) : base(path, 0)
11+
{
12+
13+
}
14+
15+
public override bool IsEncrypted => false;
16+
public override CompressionMethod CompressionMethod => CompressionMethod.None;
17+
18+
public override byte[] Read()
19+
{
20+
throw new NotImplementedException();
21+
}
22+
23+
public override FArchive CreateReader()
24+
{
25+
throw new NotImplementedException();
26+
}
27+
}

FModel/MainWindow.xaml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,14 @@
502502
</MenuItem.Icon>
503503
</MenuItem>
504504
<Separator />
505-
<MenuItem Header="Export Raw Data (.uasset)" Command="{Binding DataContext.RightClickMenuCommand}">
505+
<MenuItem Command="{Binding DataContext.RightClickMenuCommand}">
506+
<MenuItem.Header>
507+
<TextBlock
508+
Text="{Binding DataContext.SelectedItem.Extension,
509+
FallbackValue='uasset',
510+
StringFormat='Export Raw Data (.{0})',
511+
RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
512+
</MenuItem.Header>
506513
<MenuItem.CommandParameter>
507514
<MultiBinding Converter="{x:Static converters:MultiParameterConverter.Instance}">
508515
<Binding Source="Assets_Export_Data" />
@@ -649,11 +656,11 @@
649656
<TextBlock Grid.Row="0" Grid.Column="1" Text="Offset" VerticalAlignment="Center" HorizontalAlignment="Right" />
650657
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding SelectedItem.Size, ElementName=AssetsListName, FallbackValue=0, Converter={x:Static converters:SizeToStringConverter.Instance}}" VerticalAlignment="Center" HorizontalAlignment="Left" />
651658
<TextBlock Grid.Row="1" Grid.Column="1" Text="Size" VerticalAlignment="Center" HorizontalAlignment="Right" />
652-
<TextBlock Grid.Row="2" Grid.Column="0" Text="{Binding SelectedItem.Compression, ElementName=AssetsListName, FallbackValue='Unknown'}" VerticalAlignment="Center" HorizontalAlignment="Left" />
659+
<TextBlock Grid.Row="2" Grid.Column="0" Text="{Binding SelectedItem.CompressionMethod, ElementName=AssetsListName, FallbackValue='Unknown'}" VerticalAlignment="Center" HorizontalAlignment="Left" />
653660
<TextBlock Grid.Row="2" Grid.Column="1" Text="Compression Method" VerticalAlignment="Center" HorizontalAlignment="Right" />
654661
<TextBlock Grid.Row="3" Grid.Column="0" Text="{Binding SelectedItem.IsEncrypted, ElementName=AssetsListName, FallbackValue='False'}" VerticalAlignment="Center" HorizontalAlignment="Left" />
655662
<TextBlock Grid.Row="3" Grid.Column="1" Text="Is Encrypted" VerticalAlignment="Center" HorizontalAlignment="Right" />
656-
<TextBlock Grid.Row="4" Grid.Column="0" Text="{Binding SelectedItem.Archive, ElementName=AssetsListName, FallbackValue='None'}" VerticalAlignment="Center" HorizontalAlignment="Left" />
663+
<TextBlock Grid.Row="4" Grid.Column="0" Text="{Binding SelectedItem.Vfs.Name, ElementName=AssetsListName, FallbackValue='None'}" VerticalAlignment="Center" HorizontalAlignment="Left" />
657664
<TextBlock Grid.Row="4" Grid.Column="1" Text="Included In Archive" VerticalAlignment="Center" HorizontalAlignment="Right" />
658665
</Grid>
659666
</StackPanel>

FModel/MainWindow.xaml.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Windows.Controls;
77
using System.Windows.Input;
88
using AdonisUI.Controls;
9+
using CUE4Parse.FileProvider.Objects;
910
using FModel.Services;
1011
using FModel.Settings;
1112
using FModel.ViewModels;
@@ -84,7 +85,7 @@ await Task.WhenAll(
8485
#if DEBUG
8586
// await _threadWorkerView.Begin(cancellationToken =>
8687
// _applicationView.CUE4Parse.Extract(cancellationToken,
87-
// "MyProject/Content/FirstPerson/Meshes/FirstPersonProjectileMesh.uasset"));
88+
// "Marvel/Content/Marvel/Characters/1016/1016501/Meshes/SK_1016_1016501.uasset"));
8889
// await _threadWorkerView.Begin(cancellationToken =>
8990
// _applicationView.CUE4Parse.Extract(cancellationToken,
9091
// "RED/Content/Chara/ABA/Costume01/Animation/Charaselect/body/stand_body01.uasset"));
@@ -162,7 +163,7 @@ private async void OnAssetsListMouseDoubleClick(object sender, MouseButtonEventA
162163
{
163164
if (sender is not ListBox listBox) return;
164165

165-
var selectedItems = listBox.SelectedItems.Cast<AssetItem>().ToList();
166+
var selectedItems = listBox.SelectedItems.Cast<GameFile>().ToList();
166167
await _threadWorkerView.Begin(cancellationToken => { _applicationView.CUE4Parse.ExtractSelected(cancellationToken, selectedItems); });
167168
}
168169

@@ -266,7 +267,7 @@ private void OnFilterTextChanged(object sender, TextChangedEventArgs e)
266267
return;
267268

268269
var filters = textBox.Text.Trim().Split(' ');
269-
folder.AssetsList.AssetsView.Filter = o => { return o is AssetItem assetItem && filters.All(x => assetItem.FileName.Contains(x, StringComparison.OrdinalIgnoreCase)); };
270+
folder.AssetsList.AssetsView.Filter = o => { return o is GameFile entry && filters.All(x => entry.Name.Contains(x, StringComparison.OrdinalIgnoreCase)); };
270271
}
271272

272273
private void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
@@ -283,7 +284,7 @@ private async void OnPreviewKeyDown(object sender, KeyEventArgs e)
283284
switch (e.Key)
284285
{
285286
case Key.Enter:
286-
var selectedItems = listBox.SelectedItems.Cast<AssetItem>().ToList();
287+
var selectedItems = listBox.SelectedItems.Cast<GameFile>().ToList();
287288
await _threadWorkerView.Begin(cancellationToken => { _applicationView.CUE4Parse.ExtractSelected(cancellationToken, selectedItems); });
288289
break;
289290
}

FModel/ViewModels/AssetsFolderViewModel.cs

Lines changed: 34 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Text;
55
using System.Windows;
66
using System.Windows.Data;
7+
using CUE4Parse.FileProvider.Objects;
78
using CUE4Parse.UE4.Versions;
89
using CUE4Parse.UE4.VirtualFileSystem;
910
using FModel.Framework;
@@ -60,12 +61,15 @@ public FPackageFileVersion Version
6061
public RangeObservableCollection<TreeItem> Folders { get; }
6162
public ICollectionView FoldersView { get; }
6263

63-
public TreeItem(string header, string archive, string mountPoint, FPackageFileVersion version, string pathHere)
64+
public TreeItem(string header, GameFile entry, string pathHere)
6465
{
6566
Header = header;
66-
Archive = archive;
67-
MountPoint = mountPoint;
68-
Version = version;
67+
if (entry is VfsEntry vfsEntry)
68+
{
69+
Archive = vfsEntry.Vfs.Name;
70+
MountPoint = vfsEntry.Vfs.MountPoint;
71+
Version = vfsEntry.Vfs.Ver;
72+
}
6973
PathAtThisPoint = pathHere;
7074
AssetsList = new AssetsListViewModel();
7175
Folders = new RangeObservableCollection<TreeItem>();
@@ -86,7 +90,7 @@ public AssetsFolderViewModel()
8690
FoldersView = new ListCollectionView(Folders) { SortDescriptions = { new SortDescription("Header", ListSortDirection.Ascending) } };
8791
}
8892

89-
public void BulkPopulate(IReadOnlyCollection<VfsEntry> entries)
93+
public void BulkPopulate(IReadOnlyCollection<GameFile> entries)
9094
{
9195
if (entries == null || entries.Count == 0)
9296
return;
@@ -95,54 +99,48 @@ public void BulkPopulate(IReadOnlyCollection<VfsEntry> entries)
9599
{
96100
var treeItems = new RangeObservableCollection<TreeItem>();
97101
treeItems.SetSuppressionState(true);
98-
var items = new List<AssetItem>(entries.Count);
99102

100103
foreach (var entry in entries)
101104
{
102-
var item = new AssetItem(entry.Path, entry.IsEncrypted, entry.Offset, entry.Size, entry.Vfs.Name, entry.CompressionMethod);
103-
items.Add(item);
105+
TreeItem lastNode = null;
106+
var folders = entry.Path.Split('/', StringSplitOptions.RemoveEmptyEntries);
107+
var builder = new StringBuilder(64);
108+
var parentNode = treeItems;
104109

110+
for (var i = 0; i < folders.Length - 1; i++)
105111
{
106-
TreeItem lastNode = null;
107-
var folders = item.FullPath.Split('/', StringSplitOptions.RemoveEmptyEntries);
108-
var builder = new StringBuilder(64);
109-
var parentNode = treeItems;
112+
var folder = folders[i];
113+
builder.Append(folder).Append('/');
114+
lastNode = FindByHeaderOrNull(parentNode, folder);
110115

111-
for (var i = 0; i < folders.Length - 1; i++)
116+
static TreeItem FindByHeaderOrNull(IReadOnlyList<TreeItem> list, string header)
112117
{
113-
var folder = folders[i];
114-
builder.Append(folder).Append('/');
115-
lastNode = FindByHeaderOrNull(parentNode, folder);
116-
117-
static TreeItem FindByHeaderOrNull(IReadOnlyList<TreeItem> list, string header)
118+
for (var i = 0; i < list.Count; i++)
118119
{
119-
for (var i = 0; i < list.Count; i++)
120-
{
121-
if (list[i].Header == header)
122-
return list[i];
123-
}
124-
125-
return null;
120+
if (list[i].Header == header)
121+
return list[i];
126122
}
127123

128-
if (lastNode == null)
129-
{
130-
var nodePath = builder.ToString();
131-
lastNode = new TreeItem(folder, item.Archive, entry.Vfs.MountPoint, entry.Vfs.Ver, nodePath[..^1]);
132-
lastNode.Folders.SetSuppressionState(true);
133-
lastNode.AssetsList.Assets.SetSuppressionState(true);
134-
parentNode.Add(lastNode);
135-
}
124+
return null;
125+
}
136126

137-
parentNode = lastNode.Folders;
127+
if (lastNode == null)
128+
{
129+
var nodePath = builder.ToString();
130+
lastNode = new TreeItem(folder, entry, nodePath[..^1]);
131+
lastNode.Folders.SetSuppressionState(true);
132+
lastNode.AssetsList.Assets.SetSuppressionState(true);
133+
parentNode.Add(lastNode);
138134
}
139135

140-
lastNode?.AssetsList.Assets.Add(item);
136+
parentNode = lastNode.Folders;
141137
}
138+
139+
lastNode?.AssetsList.Assets.Add(entry);
142140
}
143141

144142
Folders.AddRange(treeItems);
145-
ApplicationService.ApplicationView.CUE4Parse.SearchVm.SearchResults.AddRange(items);
143+
ApplicationService.ApplicationView.CUE4Parse.SearchVm.SearchResults.AddRange(entries);
146144

147145
foreach (var folder in Folders)
148146
InvokeOnCollectionChanged(folder);
Lines changed: 4 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,109 +1,21 @@
11
using System.ComponentModel;
22
using System.Windows.Data;
3-
using CUE4Parse.Compression;
4-
using CUE4Parse.Utils;
3+
using CUE4Parse.FileProvider.Objects;
54
using FModel.Framework;
65

76
namespace FModel.ViewModels;
87

9-
public class AssetItem : ViewModel
10-
{
11-
private string _fullPath;
12-
public string FullPath
13-
{
14-
get => _fullPath;
15-
private set => SetProperty(ref _fullPath, value);
16-
}
17-
18-
private bool _isEncrypted;
19-
public bool IsEncrypted
20-
{
21-
get => _isEncrypted;
22-
private set => SetProperty(ref _isEncrypted, value);
23-
}
24-
25-
private long _offset;
26-
public long Offset
27-
{
28-
get => _offset;
29-
private set => SetProperty(ref _offset, value);
30-
}
31-
32-
private long _size;
33-
public long Size
34-
{
35-
get => _size;
36-
private set => SetProperty(ref _size, value);
37-
}
38-
39-
private string _archive;
40-
public string Archive
41-
{
42-
get => _archive;
43-
private set => SetProperty(ref _archive, value);
44-
}
45-
46-
private CompressionMethod _compression;
47-
public CompressionMethod Compression
48-
{
49-
get => _compression;
50-
private set => SetProperty(ref _compression, value);
51-
}
52-
53-
private string _directory;
54-
public string Directory
55-
{
56-
get => _directory;
57-
private set => SetProperty(ref _directory, value);
58-
}
59-
60-
private string _fileName;
61-
public string FileName
62-
{
63-
get => _fileName;
64-
private set => SetProperty(ref _fileName, value);
65-
}
66-
67-
private string _extension;
68-
public string Extension
69-
{
70-
get => _extension;
71-
private set => SetProperty(ref _extension, value);
72-
}
73-
74-
public AssetItem(string titleExtra, AssetItem asset) : this(asset.FullPath, asset.IsEncrypted, asset.Offset, asset.Size, asset.Archive, asset.Compression)
75-
{
76-
FullPath += titleExtra;
77-
}
78-
79-
public AssetItem(string fullPath, bool isEncrypted = false, long offset = 0, long size = 0, string archive = "", CompressionMethod compression = CompressionMethod.None)
80-
{
81-
FullPath = fullPath;
82-
IsEncrypted = isEncrypted;
83-
Offset = offset;
84-
Size = size;
85-
Archive = archive;
86-
Compression = compression;
87-
88-
Directory = FullPath.SubstringBeforeLast('/');
89-
FileName = FullPath.SubstringAfterLast('/');
90-
Extension = FullPath.SubstringAfterLast('.').ToLowerInvariant();
91-
}
92-
93-
public override string ToString() => FullPath;
94-
}
95-
968
public class AssetsListViewModel
979
{
98-
public RangeObservableCollection<AssetItem> Assets { get; }
10+
public RangeObservableCollection<GameFile> Assets { get; }
9911
public ICollectionView AssetsView { get; }
10012

10113
public AssetsListViewModel()
10214
{
103-
Assets = new RangeObservableCollection<AssetItem>();
15+
Assets = new RangeObservableCollection<GameFile>();
10416
AssetsView = new ListCollectionView(Assets)
10517
{
106-
SortDescriptions = { new SortDescription("FullPath", ListSortDirection.Ascending) }
18+
SortDescriptions = { new SortDescription("Path", ListSortDirection.Ascending) }
10719
};
10820
}
10921
}

0 commit comments

Comments
 (0)