- AssetBrowser Optimizations.
- Filter options added to `AssetBrowser`. - New game entry. - Togglable Model Preview. - bug fixes.
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
using MessagePack;
|
using MessagePack;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
@@ -26,10 +28,22 @@ namespace AssetStudio
|
|||||||
[Key(4)]
|
[Key(4)]
|
||||||
public ClassIDType Type { get; set; }
|
public ClassIDType Type { get; set; }
|
||||||
|
|
||||||
public bool Matches(Regex regex) => regex.IsMatch(Name)
|
public bool Matches(Dictionary<string, Regex> filters)
|
||||||
|| regex.IsMatch(Container)
|
{
|
||||||
|| regex.IsMatch(Source)
|
var matches = new List<bool>();
|
||||||
|| regex.IsMatch(PathID.ToString())
|
foreach(var filter in filters)
|
||||||
|| regex.IsMatch(Type.ToString());
|
{
|
||||||
|
matches.Add(filter.Key switch
|
||||||
|
{
|
||||||
|
string value when value.Equals(nameof(Name), StringComparison.OrdinalIgnoreCase) => filter.Value.IsMatch(Name),
|
||||||
|
string value when value.Equals(nameof(Container), StringComparison.OrdinalIgnoreCase) => filter.Value.IsMatch(Container),
|
||||||
|
string value when value.Equals(nameof(Source), StringComparison.OrdinalIgnoreCase) => filter.Value.IsMatch(Source),
|
||||||
|
string value when value.Equals(nameof(PathID), StringComparison.OrdinalIgnoreCase) => filter.Value.IsMatch(PathID.ToString()),
|
||||||
|
string value when value.Equals(nameof (Type), StringComparison.OrdinalIgnoreCase) => filter.Value.IsMatch(Type.ToString()),
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return matches.Count(x => x == true) == filters.Count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -437,6 +437,10 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
OPFPUtils.Decrypt(compressedBytesSpan, reader.FullPath);
|
OPFPUtils.Decrypt(compressedBytesSpan, reader.FullPath);
|
||||||
}
|
}
|
||||||
|
if (Game.Type.IsNetEase() && i == 0)
|
||||||
|
{
|
||||||
|
NetEaseUtils.Decrypt(compressedBytesSpan);
|
||||||
|
}
|
||||||
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
||||||
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
|
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
|
||||||
var uncompressedBytesSpan = uncompressedBytes.AsSpan(0, uncompressedSize);
|
var uncompressedBytesSpan = uncompressedBytes.AsSpan(0, uncompressedSize);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using System;
|
using AssetStudio;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.Metrics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
@@ -34,6 +36,54 @@ namespace AssetStudio
|
|||||||
m_Name = reader.ReadAlignedString();
|
m_Name = reader.ReadAlignedString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasModel() => m_Transform != null && m_Transform.m_Father.IsNull && m_Transform.m_Children.Length > 0;
|
public bool HasModel() => HasMesh(m_Transform, new List<bool>());
|
||||||
|
private static bool HasMesh(Transform m_Transform, List<bool> meshes)
|
||||||
|
{
|
||||||
|
m_Transform.m_GameObject.TryGet(out var m_GameObject);
|
||||||
|
|
||||||
|
if (m_GameObject.m_MeshRenderer != null)
|
||||||
|
{
|
||||||
|
var mesh = GetMesh(m_GameObject.m_MeshRenderer);
|
||||||
|
meshes.Add(mesh != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_GameObject.m_SkinnedMeshRenderer != null)
|
||||||
|
{
|
||||||
|
var mesh = GetMesh(m_GameObject.m_SkinnedMeshRenderer);
|
||||||
|
meshes.Add(mesh != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var pptr in m_Transform.m_Children)
|
||||||
|
{
|
||||||
|
if (pptr.TryGet(out var child))
|
||||||
|
meshes.Add(HasMesh(child, meshes));
|
||||||
|
}
|
||||||
|
|
||||||
|
return meshes.Any(x => x == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Mesh GetMesh(Renderer meshR)
|
||||||
|
{
|
||||||
|
if (meshR is SkinnedMeshRenderer sMesh)
|
||||||
|
{
|
||||||
|
if (sMesh.m_Mesh.TryGet(out var m_Mesh))
|
||||||
|
{
|
||||||
|
return m_Mesh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meshR.m_GameObject.TryGet(out var m_GameObject);
|
||||||
|
if (m_GameObject.m_MeshFilter != null)
|
||||||
|
{
|
||||||
|
if (m_GameObject.m_MeshFilter.m_Mesh.TryGet(out var m_Mesh))
|
||||||
|
{
|
||||||
|
return m_Mesh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
243
AssetStudio/Crypto/NetEaseUtils.cs
Normal file
243
AssetStudio/Crypto/NetEaseUtils.cs
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
using System;
|
||||||
|
using System.Buffers.Binary;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
//Special thanks to LukeFZ#4035.
|
||||||
|
public static class NetEaseUtils
|
||||||
|
{
|
||||||
|
private static readonly byte[] Signature = new byte[] { 0xEE, 0xDD };
|
||||||
|
public static void Decrypt(Span<byte> bytes)
|
||||||
|
{
|
||||||
|
var (encryptedOffset, encryptedSize) = ReadHeader(bytes);
|
||||||
|
var encrypted = bytes.Slice(encryptedOffset, encryptedSize);
|
||||||
|
var encryptedInts = MemoryMarshal.Cast<byte, int>(encrypted);
|
||||||
|
|
||||||
|
var seedInts = new int[] { encryptedInts[3], encryptedInts[1], encryptedInts[4], encrypted.Length, encryptedInts[2] };
|
||||||
|
var seedBytes = MemoryMarshal.AsBytes<int>(seedInts).ToArray();
|
||||||
|
var seed = (int)CRC.CalculateDigest(seedBytes, 0, (uint)seedBytes.Length);
|
||||||
|
|
||||||
|
var keyPart0 = seed ^ (encryptedInts[7] + 0x1981);
|
||||||
|
var keyPart1 = seed ^ (encrypted.Length + 0x2013);
|
||||||
|
var keyPart2 = seed ^ (encryptedInts[5] + 0x1985);
|
||||||
|
var keyPart3 = seed ^ (encryptedInts[6] + 0x2018);
|
||||||
|
|
||||||
|
for (int i = 0; i < 0x20; i++)
|
||||||
|
{
|
||||||
|
encrypted[i] ^= 0xA6;
|
||||||
|
}
|
||||||
|
|
||||||
|
var block = encrypted[0x20..];
|
||||||
|
var keyVector = new int[] { keyPart2, keyPart0, keyPart1, keyPart3 };
|
||||||
|
var keysVector = new int[] { 0x571, keyPart3, 0x892, 0x750, keyPart2, keyPart0, 0x746, keyPart1, 0x568 };
|
||||||
|
if (block.Length >= 0x80)
|
||||||
|
{
|
||||||
|
var dataBlock = block[0x80..];
|
||||||
|
var keyBlock = block[..0x80].ToArray();
|
||||||
|
var keyBlockInts = MemoryMarshal.Cast<byte, int>(keyBlock);
|
||||||
|
|
||||||
|
RC4(block[..0x80], seed);
|
||||||
|
RC4(keyBlock, keyPart1);
|
||||||
|
|
||||||
|
var blockCount = dataBlock.Length / 0x80;
|
||||||
|
for (int i = 0; i < blockCount; i++)
|
||||||
|
{
|
||||||
|
var blockOffset = i * 0x80;
|
||||||
|
var type = (byte)keysVector[i % keysVector.Length] % keyVector.Length;
|
||||||
|
var dataBlockInts = MemoryMarshal.Cast<byte, int>(dataBlock.Slice(blockOffset, 0x80));
|
||||||
|
for (int j = 0; j < 0x20; j++)
|
||||||
|
{
|
||||||
|
dataBlockInts[j] ^= keyBlockInts[j] ^ type switch
|
||||||
|
{
|
||||||
|
0 => keysVector[j % keysVector.Length] ^ (0x20 - j),
|
||||||
|
1 => keyVector[(byte)keyBlockInts[j] % keyVector.Length],
|
||||||
|
2 => keyVector[(byte)keyBlockInts[j] % keyVector.Length] ^ j,
|
||||||
|
3 => keyVector[(byte)keysVector[j % keysVector.Length] % keyVector.Length] ^ j,
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var remainingCount = dataBlock.Length % 0x80;
|
||||||
|
if (remainingCount > 0)
|
||||||
|
{
|
||||||
|
var remaining = encrypted[^remainingCount..];
|
||||||
|
for (int i = 0; i < remainingCount; i++)
|
||||||
|
{
|
||||||
|
remaining[i] ^= (byte)(keyBlock[i] ^ ((uint)keysVector[(uint)keyVector[i % keyVector.Length] % keysVector.Length] % 0xFF) ^ i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RC4(block, seed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static (int, int) ReadHeader(Span<byte> bytes)
|
||||||
|
{
|
||||||
|
var index = bytes.Search(Signature, 0);
|
||||||
|
if (index == -1 || index >= 0x40)
|
||||||
|
{
|
||||||
|
throw new Exception("Header not found !!");
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = bytes[index..];
|
||||||
|
ReadVersion(info);
|
||||||
|
ReadEncryptedSize(info, bytes.Length, out var encryptedSize);
|
||||||
|
|
||||||
|
var headerOffset = 0;
|
||||||
|
ReadHeaderOffset(info, 8, ref headerOffset);
|
||||||
|
ReadHeaderOffset(info, 9, ref headerOffset);
|
||||||
|
|
||||||
|
var headerSize = 0x30;
|
||||||
|
var encryptedOffset = 0x30;
|
||||||
|
if (headerOffset == index || headerOffset == 0)
|
||||||
|
{
|
||||||
|
if (index >= 0x20)
|
||||||
|
{
|
||||||
|
headerSize = 0x40;
|
||||||
|
encryptedOffset = 0x40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (headerOffset >= 0x20)
|
||||||
|
{
|
||||||
|
headerSize = 0x40;
|
||||||
|
encryptedOffset = 0x40;
|
||||||
|
}
|
||||||
|
if (headerOffset > index)
|
||||||
|
{
|
||||||
|
encryptedOffset += index - headerOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
encryptedSize -= headerSize;
|
||||||
|
|
||||||
|
return (encryptedOffset, encryptedSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ReadVersion(Span<byte> bytes)
|
||||||
|
{
|
||||||
|
var version = BinaryPrimitives.ReadUInt16LittleEndian(bytes[2..]);
|
||||||
|
if (version < 0x2017 || version > 0x2025)
|
||||||
|
{
|
||||||
|
throw new Exception("Unsupported version");
|
||||||
|
}
|
||||||
|
var versionString = version.ToString("X4");
|
||||||
|
Encoding.UTF8.GetBytes(versionString, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ReadEncryptedSize(Span<byte> bytes, int size, out int encryptedSize)
|
||||||
|
{
|
||||||
|
var (vectorCount, bytesCount) = (bytes[4], bytes[6]);
|
||||||
|
encryptedSize = size > 0x1000 ? 0x1000 : size;
|
||||||
|
if (vectorCount != 0x2E && bytesCount != 0x2E)
|
||||||
|
{
|
||||||
|
encryptedSize = bytesCount + 0x10 * vectorCount;
|
||||||
|
if (vectorCount == 0xAA && bytesCount == 0xBB)
|
||||||
|
{
|
||||||
|
encryptedSize = 0x1000;
|
||||||
|
}
|
||||||
|
bytes[4] = bytes[6] = 0x2E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ReadHeaderOffset(Span<byte> bytes, int index, ref int headerOffset)
|
||||||
|
{
|
||||||
|
if (bytes[index + 1] == 0x31 && bytes[index] != 0x66)
|
||||||
|
{
|
||||||
|
headerOffset = bytes[index];
|
||||||
|
bytes[index] = 0x66;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CRC
|
||||||
|
{
|
||||||
|
private static readonly uint[] Table;
|
||||||
|
|
||||||
|
static CRC()
|
||||||
|
{
|
||||||
|
Table = new uint[256];
|
||||||
|
const uint kPoly = 0x9823D6E;
|
||||||
|
for (uint i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
uint r = i;
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
if ((r & 1) != 0)
|
||||||
|
r ^= kPoly;
|
||||||
|
r >>= 1;
|
||||||
|
}
|
||||||
|
Table[i] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint _value = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
public void Update(byte[] data, uint offset, uint size)
|
||||||
|
{
|
||||||
|
for (uint i = 0; i < size; i++)
|
||||||
|
_value = (Table[(byte)_value ^ data[offset + i]] ^ (_value >> 8)) + 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint GetDigest() { return ~_value - 0x7D29C488; }
|
||||||
|
|
||||||
|
public static uint CalculateDigest(byte[] data, uint offset, uint size)
|
||||||
|
{
|
||||||
|
var crc = new CRC();
|
||||||
|
crc.Update(data, offset, size);
|
||||||
|
return crc.GetDigest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RC4(Span<byte> data, int key) => RC4(data, BitConverter.GetBytes(key));
|
||||||
|
|
||||||
|
public static void RC4(Span<byte> data, byte[] key)
|
||||||
|
{
|
||||||
|
int[] S = new int[0x100];
|
||||||
|
for (int _ = 0; _ < 0x100; _++)
|
||||||
|
{
|
||||||
|
S[_] = _;
|
||||||
|
}
|
||||||
|
|
||||||
|
int[] T = new int[0x100];
|
||||||
|
|
||||||
|
if (key.Length == 0x100)
|
||||||
|
{
|
||||||
|
Buffer.BlockCopy(key, 0, T, 0, key.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int _ = 0; _ < 0x100; _++)
|
||||||
|
{
|
||||||
|
T[_] = key[_ % key.Length];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
for (i = 0; i < 0x100; i++)
|
||||||
|
{
|
||||||
|
j = (j + S[i] + T[i]) % 0x100;
|
||||||
|
|
||||||
|
(S[j], S[i]) = (S[i], S[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = j = 0;
|
||||||
|
for (int iteration = 0; iteration < data.Length; iteration++)
|
||||||
|
{
|
||||||
|
i = (i + 1) % 0x100;
|
||||||
|
j = (j + S[i]) % 0x100;
|
||||||
|
|
||||||
|
(S[j], S[i]) = (S[i], S[j]);
|
||||||
|
var K = (uint)S[(S[j] + S[i]) % 0x100];
|
||||||
|
|
||||||
|
var k = (byte)(K << 6) | (K >> 2);
|
||||||
|
data[iteration] ^= (byte)(k + 0x3A);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Text;
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace AssetStudio
|
namespace AssetStudio
|
||||||
{
|
{
|
||||||
@@ -17,8 +18,8 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
public static int Search(this byte[] src, string value, int offset = 0) => Search(src, Encoding.UTF8.GetBytes(value), offset);
|
public static int Search(this byte[] src, string value, int offset = 0) => Search(src.AsSpan(), Encoding.UTF8.GetBytes(value), offset);
|
||||||
public static int Search(this byte[] src, byte[] pattern, int offset)
|
public static int Search(this Span<byte> src, byte[] pattern, int offset)
|
||||||
{
|
{
|
||||||
int maxFirstCharSlot = src.Length - pattern.Length + 1;
|
int maxFirstCharSlot = src.Length - pattern.Length + 1;
|
||||||
for (int i = offset; i < maxFirstCharSlot; i++)
|
for (int i = offset; i < maxFirstCharSlot; i++)
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace AssetStudio
|
|||||||
Games.Add(index++, new Game(GameType.FantasyOfWind));
|
Games.Add(index++, new Game(GameType.FantasyOfWind));
|
||||||
Games.Add(index++, new Game(GameType.ShiningNikki));
|
Games.Add(index++, new Game(GameType.ShiningNikki));
|
||||||
Games.Add(index++, new Game(GameType.HelixWaltz2));
|
Games.Add(index++, new Game(GameType.HelixWaltz2));
|
||||||
|
Games.Add(index++, new Game(GameType.NetEase));
|
||||||
}
|
}
|
||||||
public static Game GetGame(GameType gameType) => GetGame((int)gameType);
|
public static Game GetGame(GameType gameType) => GetGame((int)gameType);
|
||||||
public static Game GetGame(int index)
|
public static Game GetGame(int index)
|
||||||
@@ -132,7 +133,8 @@ namespace AssetStudio
|
|||||||
AlchemyStars,
|
AlchemyStars,
|
||||||
FantasyOfWind,
|
FantasyOfWind,
|
||||||
ShiningNikki,
|
ShiningNikki,
|
||||||
HelixWaltz2
|
HelixWaltz2,
|
||||||
|
NetEase
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GameTypes
|
public static class GameTypes
|
||||||
@@ -152,6 +154,7 @@ namespace AssetStudio
|
|||||||
public static bool IsTOT(this GameType type) => type == GameType.TOT;
|
public static bool IsTOT(this GameType type) => type == GameType.TOT;
|
||||||
public static bool IsNaraka(this GameType type) => type == GameType.Naraka;
|
public static bool IsNaraka(this GameType type) => type == GameType.Naraka;
|
||||||
public static bool IsOPFP(this GameType type) => type == GameType.OPFP;
|
public static bool IsOPFP(this GameType type) => type == GameType.OPFP;
|
||||||
|
public static bool IsNetEase(this GameType type) => type == GameType.NetEase;
|
||||||
public static bool IsGIGroup(this GameType type) => type switch
|
public static bool IsGIGroup(this GameType type) => type switch
|
||||||
{
|
{
|
||||||
GameType.GI or GameType.GI_Pack or GameType.GI_CB1 or GameType.GI_CB2 or GameType.GI_CB3 or GameType.GI_CB3Pre => true,
|
GameType.GI or GameType.GI_Pack or GameType.GI_CB1 or GameType.GI_CB2 or GameType.GI_CB3 or GameType.GI_CB3Pre => true,
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ namespace AssetStudioCLI
|
|||||||
GameName.FromAmong(GameManager.GetGameNames());
|
GameName.FromAmong(GameManager.GetGameNames());
|
||||||
|
|
||||||
GroupAssetsType.SetDefaultValue(AssetGroupOption.ByType);
|
GroupAssetsType.SetDefaultValue(AssetGroupOption.ByType);
|
||||||
MapOp.SetDefaultValue(MapOpType.Load);
|
MapOp.SetDefaultValue(MapOpType.None);
|
||||||
MapType.SetDefaultValue(ExportListType.XML);
|
MapType.SetDefaultValue(ExportListType.XML);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,9 @@
|
|||||||
<setting name="minimalAssetMap" serializeAs="String">
|
<setting name="minimalAssetMap" serializeAs="String">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
</setting>
|
</setting>
|
||||||
|
<setting name="modelsOnly" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
</AssetStudioGUI.Properties.Settings>
|
</AssetStudioGUI.Properties.Settings>
|
||||||
</userSettings>
|
</userSettings>
|
||||||
</configuration>
|
</configuration>
|
||||||
47
AssetStudioGUI/AssetBrowser.Designer.cs
generated
47
AssetStudioGUI/AssetBrowser.Designer.cs
generated
@@ -34,9 +34,9 @@ namespace AssetStudioGUI
|
|||||||
tableLayoutPanel1 = new TableLayoutPanel();
|
tableLayoutPanel1 = new TableLayoutPanel();
|
||||||
tableLayoutPanel2 = new TableLayoutPanel();
|
tableLayoutPanel2 = new TableLayoutPanel();
|
||||||
loadAssetMap = new Button();
|
loadAssetMap = new Button();
|
||||||
searchTextBox = new TextBox();
|
|
||||||
loadSelected = new Button();
|
|
||||||
clear = new Button();
|
clear = new Button();
|
||||||
|
loadSelected = new Button();
|
||||||
|
searchTextBox = new TextBox();
|
||||||
((System.ComponentModel.ISupportInitialize)assetListView).BeginInit();
|
((System.ComponentModel.ISupportInitialize)assetListView).BeginInit();
|
||||||
tableLayoutPanel1.SuspendLayout();
|
tableLayoutPanel1.SuspendLayout();
|
||||||
tableLayoutPanel2.SuspendLayout();
|
tableLayoutPanel2.SuspendLayout();
|
||||||
@@ -91,45 +91,46 @@ namespace AssetStudioGUI
|
|||||||
//
|
//
|
||||||
// loadAssetMap
|
// loadAssetMap
|
||||||
//
|
//
|
||||||
|
loadAssetMap.Dock = DockStyle.Fill;
|
||||||
loadAssetMap.Location = new System.Drawing.Point(3, 3);
|
loadAssetMap.Location = new System.Drawing.Point(3, 3);
|
||||||
loadAssetMap.Name = "loadAssetMap";
|
loadAssetMap.Name = "loadAssetMap";
|
||||||
loadAssetMap.Size = new System.Drawing.Size(94, 23);
|
loadAssetMap.Size = new System.Drawing.Size(114, 23);
|
||||||
loadAssetMap.TabIndex = 0;
|
loadAssetMap.TabIndex = 0;
|
||||||
loadAssetMap.Text = "Load AssetMap";
|
loadAssetMap.Text = "Load AssetMap";
|
||||||
loadAssetMap.UseVisualStyleBackColor = true;
|
loadAssetMap.UseVisualStyleBackColor = true;
|
||||||
loadAssetMap.Click += loadAssetMap_Click;
|
loadAssetMap.Click += loadAssetMap_Click;
|
||||||
loadAssetMap.Dock = DockStyle.Fill;
|
|
||||||
//
|
//
|
||||||
// searchTextBox
|
// clear
|
||||||
//
|
//
|
||||||
searchTextBox.Location = new System.Drawing.Point(103, 3);
|
clear.Dock = DockStyle.Fill;
|
||||||
searchTextBox.Name = "searchTextBox";
|
clear.Location = new System.Drawing.Point(123, 3);
|
||||||
searchTextBox.Size = new System.Drawing.Size(227, 23);
|
clear.Name = "clear";
|
||||||
searchTextBox.TabIndex = 3;
|
clear.Size = new System.Drawing.Size(54, 23);
|
||||||
searchTextBox.KeyPress += searchTextBox_KeyPress;
|
clear.TabIndex = 1;
|
||||||
searchTextBox.Dock = DockStyle.Fill;
|
clear.Text = "Clear";
|
||||||
|
clear.UseVisualStyleBackColor = true;
|
||||||
|
clear.Click += clear_Click;
|
||||||
//
|
//
|
||||||
// loadSelected
|
// loadSelected
|
||||||
//
|
//
|
||||||
loadSelected.Location = new System.Drawing.Point(336, 3);
|
loadSelected.Dock = DockStyle.Fill;
|
||||||
|
loadSelected.Location = new System.Drawing.Point(183, 3);
|
||||||
loadSelected.Name = "loadSelected";
|
loadSelected.Name = "loadSelected";
|
||||||
loadSelected.Size = new System.Drawing.Size(94, 23);
|
loadSelected.Size = new System.Drawing.Size(94, 23);
|
||||||
loadSelected.TabIndex = 2;
|
loadSelected.TabIndex = 2;
|
||||||
loadSelected.Text = "Load Selected";
|
loadSelected.Text = "Load Selected";
|
||||||
loadSelected.UseVisualStyleBackColor = true;
|
loadSelected.UseVisualStyleBackColor = true;
|
||||||
loadSelected.Click += loadSelected_Click;
|
loadSelected.Click += loadSelected_Click;
|
||||||
loadSelected.Dock = DockStyle.Fill;
|
|
||||||
//
|
//
|
||||||
// clear
|
// searchTextBox
|
||||||
//
|
//
|
||||||
clear.Location = new System.Drawing.Point(436, 3);
|
searchTextBox.Dock = DockStyle.Fill;
|
||||||
clear.Name = "clear";
|
searchTextBox.Location = new System.Drawing.Point(283, 3);
|
||||||
clear.Size = new System.Drawing.Size(73, 23);
|
searchTextBox.Name = "searchTextBox";
|
||||||
clear.TabIndex = 1;
|
searchTextBox.PlaceholderText = "Column Name=Regex{space}....";
|
||||||
clear.Text = "Clear";
|
searchTextBox.Size = new System.Drawing.Size(232, 23);
|
||||||
clear.UseVisualStyleBackColor = true;
|
searchTextBox.TabIndex = 3;
|
||||||
clear.Click += clear_Click;
|
searchTextBox.KeyPress += searchTextBox_KeyPress;
|
||||||
clear.Dock = DockStyle.Fill;
|
|
||||||
//
|
//
|
||||||
// AssetBrowser
|
// AssetBrowser
|
||||||
//
|
//
|
||||||
@@ -148,6 +149,8 @@ namespace AssetStudioGUI
|
|||||||
ResumeLayout(false);
|
ResumeLayout(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
private System.Windows.Forms.DataGridView assetListView;
|
private System.Windows.Forms.DataGridView assetListView;
|
||||||
private TableLayoutPanel tableLayoutPanel1;
|
private TableLayoutPanel tableLayoutPanel1;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -15,6 +15,7 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_parent = form;
|
_parent = form;
|
||||||
|
FormClosing += AssetBrowser_FormClosing;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void loadAssetMap_Click(object sender, EventArgs e)
|
private async void loadAssetMap_Click(object sender, EventArgs e)
|
||||||
@@ -34,31 +35,50 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
private void clear_Click(object sender, EventArgs e)
|
private void clear_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
ResourceMap.Clear();
|
Clear();
|
||||||
assetListView.DataSource = null;
|
|
||||||
Logger.Info($"Cleared !!");
|
Logger.Info($"Cleared !!");
|
||||||
}
|
}
|
||||||
private async void loadSelected_Click(object sender, EventArgs e)
|
private async void loadSelected_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var files = assetListView.SelectedRows.Cast<DataGridViewRow>().Select(x => x.DataBoundItem as AssetEntry).Select(x => x.Source).ToHashSet();
|
var files = assetListView.SelectedRows.Cast<DataGridViewRow>().Select(x => x.DataBoundItem as AssetEntry).Select(x => x.Source).ToHashSet();
|
||||||
|
if (files.Count != 0 && !files.Any(string.IsNullOrEmpty))
|
||||||
if (files.Count != 0 && !files.Any(x => string.IsNullOrEmpty(x)))
|
|
||||||
{
|
{
|
||||||
Logger.Info("Loading...");
|
Logger.Info("Loading...");
|
||||||
_parent.Invoke(() => _parent.LoadPaths(files.ToArray()));
|
_parent.Invoke(() => _parent.LoadPaths(files.ToArray()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void searchTextBox_KeyPress(object sender, KeyPressEventArgs e)
|
private void searchTextBox_KeyPress(object sender, KeyPressEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.KeyChar == (char)Keys.Enter)
|
if (e.KeyChar == (char)Keys.Enter)
|
||||||
{
|
{
|
||||||
|
var filters = new Dictionary<string, Regex>();
|
||||||
|
var names = typeof(AssetEntry).GetProperties().Select(x => x.Name).ToList();
|
||||||
|
|
||||||
var value = searchTextBox.Text;
|
var value = searchTextBox.Text;
|
||||||
|
var options = value.Split(' ');
|
||||||
|
for (int i = 0; i < options.Length; i++)
|
||||||
|
{
|
||||||
|
var option = options[i];
|
||||||
|
var arguments = option.Split('=');
|
||||||
|
if (arguments.Length != 2)
|
||||||
|
{
|
||||||
|
Logger.Error($"Invalid argument at index {i + 1}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var (name, regex) = (arguments[0], arguments[1]);
|
||||||
|
if (!names.Contains(name, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
Logger.Error($"Unknonw argument {name}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
filters[name] = new Regex(regex, RegexOptions.IgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
var assets = ResourceMap.GetEntries();
|
var assets = ResourceMap.GetEntries();
|
||||||
if (assets.Length != 0 && !string.IsNullOrEmpty(value))
|
if (assets.Length != 0)
|
||||||
{
|
{
|
||||||
var regex = new Regex(value, RegexOptions.IgnoreCase);
|
var regex = new Regex(value, RegexOptions.IgnoreCase);
|
||||||
assetListView.DataSource = Array.FindAll(assets, x => x.Matches(regex));
|
assetListView.DataSource = Array.FindAll(assets, x => x.Matches(filters));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -66,5 +86,15 @@ namespace AssetStudioGUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private void AssetBrowser_FormClosing(object sender, FormClosingEventArgs e)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
base.OnClosing(e);
|
||||||
|
}
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
ResourceMap.Clear();
|
||||||
|
assetListView.DataSource = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
56
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
56
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
@@ -45,6 +45,7 @@ namespace AssetStudioGUI
|
|||||||
optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
displayAll = new System.Windows.Forms.ToolStripMenuItem();
|
displayAll = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
enablePreview = new System.Windows.Forms.ToolStripMenuItem();
|
enablePreview = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
enableModelPreview = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
displayInfo = new System.Windows.Forms.ToolStripMenuItem();
|
displayInfo = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
|
toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
|
specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
|
||||||
@@ -60,6 +61,9 @@ namespace AssetStudioGUI
|
|||||||
toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
exportSelectedObjectsmergeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
exportSelectedObjectsmergeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
|
exportSelectedNodessplitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
exportAllAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
exportAllAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
exportSelectedAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
exportSelectedAssetsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
@@ -157,9 +161,6 @@ namespace AssetStudioGUI
|
|||||||
exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
|
|
||||||
exportSelectedNodessplitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
menuStrip1.SuspendLayout();
|
menuStrip1.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
|
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
|
||||||
splitContainer1.Panel1.SuspendLayout();
|
splitContainer1.Panel1.SuspendLayout();
|
||||||
@@ -251,7 +252,7 @@ namespace AssetStudioGUI
|
|||||||
//
|
//
|
||||||
// optionsToolStripMenuItem
|
// optionsToolStripMenuItem
|
||||||
//
|
//
|
||||||
optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { displayAll, enablePreview, displayInfo, toolStripMenuItem14, toolStripMenuItem18, toolStripMenuItem19, showExpOpt });
|
optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { displayAll, enablePreview, enableModelPreview, displayInfo, toolStripMenuItem14, toolStripMenuItem18, toolStripMenuItem19, showExpOpt });
|
||||||
optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
||||||
optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
|
optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
|
||||||
optionsToolStripMenuItem.Text = "Options";
|
optionsToolStripMenuItem.Text = "Options";
|
||||||
@@ -276,6 +277,14 @@ namespace AssetStudioGUI
|
|||||||
enablePreview.ToolTipText = "Toggle the loading and preview of readable assets, such as images, sounds, text, etc.\r\nDisable preview if you have performance or compatibility issues.";
|
enablePreview.ToolTipText = "Toggle the loading and preview of readable assets, such as images, sounds, text, etc.\r\nDisable preview if you have performance or compatibility issues.";
|
||||||
enablePreview.CheckedChanged += enablePreview_Check;
|
enablePreview.CheckedChanged += enablePreview_Check;
|
||||||
//
|
//
|
||||||
|
// enableModelPreview
|
||||||
|
//
|
||||||
|
enableModelPreview.CheckOnClick = true;
|
||||||
|
enableModelPreview.Name = "enableModelPreview";
|
||||||
|
enableModelPreview.Size = new System.Drawing.Size(207, 22);
|
||||||
|
enableModelPreview.Text = "Enable model preview";
|
||||||
|
enableModelPreview.CheckedChanged += enableModelPreview_CheckedChanged;
|
||||||
|
//
|
||||||
// displayInfo
|
// displayInfo
|
||||||
//
|
//
|
||||||
displayInfo.Checked = true;
|
displayInfo.Checked = true;
|
||||||
@@ -382,6 +391,25 @@ namespace AssetStudioGUI
|
|||||||
exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Text = "Export selected objects (merge) + selected AnimationClips";
|
exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Text = "Export selected objects (merge) + selected AnimationClips";
|
||||||
exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Click += exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem_Click;
|
exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem.Click += exportSelectedObjectsmergeWithAnimationClipToolStripMenuItem_Click;
|
||||||
//
|
//
|
||||||
|
// toolStripSeparator9
|
||||||
|
//
|
||||||
|
toolStripSeparator9.Name = "toolStripSeparator9";
|
||||||
|
toolStripSeparator9.Size = new System.Drawing.Size(379, 6);
|
||||||
|
//
|
||||||
|
// exportSelectedNodessplitToolStripMenuItem
|
||||||
|
//
|
||||||
|
exportSelectedNodessplitToolStripMenuItem.Name = "exportSelectedNodessplitToolStripMenuItem";
|
||||||
|
exportSelectedNodessplitToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
||||||
|
exportSelectedNodessplitToolStripMenuItem.Text = "Export selected nodes (split)";
|
||||||
|
exportSelectedNodessplitToolStripMenuItem.Click += exportSelectedNodessplitToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
|
// exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem
|
||||||
|
//
|
||||||
|
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem.Name = "exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem";
|
||||||
|
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
||||||
|
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem.Text = "Export selected nodes (split) + selected AnimationClips";
|
||||||
|
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem.Click += exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem_Click;
|
||||||
|
//
|
||||||
// exportToolStripMenuItem
|
// exportToolStripMenuItem
|
||||||
//
|
//
|
||||||
exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { exportAllAssetsMenuItem, exportSelectedAssetsMenuItem, exportFilteredAssetsMenuItem, toolStripSeparator3, exportAnimatorWithSelectedAnimationClipToolStripMenuItem, toolStripSeparator4, toolStripMenuItem2, toolStripMenuItem3, toolStripMenuItem16, toolStripSeparator2, toolStripMenuItem10 });
|
exportToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { exportAllAssetsMenuItem, exportSelectedAssetsMenuItem, exportFilteredAssetsMenuItem, toolStripSeparator3, exportAnimatorWithSelectedAnimationClipToolStripMenuItem, toolStripSeparator4, toolStripMenuItem2, toolStripMenuItem3, toolStripMenuItem16, toolStripSeparator2, toolStripMenuItem10 });
|
||||||
@@ -1229,25 +1257,6 @@ namespace AssetStudioGUI
|
|||||||
showOriginalFileToolStripMenuItem.Visible = false;
|
showOriginalFileToolStripMenuItem.Visible = false;
|
||||||
showOriginalFileToolStripMenuItem.Click += showOriginalFileToolStripMenuItem_Click;
|
showOriginalFileToolStripMenuItem.Click += showOriginalFileToolStripMenuItem_Click;
|
||||||
//
|
//
|
||||||
// toolStripSeparator9
|
|
||||||
//
|
|
||||||
toolStripSeparator9.Name = "toolStripSeparator9";
|
|
||||||
toolStripSeparator9.Size = new System.Drawing.Size(379, 6);
|
|
||||||
//
|
|
||||||
// exportSelectedNodessplitToolStripMenuItem
|
|
||||||
//
|
|
||||||
exportSelectedNodessplitToolStripMenuItem.Name = "exportSelectedNodessplitToolStripMenuItem";
|
|
||||||
exportSelectedNodessplitToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
|
||||||
exportSelectedNodessplitToolStripMenuItem.Text = "Export selected nodes (split)";
|
|
||||||
exportSelectedNodessplitToolStripMenuItem.Click += exportSelectedNodessplitToolStripMenuItem_Click;
|
|
||||||
//
|
|
||||||
// exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem
|
|
||||||
//
|
|
||||||
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem.Name = "exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem";
|
|
||||||
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem.Size = new System.Drawing.Size(382, 22);
|
|
||||||
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem.Text = "Export selected nodes (split) + selected AnimationClips";
|
|
||||||
exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem.Click += exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem_Click;
|
|
||||||
//
|
|
||||||
// AssetStudioGUIForm
|
// AssetStudioGUIForm
|
||||||
//
|
//
|
||||||
AllowDrop = true;
|
AllowDrop = true;
|
||||||
@@ -1425,6 +1434,7 @@ namespace AssetStudioGUI
|
|||||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator9;
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator9;
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportSelectedNodessplitToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem exportSelectedNodessplitToolStripMenuItem;
|
||||||
private System.Windows.Forms.ToolStripMenuItem exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem;
|
private System.Windows.Forms.ToolStripMenuItem exportSelectedNodessplitSelectedAnimationClipsToolStripMenuItem;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem enableModelPreview;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ namespace AssetStudioGUI
|
|||||||
partial class AssetStudioGUIForm : Form
|
partial class AssetStudioGUIForm : Form
|
||||||
{
|
{
|
||||||
private AssetItem lastSelectedItem;
|
private AssetItem lastSelectedItem;
|
||||||
|
private AssetBrowser assetBrowser;
|
||||||
private DirectBitmap imageTexture;
|
private DirectBitmap imageTexture;
|
||||||
private string tempClipboard;
|
private string tempClipboard;
|
||||||
|
|
||||||
@@ -107,6 +108,7 @@ namespace AssetStudioGUI
|
|||||||
displayAll.Checked = Properties.Settings.Default.displayAll;
|
displayAll.Checked = Properties.Settings.Default.displayAll;
|
||||||
displayInfo.Checked = Properties.Settings.Default.displayInfo;
|
displayInfo.Checked = Properties.Settings.Default.displayInfo;
|
||||||
enablePreview.Checked = Properties.Settings.Default.enablePreview;
|
enablePreview.Checked = Properties.Settings.Default.enablePreview;
|
||||||
|
enableModelPreview.Checked = Properties.Settings.Default.modelsOnly;
|
||||||
assetsManager.ResolveDependencies = Properties.Settings.Default.enableResolveDependencies;
|
assetsManager.ResolveDependencies = Properties.Settings.Default.enableResolveDependencies;
|
||||||
MiHoYoBinData.Encrypted = Properties.Settings.Default.encrypted;
|
MiHoYoBinData.Encrypted = Properties.Settings.Default.encrypted;
|
||||||
MiHoYoBinData.Key = Properties.Settings.Default.key;
|
MiHoYoBinData.Key = Properties.Settings.Default.key;
|
||||||
@@ -758,7 +760,7 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
switch (assetItem.Asset)
|
switch (assetItem.Asset)
|
||||||
{
|
{
|
||||||
case GameObject m_GameObject:
|
case GameObject m_GameObject when Properties.Settings.Default.modelsOnly:
|
||||||
PreviewGameObject(m_GameObject);
|
PreviewGameObject(m_GameObject);
|
||||||
break;
|
break;
|
||||||
case Texture2D m_Texture2D:
|
case Texture2D m_Texture2D:
|
||||||
@@ -789,7 +791,7 @@ namespace AssetStudioGUI
|
|||||||
case Sprite m_Sprite:
|
case Sprite m_Sprite:
|
||||||
PreviewSprite(assetItem, m_Sprite);
|
PreviewSprite(assetItem, m_Sprite);
|
||||||
break;
|
break;
|
||||||
case Animator m_Animator:
|
case Animator m_Animator when Properties.Settings.Default.modelsOnly:
|
||||||
//StatusStripUpdate("Can be exported to FBX file.");
|
//StatusStripUpdate("Can be exported to FBX file.");
|
||||||
PreviewAnimator(m_Animator);
|
PreviewAnimator(m_Animator);
|
||||||
break;
|
break;
|
||||||
@@ -1748,6 +1750,23 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
visibleAssets = exportableAssets;
|
visibleAssets = exportableAssets;
|
||||||
}
|
}
|
||||||
|
if (Properties.Settings.Default.modelsOnly)
|
||||||
|
{
|
||||||
|
var models = visibleAssets.FindAll(x => x.Type == ClassIDType.Animator || x.Type == ClassIDType.GameObject);
|
||||||
|
foreach(var model in models)
|
||||||
|
{
|
||||||
|
var hasModel = model.Asset switch
|
||||||
|
{
|
||||||
|
GameObject m_GameObject => m_GameObject.HasModel(),
|
||||||
|
Animator m_Animator => m_Animator.m_GameObject.TryGet(out var gameObject) && gameObject.HasModel(),
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
if (!hasModel)
|
||||||
|
{
|
||||||
|
visibleAssets.Remove(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (listSearch.Text != " Filter ")
|
if (listSearch.Text != " Filter ")
|
||||||
{
|
{
|
||||||
visibleAssets = visibleAssets.FindAll(
|
visibleAssets = visibleAssets.FindAll(
|
||||||
@@ -1947,6 +1966,16 @@ namespace AssetStudioGUI
|
|||||||
Properties.Settings.Default.selectedAssetMapType = assetMapTypeComboBox.SelectedIndex;
|
Properties.Settings.Default.selectedAssetMapType = assetMapTypeComboBox.SelectedIndex;
|
||||||
Properties.Settings.Default.Save();
|
Properties.Settings.Default.Save();
|
||||||
}
|
}
|
||||||
|
private void enableModelPreview_CheckedChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Properties.Settings.Default.modelsOnly = enableModelPreview.Checked;
|
||||||
|
Properties.Settings.Default.Save();
|
||||||
|
|
||||||
|
if (visibleAssets.Count > 0)
|
||||||
|
{
|
||||||
|
FilterAssetList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void specifyGame_SelectedIndexChanged(object sender, EventArgs e)
|
private void specifyGame_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@@ -2134,6 +2163,7 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
ResetForm();
|
ResetForm();
|
||||||
AssetsHelper.Clear();
|
AssetsHelper.Clear();
|
||||||
|
assetBrowser.Clear();
|
||||||
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
|
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
|
||||||
assetsManager.Game = Studio.Game;
|
assetsManager.Game = Studio.Game;
|
||||||
}
|
}
|
||||||
@@ -2242,7 +2272,7 @@ namespace AssetStudioGUI
|
|||||||
|
|
||||||
private void loadAssetMapToolStripMenuItem_Click(object sender, EventArgs e)
|
private void loadAssetMapToolStripMenuItem_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
var assetBrowser = new AssetBrowser(this);
|
assetBrowser = new AssetBrowser(this);
|
||||||
assetBrowser.Show();
|
assetBrowser.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -60,9 +60,6 @@
|
|||||||
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>312, 17</value>
|
<value>312, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
|
||||||
<value>432, 17</value>
|
|
||||||
</metadata>
|
|
||||||
<data name="fontPreviewBox.Text" xml:space="preserve">
|
<data name="fontPreviewBox.Text" xml:space="preserve">
|
||||||
<value>abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWYZ
|
<value>abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWYZ
|
||||||
1234567890.:,;'\"(!?)+-*/=
|
1234567890.:,;'\"(!?)+-*/=
|
||||||
@@ -81,6 +78,9 @@ The quick brown fox jumps over the lazy dog. 1234567890
|
|||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. 1234567890</value>
|
The quick brown fox jumps over the lazy dog. 1234567890</value>
|
||||||
</data>
|
</data>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>432, 17</value>
|
||||||
|
</metadata>
|
||||||
<metadata name="timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>553, 17</value>
|
<value>553, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
|||||||
12
AssetStudioGUI/Properties/Settings.Designer.cs
generated
12
AssetStudioGUI/Properties/Settings.Designer.cs
generated
@@ -418,5 +418,17 @@ namespace AssetStudioGUI.Properties {
|
|||||||
this["minimalAssetMap"] = value;
|
this["minimalAssetMap"] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("False")]
|
||||||
|
public bool modelsOnly {
|
||||||
|
get {
|
||||||
|
return ((bool)(this["modelsOnly"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["modelsOnly"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,5 +101,8 @@
|
|||||||
<Setting Name="minimalAssetMap" Type="System.Boolean" Scope="User">
|
<Setting Name="minimalAssetMap" Type="System.Boolean" Scope="User">
|
||||||
<Value Profile="(Default)">True</Value>
|
<Value Profile="(Default)">True</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
<Setting Name="modelsOnly" Type="System.Boolean" Scope="User">
|
||||||
|
<Value Profile="(Default)">False</Value>
|
||||||
|
</Setting>
|
||||||
</Settings>
|
</Settings>
|
||||||
</SettingsFile>
|
</SettingsFile>
|
||||||
Reference in New Issue
Block a user