├── .gitmodules
├── UAssetGUI
├── Resources
│ ├── icon.ico
│ └── dancing_cat.gif
├── UAGTheme.cs
├── FodyWeavers.xml
├── UAssetGUI.csproj.user
├── LICENSE
├── GlobalSuppressions.cs
├── ColorfulTreeView.cs
├── ProgressBarForm.cs
├── GitHubAPI.cs
├── TextPrompt.cs
├── MarkdownViewer.cs
├── MarkdownViewer.Designer.cs
├── Program.cs
├── AboutForm.cs
├── Properties
│ ├── Resources.Designer.cs
│ └── Resources.resx
├── ProgressBarForm.Designer.cs
├── TextPrompt.resx
├── AboutForm.Designer.cs
├── SettingsForm.resx
├── MarkdownViewer.resx
├── ProgressBarForm.resx
├── FindForm.resx
├── AboutForm.resx
├── MapStructTypeOverrideForm.resx
├── Form1.resx
├── FileContainerForm.resx
├── TextPrompt.Designer.cs
├── UAssetGUI.csproj
├── UAGUtils.cs
├── FodyWeavers.xsd
├── MapStructTypeOverrideForm.cs
├── UAGConfig.cs
├── FindForm.Designer.cs
├── MapStructTypeOverrideForm.Designer.cs
├── SettingsForm.cs
└── FindForm.cs
├── .gitignore
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
└── workflows
│ └── build.yml
├── LICENSE
├── README.md
└── UAssetGUI.sln
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "UAssetAPI"]
2 | path = UAssetAPI
3 | url = https://github.com/atenfyr/UAssetAPI.git
4 |
--------------------------------------------------------------------------------
/UAssetGUI/Resources/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atenfyr/UAssetGUI/HEAD/UAssetGUI/Resources/icon.ico
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vs
2 | docs
3 | packages
4 | TestResults
5 | UAssetGUI/bin
6 | UAssetGUI/obj
7 | UAssetGUI/git_commit.txt
8 |
--------------------------------------------------------------------------------
/UAssetGUI/Resources/dancing_cat.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/atenfyr/UAssetGUI/HEAD/UAssetGUI/Resources/dancing_cat.gif
--------------------------------------------------------------------------------
/UAssetGUI/UAGTheme.cs:
--------------------------------------------------------------------------------
1 | namespace UAssetGUI
2 | {
3 | public enum UAGTheme
4 | {
5 | Light,
6 | Dark
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/UAssetGUI/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/UAssetGUI/UAssetGUI.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Form
7 |
8 |
9 | Form
10 |
11 |
12 | Form
13 |
14 |
15 | Form
16 |
17 |
18 |
19 |
20 | Designer
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 | Please provide a copy of an asset that can be used to reproduce the issue if needed, along with the game's Unreal Engine version. If the asset uses unversioned properties, you should also provide a set of mappings. Your issue will NOT be reviewed if your issue cannot be replicated due to no test asset being provided.
20 |
21 | **Expected behavior**
22 | A clear and concise description of what you expected to happen.
23 |
24 | **Screenshots**
25 | If applicable, add screenshots to help explain your problem.
26 |
27 | **Desktop (please complete the following information):**
28 | - OS: [e.g. Windows 10]
29 | - Version or Commit: [e.g. 1.0.2/c7d9f8d]
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Atenfyr
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/UAssetGUI/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2025 Atenfyr
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/UAssetGUI/GlobalSuppressions.cs:
--------------------------------------------------------------------------------
1 |
2 | // This file is used by Code Analysis to maintain SuppressMessage
3 | // attributes that are applied to this project.
4 | // Project-level suppressions either have no target or are given
5 | // a specific target and scoped to a namespace, type, member, etc.
6 |
7 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~M:UAssetGUI.Form1.openToolStripMenuItem_Click(System.Object,System.EventArgs)")]
8 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~M:UAssetGUI.Form1.saveToolStripMenuItem_Click(System.Object,System.EventArgs)")]
9 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~M:UAssetGUI.Form1.menuStrip1_ItemClicked(System.Object,System.Windows.Forms.ToolStripItemClickedEventArgs)")]
10 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~M:UAssetGUI.Form1.saveAsToolStripMenuItem_Click(System.Object,System.EventArgs)")]
11 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "", Scope = "member", Target = "~M:UAssetGUI.Form1.frm_sizeChanged(System.Object,System.EventArgs)")]
--------------------------------------------------------------------------------
/UAssetGUI/ColorfulTreeView.cs:
--------------------------------------------------------------------------------
1 | using System.Drawing;
2 | using System.Windows.Forms;
3 |
4 | namespace UAssetGUI
5 | {
6 | public class ColorfulTreeView : TreeView
7 | {
8 | public ColorfulTreeView() : base()
9 | {
10 | this.DrawMode = TreeViewDrawMode.OwnerDrawText;
11 | NodeMouseClick += (sender, args) => { if (args.Button == MouseButtons.Right) SelectedNode = args.Node; };
12 | }
13 |
14 | protected override void OnDrawNode(DrawTreeNodeEventArgs e)
15 | {
16 | if (!e.Node.IsVisible) return;
17 | if (e.Node.Bounds.IsEmpty) return;
18 |
19 | Font font = e.Node.NodeFont ?? e.Node.TreeView.Font;
20 | Color fore = e.Node.ForeColor;
21 | if (fore == Color.Empty) fore = e.Node.TreeView.ForeColor;
22 | if (e.Node == e.Node.TreeView.SelectedNode)
23 | {
24 | fore = UAGPalette.HighlightForeColor;
25 | e.Graphics.FillRectangle(new SolidBrush(UAGPalette.HighlightBackColor), e.Bounds);
26 | ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, fore, UAGPalette.HighlightBackColor);
27 | TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, fore, UAGPalette.HighlightBackColor, TextFormatFlags.GlyphOverhangPadding);
28 | }
29 | else
30 | {
31 | e.Graphics.FillRectangle(new SolidBrush(UAGPalette.BackColor), e.Bounds);
32 | TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, fore, TextFormatFlags.GlyphOverhangPadding);
33 | }
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/UAssetGUI/ProgressBarForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Data;
5 | using System.Drawing;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 | using System.Windows.Forms;
10 |
11 | namespace UAssetGUI
12 | {
13 | public partial class ProgressBarForm : Form
14 | {
15 | public Form BaseForm;
16 | public int Value;
17 | public int Maximum;
18 |
19 | private const int CP_NOCLOSE_BUTTON = 0x200;
20 | protected override CreateParams CreateParams
21 | {
22 | get
23 | {
24 | CreateParams myCp = base.CreateParams;
25 | myCp.ClassStyle = myCp.ClassStyle | CP_NOCLOSE_BUTTON;
26 | return myCp;
27 | }
28 | }
29 |
30 | public void Progress(int numToAdd)
31 | {
32 | Value += numToAdd;
33 | UpdateGUI();
34 | }
35 |
36 | public void UpdateGUI()
37 | {
38 | ProgressBar.Value = Value;
39 | label1.Text = ProgressBar.Value.ToString() + "/" + ProgressBar.Maximum.ToString();
40 | }
41 |
42 | public ProgressBarForm()
43 | {
44 | InitializeComponent();
45 | }
46 |
47 | private void cancelButton_Click(object sender, EventArgs e)
48 | {
49 | if (BaseForm is FileContainerForm fcForm) fcForm.extractAllBackgroundWorker.CancelAsync();
50 | }
51 |
52 | private void ProgressBarForm_Load(object sender, EventArgs e)
53 | {
54 | ProgressBar.Value = Value;
55 | ProgressBar.Minimum = 0;
56 | ProgressBar.Maximum = Maximum;
57 | UAGPalette.RefreshTheme(this);
58 | this.AdjustFormPosition(BaseForm);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/UAssetGUI/GitHubAPI.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 |
4 | namespace UAssetGUI
5 | {
6 | public static class GitHubAPI
7 | {
8 | public static string CombineURI(params string[] uris)
9 | {
10 | string output = "";
11 | foreach (string uriBit in uris)
12 | {
13 | output += uriBit.Trim('/') + "/";
14 | }
15 | return output.TrimEnd('/');
16 | }
17 |
18 | public static string GetLatestVersionURL(string repo)
19 | {
20 | return CombineURI("https://github.com", repo, "releases", "latest");
21 | }
22 |
23 | public static Version GetLatestVersionFromGitHub(string repo)
24 | {
25 | try
26 | {
27 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(GetLatestVersionURL(repo));
28 | request.Method = "GET";
29 | request.AllowAutoRedirect = false;
30 | request.ContentType = "application/json; charset=utf-8";
31 | request.UserAgent = "UAssetGUI/" + UAGUtils._displayVersion;
32 |
33 | string newURL = null;
34 | using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
35 | {
36 | newURL = response.Headers["location"];
37 | }
38 |
39 | if (string.IsNullOrEmpty(newURL)) return null;
40 | string[] splitURL = newURL.Split('/');
41 |
42 | string finalVersionBit = splitURL[splitURL.Length - 1];
43 | if (finalVersionBit[0] == 'v') finalVersionBit = finalVersionBit.Substring(1);
44 | finalVersionBit = finalVersionBit.Replace(".0-alpha.", ".");
45 |
46 | Version.TryParse(finalVersionBit, out Version foundVersion);
47 | return foundVersion;
48 | }
49 | catch (Exception ex)
50 | {
51 | if (ex is WebException || ex is FormatException) return null;
52 | throw;
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | workflow_dispatch:
4 | push:
5 | branches:
6 | - master
7 | paths-ignore:
8 | - ".github/**"
9 | - ".gitignore"
10 | - "*.md"
11 |
12 | jobs:
13 | build:
14 | runs-on: windows-latest
15 | permissions:
16 | contents: write
17 |
18 | env:
19 | ACTIONS_ALLOW_UNSECURE_COMMANDS: true
20 |
21 | steps:
22 | - name: Checkout
23 | uses: actions/checkout@v2
24 | with:
25 | fetch-depth: 0
26 |
27 | - name: .NET Setup
28 | uses: actions/setup-dotnet@v2
29 | with:
30 | dotnet-version: '8.0.x'
31 |
32 | - name: Fetch submodules
33 | run: git submodule update --init --recursive
34 |
35 | - name: Setup MSBuild
36 | uses: microsoft/setup-msbuild@v1.1
37 |
38 | - name: Setup NuGet
39 | uses: NuGet/setup-nuget@v1.0.2
40 |
41 | - name: Navigate to workspace
42 | run: cd $GITHUB_WORKSPACE
43 |
44 | - name: Restore packages
45 | run: nuget restore UAssetGUI.sln
46 |
47 | - name: Build All
48 | run: msbuild UAssetGUI.sln /p:Configuration=ReleaseX
49 |
50 | - name: Build Publish Binary
51 | run: dotnet publish --sc false -c ReleaseX -r win-x64 -p:PublishSingleFile=true -o ./build ./UAssetGUI/UAssetGUI.csproj
52 |
53 | - name: Get Short SHA
54 | id: vars
55 | shell: bash
56 | run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
57 |
58 | - name: Get Project Version
59 | uses: bbonkr/get-version-action@v1
60 | id: get_version
61 | with:
62 | project: './UAssetGUI/UAssetGUI.csproj'
63 | show_log_message: true
64 |
65 | - name: Upload Build Artifact
66 | uses: actions/upload-artifact@v4.6.1
67 | with:
68 | name: v${{ steps.get_version.outputs.version }}-experimental-${{ steps.vars.outputs.sha_short }}
69 | path: ./build/*.exe
70 |
71 | - name: Make Experimental Pre-Release
72 | uses: softprops/action-gh-release@v2
73 | with:
74 | prerelease: true
75 | tag_name: experimental-latest
76 | name: v${{ steps.get_version.outputs.version }}-experimental-${{ steps.vars.outputs.sha_short }}
77 | files: ./build/*.exe
78 |
--------------------------------------------------------------------------------
/UAssetGUI/TextPrompt.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.Windows.Forms;
4 |
5 | namespace UAssetGUI
6 | {
7 |
8 | public partial class TextPrompt : Form
9 | {
10 | public string DisplayText = null;
11 | public string OutputText = null;
12 | public string PrefilledText = null;
13 |
14 | public TextPrompt()
15 | {
16 | InitializeComponent();
17 | }
18 |
19 | private void InitialPathPrompt_Load(object sender, EventArgs e)
20 | {
21 | mainLabel.Text = DisplayText;
22 | if (this.Owner is Form1 parentForm)
23 | {
24 | this.Text = parentForm.Text;
25 | }
26 | if (this.Owner is FileContainerForm parentForm2)
27 | {
28 | this.Text = parentForm2.Text;
29 | }
30 | UAGPalette.RefreshTheme(this);
31 | this.AdjustFormPosition();
32 | gamePathBox.Size = new Size(this.ClientSize.Width - 24, gamePathBox.ClientSize.Height);
33 |
34 | if (!string.IsNullOrEmpty(PrefilledText))
35 | {
36 | gamePathBox.Text = PrefilledText;
37 | }
38 | }
39 |
40 | private void RunOKButton()
41 | {
42 | if (gamePathBox.Text != null && gamePathBox.Text.Length > 0)
43 | {
44 | OutputText = gamePathBox.Text;
45 | this.DialogResult = DialogResult.OK;
46 | this.Close();
47 | }
48 | }
49 |
50 | private void okButton_Click(object sender, EventArgs e)
51 | {
52 | RunOKButton();
53 | }
54 |
55 | private void RunCancelButton()
56 | {
57 | OutputText = null;
58 | this.DialogResult = DialogResult.Cancel;
59 | this.Close();
60 | }
61 |
62 | private void cancelButton_Click(object sender, EventArgs e)
63 | {
64 | RunCancelButton();
65 | }
66 |
67 | private void TextPrompt_KeyDown(object sender, KeyEventArgs e)
68 | {
69 | if (e.KeyCode == Keys.Return)
70 | {
71 | RunOKButton();
72 | }
73 | else if (e.KeyCode == Keys.Escape)
74 | {
75 | RunCancelButton();
76 | }
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/UAssetGUI/MarkdownViewer.cs:
--------------------------------------------------------------------------------
1 | using Markdig;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Data;
6 | using System.Drawing;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using System.Windows.Forms;
11 |
12 | namespace UAssetGUI
13 | {
14 | public partial class MarkdownViewer : Form
15 | {
16 | public string MarkdownToDisplay = string.Empty;
17 |
18 | public MarkdownViewer()
19 | {
20 | InitializeComponent();
21 | }
22 |
23 | private void MarkdownViewer_Load(object sender, EventArgs e)
24 | {
25 | UAGPalette.RefreshTheme(this);
26 | this.AdjustFormPosition();
27 |
28 | var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
29 | string stylingHTML = "";
30 | string finalHTML = stylingHTML + "" + Markdown.ToHtml(MarkdownToDisplay, pipeline) + "";
31 |
32 | this.browser1.DocumentText = finalHTML;
33 |
34 | ForceResize();
35 | }
36 |
37 | private void closeButton_Click(object sender, EventArgs e)
38 | {
39 | this.Dispose();
40 | }
41 |
42 | internal void ForceResize()
43 | {
44 | this.browser1.Size = new Size(this.ClientSize.Width, this.ClientSize.Height - this.closeButton.Height - 20);
45 | this.closeButton.Location = new Point(this.ClientSize.Width - this.closeButton.Width - 10, this.ClientSize.Height - this.closeButton.Height - 10);
46 | }
47 |
48 | private void MarkdownViewer_Resize(object sender, EventArgs e)
49 | {
50 | ForceResize();
51 | }
52 |
53 | private void browser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
54 | {
55 | string scheme = e.Url?.Scheme;
56 | if (scheme == "http" || scheme == "https")
57 | {
58 | e.Cancel = true;
59 | UAGUtils.OpenURL(e.Url.ToString());
60 | }
61 | // otherwise, presumably "navigating" to raw HTML (scheme == "about")
62 | // not really worried about implementing this in a more secure way
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/UAssetGUI/MarkdownViewer.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace UAssetGUI
2 | {
3 | partial class MarkdownViewer
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | browser1 = new System.Windows.Forms.WebBrowser();
32 | closeButton = new System.Windows.Forms.Button();
33 | SuspendLayout();
34 | //
35 | // browser1
36 | //
37 | browser1.Dock = System.Windows.Forms.DockStyle.Top;
38 | browser1.Location = new System.Drawing.Point(0, 0);
39 | browser1.Name = "browser1";
40 | browser1.Size = new System.Drawing.Size(619, 408);
41 | browser1.TabIndex = 0;
42 | browser1.Navigating += browser1_Navigating;
43 | //
44 | // closeButton
45 | //
46 | closeButton.Anchor = System.Windows.Forms.AnchorStyles.None;
47 | closeButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
48 | closeButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
49 | closeButton.ForeColor = System.Drawing.SystemColors.ControlText;
50 | closeButton.Location = new System.Drawing.Point(518, 414);
51 | closeButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
52 | closeButton.Name = "closeButton";
53 | closeButton.Size = new System.Drawing.Size(88, 30);
54 | closeButton.TabIndex = 5;
55 | closeButton.Text = "Close";
56 | closeButton.UseVisualStyleBackColor = true;
57 | closeButton.Click += closeButton_Click;
58 | //
59 | // MarkdownViewer
60 | //
61 | AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
62 | AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
63 | ClientSize = new System.Drawing.Size(619, 454);
64 | Controls.Add(closeButton);
65 | Controls.Add(browser1);
66 | Font = new System.Drawing.Font("Microsoft Sans Serif", 10F);
67 | Name = "MarkdownViewer";
68 | Text = "MarkdownViewer";
69 | Load += MarkdownViewer_Load;
70 | Resize += MarkdownViewer_Resize;
71 | ResumeLayout(false);
72 | }
73 |
74 | #endregion
75 |
76 | private System.Windows.Forms.WebBrowser browser1;
77 | private System.Windows.Forms.Button closeButton;
78 | }
79 | }
--------------------------------------------------------------------------------
/UAssetGUI/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Drawing;
3 | using System.IO;
4 | using System.Runtime.InteropServices;
5 | using System.Windows.Forms;
6 | using UAssetAPI;
7 | using UAssetAPI.UnrealTypes;
8 | using UAssetAPI.Unversioned;
9 |
10 | namespace UAssetGUI
11 | {
12 | static class Program
13 | {
14 | [DllImport("user32.dll")]
15 | private static extern bool SetProcessDPIAware();
16 |
17 | ///
18 | /// The main entry point for the application.
19 | ///
20 | [STAThread]
21 | static void Main()
22 | {
23 | if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
24 | Application.EnableVisualStyles();
25 | Application.SetCompatibleTextRenderingDefault(false);
26 | Application.SetDefaultFont(new Font(new FontFamily("Microsoft Sans Serif"), 8.25f)); // default font changed in .NET Core 3.0
27 |
28 | string[] args = Environment.GetCommandLineArgs();
29 | if (args.Length >= 2)
30 | {
31 | Usmap selectedMappings = null;
32 |
33 | switch (args[1].ToLowerInvariant())
34 | {
35 | // tojson [mappings name]
36 | // UAssetGUI tojson A.umap B.json 23 Outriders
37 | case "tojson":
38 | UAGConfig.LoadMappings();
39 |
40 | if (args.Length < 5) break;
41 | if (args.Length >= 6) UAGConfig.TryGetMappings(args[5], out selectedMappings);
42 |
43 | EngineVersion selectedVer = EngineVersion.UNKNOWN;
44 | if (int.TryParse(args[4], out int selectedVerRaw)) selectedVer = EngineVersion.VER_UE4_0 + selectedVerRaw;
45 | else Enum.TryParse(args[4], out selectedVer);
46 |
47 | string jsonSerializedAsset = new UAsset(args[2], selectedVer, selectedMappings).SerializeJson(Newtonsoft.Json.Formatting.Indented);
48 | File.WriteAllText(args[3], jsonSerializedAsset);
49 | return;
50 | // fromjson [mappings name]
51 | // UAssetGUI fromjson B.json A.umap Outriders
52 | case "fromjson":
53 | UAGConfig.LoadMappings();
54 |
55 | if (args.Length < 4) break;
56 | if (args.Length >= 5) UAGConfig.TryGetMappings(args[4], out selectedMappings);
57 |
58 | UAsset jsonDeserializedAsset = null;
59 | using (var sr = new FileStream(args[2], FileMode.Open))
60 | {
61 | jsonDeserializedAsset = UAsset.DeserializeJson(sr);
62 | }
63 |
64 | if (jsonDeserializedAsset != null)
65 | {
66 | jsonDeserializedAsset.Mappings = selectedMappings;
67 | jsonDeserializedAsset.Write(args[3]);
68 | }
69 | return;
70 | }
71 | }
72 |
73 | Form1 f1 = new Form1
74 | {
75 | Size = new System.Drawing.Size(1000, 700)
76 | };
77 | Application.Run(f1);
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/UAssetGUI/AboutForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Windows.Forms;
5 |
6 | namespace UAssetGUI
7 | {
8 | public partial class AboutForm : Form
9 | {
10 | public string AboutText
11 | {
12 | get
13 | {
14 | return label1.Text;
15 | }
16 | set
17 | {
18 | label1.Text = value;
19 | }
20 | }
21 |
22 | public AboutForm()
23 | {
24 | InitializeComponent();
25 | }
26 |
27 | private Form1 BaseForm;
28 | private void AboutForm_Load(object sender, EventArgs e)
29 | {
30 | if (this.Owner is Form1) BaseForm = (Form1)this.Owner;
31 |
32 | UAGPalette.RefreshTheme(this);
33 | this.AdjustFormPosition();
34 | }
35 |
36 | private void closeButton_Click(object sender, EventArgs e)
37 | {
38 | this.Dispose();
39 | }
40 |
41 | private void licenseButton_Click(object sender, EventArgs e)
42 | {
43 | UAGUtils.InvokeUI(() =>
44 | {
45 | string rawMarkdownText = string.Empty;
46 | using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("UAssetGUI.LICENSE"))
47 | {
48 | if (stream != null)
49 | {
50 | using (StreamReader reader = new StreamReader(stream))
51 | {
52 | if (reader != null) rawMarkdownText = reader.ReadToEnd().Trim();
53 | }
54 | }
55 | }
56 |
57 | if (string.IsNullOrEmpty(rawMarkdownText))
58 | {
59 | UAGUtils.OpenURL("https://github.com/" + Form1.GitHubRepo + "/blob/master/LICENSE");
60 | return;
61 | }
62 |
63 | var formPopup = new MarkdownViewer();
64 | formPopup.MarkdownToDisplay = "```\n" + rawMarkdownText + "\n```";
65 | formPopup.Text = "License";
66 | formPopup.StartPosition = FormStartPosition.CenterParent;
67 | formPopup.ShowDialog(this);
68 | });
69 | }
70 |
71 | private void noticeButton_Click(object sender, EventArgs e)
72 | {
73 | UAGUtils.InvokeUI(() =>
74 | {
75 | string rawMarkdownText = string.Empty;
76 | using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("UAssetGUI.NOTICE.md"))
77 | {
78 | if (stream != null)
79 | {
80 | using (StreamReader reader = new StreamReader(stream))
81 | {
82 | if (reader != null) rawMarkdownText = reader.ReadToEnd().Trim();
83 | }
84 | }
85 | }
86 |
87 | if (string.IsNullOrEmpty(rawMarkdownText))
88 | {
89 | UAGUtils.OpenURL("https://github.com/" + Form1.GitHubRepo + "/blob/master/NOTICE.md");
90 | return;
91 | }
92 |
93 | var formPopup = new MarkdownViewer();
94 | formPopup.MarkdownToDisplay = rawMarkdownText;
95 | formPopup.Text = "List of 3rd-party software";
96 | formPopup.StartPosition = FormStartPosition.CenterParent;
97 | formPopup.ShowDialog(this);
98 | });
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/UAssetGUI/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace UAssetGUI.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UAssetGUI.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized resource of type System.Byte[].
65 | ///
66 | internal static byte[] dancing_cat {
67 | get {
68 | object obj = ResourceManager.GetObject("dancing_cat", resourceCulture);
69 | return ((byte[])(obj));
70 | }
71 | }
72 |
73 | ///
74 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon).
75 | ///
76 | internal static System.Drawing.Icon icon {
77 | get {
78 | object obj = ResourceManager.GetObject("icon", resourceCulture);
79 | return ((System.Drawing.Icon)(obj));
80 | }
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/UAssetGUI/ProgressBarForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace UAssetGUI
2 | {
3 | partial class ProgressBarForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | ProgressBar = new System.Windows.Forms.ProgressBar();
32 | cancelButton = new System.Windows.Forms.Button();
33 | label1 = new System.Windows.Forms.Label();
34 | SuspendLayout();
35 | //
36 | // ProgressBar
37 | //
38 | ProgressBar.Location = new System.Drawing.Point(18, 17);
39 | ProgressBar.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
40 | ProgressBar.Name = "ProgressBar";
41 | ProgressBar.Size = new System.Drawing.Size(201, 51);
42 | ProgressBar.TabIndex = 14;
43 | //
44 | // cancelButton
45 | //
46 | cancelButton.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
47 | cancelButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
48 | cancelButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
49 | cancelButton.ForeColor = System.Drawing.SystemColors.ControlText;
50 | cancelButton.Location = new System.Drawing.Point(134, 79);
51 | cancelButton.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
52 | cancelButton.Name = "cancelButton";
53 | cancelButton.Size = new System.Drawing.Size(90, 31);
54 | cancelButton.TabIndex = 15;
55 | cancelButton.Text = "Cancel...";
56 | cancelButton.UseVisualStyleBackColor = true;
57 | cancelButton.Click += cancelButton_Click;
58 | //
59 | // label1
60 | //
61 | label1.Location = new System.Drawing.Point(16, 79);
62 | label1.Name = "label1";
63 | label1.Size = new System.Drawing.Size(95, 30);
64 | label1.TabIndex = 16;
65 | label1.Text = "label1";
66 | label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
67 | //
68 | // ProgressBarForm
69 | //
70 | AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
71 | AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
72 | ClientSize = new System.Drawing.Size(237, 122);
73 | Controls.Add(label1);
74 | Controls.Add(cancelButton);
75 | Controls.Add(ProgressBar);
76 | FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
77 | MaximizeBox = false;
78 | MinimizeBox = false;
79 | Name = "ProgressBarForm";
80 | Text = "ProgressBarForm";
81 | Load += ProgressBarForm_Load;
82 | ResumeLayout(false);
83 | }
84 |
85 | #endregion
86 |
87 | public System.Windows.Forms.ProgressBar ProgressBar;
88 | private System.Windows.Forms.Button cancelButton;
89 | private System.Windows.Forms.Label label1;
90 | }
91 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # UAssetGUI
2 | [](https://github.com/atenfyr/UAssetGUI/releases/latest)
3 | [](https://github.com/atenfyr/UAssetGUI/releases)
4 | [](https://github.com/atenfyr/UAssetGUI/issues)
5 | [](https://github.com/atenfyr/UAssetGUI/actions)
6 | [](https://github.com/atenfyr/UAssetGUI/blob/master/LICENSE.md)
7 |
8 | UAssetGUI is a tool designed for low-level examination and modification of Unreal Engine game assets by hand.
9 |
10 |
11 |
12 | ## Installation
13 | You can find pre-built binaries of UAssetGUI in the [Releases tab of this repository](https://github.com/atenfyr/UAssetGUI/releases).
14 |
15 | ## Command line arguments
16 | You can run the program with command line arguments to perform various tasks, such as exporting and importing from UAssetAPI JSON without opening the GUI.
17 |
18 | In the following cases, the engine version can either be specified as an EngineVersion enum entry (e.g. `VER_UE4_23` to refer to 4.23, `VER_UE5_0` to refer to 5.0, etc.) or as an integer (e.g. `23` to refer to 4.23, `29` to refer to 5.0, etc.). Specifying a set of mappings is optional, but if specified, must be the name of a file within the Mappings config directory (with no extension).
19 |
20 | ### Export to JSON
21 | ```
22 | UAssetGUI tojson [mappings name]
23 | ```
24 |
25 | Example 1: `UAssetGUI tojson A.uasset B.json VER_UE5_1`
26 |
27 | Example 2: `UAssetGUI tojson A.uasset B.json 27 Astro`
28 |
29 | ### Import from JSON
30 | ```
31 | UAssetGUI fromjson [mappings name]
32 | ```
33 |
34 | Example 1: `UAssetGUI fromjson B.json A.umap`
35 |
36 | Example 2: `UAssetGUI fromjson B.json A.umap Outriders`
37 |
38 | ### Open a specific file in the GUI
39 | ```
40 | UAssetGUI [file name] [engine version] [mappings name]
41 | ```
42 |
43 | Example 1: `UAssetGUI` (to simply open the GUI without opening a file)
44 |
45 | Example 2: `UAssetGUI test.uasset`
46 |
47 | Example 3: `UAssetGUI test.uasset 23`
48 |
49 | Example 4: `UAssetGUI test.uasset VER_UE5_4 Bellwright`
50 |
51 | ## Compilation
52 | If you'd like to compile UAssetGUI for yourself, read on:
53 |
54 | ### Prerequisites
55 | * Visual Studio 2022 or later
56 | * Git
57 |
58 | ### Initial Setup
59 | 1. Clone the UAssetGUI repository:
60 |
61 | ```sh
62 | git clone https://github.com/atenfyr/UAssetGUI.git
63 | ```
64 |
65 | 2. Switch to the new UAssetGUI directory:
66 |
67 | ```sh
68 | cd UAssetGUI
69 | ```
70 |
71 | 3. Pull the required submodules:
72 |
73 | ```sh
74 | git submodule update --init
75 | ```
76 |
77 | 4. Open the `UAssetGUI.sln` solution file in Visual Studio, right-click on the UAssetGUI project in the Solution Explorer, and click "Set as Startup Project."
78 |
79 | 5. Right-click on the solution name in the Solution Explorer, and press "Restore Nuget Packages."
80 |
81 | 6. Press the "Start" button or press F5 to compile and open UAssetGUI.
82 |
83 | ## Contributing
84 | Any contributions, whether through pull requests or issues, that you make are greatly appreciated.
85 |
86 | If you have an Unreal Engine .uasset file that displays "failed to maintain binary equality," feel free to submit an issue on [the UAssetAPI issues page](https://github.com/atenfyr/UAssetAPI/issues) with a copy of the asset in question along with the name of the game, the Unreal version that it was cooked with, and a mappings file for the game, if needed.
87 |
88 | ## License
89 | UAssetAPI and UAssetGUI are distributed under the MIT license, which you can view in detail in the [LICENSE file](LICENSE).
90 |
--------------------------------------------------------------------------------
/UAssetGUI/TextPrompt.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/UAssetGUI/AboutForm.Designer.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace UAssetGUI
3 | {
4 | partial class AboutForm
5 | {
6 | ///
7 | /// Required designer variable.
8 | ///
9 | private System.ComponentModel.IContainer components = null;
10 |
11 | ///
12 | /// Clean up any resources being used.
13 | ///
14 | /// true if managed resources should be disposed; otherwise, false.
15 | protected override void Dispose(bool disposing)
16 | {
17 | if (disposing && (components != null))
18 | {
19 | components.Dispose();
20 | }
21 | base.Dispose(disposing);
22 | }
23 |
24 | #region Windows Form Designer generated code
25 |
26 | ///
27 | /// Required method for Designer support - do not modify
28 | /// the contents of this method with the code editor.
29 | ///
30 | private void InitializeComponent()
31 | {
32 | this.closeButton = new System.Windows.Forms.Button();
33 | this.licenseButton = new System.Windows.Forms.Button();
34 | this.label1 = new System.Windows.Forms.Label();
35 | this.noticeButton = new System.Windows.Forms.Button();
36 | this.SuspendLayout();
37 | //
38 | // closeButton
39 | //
40 | this.closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
41 | this.closeButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
42 | this.closeButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
43 | this.closeButton.ForeColor = System.Drawing.SystemColors.ControlText;
44 | this.closeButton.Location = new System.Drawing.Point(320, 274);
45 | this.closeButton.Name = "closeButton";
46 | this.closeButton.Size = new System.Drawing.Size(75, 26);
47 | this.closeButton.TabIndex = 4;
48 | this.closeButton.Text = "Close";
49 | this.closeButton.UseVisualStyleBackColor = true;
50 | this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
51 | //
52 | // licenseButton
53 | //
54 | this.licenseButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
55 | this.licenseButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
56 | this.licenseButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
57 | this.licenseButton.ForeColor = System.Drawing.SystemColors.ControlText;
58 | this.licenseButton.Location = new System.Drawing.Point(12, 274);
59 | this.licenseButton.Name = "licenseButton";
60 | this.licenseButton.Size = new System.Drawing.Size(103, 26);
61 | this.licenseButton.TabIndex = 2;
62 | this.licenseButton.Text = "View license...";
63 | this.licenseButton.UseVisualStyleBackColor = true;
64 | this.licenseButton.Click += new System.EventHandler(this.licenseButton_Click);
65 | //
66 | // label1
67 | //
68 | this.label1.Dock = System.Windows.Forms.DockStyle.Top;
69 | this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F);
70 | this.label1.Location = new System.Drawing.Point(0, 0);
71 | this.label1.Name = "label1";
72 | this.label1.Size = new System.Drawing.Size(407, 271);
73 | this.label1.TabIndex = 1;
74 | this.label1.Text = "AboutText should be overridden before displaying this form";
75 | this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
76 | //
77 | // noticeButton
78 | //
79 | this.noticeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
80 | this.noticeButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
81 | this.noticeButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
82 | this.noticeButton.ForeColor = System.Drawing.SystemColors.ControlText;
83 | this.noticeButton.Location = new System.Drawing.Point(121, 274);
84 | this.noticeButton.Name = "noticeButton";
85 | this.noticeButton.Size = new System.Drawing.Size(161, 26);
86 | this.noticeButton.TabIndex = 3;
87 | this.noticeButton.Text = "View 3rd-party software...";
88 | this.noticeButton.UseVisualStyleBackColor = true;
89 | this.noticeButton.Click += new System.EventHandler(this.noticeButton_Click);
90 | //
91 | // AboutForm
92 | //
93 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
94 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
95 | this.ClientSize = new System.Drawing.Size(407, 312);
96 | this.Controls.Add(this.noticeButton);
97 | this.Controls.Add(this.label1);
98 | this.Controls.Add(this.licenseButton);
99 | this.Controls.Add(this.closeButton);
100 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
101 | this.Name = "AboutForm";
102 | this.Text = "About";
103 | this.Load += new System.EventHandler(this.AboutForm_Load);
104 | this.ResumeLayout(false);
105 |
106 | }
107 |
108 | #endregion
109 |
110 | private System.Windows.Forms.Button closeButton;
111 | private System.Windows.Forms.Button licenseButton;
112 | private System.Windows.Forms.Label label1;
113 | private System.Windows.Forms.Button noticeButton;
114 | }
115 | }
--------------------------------------------------------------------------------
/UAssetGUI/SettingsForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/UAssetGUI/MarkdownViewer.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/UAssetGUI/ProgressBarForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/UAssetGUI/FindForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/UAssetGUI/AboutForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/UAssetGUI/MapStructTypeOverrideForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/UAssetGUI/Form1.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 166, 17
122 |
123 |
124 | 17, 17
125 |
126 |
--------------------------------------------------------------------------------
/UAssetGUI/FileContainerForm.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 17, 17
122 |
123 |
124 | 132, 17
125 |
126 |
--------------------------------------------------------------------------------
/UAssetGUI/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 |
122 | ..\Resources\dancing_cat.gif;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
123 |
124 |
125 | ..\Resources\icon.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
126 |
127 |
--------------------------------------------------------------------------------
/UAssetGUI/TextPrompt.Designer.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms;
2 |
3 | namespace UAssetGUI
4 | {
5 | partial class TextPrompt
6 | {
7 | ///
8 | /// Required designer variable.
9 | ///
10 | private System.ComponentModel.IContainer components = null;
11 |
12 | ///
13 | /// Clean up any resources being used.
14 | ///
15 | /// true if managed resources should be disposed; otherwise, false.
16 | protected override void Dispose(bool disposing)
17 | {
18 | if (disposing && (components != null))
19 | {
20 | components.Dispose();
21 | }
22 | base.Dispose(disposing);
23 | }
24 |
25 | #region Windows Form Designer generated code
26 |
27 | ///
28 | /// Required method for Designer support - do not modify
29 | /// the contents of this method with the code editor.
30 | ///
31 | private void InitializeComponent()
32 | {
33 | this.mainLabel = new System.Windows.Forms.Label();
34 | this.gamePathBox = new System.Windows.Forms.TextBox();
35 | this.cancelButton = new System.Windows.Forms.Button();
36 | this.okButton = new System.Windows.Forms.Button();
37 | this.SuspendLayout();
38 | //
39 | // mainLabel
40 | //
41 | this.mainLabel.Anchor = System.Windows.Forms.AnchorStyles.Top;
42 | this.mainLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F);
43 | this.mainLabel.Location = new System.Drawing.Point(12, 13);
44 | this.mainLabel.Name = "mainLabel";
45 | this.mainLabel.Size = new System.Drawing.Size(361, 20);
46 | this.mainLabel.TabIndex = 4;
47 | this.mainLabel.Text = "Select your game installation directory:";
48 | this.mainLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
49 | //
50 | // gamePathBox
51 | //
52 | this.gamePathBox.Anchor = System.Windows.Forms.AnchorStyles.Left;
53 | this.gamePathBox.Location = new System.Drawing.Point(12, 47);
54 | this.gamePathBox.Name = "gamePathBox";
55 | this.gamePathBox.Size = new System.Drawing.Size(361, 20);
56 | this.gamePathBox.TabIndex = 0;
57 | this.gamePathBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextPrompt_KeyDown);
58 | //
59 | // cancelButton
60 | //
61 | this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
62 | this.cancelButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(51)))), ((int)(((byte)(51)))));
63 | this.cancelButton.FlatAppearance.BorderColor = System.Drawing.Color.Black;
64 | this.cancelButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
65 | this.cancelButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
66 | this.cancelButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(225)))), ((int)(((byte)(225)))), ((int)(((byte)(225)))));
67 | this.cancelButton.Location = new System.Drawing.Point(70, 79);
68 | this.cancelButton.MinimumSize = new System.Drawing.Size(0, 26);
69 | this.cancelButton.Name = "cancelButton";
70 | this.cancelButton.Size = new System.Drawing.Size(67, 26);
71 | this.cancelButton.TabIndex = 3;
72 | this.cancelButton.Text = "Cancel";
73 | this.cancelButton.UseVisualStyleBackColor = false;
74 | this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
75 | //
76 | // okButton
77 | //
78 | this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
79 | this.okButton.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(51)))), ((int)(((byte)(51)))), ((int)(((byte)(51)))));
80 | this.okButton.FlatAppearance.BorderColor = System.Drawing.Color.Black;
81 | this.okButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
82 | this.okButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
83 | this.okButton.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(225)))), ((int)(((byte)(225)))), ((int)(((byte)(225)))));
84 | this.okButton.Location = new System.Drawing.Point(15, 79);
85 | this.okButton.MinimumSize = new System.Drawing.Size(0, 26);
86 | this.okButton.Name = "okButton";
87 | this.okButton.Size = new System.Drawing.Size(49, 26);
88 | this.okButton.TabIndex = 2;
89 | this.okButton.Text = "OK";
90 | this.okButton.UseVisualStyleBackColor = false;
91 | this.okButton.Click += new System.EventHandler(this.okButton_Click);
92 | //
93 | // TextPrompt
94 | //
95 | this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
96 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
97 | this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(42)))), ((int)(((byte)(45)))));
98 | this.ClientSize = new System.Drawing.Size(385, 114);
99 | this.Controls.Add(this.cancelButton);
100 | this.Controls.Add(this.okButton);
101 | this.Controls.Add(this.gamePathBox);
102 | this.Controls.Add(this.mainLabel);
103 | this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(225)))), ((int)(((byte)(225)))), ((int)(((byte)(225)))));
104 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
105 | this.MaximizeBox = false;
106 | this.Name = "TextPrompt";
107 | this.Text = "InitialPathPrompt";
108 | this.Load += new System.EventHandler(this.InitialPathPrompt_Load);
109 | this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextPrompt_KeyDown);
110 | this.ResumeLayout(false);
111 | this.PerformLayout();
112 |
113 | }
114 |
115 | #endregion
116 |
117 | private System.Windows.Forms.Label mainLabel;
118 | private System.Windows.Forms.TextBox gamePathBox;
119 | private Button okButton;
120 | private Button cancelButton;
121 | }
122 | }
--------------------------------------------------------------------------------
/UAssetGUI/UAssetGUI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {88A998F1-C512-416F-ADED-120E50AFE6F3}
4 | WinExe
5 | net8.0-windows
6 | true
7 | false
8 | true
9 | UAssetGUI
10 | UAssetGUI
11 | Copyright © Atenfyr 2024
12 | 1.0.4.0
13 | 1.0.4.0
14 | bin\$(Configuration)\
15 | Debug;Release;DebugVerbose;DebugTracing;ReleaseX
16 | true
17 | false
18 | AnyCPU;x86
19 |
20 |
21 | full
22 |
23 |
24 | full
25 |
26 |
27 | full
28 |
29 |
30 | full
31 |
32 |
33 | full
34 |
35 |
36 | full
37 |
38 |
39 | embedded
40 |
41 |
42 | embedded
43 | True
44 |
45 |
46 | embedded
47 |
48 |
49 | embedded
50 | True
51 |
52 |
53 | Resources\icon.ico
54 | true
55 | 1.0.4
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | Component
73 |
74 |
75 | Form
76 |
77 |
78 | FindForm.cs
79 |
80 |
81 | Form
82 |
83 |
84 | AboutForm.cs
85 |
86 |
87 | Form
88 |
89 |
90 | Form1.cs
91 |
92 |
93 | Form
94 |
95 |
96 | MapStructTypeOverrideForm.cs
97 |
98 |
99 | Form
100 |
101 |
102 | SettingsForm.cs
103 |
104 |
105 | Form
106 |
107 |
108 | TextPrompt.cs
109 |
110 |
111 | FindForm.cs
112 |
113 |
114 | AboutForm.cs
115 |
116 |
117 | Form1.cs
118 | Designer
119 |
120 |
121 | MapStructTypeOverrideForm.cs
122 |
123 |
124 | ResXFileCodeGenerator
125 | Resources.Designer.cs
126 | Designer
127 |
128 |
129 | True
130 | Resources.resx
131 | True
132 |
133 |
134 | SettingsForm.cs
135 |
136 |
137 | TextPrompt.cs
138 |
139 |
140 |
141 |
142 |
143 | Never
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | all
155 |
156 |
157 |
158 | all
159 |
160 |
161 |
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/UAssetGUI/UAGUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.ComponentModel;
4 | using System.Diagnostics;
5 | using System.Drawing;
6 | using System.Reflection;
7 | using System.Text;
8 | using System.Windows.Forms;
9 | using UAssetAPI;
10 | using UAssetAPI.UnrealTypes;
11 |
12 | namespace UAssetGUI
13 | {
14 | public static class UAGUtils
15 | {
16 | internal static string _displayVersion = string.Empty;
17 |
18 | public static T TryGetElement(this T[] array, int index)
19 | {
20 | if (array != null && index < array.Length)
21 | {
22 | return array[index];
23 | }
24 | return default(T);
25 | }
26 |
27 | public static object ArbitraryTryParse(this string input, Type type)
28 | {
29 | try
30 | {
31 | var converter = TypeDescriptor.GetConverter(type);
32 | if (converter != null)
33 | {
34 | return converter.ConvertFromString(input);
35 | }
36 | }
37 | catch (NotSupportedException) { }
38 | return null;
39 | }
40 |
41 | public static ContextMenuStrip MergeContextMenus(ContextMenuStrip one, ContextMenuStrip two)
42 | {
43 | if (one == null) return two;
44 | if (two == null) return one;
45 |
46 | one.Items.AddRange(two.Items);
47 | return one;
48 | }
49 |
50 | // ((Form1)x.DataGridView.Parent).nameMapContext;
51 | public static void UpdateContextMenuStripOfRow(DataGridViewRow x, ContextMenuStrip strip)
52 | {
53 | x.ContextMenuStrip = MergeContextMenus(x.ContextMenuStrip, strip);
54 | x.HeaderCell.ContextMenuStrip = MergeContextMenus(x.HeaderCell.ContextMenuStrip, strip);
55 | foreach (DataGridViewCell y in x.Cells)
56 | {
57 | y.ContextMenuStrip = MergeContextMenus(y.ContextMenuStrip, strip);
58 | }
59 | }
60 |
61 | public static void AdjustFormPosition(this Form frm1, Form overrideOwner = null)
62 | {
63 | if (overrideOwner == null) overrideOwner = frm1.Owner;
64 | if (overrideOwner != null) frm1.Location = new Point((overrideOwner.Location.X + overrideOwner.Width / 2) - (frm1.Width / 2), (overrideOwner.Location.Y + overrideOwner.Height / 2) - (frm1.Height / 2));
65 | }
66 |
67 | public static void UpdateObjectPropertyValues(UAsset asset, DataGridViewRow row, DataGridView dgv, FPackageIndex objData, int column = 3)
68 | {
69 | if (dgv == null || row == null || objData == null) return;
70 |
71 | bool underlineStyle = false;
72 | if (objData.IsImport() && objData == null)
73 | {
74 | row.Cells[column].Value = string.Empty;
75 | }
76 | else
77 | {
78 | row.Cells[column].Value = objData.IsExport() ? "Jump" : (objData.IsImport() ? objData.ToImport(asset)?.ObjectName?.ToString() : string.Empty);
79 | row.Cells[column].Tag = "CategoryJump";
80 | if (objData.IsExport()) underlineStyle = true;
81 | }
82 | row.Cells[column].ReadOnly = objData.IsImport();
83 |
84 | DataGridViewCellStyle sty = new DataGridViewCellStyle();
85 | if (underlineStyle)
86 | {
87 | Font styFont = new Font(dgv.Font.Name, UAGPalette.RecommendedFontSize, FontStyle.Underline);
88 | sty.Font = styFont;
89 | sty.ForeColor = UAGPalette.LinkColor;
90 | }
91 | row.Cells[column].Style = sty;
92 | }
93 |
94 | public static T[] StripNullsFromArray(this T[] usArr)
95 | {
96 | int c = 0;
97 | for (int num = 0; num < usArr.Length; num++)
98 | {
99 | if (usArr[num] != null) c++;
100 | }
101 |
102 | var newData = new T[c];
103 | int indexAdded = 0;
104 | for (int num = 0; num < usArr.Length; num++)
105 | {
106 | if (usArr[num] != null) newData[indexAdded++] = usArr[num];
107 | }
108 | return newData;
109 | }
110 |
111 | public static List StripNullsFromList(this List usList)
112 | {
113 | for (int num = 0; num < usList.Count; num++)
114 | {
115 | if (usList[num] == null)
116 | {
117 | usList.RemoveAt(num);
118 | num--;
119 | }
120 | }
121 | return usList;
122 | }
123 |
124 | public static string ConvertByteArrayToString(this byte[] val)
125 | {
126 | if (val == null) return "";
127 | return BitConverter.ToString(val).Replace("-", " ");
128 | }
129 |
130 | public static byte[] ConvertStringToByteArray(this string val)
131 | {
132 | if (string.IsNullOrWhiteSpace(val)) return Array.Empty();
133 | string[] rawStringArr = val.Split(' ');
134 | byte[] byteArr = new byte[rawStringArr.Length];
135 | for (int i = 0; i < rawStringArr.Length; i++) byteArr[i] = Convert.ToByte(rawStringArr[i], 16);
136 | return byteArr;
137 | }
138 |
139 | public static string ShortcutToText(Keys shortcutKeys)
140 | {
141 | return TypeDescriptor.GetConverter(typeof(Keys)).ConvertToString(shortcutKeys);
142 | }
143 |
144 | /*
145 | UAssetGUI versions are formatted as follows: MAJOR.MINOR.BUILD
146 | * MAJOR - incremented for very big changes or backwards-incompatible changes
147 | * MINOR - incremented for notable changes
148 | * BUILD - incremented for bug fixes or very small improvements
149 | */
150 | public static bool IsUAGVersionLower(this Version v1)
151 | {
152 | Version fullUagVersion = new Version(Assembly.GetExecutingAssembly().GetCustomAttribute().InformationalVersion);
153 | return v1.CompareTo(fullUagVersion) > 0;
154 | }
155 |
156 | public static string FEncode(this FString val)
157 | {
158 | if (val == null) return FString.NullCase;
159 | return val.Value.Replace("\n", "\\n").Replace("\r", "\\r");
160 | }
161 |
162 | public static FString FDecode(this string val, string encodingHeaderName)
163 | {
164 | if (val == FString.NullCase) return null;
165 | return FString.FromString(val.Replace("\\n", "\n").Replace("\\r", "\r"), encodingHeaderName.Equals(Encoding.Unicode.HeaderName) ? Encoding.Unicode : Encoding.ASCII);
166 | }
167 |
168 | public static void OpenURL(string url)
169 | {
170 | Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
171 | }
172 |
173 | public static void OpenDirectory(string dir)
174 | {
175 | Process.Start(new ProcessStartInfo()
176 | {
177 | FileName = dir,
178 | UseShellExecute = true,
179 | Verb = "open"
180 | });
181 | }
182 |
183 | private static Control internalForm;
184 | public static void InitializeInvoke(Control control)
185 | {
186 | internalForm = control;
187 | }
188 |
189 | public static bool InvokeUI(Action act)
190 | {
191 | if (internalForm == null) return false;
192 | if (internalForm.InvokeRequired)
193 | {
194 | internalForm.Invoke(act);
195 | }
196 | else
197 | {
198 | act();
199 | }
200 | return true;
201 | }
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/UAssetGUI/FodyWeavers.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
13 |
14 |
15 |
16 |
17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
18 |
19 |
20 |
21 |
22 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
23 |
24 |
25 |
26 |
27 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
28 |
29 |
30 |
31 |
32 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
33 |
34 |
35 |
36 |
37 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
38 |
39 |
40 |
41 |
42 | The order of preloaded assemblies, delimited with line breaks.
43 |
44 |
45 |
46 |
47 |
48 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
49 |
50 |
51 |
52 |
53 | Controls if .pdbs for reference assemblies are also embedded.
54 |
55 |
56 |
57 |
58 | Controls if runtime assemblies are also embedded.
59 |
60 |
61 |
62 |
63 | Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.
64 |
65 |
66 |
67 |
68 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
69 |
70 |
71 |
72 |
73 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
74 |
75 |
76 |
77 |
78 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.
79 |
80 |
81 |
82 |
83 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
84 |
85 |
86 |
87 |
88 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
89 |
90 |
91 |
92 |
93 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
94 |
95 |
96 |
97 |
98 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
99 |
100 |
101 |
102 |
103 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.
104 |
105 |
106 |
107 |
108 | A list of unmanaged 32 bit assembly names to include, delimited with |.
109 |
110 |
111 |
112 |
113 | A list of unmanaged 64 bit assembly names to include, delimited with |.
114 |
115 |
116 |
117 |
118 | The order of preloaded assemblies, delimited with |.
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
127 |
128 |
129 |
130 |
131 | A comma-separated list of error codes that can be safely ignored in assembly verification.
132 |
133 |
134 |
135 |
136 | 'false' to turn off automatic generation of the XML Schema file.
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/UAssetGUI/MapStructTypeOverrideForm.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Reflection;
6 | using System.Text;
7 | using System.Windows.Forms;
8 | using UAssetAPI;
9 | using UAssetAPI.UnrealTypes;
10 |
11 | namespace UAssetGUI
12 | {
13 | public partial class MapStructTypeOverrideForm : Form
14 | {
15 | public static Dictionary> MapStructTypeOverride = null;
16 |
17 | public MapStructTypeOverrideForm()
18 | {
19 | InitializeComponent();
20 |
21 | infoLabel.Text = "This table maps MapProperty names to the type of the structs within them. You can use header dumps to determine these values if necessary.";
22 |
23 | if (!SystemInformation.TerminalServerSession)
24 | {
25 | Type ourGridType = mstoDataGridView.GetType();
26 | PropertyInfo pi = ourGridType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
27 | pi.SetValue(mstoDataGridView, true, null);
28 | }
29 | }
30 |
31 | private static void CheckIfMapStructTypeOverrideIsNull()
32 | {
33 | if (MapStructTypeOverride == null) MapStructTypeOverride = new UAsset().MapStructTypeOverride;
34 | }
35 |
36 | private void MapStructTypeOverrideForm_Resize(object sender, EventArgs e)
37 | {
38 | ForceResize();
39 | }
40 |
41 | public void ForceResize()
42 | {
43 | mstoDataGridView.Height = closeButton.Location.Y - infoLabel.Location.Y - infoLabel.Height - 9;
44 | }
45 |
46 | private void AddColumns(string[] ourColumns)
47 | {
48 | for (int i = 0; i < ourColumns.Length; i++)
49 | {
50 | DataGridViewColumn dgc = new DataGridViewTextBoxColumn
51 | {
52 | HeaderText = ourColumns[i]
53 | };
54 |
55 | dgc.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
56 | if (i >= (ourColumns.Length - 1))
57 | {
58 | dgc.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
59 | }
60 |
61 | dgc.SortMode = DataGridViewColumnSortMode.NotSortable;
62 | mstoDataGridView.Columns.Add(dgc);
63 | }
64 | }
65 |
66 | private void MapStructTypeOverrideForm_Load(object sender, EventArgs e)
67 | {
68 | CheckIfMapStructTypeOverrideIsNull();
69 |
70 | UAGPalette.RefreshTheme(this);
71 | ForceResize();
72 | this.AdjustFormPosition();
73 |
74 | LoadOntoDGV();
75 | }
76 |
77 | private void SaveFromDGV()
78 | {
79 | CheckIfMapStructTypeOverrideIsNull();
80 |
81 | MapStructTypeOverride.Clear();
82 | foreach (DataGridViewRow row in mstoDataGridView.Rows)
83 | {
84 | string mapName = row.Cells[0].Value as string;
85 | string keyName = row.Cells[1].Value as string;
86 | string valueName = row.Cells[2].Value as string;
87 | if (mapName == null || keyName == null || valueName == null) continue;
88 | MapStructTypeOverride.Add(mapName, new Tuple(FString.FromString(keyName), FString.FromString(valueName)));
89 | }
90 | SaveToConfig();
91 | }
92 |
93 | private void LoadOntoDGV()
94 | {
95 | CheckIfMapStructTypeOverrideIsNull();
96 |
97 | mstoDataGridView.Visible = true;
98 | mstoDataGridView.Columns.Clear();
99 | mstoDataGridView.Rows.Clear();
100 | mstoDataGridView.AllowUserToAddRows = true;
101 | mstoDataGridView.ReadOnly = false;
102 | mstoDataGridView.BackgroundColor = UAGPalette.DataGridViewActiveColor;
103 | AddColumns(new string[] { "Map Name", "Key Struct Type Name", "Value Struct Type Name" });
104 |
105 | foreach (KeyValuePair> entry in MapStructTypeOverride)
106 | {
107 | mstoDataGridView.Rows.Add(new object[] { entry.Key.ToString(), entry.Value.Item1?.ToString() ?? FString.NullCase, entry.Value.Item2?.ToString() ?? FString.NullCase });
108 | }
109 | }
110 |
111 | internal static void SaveToConfig()
112 | {
113 | CheckIfMapStructTypeOverrideIsNull();
114 |
115 | UAGConfig.Data.MapStructTypeOverride = ExportData(Formatting.None);
116 | UAGConfig.Save();
117 | }
118 |
119 | internal static void LoadFromConfig()
120 | {
121 | CheckIfMapStructTypeOverrideIsNull();
122 |
123 | ImportData(UAGConfig.Data.MapStructTypeOverride);
124 | }
125 |
126 | private static void ImportData(string data)
127 | {
128 | if (data == null) return;
129 | CheckIfMapStructTypeOverrideIsNull();
130 |
131 | Dictionary temp = JsonConvert.DeserializeObject>(data);
132 | if (temp == null || temp.Count == 0) return;
133 |
134 | MapStructTypeOverride.Clear();
135 | foreach (KeyValuePair entry in temp)
136 | {
137 | MapStructTypeOverride.Add(entry.Key, new Tuple(FString.FromString(entry.Value[0]), FString.FromString(entry.Value[1])));
138 | }
139 | }
140 |
141 | private static string ExportData(Formatting formatting = Formatting.Indented)
142 | {
143 | CheckIfMapStructTypeOverrideIsNull();
144 |
145 | StringBuilder sb = new StringBuilder();
146 | StringWriter sw = new StringWriter(sb);
147 |
148 | using (JsonWriter writer = new JsonTextWriter(sw))
149 | {
150 | writer.Formatting = formatting;
151 |
152 | writer.WriteStartObject();
153 | foreach (KeyValuePair> entry in MapStructTypeOverride)
154 | {
155 | writer.WritePropertyName(entry.Key.ToString());
156 | writer.WriteStartArray();
157 | writer.WriteValue(entry.Value.Item1?.ToString());
158 | writer.WriteValue(entry.Value.Item2?.ToString());
159 | writer.WriteEnd();
160 | }
161 | writer.WriteEndObject();
162 | }
163 |
164 | return sb.ToString();
165 | }
166 |
167 | private void mstoDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e)
168 | {
169 | SaveFromDGV();
170 | }
171 |
172 | private void refreshButton_Click(object sender, EventArgs e)
173 | {
174 | LoadOntoDGV();
175 | }
176 |
177 | private void closeButton_Click(object sender, EventArgs e)
178 | {
179 | this.Close();
180 | }
181 |
182 | private void importButton_Click(object sender, EventArgs e)
183 | {
184 | using (OpenFileDialog openFileDialog = new OpenFileDialog())
185 | {
186 | openFileDialog.Filter = "Map Struct Type Override JSON (*.json)|*.json|All files (*.*)|*.*";
187 | openFileDialog.FilterIndex = 1;
188 | openFileDialog.RestoreDirectory = true;
189 |
190 | if (openFileDialog.ShowDialog() == DialogResult.OK)
191 | {
192 | ImportData(File.ReadAllText(openFileDialog.FileName));
193 | LoadOntoDGV();
194 | SaveToConfig();
195 | }
196 | }
197 | }
198 |
199 | private void exportButton_Click(object sender, EventArgs e)
200 | {
201 | using (SaveFileDialog dialog = new SaveFileDialog())
202 | {
203 | dialog.Filter = "Map Struct Type Override JSON (*.json)|*.json|All files (*.*)|*.*";
204 | dialog.FilterIndex = 1;
205 | dialog.RestoreDirectory = true;
206 |
207 | DialogResult res = dialog.ShowDialog();
208 | if (res == DialogResult.OK)
209 | {
210 | SaveFromDGV();
211 | File.WriteAllText(dialog.FileName, ExportData());
212 | }
213 | }
214 | }
215 |
216 | private void resetButton_Click(object sender, EventArgs e)
217 | {
218 | DialogResult res = MessageBox.Show("Are you sure you want to reset the table to its defaults?", this.Text, MessageBoxButtons.OKCancel);
219 | if (res != DialogResult.OK) return;
220 |
221 | MapStructTypeOverride = null;
222 | CheckIfMapStructTypeOverrideIsNull();
223 | LoadOntoDGV();
224 | SaveToConfig();
225 | }
226 | }
227 | }
228 |
--------------------------------------------------------------------------------
/UAssetGUI/UAGConfig.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.IO;
5 | using System.Windows.Forms;
6 | using UAssetAPI;
7 | using UAssetAPI.Unversioned;
8 |
9 | namespace UAssetGUI
10 | {
11 | public struct UAGConfigData
12 | {
13 | public string PreferredVersion;
14 | public string PreferredMappings;
15 | public string Theme;
16 | public string MapStructTypeOverride;
17 | public string FavoriteThing;
18 | public int DataZoom;
19 | public bool ChangeValuesOnScroll;
20 | public bool EnableDynamicTree;
21 | public bool EnableDiscordRPC;
22 | public bool DoubleClickToEdit;
23 | public bool EnableBak;
24 | public bool RestoreSize;
25 | public bool EnableUpdateNotice;
26 | public bool EnablePrettyBytecode;
27 | public int StartupWidth;
28 | public int StartupHeight;
29 | public int CustomSerializationFlags;
30 |
31 | public UAGConfigData()
32 | {
33 | PreferredVersion = string.Empty;
34 | Theme = string.Empty;
35 | MapStructTypeOverride = string.Empty;
36 | FavoriteThing = string.Empty;
37 | DataZoom = 0;
38 | ChangeValuesOnScroll = true;
39 | EnableDynamicTree = true;
40 | EnableDiscordRPC = true;
41 | DoubleClickToEdit = true;
42 | EnableBak = true;
43 | RestoreSize = true;
44 | EnableUpdateNotice = true;
45 | EnablePrettyBytecode = true;
46 | StartupWidth = 1000;
47 | StartupHeight = 700;
48 | CustomSerializationFlags = 0;
49 | }
50 | }
51 |
52 | public static class UAGConfig
53 | {
54 | public static UAGConfigData Data;
55 | public static Dictionary AllMappings = new Dictionary();
56 | public readonly static string ConfigFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "UAssetGUI");
57 | public readonly static string MappingsFolder = Path.Combine(ConfigFolder, "Mappings");
58 | public readonly static string StagingFolder = Path.Combine(ConfigFolder, "Staging");
59 | public readonly static string ExtractedFolder = Path.Combine(ConfigFolder, "Extracted");
60 |
61 | internal static bool DifferentStagingPerPak = false;
62 |
63 | public static void LoadMappings()
64 | {
65 | Directory.CreateDirectory(ConfigFolder);
66 | Directory.CreateDirectory(MappingsFolder);
67 |
68 | AllMappings.Clear();
69 | string[] allMappingFiles = Directory.GetFiles(MappingsFolder, "*.usmap", SearchOption.TopDirectoryOnly);
70 | foreach (string mappingPath in allMappingFiles)
71 | {
72 | AllMappings.Add(Path.GetFileNameWithoutExtension(mappingPath), mappingPath);
73 | }
74 | }
75 |
76 | public static string[] GetStagingFiles(string pakPath, out string[] fixedPathsOnDisk)
77 | {
78 | string rootDir = DifferentStagingPerPak ? Path.Combine(StagingFolder, Path.GetFileNameWithoutExtension(pakPath)) : StagingFolder;
79 | Directory.CreateDirectory(rootDir);
80 |
81 | fixedPathsOnDisk = Directory.GetFiles(rootDir, "*.*", SearchOption.AllDirectories);
82 | string[] res = new string[fixedPathsOnDisk.Length]; Array.Copy(fixedPathsOnDisk, res, fixedPathsOnDisk.Length);
83 | for (int i = 0; i < res.Length; i++)
84 | {
85 | res[i] = res[i].Replace(Path.DirectorySeparatorChar, '/').Substring(rootDir.Length).TrimStart('/');
86 | }
87 |
88 | return res;
89 | }
90 |
91 | public static void StageFile(string rawPathOnDisk, string CurrentContainerPath, string newPath = null)
92 | {
93 | if (newPath == null) newPath = Path.GetFileName(rawPathOnDisk);
94 | newPath = newPath.Replace('/', Path.DirectorySeparatorChar);
95 |
96 | var finalPath = DifferentStagingPerPak ? Path.Combine(StagingFolder, Path.GetFileNameWithoutExtension(CurrentContainerPath), newPath) : Path.Combine(StagingFolder, newPath);
97 | try { Directory.CreateDirectory(Path.GetDirectoryName(finalPath)); } catch { return; } // fail silently if cant make the directory we need
98 |
99 | try { Directory.Delete(finalPath, true); } catch { } // if we turn a directory into a file, try and get rid of the directory
100 |
101 | File.Copy(rawPathOnDisk, finalPath, true);
102 | try { File.Copy(Path.ChangeExtension(rawPathOnDisk, ".uexp"), Path.ChangeExtension(finalPath, ".uexp"), true); } catch { }
103 | try { File.Copy(Path.ChangeExtension(rawPathOnDisk, ".ubulk"), Path.ChangeExtension(finalPath, ".ubulk"), true); } catch { }
104 | }
105 |
106 | public static void StageFile(DirectoryTreeItem item, string newPath = null)
107 | {
108 | // recursive if we were given a directory
109 | if (!item.IsFile)
110 | {
111 | foreach (var child in item.Children) StageFile(child.Value, newPath == null ? null : Path.Combine(newPath, child.Value.Name));
112 | return;
113 | }
114 |
115 | if (newPath == null) newPath = item.FullPath;
116 | newPath = newPath.Replace('/', Path.DirectorySeparatorChar);
117 |
118 | string outputPath = item.SaveFileToTemp();
119 | var finalPath = DifferentStagingPerPak ? Path.Combine(StagingFolder, Path.GetFileNameWithoutExtension(item.ParentForm.CurrentContainerPath), newPath) : Path.Combine(StagingFolder, newPath);
120 | if (outputPath == null || finalPath == null) return;
121 | try { Directory.CreateDirectory(Path.GetDirectoryName(finalPath)); } catch { return; } // fail silently if cant make the directory we need
122 |
123 | try { Directory.Delete(finalPath, true); } catch { } // if we turn a directory into a file, try and get rid of the directory
124 |
125 | File.Copy(outputPath, finalPath, true);
126 | try { File.Copy(Path.ChangeExtension(outputPath, ".uexp"), Path.ChangeExtension(finalPath, ".uexp"), true); } catch { }
127 | try { File.Copy(Path.ChangeExtension(outputPath, ".ubulk"), Path.ChangeExtension(finalPath, ".ubulk"), true); } catch { }
128 | try { File.Delete(outputPath); } catch { }
129 | try { File.Delete(Path.ChangeExtension(outputPath, ".uexp")); } catch { }
130 | try { File.Delete(Path.ChangeExtension(outputPath, ".ubulk")); } catch { }
131 | }
132 |
133 | public static string ExtractFile(DirectoryTreeItem item, FileStream stream2 = null, PakReader reader2 = null)
134 | {
135 | var finalPath = Path.Combine(ExtractedFolder, item.FullPath.Replace('/', Path.DirectorySeparatorChar));
136 |
137 | // recursive if we were given a directory
138 | if (!item.IsFile)
139 | {
140 | foreach (var child in item.Children) ExtractFile(child.Value, stream2, reader2);
141 | return finalPath;
142 | }
143 |
144 | return item.SaveFileToTemp(ExtractedFolder, stream2, reader2);
145 | }
146 |
147 | public static bool TryGetMappings(string name, out Usmap mappings)
148 | {
149 | if (AllMappings.TryGetValue(name, out string value))
150 | {
151 | try
152 | {
153 | mappings = new Usmap(value);
154 | return true;
155 | }
156 | catch
157 | {
158 | UAGUtils.InvokeUI(() =>
159 | {
160 | MessageBox.Show("Failed to parse mappings: " + name, "Notice");
161 |
162 | // update list of mappings for good measure
163 | foreach (var form in Application.OpenForms)
164 | {
165 | if (form is Form1 form1)
166 | {
167 | form1.UpdateMappings("No mappings", false);
168 | }
169 | }
170 | });
171 | }
172 | }
173 |
174 | mappings = null;
175 | return false;
176 | }
177 |
178 | public static void Save()
179 | {
180 | SaveCustomFile("config.json", JsonConvert.SerializeObject(Data, Formatting.Indented));
181 | }
182 |
183 | public static string SaveCustomFile(string name, string text, string subFolder = null)
184 | {
185 | string outPath = Path.Combine(ConfigFolder, name);
186 | if (!string.IsNullOrEmpty(subFolder)) outPath = Path.Combine(ConfigFolder, subFolder, name);
187 |
188 | Directory.CreateDirectory(Path.GetDirectoryName(outPath));
189 | File.WriteAllText(outPath, text);
190 |
191 | return outPath;
192 | }
193 |
194 | public static void Load()
195 | {
196 | try
197 | {
198 | Directory.CreateDirectory(ConfigFolder);
199 | Data = JsonConvert.DeserializeObject(File.ReadAllText(Path.Combine(ConfigFolder, "config.json")));
200 | }
201 | catch
202 | {
203 | Data = new UAGConfigData();
204 | Save();
205 | }
206 | }
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/UAssetGUI/FindForm.Designer.cs:
--------------------------------------------------------------------------------
1 |
2 | namespace UAssetGUI
3 | {
4 | partial class FindForm
5 | {
6 | ///
7 | /// Required designer variable.
8 | ///
9 | private System.ComponentModel.IContainer components = null;
10 |
11 | ///
12 | /// Clean up any resources being used.
13 | ///
14 | /// true if managed resources should be disposed; otherwise, false.
15 | protected override void Dispose(bool disposing)
16 | {
17 | if (disposing && (components != null))
18 | {
19 | components.Dispose();
20 | }
21 | base.Dispose(disposing);
22 | }
23 |
24 | #region Windows Form Designer generated code
25 |
26 | ///
27 | /// Required method for Designer support - do not modify
28 | /// the contents of this method with the code editor.
29 | ///
30 | private void InitializeComponent()
31 | {
32 | this.closeButton = new System.Windows.Forms.Button();
33 | this.label1 = new System.Windows.Forms.Label();
34 | this.searchForBox = new System.Windows.Forms.TextBox();
35 | this.nextButton = new System.Windows.Forms.Button();
36 | this.searchDirectionGroupBox = new System.Windows.Forms.GroupBox();
37 | this.searchDirBackwardButton = new System.Windows.Forms.RadioButton();
38 | this.searchDirForwardButton = new System.Windows.Forms.RadioButton();
39 | this.optionsGroupBox = new System.Windows.Forms.GroupBox();
40 | this.useRegexCheckBox = new System.Windows.Forms.CheckBox();
41 | this.caseSensitiveCheckBox = new System.Windows.Forms.CheckBox();
42 | this.progressBar1 = new System.Windows.Forms.ProgressBar();
43 | this.searchDirectionGroupBox.SuspendLayout();
44 | this.optionsGroupBox.SuspendLayout();
45 | this.SuspendLayout();
46 | //
47 | // closeButton
48 | //
49 | this.closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
50 | this.closeButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
51 | this.closeButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
52 | this.closeButton.ForeColor = System.Drawing.SystemColors.ControlText;
53 | this.closeButton.Location = new System.Drawing.Point(224, 124);
54 | this.closeButton.Name = "closeButton";
55 | this.closeButton.Size = new System.Drawing.Size(75, 26);
56 | this.closeButton.TabIndex = 6;
57 | this.closeButton.Text = "Close";
58 | this.closeButton.UseVisualStyleBackColor = true;
59 | this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
60 | //
61 | // label1
62 | //
63 | this.label1.AutoSize = true;
64 | this.label1.Location = new System.Drawing.Point(12, 19);
65 | this.label1.Name = "label1";
66 | this.label1.Size = new System.Drawing.Size(59, 13);
67 | this.label1.TabIndex = 6;
68 | this.label1.Text = "Search for:";
69 | //
70 | // searchForBox
71 | //
72 | this.searchForBox.Location = new System.Drawing.Point(77, 16);
73 | this.searchForBox.Name = "searchForBox";
74 | this.searchForBox.Size = new System.Drawing.Size(222, 20);
75 | this.searchForBox.TabIndex = 0;
76 | //
77 | // nextButton
78 | //
79 | this.nextButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
80 | this.nextButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
81 | this.nextButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
82 | this.nextButton.ForeColor = System.Drawing.SystemColors.ControlText;
83 | this.nextButton.Location = new System.Drawing.Point(143, 124);
84 | this.nextButton.Name = "nextButton";
85 | this.nextButton.Size = new System.Drawing.Size(75, 26);
86 | this.nextButton.TabIndex = 5;
87 | this.nextButton.Text = "Next";
88 | this.nextButton.UseVisualStyleBackColor = true;
89 | this.nextButton.Click += new System.EventHandler(this.nextButton_Click);
90 | //
91 | // searchDirectionGroupBox
92 | //
93 | this.searchDirectionGroupBox.Controls.Add(this.searchDirBackwardButton);
94 | this.searchDirectionGroupBox.Controls.Add(this.searchDirForwardButton);
95 | this.searchDirectionGroupBox.Location = new System.Drawing.Point(200, 42);
96 | this.searchDirectionGroupBox.Name = "searchDirectionGroupBox";
97 | this.searchDirectionGroupBox.Size = new System.Drawing.Size(99, 65);
98 | this.searchDirectionGroupBox.TabIndex = 11;
99 | this.searchDirectionGroupBox.TabStop = false;
100 | this.searchDirectionGroupBox.Text = "Search direction";
101 | //
102 | // searchDirBackwardButton
103 | //
104 | this.searchDirBackwardButton.AutoSize = true;
105 | this.searchDirBackwardButton.Location = new System.Drawing.Point(6, 42);
106 | this.searchDirBackwardButton.Name = "searchDirBackwardButton";
107 | this.searchDirBackwardButton.Size = new System.Drawing.Size(73, 17);
108 | this.searchDirBackwardButton.TabIndex = 4;
109 | this.searchDirBackwardButton.TabStop = true;
110 | this.searchDirBackwardButton.Text = "Backward";
111 | this.searchDirBackwardButton.UseVisualStyleBackColor = true;
112 | //
113 | // searchDirForwardButton
114 | //
115 | this.searchDirForwardButton.AutoSize = true;
116 | this.searchDirForwardButton.Location = new System.Drawing.Point(6, 19);
117 | this.searchDirForwardButton.Name = "searchDirForwardButton";
118 | this.searchDirForwardButton.Size = new System.Drawing.Size(63, 17);
119 | this.searchDirForwardButton.TabIndex = 3;
120 | this.searchDirForwardButton.TabStop = true;
121 | this.searchDirForwardButton.Text = "Forward";
122 | this.searchDirForwardButton.UseVisualStyleBackColor = true;
123 | //
124 | // optionsGroupBox
125 | //
126 | this.optionsGroupBox.Controls.Add(this.useRegexCheckBox);
127 | this.optionsGroupBox.Controls.Add(this.caseSensitiveCheckBox);
128 | this.optionsGroupBox.Location = new System.Drawing.Point(15, 42);
129 | this.optionsGroupBox.Name = "optionsGroupBox";
130 | this.optionsGroupBox.Size = new System.Drawing.Size(164, 65);
131 | this.optionsGroupBox.TabIndex = 12;
132 | this.optionsGroupBox.TabStop = false;
133 | this.optionsGroupBox.Text = "Options";
134 | //
135 | // useRegexCheckBox
136 | //
137 | this.useRegexCheckBox.AutoSize = true;
138 | this.useRegexCheckBox.Location = new System.Drawing.Point(6, 42);
139 | this.useRegexCheckBox.Name = "useRegexCheckBox";
140 | this.useRegexCheckBox.Size = new System.Drawing.Size(74, 17);
141 | this.useRegexCheckBox.TabIndex = 2;
142 | this.useRegexCheckBox.Text = "Use regex";
143 | this.useRegexCheckBox.UseVisualStyleBackColor = true;
144 | //
145 | // caseSensitiveCheckBox
146 | //
147 | this.caseSensitiveCheckBox.AutoSize = true;
148 | this.caseSensitiveCheckBox.Location = new System.Drawing.Point(6, 19);
149 | this.caseSensitiveCheckBox.Name = "caseSensitiveCheckBox";
150 | this.caseSensitiveCheckBox.Size = new System.Drawing.Size(94, 17);
151 | this.caseSensitiveCheckBox.TabIndex = 1;
152 | this.caseSensitiveCheckBox.Text = "Case sensitive";
153 | this.caseSensitiveCheckBox.UseVisualStyleBackColor = true;
154 | //
155 | // progressBar1
156 | //
157 | this.progressBar1.Location = new System.Drawing.Point(15, 126);
158 | this.progressBar1.Name = "progressBar1";
159 | this.progressBar1.Size = new System.Drawing.Size(114, 23);
160 | this.progressBar1.TabIndex = 13;
161 | //
162 | // FindForm
163 | //
164 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
165 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
166 | this.ClientSize = new System.Drawing.Size(311, 162);
167 | this.Controls.Add(this.progressBar1);
168 | this.Controls.Add(this.optionsGroupBox);
169 | this.Controls.Add(this.searchDirectionGroupBox);
170 | this.Controls.Add(this.nextButton);
171 | this.Controls.Add(this.searchForBox);
172 | this.Controls.Add(this.label1);
173 | this.Controls.Add(this.closeButton);
174 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
175 | this.Name = "FindForm";
176 | this.Text = "Find";
177 | this.Load += new System.EventHandler(this.FindForm_Load);
178 | this.searchDirectionGroupBox.ResumeLayout(false);
179 | this.searchDirectionGroupBox.PerformLayout();
180 | this.optionsGroupBox.ResumeLayout(false);
181 | this.optionsGroupBox.PerformLayout();
182 | this.ResumeLayout(false);
183 | this.PerformLayout();
184 |
185 | }
186 |
187 | #endregion
188 |
189 | private System.Windows.Forms.Button closeButton;
190 | private System.Windows.Forms.Label label1;
191 | private System.Windows.Forms.TextBox searchForBox;
192 | private System.Windows.Forms.Button nextButton;
193 | private System.Windows.Forms.GroupBox searchDirectionGroupBox;
194 | private System.Windows.Forms.RadioButton searchDirBackwardButton;
195 | private System.Windows.Forms.RadioButton searchDirForwardButton;
196 | private System.Windows.Forms.GroupBox optionsGroupBox;
197 | private System.Windows.Forms.CheckBox useRegexCheckBox;
198 | private System.Windows.Forms.CheckBox caseSensitiveCheckBox;
199 | private System.Windows.Forms.ProgressBar progressBar1;
200 | }
201 | }
--------------------------------------------------------------------------------
/UAssetGUI/MapStructTypeOverrideForm.Designer.cs:
--------------------------------------------------------------------------------
1 | namespace UAssetGUI
2 | {
3 | partial class MapStructTypeOverrideForm
4 | {
5 | ///
6 | /// Required designer variable.
7 | ///
8 | private System.ComponentModel.IContainer components = null;
9 |
10 | ///
11 | /// Clean up any resources being used.
12 | ///
13 | /// true if managed resources should be disposed; otherwise, false.
14 | protected override void Dispose(bool disposing)
15 | {
16 | if (disposing && (components != null))
17 | {
18 | components.Dispose();
19 | }
20 | base.Dispose(disposing);
21 | }
22 |
23 | #region Windows Form Designer generated code
24 |
25 | ///
26 | /// Required method for Designer support - do not modify
27 | /// the contents of this method with the code editor.
28 | ///
29 | private void InitializeComponent()
30 | {
31 | System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
32 | this.mstoDataGridView = new System.Windows.Forms.DataGridView();
33 | this.infoLabel = new System.Windows.Forms.Label();
34 | this.refreshButton = new System.Windows.Forms.Button();
35 | this.closeButton = new System.Windows.Forms.Button();
36 | this.exportButton = new System.Windows.Forms.Button();
37 | this.importButton = new System.Windows.Forms.Button();
38 | this.resetButton = new System.Windows.Forms.Button();
39 | ((System.ComponentModel.ISupportInitialize)(this.mstoDataGridView)).BeginInit();
40 | this.SuspendLayout();
41 | //
42 | // mstoDataGridView
43 | //
44 | this.mstoDataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
45 | | System.Windows.Forms.AnchorStyles.Right)));
46 | this.mstoDataGridView.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
47 | this.mstoDataGridView.BackgroundColor = System.Drawing.Color.LightGray;
48 | this.mstoDataGridView.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
49 | this.mstoDataGridView.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
50 | this.mstoDataGridView.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
51 | dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
52 | dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Control;
53 | dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F);
54 | dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.WindowText;
55 | dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
56 | dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
57 | dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
58 | this.mstoDataGridView.ColumnHeadersDefaultCellStyle = dataGridViewCellStyle1;
59 | this.mstoDataGridView.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
60 | this.mstoDataGridView.EditMode = System.Windows.Forms.DataGridViewEditMode.EditOnEnter;
61 | this.mstoDataGridView.EnableHeadersVisualStyles = false;
62 | this.mstoDataGridView.Location = new System.Drawing.Point(12, 52);
63 | this.mstoDataGridView.Name = "mstoDataGridView";
64 | this.mstoDataGridView.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
65 | this.mstoDataGridView.RowHeadersWidth = 60;
66 | this.mstoDataGridView.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
67 | this.mstoDataGridView.Size = new System.Drawing.Size(545, 289);
68 | this.mstoDataGridView.TabIndex = 1;
69 | this.mstoDataGridView.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.mstoDataGridView_CellEndEdit);
70 | //
71 | // infoLabel
72 | //
73 | this.infoLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
74 | | System.Windows.Forms.AnchorStyles.Right)));
75 | this.infoLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.25F);
76 | this.infoLabel.Location = new System.Drawing.Point(13, 9);
77 | this.infoLabel.Name = "infoLabel";
78 | this.infoLabel.Size = new System.Drawing.Size(544, 40);
79 | this.infoLabel.TabIndex = 0;
80 | this.infoLabel.Text = "blah blah blah";
81 | this.infoLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
82 | //
83 | // refreshButton
84 | //
85 | this.refreshButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
86 | this.refreshButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
87 | this.refreshButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
88 | this.refreshButton.Location = new System.Drawing.Point(12, 347);
89 | this.refreshButton.Name = "refreshButton";
90 | this.refreshButton.Size = new System.Drawing.Size(75, 26);
91 | this.refreshButton.TabIndex = 2;
92 | this.refreshButton.Text = "Refresh";
93 | this.refreshButton.UseVisualStyleBackColor = true;
94 | this.refreshButton.Click += new System.EventHandler(this.refreshButton_Click);
95 | //
96 | // closeButton
97 | //
98 | this.closeButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
99 | this.closeButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
100 | this.closeButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
101 | this.closeButton.ForeColor = System.Drawing.SystemColors.ControlText;
102 | this.closeButton.Location = new System.Drawing.Point(482, 347);
103 | this.closeButton.Name = "closeButton";
104 | this.closeButton.Size = new System.Drawing.Size(75, 26);
105 | this.closeButton.TabIndex = 3;
106 | this.closeButton.Text = "Close";
107 | this.closeButton.UseVisualStyleBackColor = true;
108 | this.closeButton.Click += new System.EventHandler(this.closeButton_Click);
109 | //
110 | // exportButton
111 | //
112 | this.exportButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
113 | this.exportButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
114 | this.exportButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
115 | this.exportButton.Location = new System.Drawing.Point(174, 347);
116 | this.exportButton.Name = "exportButton";
117 | this.exportButton.Size = new System.Drawing.Size(75, 26);
118 | this.exportButton.TabIndex = 4;
119 | this.exportButton.Text = "Export";
120 | this.exportButton.UseVisualStyleBackColor = true;
121 | this.exportButton.Click += new System.EventHandler(this.exportButton_Click);
122 | //
123 | // importButton
124 | //
125 | this.importButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
126 | this.importButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
127 | this.importButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
128 | this.importButton.Location = new System.Drawing.Point(93, 347);
129 | this.importButton.Name = "importButton";
130 | this.importButton.Size = new System.Drawing.Size(75, 26);
131 | this.importButton.TabIndex = 5;
132 | this.importButton.Text = "Import";
133 | this.importButton.UseVisualStyleBackColor = true;
134 | this.importButton.Click += new System.EventHandler(this.importButton_Click);
135 | //
136 | // resetButton
137 | //
138 | this.resetButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
139 | this.resetButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
140 | this.resetButton.Font = new System.Drawing.Font("Arial", 8F, System.Drawing.FontStyle.Bold);
141 | this.resetButton.Location = new System.Drawing.Point(401, 347);
142 | this.resetButton.Name = "resetButton";
143 | this.resetButton.Size = new System.Drawing.Size(75, 26);
144 | this.resetButton.TabIndex = 6;
145 | this.resetButton.Text = "Reset";
146 | this.resetButton.UseVisualStyleBackColor = true;
147 | this.resetButton.Click += new System.EventHandler(this.resetButton_Click);
148 | //
149 | // MapStructTypeOverrideForm
150 | //
151 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
152 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
153 | this.ClientSize = new System.Drawing.Size(569, 379);
154 | this.Controls.Add(this.resetButton);
155 | this.Controls.Add(this.importButton);
156 | this.Controls.Add(this.exportButton);
157 | this.Controls.Add(this.closeButton);
158 | this.Controls.Add(this.refreshButton);
159 | this.Controls.Add(this.infoLabel);
160 | this.Controls.Add(this.mstoDataGridView);
161 | this.Name = "MapStructTypeOverrideForm";
162 | this.Text = "Map Struct Type Overrides";
163 | this.Load += new System.EventHandler(this.MapStructTypeOverrideForm_Load);
164 | this.Resize += new System.EventHandler(this.MapStructTypeOverrideForm_Resize);
165 | ((System.ComponentModel.ISupportInitialize)(this.mstoDataGridView)).EndInit();
166 | this.ResumeLayout(false);
167 |
168 | }
169 |
170 | #endregion
171 | private System.Windows.Forms.Label infoLabel;
172 | internal System.Windows.Forms.DataGridView mstoDataGridView;
173 | private System.Windows.Forms.Button refreshButton;
174 | private System.Windows.Forms.Button closeButton;
175 | private System.Windows.Forms.Button exportButton;
176 | private System.Windows.Forms.Button importButton;
177 | private System.Windows.Forms.Button resetButton;
178 | }
179 | }
--------------------------------------------------------------------------------
/UAssetGUI/SettingsForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Drawing;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Windows.Forms;
7 | using UAssetAPI;
8 |
9 | namespace UAssetGUI
10 | {
11 | public partial class SettingsForm : Form
12 | {
13 | public SettingsForm()
14 | {
15 | InitializeComponent();
16 | numericUpDown1.MouseWheel += NumericUpDown1_MouseWheel;
17 | }
18 |
19 | private Form1 BaseForm;
20 | private bool _readyToUpdateTheme = false;
21 | private void SettingsForm_Load(object sender, EventArgs e)
22 | {
23 | if (this.Owner is Form1) BaseForm = (Form1)this.Owner;
24 |
25 | customSerializationFlagsBox.BeginUpdate();
26 | customSerializationFlagsBox.Items.Clear();
27 | List allFlags = Enum.GetValues(typeof(CustomSerializationFlags)).Cast().ToList();
28 | int entryIdx = 0;
29 | for (int i = 0; i < allFlags.Count; i++)
30 | {
31 | CustomSerializationFlags option = allFlags[i];
32 | if (option == 0) continue;
33 |
34 | customSerializationFlagsBox.Items.Add(option.ToString());
35 | customSerializationFlagsBox.SetItemChecked(entryIdx++, (UAGConfig.Data.CustomSerializationFlags & (int)option) > 0);
36 | }
37 | customSerializationFlagsBox.EndUpdate();
38 |
39 | themeComboBox.DataSource = Enum.GetValues(typeof(UAGTheme));
40 | themeComboBox.SelectedIndex = (int)UAGPalette.GetCurrentTheme();
41 | valuesOnScroll.Checked = UAGConfig.Data.ChangeValuesOnScroll;
42 | doubleClickToEdit.Checked = UAGConfig.Data.DoubleClickToEdit;
43 | enableDiscordRpc.Checked = UAGConfig.Data.EnableDiscordRPC;
44 | enableDynamicTree.Checked = UAGConfig.Data.EnableDynamicTree;
45 | favoriteThingBox.Text = UAGConfig.Data.FavoriteThing;
46 | numericUpDown1.Value = UAGConfig.Data.DataZoom;
47 | enableBak.Checked = UAGConfig.Data.EnableBak;
48 | enablePrettyBytecode.Checked = UAGConfig.Data.EnablePrettyBytecode;
49 | restoreSize.Checked = UAGConfig.Data.RestoreSize;
50 | enableUpdateNotice.Checked = UAGConfig.Data.EnableUpdateNotice;
51 |
52 | UAGPalette.RefreshTheme(this);
53 | this.AdjustFormPosition();
54 | _readyToUpdateTheme = true;
55 | }
56 |
57 | private void closeButton_Click(object sender, EventArgs e)
58 | {
59 | this.Close();
60 | }
61 |
62 | private void aboutButton_Click(object sender, EventArgs e)
63 | {
64 | var softwareAgeInYears = (int.Parse(DateTime.Now.ToString("yyyyMMdd")) - 20200723) / 10000;
65 |
66 | UAGUtils.InvokeUI(() =>
67 | {
68 | var formPopup = new AboutForm();
69 |
70 | formPopup.AboutText = (this.Owner as Form1).DisplayVersion + "\n" +
71 | "By atenfyr\n" +
72 | "\nThank you to trumank, LongerWarrior, Kaiheilos, and others for all your generous contributions to this software\n" +
73 | "\nThank you to the love of my life for listening to me and supporting me despite not caring at all about any of this\n" +
74 | "\nThank you for using this thing even after " + softwareAgeInYears + " years\n";
75 |
76 | formPopup.StartPosition = FormStartPosition.CenterParent;
77 | formPopup.ShowDialog(this);
78 | });
79 | }
80 |
81 | private void themeComboBox_SelectedIndexChanged(object sender, EventArgs e)
82 | {
83 | if (!_readyToUpdateTheme) return;
84 | Enum.TryParse(themeComboBox.SelectedValue.ToString(), out UAGTheme nextTheme);
85 | UAGPalette.SetCurrentTheme(nextTheme);
86 | UAGPalette.RefreshTheme(BaseForm);
87 | UAGPalette.RefreshTheme(this);
88 | }
89 |
90 | private void valuesOnScroll_CheckedChanged(object sender, EventArgs e)
91 | {
92 | UAGConfig.Data.ChangeValuesOnScroll = valuesOnScroll.Checked;
93 | }
94 |
95 | private void enableDynamicTree_CheckedChanged(object sender, EventArgs e)
96 | {
97 | UAGConfig.Data.EnableDynamicTree = enableDynamicTree.Checked;
98 | }
99 |
100 | private void doubleClickToEdit_CheckedChanged(object sender, EventArgs e)
101 | {
102 | UAGConfig.Data.DoubleClickToEdit = doubleClickToEdit.Checked;
103 | //BaseForm.dataGridView1.EditMode = UAGConfig.Data.DoubleClickToEdit ? DataGridViewEditMode.EditProgrammatically : DataGridViewEditMode.EditOnEnter;
104 | }
105 |
106 | private void enableBak_CheckedChanged(object sender, EventArgs e)
107 | {
108 | UAGConfig.Data.EnableBak = enableBak.Checked;
109 | }
110 |
111 | private void restoreSize_CheckedChanged(object sender, EventArgs e)
112 | {
113 | UAGConfig.Data.RestoreSize = restoreSize.Checked;
114 | }
115 |
116 | private void enableUpdateNotice_CheckedChanged(object sender, EventArgs e)
117 | {
118 | UAGConfig.Data.EnableUpdateNotice = enableUpdateNotice.Checked;
119 | }
120 |
121 | private void enablePrettyBytecode_CheckedChanged(object sender, EventArgs e)
122 | {
123 | UAGConfig.Data.EnablePrettyBytecode = enablePrettyBytecode.Checked;
124 | }
125 |
126 | private void enableDiscordRpc_CheckedChanged(object sender, EventArgs e)
127 | {
128 | UAGConfig.Data.EnableDiscordRPC = enableDiscordRpc.Checked;
129 | if (UAGConfig.Data.EnableDiscordRPC)
130 | {
131 | BaseForm.UpdateRPC();
132 | }
133 | else
134 | {
135 | BaseForm.DiscordRPC.ClearPresence();
136 | }
137 | }
138 |
139 | private bool isCurrentlyComicSans = false;
140 | private void favoriteThingBox_TextChanged(object sender, EventArgs e)
141 | {
142 | UAGConfig.Data.FavoriteThing = favoriteThingBox.Text;
143 | string favoriteThingLowered = UAGConfig.Data.FavoriteThing.ToLowerInvariant().Trim();
144 |
145 | if (UAGPalette.IsComicSans())
146 | {
147 | isCurrentlyComicSans = true;
148 | UAGPalette.RefreshTheme(BaseForm);
149 | UAGPalette.RefreshTheme(this);
150 | }
151 | else if (isCurrentlyComicSans)
152 | {
153 | isCurrentlyComicSans = false;
154 | UAGPalette.RefreshTheme(BaseForm);
155 | UAGPalette.RefreshTheme(this);
156 | }
157 |
158 | if (favoriteThingLowered == "atenfyr" || favoriteThingLowered == "adolescent")
159 | {
160 | // need MemoryStream to remain open until we're done using the image
161 | // no need to dispose MemoryStream so let's just let GC handle it once image stops being used
162 | var strm = new MemoryStream(Properties.Resources.dancing_cat);
163 | this.pictureBox1.Image = Image.FromStream(strm);
164 | this.pictureBox1.Visible = true;
165 | }
166 | else
167 | {
168 | this.pictureBox1.Visible = false;
169 | }
170 | }
171 |
172 | private void SettingsForm_FormClosing(object sender, FormClosingEventArgs e)
173 | {
174 | UAGConfig.Save();
175 | UAGPalette.RefreshTheme(BaseForm);
176 | UAGPalette.RefreshTheme(this);
177 | }
178 |
179 | private void numericUpDown1_ValueChanged(object sender, EventArgs e)
180 | {
181 | UAGConfig.Data.DataZoom = (int)numericUpDown1.Value;
182 | UAGPalette.RefreshTheme(BaseForm);
183 | UAGPalette.RefreshTheme(this);
184 |
185 | // Refresh dgv row heights
186 | UAGUtils.InvokeUI(() =>
187 | {
188 | if (BaseForm.tableEditor != null)
189 | {
190 | BaseForm.tableEditor.Save(true);
191 | }
192 | });
193 | }
194 |
195 | private void customSerializationFlagsBox_Click(object sender, EventArgs e)
196 | {
197 | // this logic is here to prevent default list box selection logic
198 |
199 | // The following block of code is modified and adapted from source code on StackOverflow created and licensed by user Hath, copyright 2008: https://stackoverflow.com/a/334672
200 | // The original code is adapted for usage in this software under the terms of the CC BY-SA 2.5 license: https://creativecommons.org/licenses/by-sa/2.5/
201 | /*
202 | UNLESS OTHERWISE AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE
203 | WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
204 | CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
205 | INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS
206 | FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT
207 | OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR
208 | NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED
209 | WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
210 | */
211 | for (int i = 0; i < customSerializationFlagsBox.Items.Count; i++)
212 | {
213 | if (customSerializationFlagsBox.GetItemRectangle(i).Contains(customSerializationFlagsBox.PointToClient(MousePosition)))
214 | {
215 | customSerializationFlagsBox.SetItemChecked(i, !customSerializationFlagsBox.GetItemChecked(i));
216 | }
217 | }
218 |
219 | // update config
220 | CustomSerializationFlags res = 0;
221 | for (int i = 0; i < customSerializationFlagsBox.Items.Count; i++)
222 | {
223 | string item = customSerializationFlagsBox.Items[i] as string;
224 | if (item == null) continue;
225 | if (customSerializationFlagsBox.GetItemChecked(i))
226 | {
227 | res |= Enum.Parse(item);
228 | }
229 | }
230 |
231 | UAGConfig.Data.CustomSerializationFlags = (int)res;
232 | }
233 |
234 | private void NumericUpDown1_MouseWheel(object sender, MouseEventArgs e)
235 | {
236 | // override default scroll logic to prevent weird +3 problem
237 | if (e.Delta == 0) return;
238 | ((HandledMouseEventArgs)e).Handled = true;
239 |
240 | UAGUtils.InvokeUI(() =>
241 | {
242 | decimal newValue = numericUpDown1.Value + (e.Delta > 0 ? 1 : -1);
243 | if (newValue < numericUpDown1.Minimum) newValue = numericUpDown1.Minimum;
244 | if (newValue > numericUpDown1.Maximum) newValue = numericUpDown1.Maximum;
245 | numericUpDown1.Value = newValue;
246 | });
247 | }
248 | }
249 | }
250 |
--------------------------------------------------------------------------------
/UAssetGUI.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.4.33103.184
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UAssetAPI", "UAssetAPI\UAssetAPI\UAssetAPI.csproj", "{178417EC-1177-413E-BE85-C83AECD64279}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UAssetAPI.Tests", "UAssetAPI\UAssetAPI.Tests\UAssetAPI.Tests.csproj", "{CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UAssetGUI", "UAssetGUI\UAssetGUI.csproj", "{88A998F1-C512-416F-ADED-120E50AFE6F3}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UAssetAPI.Benchmark", "UAssetAPI\UAssetAPI.Benchmark\UAssetAPI.Benchmark.csproj", "{A74E7E85-1797-477C-AEC1-583AE7D109D0}"
13 | EndProject
14 | Global
15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
16 | Debug|Any CPU = Debug|Any CPU
17 | Debug|x64 = Debug|x64
18 | Debug|x86 = Debug|x86
19 | DebugTracing|Any CPU = DebugTracing|Any CPU
20 | DebugTracing|x64 = DebugTracing|x64
21 | DebugTracing|x86 = DebugTracing|x86
22 | DebugVerbose|Any CPU = DebugVerbose|Any CPU
23 | DebugVerbose|x64 = DebugVerbose|x64
24 | DebugVerbose|x86 = DebugVerbose|x86
25 | Release|Any CPU = Release|Any CPU
26 | Release|x64 = Release|x64
27 | Release|x86 = Release|x86
28 | ReleaseX|Any CPU = ReleaseX|Any CPU
29 | ReleaseX|x64 = ReleaseX|x64
30 | ReleaseX|x86 = ReleaseX|x86
31 | EndGlobalSection
32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
33 | {178417EC-1177-413E-BE85-C83AECD64279}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {178417EC-1177-413E-BE85-C83AECD64279}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {178417EC-1177-413E-BE85-C83AECD64279}.Debug|x64.ActiveCfg = Debug|Any CPU
36 | {178417EC-1177-413E-BE85-C83AECD64279}.Debug|x64.Build.0 = Debug|Any CPU
37 | {178417EC-1177-413E-BE85-C83AECD64279}.Debug|x86.ActiveCfg = Debug|x86
38 | {178417EC-1177-413E-BE85-C83AECD64279}.Debug|x86.Build.0 = Debug|x86
39 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugTracing|Any CPU.ActiveCfg = DebugTracing|Any CPU
40 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugTracing|Any CPU.Build.0 = DebugTracing|Any CPU
41 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugTracing|x64.ActiveCfg = DebugTracing|Any CPU
42 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugTracing|x64.Build.0 = DebugTracing|Any CPU
43 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugTracing|x86.ActiveCfg = DebugTracing|x86
44 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugTracing|x86.Build.0 = DebugTracing|x86
45 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugVerbose|Any CPU.ActiveCfg = DebugVerbose|Any CPU
46 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugVerbose|Any CPU.Build.0 = DebugVerbose|Any CPU
47 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugVerbose|x64.ActiveCfg = DebugVerbose|Any CPU
48 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugVerbose|x64.Build.0 = DebugVerbose|Any CPU
49 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugVerbose|x86.ActiveCfg = DebugVerbose|x86
50 | {178417EC-1177-413E-BE85-C83AECD64279}.DebugVerbose|x86.Build.0 = DebugVerbose|x86
51 | {178417EC-1177-413E-BE85-C83AECD64279}.Release|Any CPU.ActiveCfg = Release|Any CPU
52 | {178417EC-1177-413E-BE85-C83AECD64279}.Release|Any CPU.Build.0 = Release|Any CPU
53 | {178417EC-1177-413E-BE85-C83AECD64279}.Release|x64.ActiveCfg = Release|Any CPU
54 | {178417EC-1177-413E-BE85-C83AECD64279}.Release|x64.Build.0 = Release|Any CPU
55 | {178417EC-1177-413E-BE85-C83AECD64279}.Release|x86.ActiveCfg = Release|x86
56 | {178417EC-1177-413E-BE85-C83AECD64279}.Release|x86.Build.0 = Release|x86
57 | {178417EC-1177-413E-BE85-C83AECD64279}.ReleaseX|Any CPU.ActiveCfg = Release|Any CPU
58 | {178417EC-1177-413E-BE85-C83AECD64279}.ReleaseX|Any CPU.Build.0 = Release|Any CPU
59 | {178417EC-1177-413E-BE85-C83AECD64279}.ReleaseX|x64.ActiveCfg = Release|Any CPU
60 | {178417EC-1177-413E-BE85-C83AECD64279}.ReleaseX|x64.Build.0 = Release|Any CPU
61 | {178417EC-1177-413E-BE85-C83AECD64279}.ReleaseX|x86.ActiveCfg = Release|x86
62 | {178417EC-1177-413E-BE85-C83AECD64279}.ReleaseX|x86.Build.0 = Release|x86
63 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
64 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Debug|Any CPU.Build.0 = Debug|Any CPU
65 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Debug|x64.ActiveCfg = Debug|Any CPU
66 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Debug|x64.Build.0 = Debug|Any CPU
67 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Debug|x86.ActiveCfg = Debug|x86
68 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Debug|x86.Build.0 = Debug|x86
69 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugTracing|Any CPU.ActiveCfg = DebugTracing|Any CPU
70 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugTracing|Any CPU.Build.0 = DebugTracing|Any CPU
71 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugTracing|x64.ActiveCfg = DebugTracing|Any CPU
72 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugTracing|x64.Build.0 = DebugTracing|Any CPU
73 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugTracing|x86.ActiveCfg = DebugTracing|x86
74 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugTracing|x86.Build.0 = DebugTracing|x86
75 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugVerbose|Any CPU.ActiveCfg = DebugVerbose|Any CPU
76 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugVerbose|Any CPU.Build.0 = DebugVerbose|Any CPU
77 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugVerbose|x64.ActiveCfg = DebugVerbose|Any CPU
78 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugVerbose|x64.Build.0 = DebugVerbose|Any CPU
79 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugVerbose|x86.ActiveCfg = DebugVerbose|x86
80 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.DebugVerbose|x86.Build.0 = DebugVerbose|x86
81 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Release|Any CPU.ActiveCfg = Release|Any CPU
82 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Release|Any CPU.Build.0 = Release|Any CPU
83 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Release|x64.ActiveCfg = Release|Any CPU
84 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Release|x64.Build.0 = Release|Any CPU
85 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Release|x86.ActiveCfg = Release|x86
86 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.Release|x86.Build.0 = Release|x86
87 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.ReleaseX|Any CPU.ActiveCfg = Release|Any CPU
88 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.ReleaseX|Any CPU.Build.0 = Release|Any CPU
89 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.ReleaseX|x64.ActiveCfg = Release|Any CPU
90 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.ReleaseX|x64.Build.0 = Release|Any CPU
91 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.ReleaseX|x86.ActiveCfg = Release|x86
92 | {CB796120-5EF8-4E9D-BCDB-D2F60A4EFC69}.ReleaseX|x86.Build.0 = Release|x86
93 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
94 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
95 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Debug|x64.ActiveCfg = Debug|Any CPU
96 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Debug|x64.Build.0 = Debug|Any CPU
97 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Debug|x86.ActiveCfg = Debug|x86
98 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Debug|x86.Build.0 = Debug|x86
99 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugTracing|Any CPU.ActiveCfg = DebugTracing|Any CPU
100 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugTracing|Any CPU.Build.0 = DebugTracing|Any CPU
101 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugTracing|x64.ActiveCfg = DebugTracing|Any CPU
102 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugTracing|x64.Build.0 = DebugTracing|Any CPU
103 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugTracing|x86.ActiveCfg = DebugTracing|x86
104 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugTracing|x86.Build.0 = DebugTracing|x86
105 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugVerbose|Any CPU.ActiveCfg = DebugVerbose|Any CPU
106 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugVerbose|Any CPU.Build.0 = DebugVerbose|Any CPU
107 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugVerbose|x64.ActiveCfg = DebugVerbose|Any CPU
108 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugVerbose|x64.Build.0 = DebugVerbose|Any CPU
109 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugVerbose|x86.ActiveCfg = DebugVerbose|x86
110 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.DebugVerbose|x86.Build.0 = DebugVerbose|x86
111 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
112 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Release|Any CPU.Build.0 = Release|Any CPU
113 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Release|x64.ActiveCfg = Release|Any CPU
114 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Release|x64.Build.0 = Release|Any CPU
115 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Release|x86.ActiveCfg = Release|x86
116 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.Release|x86.Build.0 = Release|x86
117 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.ReleaseX|Any CPU.ActiveCfg = ReleaseX|Any CPU
118 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.ReleaseX|Any CPU.Build.0 = ReleaseX|Any CPU
119 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.ReleaseX|x64.ActiveCfg = ReleaseX|Any CPU
120 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.ReleaseX|x64.Build.0 = ReleaseX|Any CPU
121 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.ReleaseX|x86.ActiveCfg = ReleaseX|x86
122 | {88A998F1-C512-416F-ADED-120E50AFE6F3}.ReleaseX|x86.Build.0 = ReleaseX|x86
123 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
124 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
125 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Debug|x64.ActiveCfg = Debug|Any CPU
126 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Debug|x64.Build.0 = Debug|Any CPU
127 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Debug|x86.ActiveCfg = Debug|x86
128 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Debug|x86.Build.0 = Debug|x86
129 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugTracing|Any CPU.ActiveCfg = DebugTracing|Any CPU
130 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugTracing|Any CPU.Build.0 = DebugTracing|Any CPU
131 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugTracing|x64.ActiveCfg = DebugTracing|Any CPU
132 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugTracing|x64.Build.0 = DebugTracing|Any CPU
133 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugTracing|x86.ActiveCfg = DebugTracing|x86
134 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugTracing|x86.Build.0 = DebugTracing|x86
135 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugVerbose|Any CPU.ActiveCfg = DebugVerbose|Any CPU
136 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugVerbose|Any CPU.Build.0 = DebugVerbose|Any CPU
137 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugVerbose|x64.ActiveCfg = DebugVerbose|Any CPU
138 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugVerbose|x64.Build.0 = DebugVerbose|Any CPU
139 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugVerbose|x86.ActiveCfg = DebugVerbose|x86
140 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.DebugVerbose|x86.Build.0 = DebugVerbose|x86
141 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
142 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Release|Any CPU.Build.0 = Release|Any CPU
143 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Release|x64.ActiveCfg = Release|Any CPU
144 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Release|x64.Build.0 = Release|Any CPU
145 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Release|x86.ActiveCfg = Release|x86
146 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.Release|x86.Build.0 = Release|x86
147 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.ReleaseX|Any CPU.ActiveCfg = Release|Any CPU
148 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.ReleaseX|Any CPU.Build.0 = Release|Any CPU
149 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.ReleaseX|x64.ActiveCfg = Release|Any CPU
150 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.ReleaseX|x64.Build.0 = Release|Any CPU
151 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.ReleaseX|x86.ActiveCfg = Release|x86
152 | {A74E7E85-1797-477C-AEC1-583AE7D109D0}.ReleaseX|x86.Build.0 = Release|x86
153 | EndGlobalSection
154 | GlobalSection(SolutionProperties) = preSolution
155 | HideSolutionNode = FALSE
156 | EndGlobalSection
157 | GlobalSection(ExtensibilityGlobals) = postSolution
158 | SolutionGuid = {7A4553E8-6A4B-46A5-B429-7F9128492CAD}
159 | EndGlobalSection
160 | EndGlobal
161 |
--------------------------------------------------------------------------------
/UAssetGUI/FindForm.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text.RegularExpressions;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using System.Windows.Forms;
8 |
9 | namespace UAssetGUI
10 | {
11 | public partial class FindForm : Form
12 | {
13 | public string SearchTerm = string.Empty;
14 | public bool UseRegex = false;
15 | public Regex RegularExpression;
16 | public bool CaseSensitive = false;
17 | public SearchDirection CurrentSearchDirection = SearchDirection.Forward;
18 |
19 | public FindForm()
20 | {
21 | InitializeComponent();
22 | progressBar1.Visible = false;
23 | searchDirForwardButton.Tag = SearchDirection.Forward;
24 | searchDirBackwardButton.Tag = SearchDirection.Backward;
25 | searchDirForwardButton.Checked = true;
26 | }
27 |
28 | private Form1 BaseForm;
29 | private void FindForm_Load(object sender, EventArgs e)
30 | {
31 | if (this.Owner is Form1) BaseForm = (Form1)this.Owner;
32 |
33 | UAGPalette.RefreshTheme(this);
34 | this.AdjustFormPosition();
35 | }
36 |
37 | private void SyncSettings()
38 | {
39 | SearchTerm = searchForBox.Text.Trim();
40 | CaseSensitive = caseSensitiveCheckBox.Checked;
41 | UseRegex = useRegexCheckBox.Checked;
42 | CurrentSearchDirection = (SearchDirection)(searchDirectionGroupBox.Controls.OfType().FirstOrDefault(n => n.Checked).Tag);
43 |
44 | if (UseRegex)
45 | {
46 | RegexOptions ourOptions = RegexOptions.Compiled | RegexOptions.Multiline;
47 | if (!CaseSensitive) ourOptions |= RegexOptions.IgnoreCase;
48 | RegularExpression = new Regex(SearchTerm, ourOptions);
49 | }
50 | }
51 |
52 | private void closeButton_Click(object sender, EventArgs e)
53 | {
54 | if (ts != null) ts.Cancel();
55 | this.Dispose();
56 | }
57 |
58 | private bool DoesTextQualify(string txt)
59 | {
60 | if (UseRegex) return RegularExpression.IsMatch(txt);
61 | return CaseSensitive ? txt.Contains(SearchTerm) : (txt.IndexOf(SearchTerm, StringComparison.OrdinalIgnoreCase) >= 0);
62 | }
63 |
64 | private void TraverseToPopulatePreviouslyExpandedNodes(ISet previouslyExpandedNodes, TreeNodeCollection nodes)
65 | {
66 | foreach (TreeNode node in nodes)
67 | {
68 | if (node.IsExpanded) previouslyExpandedNodes.Add(node);
69 | TraverseToPopulatePreviouslyExpandedNodes(previouslyExpandedNodes, node.Nodes);
70 | }
71 | }
72 |
73 | private void PerformSearch(CancellationToken cancelToken)
74 | {
75 | bool foundSomething = false; bool wasCanceled = false; TreeNode originalNode = null; TreeNode examiningNode = null; int minRow = -1;
76 |
77 | ISet previouslyExpandedNodes = new HashSet();
78 |
79 | UAGUtils.InvokeUI(() =>
80 | {
81 | progressBar1.Visible = true;
82 | progressBar1.Value = 0;
83 | progressBar1.Maximum = BaseForm.treeView1.GetNodeCount(true);
84 | BaseForm.dataGridView1.SuspendLayout();
85 | BaseForm.treeView1.SuspendLayout();
86 | BaseForm.treeView1.BeginUpdate();
87 |
88 | originalNode = BaseForm.treeView1.SelectedNode;
89 | examiningNode = BaseForm.treeView1.SelectedNode;
90 | minRow = BaseForm.dataGridView1.SelectedRows.Count > 0 ? BaseForm.dataGridView1.SelectedRows[0].Index : (BaseForm.dataGridView1.SelectedCells.Count > 0 ? BaseForm.dataGridView1.SelectedCells[0].RowIndex : -1);
91 |
92 | // store previously expanded nodes; could take a second
93 | TraverseToPopulatePreviouslyExpandedNodes(previouslyExpandedNodes, BaseForm.treeView1.Nodes);
94 | });
95 |
96 | try
97 | {
98 | while (examiningNode != null)
99 | {
100 | if (cancelToken.IsCancellationRequested)
101 | {
102 | foundSomething = false; wasCanceled = true;
103 | MessageBox.Show("Operation canceled.");
104 | break;
105 | }
106 |
107 | UAGUtils.InvokeUI(() =>
108 | {
109 | // if dynamic tree, expand
110 | if (examiningNode is PointingTreeNode ptn)
111 | {
112 | if (!ptn.ChildrenInitialized)
113 | {
114 | BaseForm.tableEditor.FillOutSubnodes(ptn, false);
115 | }
116 | }
117 |
118 | BaseForm.treeView1.SelectedNode = examiningNode;
119 | BaseForm.UpdateModeFromSelectedNode(examiningNode);
120 |
121 | // check node name
122 | if (DoesTextQualify(examiningNode.Text) && examiningNode != originalNode)
123 | {
124 | foundSomething = true;
125 | return;
126 | }
127 |
128 | // check dgv
129 | if (BaseForm.dataGridView1 != null && BaseForm.dataGridView1.Enabled && BaseForm.dataGridView1.Visible && BaseForm.dataGridView1.Rows.Count > 0)
130 | {
131 | int rowNum = CurrentSearchDirection == SearchDirection.Forward ? 0 : BaseForm.dataGridView1.Rows.Count - 1;
132 | bool isSatisfied = false;
133 | while (!isSatisfied)
134 | {
135 | int oldRowNum = rowNum;
136 |
137 | rowNum += CurrentSearchDirection == SearchDirection.Forward ? 1 : -1;
138 | isSatisfied = CurrentSearchDirection == SearchDirection.Forward ? rowNum >= BaseForm.dataGridView1.Rows.Count : rowNum < 0;
139 |
140 | DataGridViewRow row = BaseForm.dataGridView1.Rows[oldRowNum];
141 | if (minRow >= 0 && CurrentSearchDirection == SearchDirection.Forward && oldRowNum <= minRow) continue;
142 | if (minRow >= 0 && CurrentSearchDirection == SearchDirection.Backward && oldRowNum >= minRow) continue;
143 |
144 | if (row == null || row.Cells == null) continue;
145 | foreach (DataGridViewCell cell in row.Cells)
146 | {
147 | if (cell == null || cell.Value == null) continue;
148 |
149 | if (DoesTextQualify(cell.Value.ToString()))
150 | {
151 | if (!cell.Displayed) BaseForm.dataGridView1.FirstDisplayedScrollingRowIndex = row.Index;
152 | BaseForm.treeView1.SelectedNode.EnsureVisible();
153 | row.Selected = true;
154 | cell.Selected = true;
155 | foundSomething = true;
156 | }
157 |
158 | if (foundSomething) return;
159 | }
160 |
161 | if (foundSomething) return;
162 | }
163 | }
164 |
165 | if (foundSomething) return;
166 | minRow = -1;
167 |
168 | if (progressBar1.Value < progressBar1.Maximum) progressBar1.Value++;
169 | examiningNode = UAGFindUtils.GetNextNode(examiningNode, CurrentSearchDirection, previouslyExpandedNodes, BaseForm.tableEditor);
170 | });
171 |
172 | if (foundSomething) break;
173 | }
174 | }
175 | finally
176 | {
177 | UAGUtils.InvokeUI(() =>
178 | {
179 | progressBar1.Value = progressBar1.Maximum;
180 | BaseForm.dataGridView1.ResumeLayout();
181 | BaseForm.treeView1.ResumeLayout();
182 | BaseForm.treeView1.EndUpdate();
183 |
184 | if (!foundSomething)
185 | {
186 | BaseForm.treeView1.SelectedNode = originalNode;
187 | BaseForm.UpdateModeFromSelectedNode(originalNode);
188 | if (!wasCanceled) MessageBox.Show("0 results found.");
189 | }
190 | });
191 | }
192 | }
193 |
194 | private readonly CancellationTokenSource ts = new CancellationTokenSource();
195 | private void nextButton_Click(object sender, EventArgs e)
196 | {
197 | SyncSettings();
198 | if (BaseForm.tableEditor == null || BaseForm.tableEditor.asset == null) return;
199 |
200 | Task.Run(() =>
201 | {
202 | PerformSearch(ts.Token);
203 | });
204 | }
205 | }
206 |
207 | public enum SearchDirection
208 | {
209 | Forward,
210 | Backward
211 | }
212 |
213 | public static class UAGFindUtils
214 | {
215 | public static TreeNode GetLastNode(TreeNode node, TableHandler handler)
216 | {
217 | // if dynamic tree, expand
218 | if (node is PointingTreeNode ptn)
219 | {
220 | if (!ptn.ChildrenInitialized)
221 | {
222 | handler.FillOutSubnodes(ptn, false);
223 | }
224 | }
225 |
226 | if (node.Nodes.Count == 0) return node;
227 | return GetLastNode(node.Nodes[node.Nodes.Count - 1], handler);
228 | }
229 |
230 | public static TreeNode GetNextNode(TreeNode node, SearchDirection dir, ISet previouslyExpandedNodes, TableHandler handler, bool canGoDown = true)
231 | {
232 | if (node == null) return null;
233 |
234 | if (dir == SearchDirection.Forward)
235 | {
236 | if (node.Nodes.Count != 0 && canGoDown) return node.Nodes[0]; // go down one
237 |
238 | // we don't need this node anymore
239 | if (previouslyExpandedNodes.Contains(node))
240 | {
241 | node.Expand();
242 | }
243 | else
244 | {
245 | node.Collapse();
246 | }
247 |
248 | if (node.NextNode != null) return node.NextNode; // go forward one
249 | return GetNextNode(node.Parent, dir, previouslyExpandedNodes, handler, false); // go up one
250 | }
251 | else if (dir == SearchDirection.Backward)
252 | {
253 | // we don't need this node anymore
254 | if (previouslyExpandedNodes.Contains(node))
255 | {
256 | node.Expand();
257 | }
258 | else
259 | {
260 | node.Collapse();
261 | }
262 |
263 | if (node.PrevNode != null && node.PrevNode.Nodes.Count != 0) return GetLastNode(node.PrevNode, handler); // go backwards one (to previous sibling's last descendant)
264 | if (node.PrevNode != null) return node.PrevNode; // go backwards one (to previous sibling directly)
265 | return node.Parent; // go up one (to parent)
266 | }
267 |
268 | return null;
269 | }
270 | }
271 | }
272 |
--------------------------------------------------------------------------------