diff --git a/AssetStudio/AssetEntry.cs b/AssetStudio/AssetEntry.cs deleted file mode 100644 index 6ef42a4..0000000 --- a/AssetStudio/AssetEntry.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace AssetStudio -{ - public class AssetEntry - { - public string Name { get; set; } - public string Container { get; set; } - public string Source { get; set; } - public long PathID { get; set; } - public ClassIDType Type { get; set; } - } -} diff --git a/AssetStudio/AssetIndex.cs b/AssetStudio/AssetIndex.cs new file mode 100644 index 0000000..8154b60 --- /dev/null +++ b/AssetStudio/AssetIndex.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; + +namespace AssetStudio +{ + public record AssetIndex + { + public Dictionary Types { get; set; } + public record SubAssetInfo + { + public string Name { get; set; } + public byte PathHashPre { get; set; } + public uint PathHashLast { get; set; } + } + public Dictionary> SubAssets { get; set; } + public Dictionary> Dependencies { get; set; } + public List PreloadBlocks { get; set; } + public List PreloadShaderBlocks { get; set; } + public record BlockInfo + { + public byte Language { get; set; } + public uint Id { get; set; } + public uint Offset { get; set; } + } + public Dictionary Assets { get; set; } + public List SortList { get; set; } + + public AssetIndex() + { + Types = new Dictionary(); + SubAssets = new Dictionary>(); + Dependencies = new Dictionary>(); + PreloadBlocks = new List(); + PreloadShaderBlocks = new List(); + Assets = new Dictionary(); + SortList = new List(); + } + } +} diff --git a/AssetStudio/AssetMap.cs b/AssetStudio/AssetMap.cs new file mode 100644 index 0000000..b0d750a --- /dev/null +++ b/AssetStudio/AssetMap.cs @@ -0,0 +1,35 @@ +using MessagePack; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace AssetStudio +{ + [MessagePackObject] + public record AssetMap + { + [Key(0)] + public GameType GameType { get; set; } + [Key(1)] + public AssetEntry[] AssetEntries { get; set; } + } + [MessagePackObject] + public record AssetEntry + { + [Key(0)] + public string Name { get; set; } + [Key(1)] + public string Container { get; set; } + [Key(2)] + public string Source { get; set; } + [Key(3)] + public long PathID { get; set; } + [Key(4)] + public ClassIDType Type { get; set; } + + public bool Matches(Regex regex) => regex.IsMatch(Name) + || regex.IsMatch(Container) + || regex.IsMatch(Source) + || regex.IsMatch(PathID.ToString()) + || regex.IsMatch(Type.ToString()); + } +} diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj index 1717872..898611e 100644 --- a/AssetStudio/AssetStudio.csproj +++ b/AssetStudio/AssetStudio.csproj @@ -11,6 +11,7 @@ + diff --git a/AssetStudio/AssetsHelper.cs b/AssetStudio/AssetsHelper.cs index 62a330c..74dd6bf 100644 --- a/AssetStudio/AssetsHelper.cs +++ b/AssetStudio/AssetsHelper.cs @@ -9,6 +9,7 @@ using Newtonsoft.Json; using System.Text.RegularExpressions; using System.Xml; using System.Text; +using MessagePack; namespace AssetStudio { @@ -16,6 +17,7 @@ namespace AssetStudio { public const string MapName = "Maps"; + public static bool Minimal = true; public static CancellationTokenSource tokenSource = new CancellationTokenSource(); private static string BaseFolder = ""; @@ -34,7 +36,7 @@ namespace AssetStudio { Directory.CreateDirectory(MapName); var files = Directory.GetFiles(MapName, "*.bin", SearchOption.TopDirectoryOnly); - return files.Select(x => Path.GetFileNameWithoutExtension(x)).ToArray(); + return files.Select(Path.GetFileNameWithoutExtension).ToArray(); } public static void Clear() @@ -132,12 +134,11 @@ namespace AssetStudio Logger.Info("Building CABMap has been cancelled !!"); return; } - var dependencies = assetsFile.m_Externals.Select(x => x.fileName).ToArray(); var entry = new Entry() { Path = relativePath, Offset = assetsFile.offset, - Dependencies = dependencies + Dependencies = assetsFile.m_Externals.Select(x => x.fileName).ToArray() }; if (CABMap.ContainsKey(assetsFile.fileName)) @@ -192,17 +193,16 @@ namespace AssetStudio var path = reader.ReadString(); var offset = reader.ReadInt64(); var depCount = reader.ReadInt32(); - var dependencies = new List(); + var dependencies = new string[depCount]; for (int j = 0; j < depCount; j++) { - var dependancy = reader.ReadString(); - dependencies.Add(dependancy); + dependencies[j] = reader.ReadString(); } var entry = new Entry() { Path = path, Offset = offset, - Dependencies = dependencies.ToArray() + Dependencies = dependencies }; CABMap.Add(cab, entry); } @@ -230,7 +230,7 @@ namespace AssetStudio UpdateContainers(assets, game); - ExportAssetsMap(assets.ToArray(), mapName, savePath, exportListType, resetEvent); + ExportAssetsMap(assets.ToArray(), game, mapName, savePath, exportListType, resetEvent); } catch(Exception e) { @@ -283,13 +283,13 @@ namespace AssetStudio } obj = null; asset.Name = assetBundle.m_Name; - exportable = false; + exportable = !Minimal; break; case ClassIDType.GameObject: var gameObject = new GameObject(objectReader); obj = gameObject; asset.Name = gameObject.m_Name; - exportable = false; + exportable = !Minimal; break; case ClassIDType.Shader when Shader.Parsable: asset.Name = objectReader.ReadAlignedString(); @@ -306,7 +306,6 @@ namespace AssetStudio case ClassIDType.MiHoYoBinData: var MiHoYoBinData = new MiHoYoBinData(objectReader); obj = MiHoYoBinData; - exportable = true; break; case ClassIDType.IndexObject: var indexObject = new IndexObject(objectReader); @@ -316,6 +315,7 @@ namespace AssetStudio mihoyoBinDataNames.Add((index.Value.Object, index.Key)); } asset.Name = "IndexObject"; + exportable = !Minimal; break; case ClassIDType.Font: case ClassIDType.Material: @@ -329,7 +329,8 @@ namespace AssetStudio asset.Name = objectReader.ReadAlignedString(); break; default: - exportable = false; + asset.Name = objectReader.type.ToString(); + exportable = !Minimal; break; } } @@ -428,7 +429,7 @@ namespace AssetStudio } } - private static void ExportAssetsMap(AssetEntry[] toExportAssets, string name, string savePath, ExportListType exportListType, ManualResetEvent resetEvent = null) + private static void ExportAssetsMap(AssetEntry[] toExportAssets, Game game, string name, string savePath, ExportListType exportListType, ManualResetEvent resetEvent = null) { ThreadPool.QueueUserWorkItem(state => { @@ -436,13 +437,12 @@ namespace AssetStudio Progress.Reset(); - string filename; + string filename = Path.Combine(savePath, $"{name}{exportListType.GetExtension()}"); switch (exportListType) { case ExportListType.XML: - filename = Path.Combine(savePath, $"{name}.xml"); - var settings = new XmlWriterSettings() { Indent = true }; - using (XmlWriter writer = XmlWriter.Create(filename, settings)) + var xmlSettings = new XmlWriterSettings() { Indent = true }; + using (XmlWriter writer = XmlWriter.Create(filename, xmlSettings)) { writer.WriteStartDocument(); writer.WriteStartElement("Assets"); @@ -466,7 +466,6 @@ namespace AssetStudio } break; case ExportListType.JSON: - filename = Path.Combine(savePath, $"{name}.json"); using (StreamWriter file = File.CreateText(filename)) { var serializer = new JsonSerializer() { Formatting = Newtonsoft.Json.Formatting.Indented }; @@ -474,10 +473,20 @@ namespace AssetStudio serializer.Serialize(file, toExportAssets); } break; + case ExportListType.MessagePack: + using (var file = File.Create(filename)) + { + var assetMap = new AssetMap + { + GameType = game.Type, + AssetEntries = toExportAssets + }; + MessagePackSerializer.Serialize(file, assetMap, MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray)); + } + break; } - Logger.Info($"Finished exporting asset list with {toExportAssets.Length} items."); - Logger.Info($"AssetMap build successfully !!"); + Logger.Info($"Finished buidling AssetMap with {toExportAssets.Length} assets."); resetEvent?.Set(); }); @@ -501,7 +510,7 @@ namespace AssetStudio DumpCABMap(mapName); Logger.Info($"Map build successfully !! {collision} collisions found"); - ExportAssetsMap(assets.ToArray(), mapName, savePath, exportListType, resetEvent); + ExportAssetsMap(assets.ToArray(), game, mapName, savePath, exportListType, resetEvent); } } } diff --git a/AssetStudio/ExportTypeList.cs b/AssetStudio/ExportTypeList.cs index e0edee0..fc1574b 100644 --- a/AssetStudio/ExportTypeList.cs +++ b/AssetStudio/ExportTypeList.cs @@ -3,7 +3,8 @@ public enum ExportListType { XML, - JSON + JSON, + MessagePack } public static class ExportListTypeExtensions @@ -12,6 +13,7 @@ { ExportListType.XML => ".xml", ExportListType.JSON => ".json", + ExportListType.MessagePack => ".map", _ => throw new System.NotImplementedException(), }; } diff --git a/AssetStudio/ResourceIndex.cs b/AssetStudio/ResourceIndex.cs index bdbe8b6..b45e33f 100644 --- a/AssetStudio/ResourceIndex.cs +++ b/AssetStudio/ResourceIndex.cs @@ -2,7 +2,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text; namespace AssetStudio @@ -86,38 +85,4 @@ namespace AssetStudio return string.Empty; } } - - public record AssetIndex - { - public Dictionary Types { get; set; } - public record SubAssetInfo - { - public string Name { get; set; } - public byte PathHashPre { get; set; } - public uint PathHashLast { get; set; } - } - public Dictionary> SubAssets { get; set; } - public Dictionary> Dependencies { get; set; } - public List PreloadBlocks { get; set; } - public List PreloadShaderBlocks { get; set; } - public record BlockInfo - { - public byte Language { get; set; } - public uint Id { get; set; } - public uint Offset { get; set; } - } - public Dictionary Assets { get; set; } - public List SortList { get; set; } - - public AssetIndex() - { - Types = new Dictionary(); - SubAssets = new Dictionary>(); - Dependencies = new Dictionary>(); - PreloadBlocks = new List(); - PreloadShaderBlocks = new List(); - Assets = new Dictionary(); - SortList = new List(); - } - } } diff --git a/AssetStudio/ResourceMap.cs b/AssetStudio/ResourceMap.cs new file mode 100644 index 0000000..55522e0 --- /dev/null +++ b/AssetStudio/ResourceMap.cs @@ -0,0 +1,37 @@ +using MessagePack; +using System; +using System.IO; + +namespace AssetStudio +{ + public static class ResourceMap + { + private static AssetMap Instance; + public static AssetEntry[] GetEntries() => Instance.AssetEntries; + public static void FromFile(string path) + { + if (!string.IsNullOrEmpty(path)) + { + Logger.Info(string.Format("Parsing....")); + try + { + using var stream = File.OpenRead(path); + Instance = MessagePackSerializer.Deserialize(stream, MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray)); + } + catch (Exception e) + { + Logger.Error("AssetMap was not loaded"); + Console.WriteLine(e.ToString()); + return; + } + Logger.Info("Loaded !!"); + } + } + + public static void Clear() + { + Instance.GameType = GameType.Normal; + Instance.AssetEntries = null; + } + } +} diff --git a/AssetStudioCLI/App.config b/AssetStudioCLI/App.config index 06ca71a..c178c08 100644 --- a/AssetStudioCLI/App.config +++ b/AssetStudioCLI/App.config @@ -22,5 +22,6 @@ + \ No newline at end of file diff --git a/AssetStudioCLI/Program.cs b/AssetStudioCLI/Program.cs index 70edf67..5ef8360 100644 --- a/AssetStudioCLI/Program.cs +++ b/AssetStudioCLI/Program.cs @@ -27,6 +27,7 @@ namespace AssetStudioCLI Studio.Game = game; Logger.Default = new ConsoleLogger(); + AssetsHelper.Minimal = Settings.Default.minimalAssetMap; Shader.Parsable = !Settings.Default.disableShader; Renderer.Parsable = !Settings.Default.disableRenderer; assetsManager.Silent = o.Silent; diff --git a/AssetStudioCLI/Settings.cs b/AssetStudioCLI/Settings.cs index 0f2cf7c..4a9a71d 100644 --- a/AssetStudioCLI/Settings.cs +++ b/AssetStudioCLI/Settings.cs @@ -69,6 +69,7 @@ namespace AssetStudioCLI.Properties { public bool exportMiHoYoBinData => AppSettings.Get("exportMiHoYoBinData", true); public bool disableShader => AppSettings.Get("disableShader", false); public bool disableRenderer => AppSettings.Get("disableRenderer", false); + public bool minimalAssetMap => AppSettings.Get("minimalAssetMap", true); } } diff --git a/AssetStudioGUI/App.config b/AssetStudioGUI/App.config index acc4f2a..6886bc2 100644 --- a/AssetStudioGUI/App.config +++ b/AssetStudioGUI/App.config @@ -100,6 +100,9 @@ False + + True + \ No newline at end of file diff --git a/AssetStudioGUI/AssetBrowser.Designer.cs b/AssetStudioGUI/AssetBrowser.Designer.cs new file mode 100644 index 0000000..1aaa7c4 --- /dev/null +++ b/AssetStudioGUI/AssetBrowser.Designer.cs @@ -0,0 +1,117 @@ +namespace AssetStudioGUI +{ + partial class AssetBrowser + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + assetListView = new System.Windows.Forms.DataGridView(); + fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + loadAssetMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + searchTextBox = new System.Windows.Forms.ToolStripTextBox(); + menuStrip1 = new System.Windows.Forms.MenuStrip(); + ((System.ComponentModel.ISupportInitialize)assetListView).BeginInit(); + menuStrip1.SuspendLayout(); + SuspendLayout(); + // + // assetListView + // + assetListView.AllowUserToAddRows = false; + assetListView.AllowUserToDeleteRows = false; + assetListView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + assetListView.Location = new System.Drawing.Point(12, 27); + assetListView.Name = "assetListView"; + assetListView.ReadOnly = true; + assetListView.RowTemplate.Height = 25; + assetListView.Size = new System.Drawing.Size(524, 268); + assetListView.TabIndex = 2; + assetListView.RowHeaderMouseDoubleClick += assetListView_RowHeaderMouseDoubleClick; + // + // fileToolStripMenuItem + // + fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { loadAssetMapToolStripMenuItem, clearToolStripMenuItem }); + fileToolStripMenuItem.Name = "fileToolStripMenuItem"; + fileToolStripMenuItem.Size = new System.Drawing.Size(37, 23); + fileToolStripMenuItem.Text = "File"; + // + // loadAssetMapToolStripMenuItem + // + loadAssetMapToolStripMenuItem.Name = "loadAssetMapToolStripMenuItem"; + loadAssetMapToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + loadAssetMapToolStripMenuItem.Text = "Load AssetMap"; + loadAssetMapToolStripMenuItem.Click += loadAssetMapToolStripMenuItem_Click; + // + // clearToolStripMenuItem + // + clearToolStripMenuItem.Name = "clearToolStripMenuItem"; + clearToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + clearToolStripMenuItem.Text = "Clear"; + clearToolStripMenuItem.Click += clearToolStripMenuItem_Click; + // + // searchTextBox + // + searchTextBox.Name = "searchTextBox"; + searchTextBox.Size = new System.Drawing.Size(500, 23); + searchTextBox.KeyPress += toolStripTextBox1_KeyPress; + // + // menuStrip1 + // + menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { fileToolStripMenuItem, searchTextBox }); + menuStrip1.Location = new System.Drawing.Point(0, 0); + menuStrip1.Name = "menuStrip1"; + menuStrip1.Size = new System.Drawing.Size(548, 27); + menuStrip1.TabIndex = 1; + menuStrip1.Text = "menuStrip1"; + // + // AssetBrowser + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(548, 307); + Controls.Add(assetListView); + Controls.Add(menuStrip1); + MainMenuStrip = menuStrip1; + Name = "AssetBrowser"; + ShowIcon = false; + StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + Text = "Asset Browser"; + ((System.ComponentModel.ISupportInitialize)assetListView).EndInit(); + menuStrip1.ResumeLayout(false); + menuStrip1.PerformLayout(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + private System.Windows.Forms.DataGridView assetListView; + private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem loadAssetMapToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem clearToolStripMenuItem; + private System.Windows.Forms.ToolStripTextBox searchTextBox; + private System.Windows.Forms.MenuStrip menuStrip1; + } +} \ No newline at end of file diff --git a/AssetStudioGUI/AssetBrowser.cs b/AssetStudioGUI/AssetBrowser.cs new file mode 100644 index 0000000..7a28801 --- /dev/null +++ b/AssetStudioGUI/AssetBrowser.cs @@ -0,0 +1,79 @@ +using System; +using System.IO; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Forms; +using AssetStudio; + +namespace AssetStudioGUI +{ + partial class AssetBrowser : Form + { + private readonly AssetStudioGUIForm _parent; + public AssetBrowser(AssetStudioGUIForm form) + { + InitializeComponent(); + _parent = form; + } + + private async void loadAssetMapToolStripMenuItem_Click(object sender, EventArgs e) + { + fileToolStripMenuItem.DropDown.Visible = false; + + var openFileDialog = new OpenFileDialog() { Multiselect = false, Filter = "AssetMap File|*.map" }; + if (openFileDialog.ShowDialog(this) == DialogResult.OK) + { + var path = openFileDialog.FileName; + Logger.Info($"Loading AssetMap..."); + InvokeUpdate(loadAssetMapToolStripMenuItem, false); + await Task.Run(() => ResourceMap.FromFile(path)); + assetListView.DataSource = ResourceMap.GetEntries(); + InvokeUpdate(loadAssetMapToolStripMenuItem, true); + } + } + private void clearToolStripMenuItem_Click(object sender, EventArgs e) + { + ResourceMap.Clear(); + assetListView.DataSource = null; + Logger.Info($"Cleared !!"); + } + private async void assetListView_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) + { + var entry = assetListView.CurrentRow.DataBoundItem as AssetEntry; + + if (!string.IsNullOrEmpty(entry.Source)) + { + Logger.Info("Loading..."); + _parent.Invoke(() => _parent.LoadPaths(entry.Source)); + } + } + private void InvokeUpdate(ToolStripItem item, bool value) + { + if (InvokeRequired) + { + BeginInvoke(new Action(() => { item.Enabled = value; })); + } + else + { + item.Enabled = value; + } + } + + private void toolStripTextBox1_KeyPress(object sender, KeyPressEventArgs e) + { + if (e.KeyChar == (char)Keys.Enter) + { + var value = searchTextBox.Text; + if (!string.IsNullOrEmpty(value)) + { + var regex = new Regex(value); + assetListView.DataSource = Array.FindAll(ResourceMap.GetEntries(), x => x.Matches(regex)); + } + else + { + assetListView.DataSource = ResourceMap.GetEntries(); + } + } + } + } +} diff --git a/AssetStudioGUI/AssetBrowser.resx b/AssetStudioGUI/AssetBrowser.resx new file mode 100644 index 0000000..bd89542 --- /dev/null +++ b/AssetStudioGUI/AssetBrowser.resx @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 142, 17 + + \ No newline at end of file diff --git a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs index e79639e..8f43691 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.Designer.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.Designer.cs @@ -93,6 +93,7 @@ namespace AssetStudioGUI clearConsoleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); miscToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); MapNameComboBox = new System.Windows.Forms.ToolStripComboBox(); + buildMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); buildBothToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); clearMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); toolStripSeparator7 = new System.Windows.Forms.ToolStripSeparator(); @@ -101,6 +102,7 @@ namespace AssetStudioGUI assetMapTypeComboBox = new System.Windows.Forms.ToolStripComboBox(); toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); loadAIToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + assetBrowserToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); assetHelpersToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); MapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); assetMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -155,7 +157,6 @@ namespace AssetStudioGUI exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem(); goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - buildMapToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); menuStrip1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit(); splitContainer1.Panel1.SuspendLayout(); @@ -600,7 +601,7 @@ namespace AssetStudioGUI // // miscToolStripMenuItem // - miscToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { MapNameComboBox, buildMapToolStripMenuItem, buildBothToolStripMenuItem, clearMapToolStripMenuItem, toolStripSeparator7, assetMapNameTextBox, buildAssetMapToolStripMenuItem, assetMapTypeComboBox, toolStripSeparator8, loadAIToolStripMenuItem }); + miscToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { MapNameComboBox, buildMapToolStripMenuItem, buildBothToolStripMenuItem, clearMapToolStripMenuItem, toolStripSeparator7, assetMapNameTextBox, buildAssetMapToolStripMenuItem, assetMapTypeComboBox, toolStripSeparator8, loadAIToolStripMenuItem, assetBrowserToolStripMenuItem }); miscToolStripMenuItem.Name = "miscToolStripMenuItem"; miscToolStripMenuItem.Size = new System.Drawing.Size(47, 20); miscToolStripMenuItem.Text = "Misc."; @@ -670,6 +671,13 @@ namespace AssetStudioGUI loadAIToolStripMenuItem.Text = "Load AI"; loadAIToolStripMenuItem.Click += loadAIToolStripMenuItem_Click; // + // assetBrowserToolStripMenuItem + // + assetBrowserToolStripMenuItem.Name = "assetBrowserToolStripMenuItem"; + assetBrowserToolStripMenuItem.Size = new System.Drawing.Size(181, 22); + assetBrowserToolStripMenuItem.Text = "Asset Browser"; + assetBrowserToolStripMenuItem.Click += loadAssetMapToolStripMenuItem_Click; + // // assetHelpersToolStripMenuItem // assetHelpersToolStripMenuItem.Name = "assetHelpersToolStripMenuItem"; @@ -1391,6 +1399,7 @@ namespace AssetStudioGUI private System.Windows.Forms.ToolStripSeparator toolStripSeparator7; private System.Windows.Forms.ToolStripSeparator toolStripSeparator8; private System.Windows.Forms.ToolStripMenuItem buildMapToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem assetBrowserToolStripMenuItem; } } diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index f1d5d11..20f5a9b 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -110,6 +110,7 @@ namespace AssetStudioGUI assetsManager.ResolveDependencies = Properties.Settings.Default.enableResolveDependencies; MiHoYoBinData.Encrypted = Properties.Settings.Default.encrypted; MiHoYoBinData.Key = Properties.Settings.Default.key; + AssetsHelper.Minimal = Properties.Settings.Default.minimalAssetMap; Renderer.Parsable = !Properties.Settings.Default.disableRenderer; Shader.Parsable = !Properties.Settings.Default.disableShader; } @@ -164,6 +165,12 @@ namespace AssetStudioGUI var paths = (string[])e.Data.GetData(DataFormats.FileDrop); if (paths.Length > 0) { + LoadPaths(paths); + } + } + + public async void LoadPaths(params string[] paths) + { ResetForm(); assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text; assetsManager.Game = Studio.Game; @@ -181,7 +188,6 @@ namespace AssetStudioGUI } BuildAssetStructures(); } - } private async void loadFile_Click(object sender, EventArgs e) { @@ -1233,84 +1239,16 @@ namespace AssetStudioGUI private void PreviewGameObject(GameObject m_GameObject) { var model = new ModelConverter(m_GameObject, Properties.Settings.Default.convertType, Studio.Game, false, Array.Empty()); - if (model.MeshList.Count > 0) - { - viewMatrixData = Matrix4.CreateRotationY(-(float)Math.PI / 4) * Matrix4.CreateRotationX(-(float)Math.PI / 6); - #region Vertices - vertexData = model.MeshList.SelectMany(x => x.VertexList).Select(x => new Vector3(x.Vertex.X, x.Vertex.Y, x.Vertex.Z)).ToArray(); - // Calculate Bounding - Vector3 min = vertexData.Aggregate(Vector3.ComponentMin); - Vector3 max = vertexData.Aggregate(Vector3.ComponentMax); - - // Calculate modelMatrix - Vector3 dist = max - min; - Vector3 offset = (max - min) / 2; - float d = Math.Max(1e-5f, dist.Length); - modelMatrixData = Matrix4.CreateTranslation(-offset) * Matrix4.CreateScale(2f / d); - #endregion - #region Indicies - int meshOffset = 0; - var indices = new List(); - foreach (var mesh in model.MeshList) - { - foreach (var submesh in mesh.SubmeshList) - { - foreach (var face in submesh.FaceList) - { - foreach (var index in face.VertexIndices) - { - indices.Add(submesh.BaseVertex + index + meshOffset); + PreviewModel(model); } - } - } - meshOffset += mesh.VertexList.Count; - } - indiceData = indices.ToArray(); - #endregion - #region Normals - normalData = model.MeshList.SelectMany(x => x.VertexList).Select(x => new Vector3(x.Normal.X, x.Normal.Y, x.Normal.Z)).ToArray(); - // calculate normal by ourself - normal2Data = new Vector3[vertexData.Length]; - int[] normalCalculatedCount = new int[vertexData.Length]; - Array.Fill(normal2Data, Vector3.Zero); - Array.Fill(normalCalculatedCount, 0); - for (int j = 0; j < indiceData.Length; j += 3) - { - Vector3 dir1 = vertexData[indiceData[j + 1]] - vertexData[indiceData[j]]; - Vector3 dir2 = vertexData[indiceData[j + 2]] - vertexData[indiceData[j]]; - Vector3 normal = Vector3.Cross(dir1, dir2); - normal.Normalize(); - for (int k = 0; k < 3; k++) - { - normal2Data[indiceData[j + k]] += normal; - normalCalculatedCount[indiceData[j + k]]++; - } - } - for (int j = 0; j < vertexData.Length; j++) - { - if (normalCalculatedCount[j] == 0) - normal2Data[j] = new Vector3(0, 1, 0); - else - normal2Data[j] /= normalCalculatedCount[j]; - } - #endregion - #region Colors - colorData = model.MeshList.SelectMany(x => x.VertexList).Select(x => new Vector4(x.Color.R, x.Color.G, x.Color.B, x.Color.A)).ToArray(); - #endregion - glControl.Visible = true; - CreateVAO(); - StatusStripUpdate("Using OpenGL Version: " + GL.GetString(StringName.Version) + "\n" - + "'Mouse Left'=Rotate | 'Mouse Right'=Move | 'Mouse Wheel'=Zoom \n" - + "'Ctrl W'=Wireframe | 'Ctrl S'=Shade | 'Ctrl N'=ReNormal "); - } - else - { - StatusStripUpdate("Unable to preview this model"); - } - } private void PreviewAnimator(Animator m_Animator) - { + { var model = new ModelConverter(m_Animator, Properties.Settings.Default.convertType, Studio.Game, false, Array.Empty()); + PreviewModel(model); + } + + private void PreviewModel(ModelConverter model) + { if (model.MeshList.Count > 0) { viewMatrixData = Matrix4.CreateRotationY(-(float)Math.PI / 4) * Matrix4.CreateRotationX(-(float)Math.PI / 6); @@ -2267,6 +2205,12 @@ namespace AssetStudioGUI InvokeUpdate(miscToolStripMenuItem, true); } + private void loadAssetMapToolStripMenuItem_Click(object sender, EventArgs e) + { + var assetBrowser = new AssetBrowser(this); + assetBrowser.Show(); + } + #region FMOD private void FMODinit() { diff --git a/AssetStudioGUI/ExportOptions.Designer.cs b/AssetStudioGUI/ExportOptions.Designer.cs index 78a43e7..d052025 100644 --- a/AssetStudioGUI/ExportOptions.Designer.cs +++ b/AssetStudioGUI/ExportOptions.Designer.cs @@ -71,12 +71,13 @@ namespace AssetStudioGUI key = new System.Windows.Forms.NumericUpDown(); keyToolTip = new System.Windows.Forms.ToolTip(components); groupBox4 = new System.Windows.Forms.GroupBox(); + disableShader = new System.Windows.Forms.CheckBox(); + disableRenderer = new System.Windows.Forms.CheckBox(); skipContainer = new System.Windows.Forms.CheckBox(); enableResolveDependencies = new System.Windows.Forms.CheckBox(); resolveToolTip = new System.Windows.Forms.ToolTip(components); skipToolTip = new System.Windows.Forms.ToolTip(components); - disableRenderer = new System.Windows.Forms.CheckBox(); - disableShader = new System.Windows.Forms.CheckBox(); + minimalAssetMap = new System.Windows.Forms.CheckBox(); groupBox1.SuspendLayout(); panel1.SuspendLayout(); groupBox2.SuspendLayout(); @@ -537,6 +538,7 @@ namespace AssetStudioGUI // groupBox4 // groupBox4.AutoSize = true; + groupBox4.Controls.Add(minimalAssetMap); groupBox4.Controls.Add(disableShader); groupBox4.Controls.Add(disableRenderer); groupBox4.Controls.Add(skipContainer); @@ -547,11 +549,35 @@ namespace AssetStudioGUI groupBox4.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); groupBox4.Name = "groupBox4"; groupBox4.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3); - groupBox4.Size = new System.Drawing.Size(272, 176); + groupBox4.Size = new System.Drawing.Size(272, 187); groupBox4.TabIndex = 13; groupBox4.TabStop = false; groupBox4.Text = "Options"; // + // disableShader + // + disableShader.AutoSize = true; + disableShader.Location = new System.Drawing.Point(8, 121); + disableShader.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + disableShader.Name = "disableShader"; + disableShader.Size = new System.Drawing.Size(103, 19); + disableShader.TabIndex = 16; + disableShader.Text = "Disable Shader"; + skipToolTip.SetToolTip(disableShader, "Skips the container recovery step.\nImproves loading when dealing with a large number of files."); + disableShader.UseVisualStyleBackColor = true; + // + // disableRenderer + // + disableRenderer.AutoSize = true; + disableRenderer.Location = new System.Drawing.Point(8, 96); + disableRenderer.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); + disableRenderer.Name = "disableRenderer"; + disableRenderer.Size = new System.Drawing.Size(114, 19); + disableRenderer.TabIndex = 15; + disableRenderer.Text = "Disable Renderer"; + skipToolTip.SetToolTip(disableRenderer, "Skips the container recovery step.\nImproves loading when dealing with a large number of files."); + disableRenderer.UseVisualStyleBackColor = true; + // // skipContainer // skipContainer.AutoSize = true; @@ -580,29 +606,15 @@ namespace AssetStudioGUI resolveToolTip.SetToolTip(enableResolveDependencies, "Toggle the behaviour of loading assets.\r\nDisable to load file(s) without its dependencies."); enableResolveDependencies.UseVisualStyleBackColor = true; // - // disableRenderer + // minimalAssetMap // - disableRenderer.AutoSize = true; - disableRenderer.Location = new System.Drawing.Point(8, 96); - disableRenderer.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - disableRenderer.Name = "disableRenderer"; - disableRenderer.Size = new System.Drawing.Size(114, 19); - disableRenderer.TabIndex = 15; - disableRenderer.Text = "Disable Renderer"; - skipToolTip.SetToolTip(disableRenderer, "Skips the container recovery step.\nImproves loading when dealing with a large number of files."); - disableRenderer.UseVisualStyleBackColor = true; - // - // disableShader - // - disableShader.AutoSize = true; - disableShader.Location = new System.Drawing.Point(8, 121); - disableShader.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); - disableShader.Name = "disableShader"; - disableShader.Size = new System.Drawing.Size(103, 19); - disableShader.TabIndex = 16; - disableShader.Text = "Disable Shader"; - skipToolTip.SetToolTip(disableShader, "Skips the container recovery step.\nImproves loading when dealing with a large number of files."); - disableShader.UseVisualStyleBackColor = true; + minimalAssetMap.AutoSize = true; + minimalAssetMap.Location = new System.Drawing.Point(8, 146); + minimalAssetMap.Name = "minimalAssetMap"; + minimalAssetMap.Size = new System.Drawing.Size(125, 19); + minimalAssetMap.TabIndex = 17; + minimalAssetMap.Text = "Minimal AssetMap"; + minimalAssetMap.UseVisualStyleBackColor = true; // // ExportOptions // @@ -687,5 +699,6 @@ namespace AssetStudioGUI private System.Windows.Forms.ToolTip skipToolTip; private System.Windows.Forms.CheckBox disableShader; private System.Windows.Forms.CheckBox disableRenderer; + private System.Windows.Forms.CheckBox minimalAssetMap; } } \ No newline at end of file diff --git a/AssetStudioGUI/ExportOptions.cs b/AssetStudioGUI/ExportOptions.cs index c23476e..0a54d4f 100644 --- a/AssetStudioGUI/ExportOptions.cs +++ b/AssetStudioGUI/ExportOptions.cs @@ -44,6 +44,7 @@ namespace AssetStudioGUI key.Value = Properties.Settings.Default.key; disableRenderer.Checked = Properties.Settings.Default.disableRenderer; disableShader.Checked = Properties.Settings.Default.disableShader; + minimalAssetMap.Checked = Properties.Settings.Default.minimalAssetMap; } private void OKbutton_Click(object sender, EventArgs e) @@ -79,9 +80,11 @@ namespace AssetStudioGUI Properties.Settings.Default.key = (byte)key.Value; Properties.Settings.Default.disableRenderer = disableRenderer.Checked; Properties.Settings.Default.disableShader = disableShader.Checked; + Properties.Settings.Default.minimalAssetMap = minimalAssetMap.Checked; Properties.Settings.Default.Save(); MiHoYoBinData.Key = (byte)key.Value; MiHoYoBinData.Encrypted = encrypted.Checked; + AssetsHelper.Minimal = Properties.Settings.Default.minimalAssetMap; Renderer.Parsable = !Properties.Settings.Default.disableRenderer; Shader.Parsable = !Properties.Settings.Default.disableShader; DialogResult = DialogResult.OK; diff --git a/AssetStudioGUI/ExportOptions.resx b/AssetStudioGUI/ExportOptions.resx index 485af80..b787a62 100644 --- a/AssetStudioGUI/ExportOptions.resx +++ b/AssetStudioGUI/ExportOptions.resx @@ -60,12 +60,6 @@ 17, 17 - - 17, 17 - - - 162, 17 - 162, 17 @@ -75,9 +69,6 @@ 273, 17 - - 273, 17 - 57 diff --git a/AssetStudioGUI/Properties/Settings.Designer.cs b/AssetStudioGUI/Properties/Settings.Designer.cs index ef464bb..b80acd4 100644 --- a/AssetStudioGUI/Properties/Settings.Designer.cs +++ b/AssetStudioGUI/Properties/Settings.Designer.cs @@ -406,5 +406,17 @@ namespace AssetStudioGUI.Properties { this["disableRenderer"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool minimalAssetMap { + get { + return ((bool)(this["minimalAssetMap"])); + } + set { + this["minimalAssetMap"] = value; + } + } } } diff --git a/AssetStudioGUI/Properties/Settings.settings b/AssetStudioGUI/Properties/Settings.settings index 4495fcb..0ef09de 100644 --- a/AssetStudioGUI/Properties/Settings.settings +++ b/AssetStudioGUI/Properties/Settings.settings @@ -98,5 +98,8 @@ False + + True + \ No newline at end of file diff --git a/AssetStudioUtility/ModelConverter.cs b/AssetStudioUtility/ModelConverter.cs index 5b7b2d2..b36586a 100644 --- a/AssetStudioUtility/ModelConverter.cs +++ b/AssetStudioUtility/ModelConverter.cs @@ -711,6 +711,8 @@ namespace AssetStudio dest = 2; else if (texEnv.Key.Contains("Normal")) dest = 1; + else if (Game.Type.IsSRGroup() && texEnv.Key.Contains("Pack")) + dest = 0; texture.Dest = dest;