├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── UnrealPakGUI.sln └── UnrealPakGUI ├── FormLogs.Designer.cs ├── FormLogs.cs ├── FormLogs.resx ├── Mainform.Designer.cs ├── Mainform.cs ├── Mainform.resx ├── PakBatch.cs ├── Program.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── UE4.ico ├── UnrealPakGUI.csproj └── app.config /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | bld/ 24 | [Bb]in/ 25 | [Oo]bj/ 26 | [Ll]og/ 27 | 28 | # Visual Studio 2015/2017 cache/options directory 29 | .vs/ 30 | # Uncomment if you have tasks that create the project's static files in wwwroot 31 | #wwwroot/ 32 | 33 | # Visual Studio 2017 auto generated files 34 | Generated\ Files/ 35 | 36 | # MSTest test Results 37 | [Tt]est[Rr]esult*/ 38 | [Bb]uild[Ll]og.* 39 | 40 | # NUNIT 41 | *.VisualState.xml 42 | TestResult.xml 43 | 44 | # Build Results of an ATL Project 45 | [Dd]ebugPS/ 46 | [Rr]eleasePS/ 47 | dlldata.c 48 | 49 | # Benchmark Results 50 | BenchmarkDotNet.Artifacts/ 51 | 52 | # .NET Core 53 | project.lock.json 54 | project.fragment.lock.json 55 | artifacts/ 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_h.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *_wpftmp.csproj 81 | *.log 82 | *.vspscc 83 | *.vssscc 84 | .builds 85 | *.pidb 86 | *.svclog 87 | *.scc 88 | 89 | # Chutzpah Test files 90 | _Chutzpah* 91 | 92 | # Visual C++ cache files 93 | ipch/ 94 | *.aps 95 | *.ncb 96 | *.opendb 97 | *.opensdf 98 | *.sdf 99 | *.cachefile 100 | *.VC.db 101 | *.VC.VC.opendb 102 | 103 | # Visual Studio profiler 104 | *.psess 105 | *.vsp 106 | *.vspx 107 | *.sap 108 | 109 | # Visual Studio Trace Files 110 | *.e2e 111 | 112 | # TFS 2012 Local Workspace 113 | $tf/ 114 | 115 | # Guidance Automation Toolkit 116 | *.gpState 117 | 118 | # ReSharper is a .NET coding add-in 119 | _ReSharper*/ 120 | *.[Rr]e[Ss]harper 121 | *.DotSettings.user 122 | 123 | # JustCode is a .NET coding add-in 124 | .JustCode 125 | 126 | # TeamCity is a build add-in 127 | _TeamCity* 128 | 129 | # DotCover is a Code Coverage Tool 130 | *.dotCover 131 | 132 | # AxoCover is a Code Coverage Tool 133 | .axoCover/* 134 | !.axoCover/settings.json 135 | 136 | # Visual Studio code coverage results 137 | *.coverage 138 | *.coveragexml 139 | 140 | # NCrunch 141 | _NCrunch_* 142 | .*crunch*.local.xml 143 | nCrunchTemp_* 144 | 145 | # MightyMoose 146 | *.mm.* 147 | AutoTest.Net/ 148 | 149 | # Web workbench (sass) 150 | .sass-cache/ 151 | 152 | # Installshield output folder 153 | [Ee]xpress/ 154 | 155 | # DocProject is a documentation generator add-in 156 | DocProject/buildhelp/ 157 | DocProject/Help/*.HxT 158 | DocProject/Help/*.HxC 159 | DocProject/Help/*.hhc 160 | DocProject/Help/*.hhk 161 | DocProject/Help/*.hhp 162 | DocProject/Help/Html2 163 | DocProject/Help/html 164 | 165 | # Click-Once directory 166 | publish/ 167 | 168 | # Publish Web Output 169 | *.[Pp]ublish.xml 170 | *.azurePubxml 171 | # Note: Comment the next line if you want to checkin your web deploy settings, 172 | # but database connection strings (with potential passwords) will be unencrypted 173 | *.pubxml 174 | *.publishproj 175 | 176 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 177 | # checkin your Azure Web App publish settings, but sensitive information contained 178 | # in these scripts will be unencrypted 179 | PublishScripts/ 180 | 181 | # NuGet Packages 182 | *.nupkg 183 | # The packages folder can be ignored because of Package Restore 184 | **/[Pp]ackages/* 185 | # except build/, which is used as an MSBuild target. 186 | !**/[Pp]ackages/build/ 187 | # Uncomment if necessary however generally it will be regenerated when needed 188 | #!**/[Pp]ackages/repositories.config 189 | # NuGet v3's project.json files produces more ignorable files 190 | *.nuget.props 191 | *.nuget.targets 192 | 193 | # Microsoft Azure Build Output 194 | csx/ 195 | *.build.csdef 196 | 197 | # Microsoft Azure Emulator 198 | ecf/ 199 | rcf/ 200 | 201 | # Windows Store app package directories and files 202 | AppPackages/ 203 | BundleArtifacts/ 204 | Package.StoreAssociation.xml 205 | _pkginfo.txt 206 | *.appx 207 | 208 | # Visual Studio cache files 209 | # files ending in .cache can be ignored 210 | *.[Cc]ache 211 | # but keep track of directories ending in .cache 212 | !*.[Cc]ache/ 213 | 214 | # Others 215 | ClientBin/ 216 | ~$* 217 | *~ 218 | *.dbmdl 219 | *.dbproj.schemaview 220 | *.jfm 221 | *.pfx 222 | *.publishsettings 223 | orleans.codegen.cs 224 | 225 | # Including strong name files can present a security risk 226 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 227 | #*.snk 228 | 229 | # Since there are multiple workflows, uncomment next line to ignore bower_components 230 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 231 | #bower_components/ 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | ServiceFabricBackup/ 244 | *.rptproj.bak 245 | 246 | # SQL Server files 247 | *.mdf 248 | *.ldf 249 | *.ndf 250 | 251 | # Business Intelligence projects 252 | *.rdl.data 253 | *.bim.layout 254 | *.bim_*.settings 255 | *.rptproj.rsuser 256 | 257 | # Microsoft Fakes 258 | FakesAssemblies/ 259 | 260 | # GhostDoc plugin setting file 261 | *.GhostDoc.xml 262 | 263 | # Node.js Tools for Visual Studio 264 | .ntvs_analysis.dat 265 | node_modules/ 266 | 267 | # Visual Studio 6 build log 268 | *.plg 269 | 270 | # Visual Studio 6 workspace options file 271 | *.opt 272 | 273 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 274 | *.vbw 275 | 276 | # Visual Studio LightSwitch build output 277 | **/*.HTMLClient/GeneratedArtifacts 278 | **/*.DesktopClient/GeneratedArtifacts 279 | **/*.DesktopClient/ModelManifest.xml 280 | **/*.Server/GeneratedArtifacts 281 | **/*.Server/ModelManifest.xml 282 | _Pvt_Extensions 283 | 284 | # Paket dependency manager 285 | .paket/paket.exe 286 | paket-files/ 287 | 288 | # FAKE - F# Make 289 | .fake/ 290 | 291 | # JetBrains Rider 292 | .idea/ 293 | *.sln.iml 294 | 295 | # CodeRush personal settings 296 | .cr/personal 297 | 298 | # Python Tools for Visual Studio (PTVS) 299 | __pycache__/ 300 | *.pyc 301 | 302 | # Cake - Uncomment if you are using it 303 | # tools/** 304 | # !tools/packages.config 305 | 306 | # Tabs Studio 307 | *.tss 308 | 309 | # Telerik's JustMock configuration file 310 | *.jmconfig 311 | 312 | # BizTalk build output 313 | *.btp.cs 314 | *.btm.cs 315 | *.odx.cs 316 | *.xsd.cs 317 | 318 | # OpenCover UI analysis results 319 | OpenCover/ 320 | 321 | # Azure Stream Analytics local run output 322 | ASALocalRun/ 323 | 324 | # MSBuild Binary and Structured Log 325 | *.binlog 326 | 327 | # NVidia Nsight GPU debugger configuration file 328 | *.nvuser 329 | 330 | # MFractors (Xamarin productivity tool) working folder 331 | .mfractor/ 332 | 333 | # Local History for Visual Studio 334 | .localhistory/ 335 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Tianyu Shao 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnrealPakGUI 2 | 3 | The intended usage of this tool is for unreal developers to create patches and add-on content cocked with the editor. The List & Extract feature is just for validating packed files, not for the purpose of unpacking & repacking or modding. 4 | 5 | ## Usage 6 | 7 | ### Files and Directories 8 | 9 | #### Engine Dir 10 | 11 | This is for finding the UnrealPak.exe executable. It's the path containing unreal's Engine folder, i.e. D:/UnrealEngine/UE_4.26. Alternatively you can copy your UnrealPak.exe to the folder where UnrealPakGUI.exe is and leave this field empty. 12 | 13 | #### Crypto File 14 | 15 | This is for encrypting/decrypting your pak file. If encryption is not necessary, leave it empty. This file can be found in the Saved folder under your unreal project directory after having packed your project at least once in editor with a crypto key. 16 | 17 | #### UProject File 18 | 19 | Self-explanatory. This is for getting the project name. Required for the Content Files Only option; 20 | 21 | ### Options 22 | 23 | #### Content Files Only 24 | 25 | If checked, only files under "Content" and its subfolders are packed, so the pak mount point will be set to ../../../\/Content/*. Otherwise mount point is set to the common root directory of the input files. This is intend for the usage where you want to pack cooked assets in the Saved/Cooked/WindowsNoEditor/\/Content folder with a valid mount point. 26 | 27 | #### Compression 28 | 29 | Self-explanatory. Check this if you want to compress your pak file. 30 | 31 | #### Encryption 32 | 33 | Self-explanatory. Requires a valid Crypto.json file. 34 | 35 | ### Modes 36 | 37 | #### Single Pak 38 | 39 | Create a single pak file from the list. Add files/folders by dragging them onto the list. Remove files/folders by selecting them and click Remove or Clear the list by clicking Remove All. Click Create Pak to start packing. 40 | 41 | #### Batch Mode 42 | 43 | Batch creating pak files to the Output Dir. 44 | 45 | Option As Patch - If checked, a suffix _p will be added to each created pak file. Pak files with the _p suffix are considered patches by unreal engine. Contents in a patch pak file will override those in the original game pak file. 46 | 47 | Option Folder Pak - This is an ease-of-use option. The default behavior of drag & drop is creating a pak file for each drag & drop operation. If this option is checked, a pak file will be created for each folder in a single drag & drop operation. 48 | 49 | #### List & Extract 50 | 51 | List pak contents by drag & drop pak file onto the list. Optionally extract its content to the Extract To directory. If the pak file is encrypted, then the option Encryption should be checked and a valid Crypto.json file must be provided. 52 | -------------------------------------------------------------------------------- /UnrealPakGUI.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28307.572 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnrealPakGUI", "UnrealPakGUI\UnrealPakGUI.csproj", "{7429BFF7-B83B-4006-BD89-E91AF9A64378}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {7429BFF7-B83B-4006-BD89-E91AF9A64378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {7429BFF7-B83B-4006-BD89-E91AF9A64378}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {7429BFF7-B83B-4006-BD89-E91AF9A64378}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {7429BFF7-B83B-4006-BD89-E91AF9A64378}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2D5CA55E-AF53-43CD-B6ED-1D8407267E52} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /UnrealPakGUI/FormLogs.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace UnrealPakGUI 2 | { 3 | partial class FormLogs 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.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormLogs)); 32 | this.TB_Logs = new System.Windows.Forms.TextBox(); 33 | this.fileSystemWatcher1 = new System.IO.FileSystemWatcher(); 34 | this.BTN_ClearLogs = new System.Windows.Forms.Button(); 35 | ((System.ComponentModel.ISupportInitialize)(this.fileSystemWatcher1)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // TB_Logs 39 | // 40 | this.TB_Logs.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 41 | | System.Windows.Forms.AnchorStyles.Left) 42 | | System.Windows.Forms.AnchorStyles.Right))); 43 | this.TB_Logs.Location = new System.Drawing.Point(12, 12); 44 | this.TB_Logs.Multiline = true; 45 | this.TB_Logs.Name = "TB_Logs"; 46 | this.TB_Logs.ReadOnly = true; 47 | this.TB_Logs.ScrollBars = System.Windows.Forms.ScrollBars.Both; 48 | this.TB_Logs.Size = new System.Drawing.Size(733, 473); 49 | this.TB_Logs.TabIndex = 9; 50 | // 51 | // fileSystemWatcher1 52 | // 53 | this.fileSystemWatcher1.EnableRaisingEvents = true; 54 | this.fileSystemWatcher1.SynchronizingObject = this; 55 | // 56 | // BTN_ClearLogs 57 | // 58 | this.BTN_ClearLogs.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 59 | this.BTN_ClearLogs.Location = new System.Drawing.Point(670, 491); 60 | this.BTN_ClearLogs.Name = "BTN_ClearLogs"; 61 | this.BTN_ClearLogs.Size = new System.Drawing.Size(75, 23); 62 | this.BTN_ClearLogs.TabIndex = 10; 63 | this.BTN_ClearLogs.Text = "Clear Logs"; 64 | this.BTN_ClearLogs.UseVisualStyleBackColor = true; 65 | this.BTN_ClearLogs.Click += new System.EventHandler(this.BTN_ClearLogs_Click); 66 | // 67 | // FormLogs 68 | // 69 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 70 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 71 | this.ClientSize = new System.Drawing.Size(757, 526); 72 | this.Controls.Add(this.BTN_ClearLogs); 73 | this.Controls.Add(this.TB_Logs); 74 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; 75 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 76 | this.Name = "FormLogs"; 77 | this.ShowInTaskbar = false; 78 | this.Text = "Logs"; 79 | this.TopMost = true; 80 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormLogs_FormClosing); 81 | ((System.ComponentModel.ISupportInitialize)(this.fileSystemWatcher1)).EndInit(); 82 | this.ResumeLayout(false); 83 | this.PerformLayout(); 84 | 85 | } 86 | 87 | #endregion 88 | 89 | private System.Windows.Forms.TextBox TB_Logs; 90 | private System.IO.FileSystemWatcher fileSystemWatcher1; 91 | private System.Windows.Forms.Button BTN_ClearLogs; 92 | } 93 | } -------------------------------------------------------------------------------- /UnrealPakGUI/FormLogs.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.Windows.Forms; 9 | 10 | namespace UnrealPakGUI 11 | { 12 | public partial class FormLogs : Form 13 | { 14 | public FormLogs() 15 | { 16 | InitializeComponent(); 17 | } 18 | 19 | public void ShowLog(string Line) 20 | { 21 | TB_Logs.AppendText(Line + "\r\n"); 22 | } 23 | 24 | public void ClearLog() 25 | { 26 | TB_Logs.Clear(); 27 | } 28 | 29 | private void FormLogs_FormClosing(object sender, FormClosingEventArgs e) 30 | { 31 | this.Hide(); 32 | e.Cancel = true; 33 | } 34 | 35 | private void BTN_ClearLogs_Click(object sender, EventArgs e) 36 | { 37 | ClearLog(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /UnrealPakGUI/Mainform.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace UnrealPakGUI 2 | { 3 | partial class MainForm 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 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); 33 | this.BTN_BrowseEngineDir = new System.Windows.Forms.Button(); 34 | this.label1 = new System.Windows.Forms.Label(); 35 | this.BTN_BrowseCryptoFile = new System.Windows.Forms.Button(); 36 | this.label2 = new System.Windows.Forms.Label(); 37 | this.OFD_BrowseCryptoFile = new System.Windows.Forms.OpenFileDialog(); 38 | this.FBD_BrowseDir = new System.Windows.Forms.FolderBrowserDialog(); 39 | this.OFD_BrowseOutputFile = new System.Windows.Forms.OpenFileDialog(); 40 | this.LB_FilesToPak = new System.Windows.Forms.ListBox(); 41 | this.label4 = new System.Windows.Forms.Label(); 42 | this.BTN_BrowseProjectFile = new System.Windows.Forms.Button(); 43 | this.OFD_BrowseProjectFile = new System.Windows.Forms.OpenFileDialog(); 44 | this.BTN_RemoveItems = new System.Windows.Forms.Button(); 45 | this.BTN_CreatePak = new System.Windows.Forms.Button(); 46 | this.OFD_AddFiles = new System.Windows.Forms.OpenFileDialog(); 47 | this.BTN_RemoveAll = new System.Windows.Forms.Button(); 48 | this.tabControl1 = new System.Windows.Forms.TabControl(); 49 | this.tabPage1 = new System.Windows.Forms.TabPage(); 50 | this.tabPage2 = new System.Windows.Forms.TabPage(); 51 | this.TV_BatchFiles = new System.Windows.Forms.TreeView(); 52 | this.BTN_BatchRemove = new System.Windows.Forms.Button(); 53 | this.BTN_BatchCreatePaks = new System.Windows.Forms.Button(); 54 | this.BTN_BatchRemoveAll = new System.Windows.Forms.Button(); 55 | this.BTN_BrowseBatchOutputDir = new System.Windows.Forms.Button(); 56 | this.label3 = new System.Windows.Forms.Label(); 57 | this.CKB_FolderPak = new System.Windows.Forms.CheckBox(); 58 | this.CKB_AsPatch = new System.Windows.Forms.CheckBox(); 59 | this.TB_BatchOutputDir = new System.Windows.Forms.TextBox(); 60 | this.tabPage3 = new System.Windows.Forms.TabPage(); 61 | this.label6 = new System.Windows.Forms.Label(); 62 | this.BTN_Extract = new System.Windows.Forms.Button(); 63 | this.BTN_BrowseExtractToDir = new System.Windows.Forms.Button(); 64 | this.label5 = new System.Windows.Forms.Label(); 65 | this.TB_ExtractToDir = new System.Windows.Forms.TextBox(); 66 | this.TV_ListPak = new System.Windows.Forms.TreeView(); 67 | this.TT_ToolTip = new System.Windows.Forms.ToolTip(this.components); 68 | this.CKB_ContentOnly = new System.Windows.Forms.CheckBox(); 69 | this.CKB_Encryption = new System.Windows.Forms.CheckBox(); 70 | this.TB_ProjectFile = new System.Windows.Forms.TextBox(); 71 | this.TB_CryptoFile = new System.Windows.Forms.TextBox(); 72 | this.TB_EngineDir = new System.Windows.Forms.TextBox(); 73 | this.CKB_Compression = new System.Windows.Forms.CheckBox(); 74 | this.statusStrip1 = new System.Windows.Forms.StatusStrip(); 75 | this.BTN_Logs = new System.Windows.Forms.ToolStripDropDownButton(); 76 | this.tabControl1.SuspendLayout(); 77 | this.tabPage1.SuspendLayout(); 78 | this.tabPage2.SuspendLayout(); 79 | this.tabPage3.SuspendLayout(); 80 | this.statusStrip1.SuspendLayout(); 81 | this.SuspendLayout(); 82 | // 83 | // BTN_BrowseEngineDir 84 | // 85 | this.BTN_BrowseEngineDir.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 86 | this.BTN_BrowseEngineDir.Location = new System.Drawing.Point(734, 10); 87 | this.BTN_BrowseEngineDir.Name = "BTN_BrowseEngineDir"; 88 | this.BTN_BrowseEngineDir.Size = new System.Drawing.Size(32, 23); 89 | this.BTN_BrowseEngineDir.TabIndex = 1; 90 | this.BTN_BrowseEngineDir.Text = "..."; 91 | this.TT_ToolTip.SetToolTip(this.BTN_BrowseEngineDir, "Browse Engine Directory"); 92 | this.BTN_BrowseEngineDir.UseVisualStyleBackColor = true; 93 | this.BTN_BrowseEngineDir.Click += new System.EventHandler(this.BTN_BrowseEngineDir_Click); 94 | // 95 | // label1 96 | // 97 | this.label1.AutoSize = true; 98 | this.label1.Location = new System.Drawing.Point(13, 15); 99 | this.label1.Name = "label1"; 100 | this.label1.Size = new System.Drawing.Size(65, 12); 101 | this.label1.TabIndex = 3; 102 | this.label1.Text = "Engine Dir"; 103 | // 104 | // BTN_BrowseCryptoFile 105 | // 106 | this.BTN_BrowseCryptoFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 107 | this.BTN_BrowseCryptoFile.Location = new System.Drawing.Point(734, 38); 108 | this.BTN_BrowseCryptoFile.Name = "BTN_BrowseCryptoFile"; 109 | this.BTN_BrowseCryptoFile.Size = new System.Drawing.Size(32, 23); 110 | this.BTN_BrowseCryptoFile.TabIndex = 3; 111 | this.BTN_BrowseCryptoFile.Text = "..."; 112 | this.TT_ToolTip.SetToolTip(this.BTN_BrowseCryptoFile, "Browse Crypto file"); 113 | this.BTN_BrowseCryptoFile.UseVisualStyleBackColor = true; 114 | this.BTN_BrowseCryptoFile.Click += new System.EventHandler(this.BTN_BrowseCryptoFile_Click); 115 | // 116 | // label2 117 | // 118 | this.label2.AutoSize = true; 119 | this.label2.Location = new System.Drawing.Point(13, 43); 120 | this.label2.Name = "label2"; 121 | this.label2.Size = new System.Drawing.Size(71, 12); 122 | this.label2.TabIndex = 3; 123 | this.label2.Text = "Crypto File"; 124 | // 125 | // OFD_BrowseCryptoFile 126 | // 127 | this.OFD_BrowseCryptoFile.DefaultExt = "json"; 128 | this.OFD_BrowseCryptoFile.Filter = "Crypto Files|*.json"; 129 | // 130 | // OFD_BrowseOutputFile 131 | // 132 | this.OFD_BrowseOutputFile.CheckFileExists = false; 133 | this.OFD_BrowseOutputFile.DefaultExt = "pak"; 134 | this.OFD_BrowseOutputFile.Filter = "Unreal Pak Files|*.pak"; 135 | // 136 | // LB_FilesToPak 137 | // 138 | this.LB_FilesToPak.AllowDrop = true; 139 | this.LB_FilesToPak.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 140 | | System.Windows.Forms.AnchorStyles.Left) 141 | | System.Windows.Forms.AnchorStyles.Right))); 142 | this.LB_FilesToPak.FormattingEnabled = true; 143 | this.LB_FilesToPak.ItemHeight = 12; 144 | this.LB_FilesToPak.Location = new System.Drawing.Point(6, 6); 145 | this.LB_FilesToPak.Name = "LB_FilesToPak"; 146 | this.LB_FilesToPak.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended; 147 | this.LB_FilesToPak.Size = new System.Drawing.Size(629, 412); 148 | this.LB_FilesToPak.TabIndex = 0; 149 | this.TT_ToolTip.SetToolTip(this.LB_FilesToPak, "Pack files into a single pak file. Drag files here."); 150 | this.LB_FilesToPak.DragDrop += new System.Windows.Forms.DragEventHandler(this.LB_FilesToPak_DragDrop); 151 | this.LB_FilesToPak.DragEnter += new System.Windows.Forms.DragEventHandler(this.LB_FilesToPak_DragEnter); 152 | this.LB_FilesToPak.DragOver += new System.Windows.Forms.DragEventHandler(this.LB_FilesToPak_DragEnter); 153 | // 154 | // label4 155 | // 156 | this.label4.AutoSize = true; 157 | this.label4.Location = new System.Drawing.Point(13, 71); 158 | this.label4.Name = "label4"; 159 | this.label4.Size = new System.Drawing.Size(83, 12); 160 | this.label4.TabIndex = 3; 161 | this.label4.Text = "UProject File"; 162 | // 163 | // BTN_BrowseProjectFile 164 | // 165 | this.BTN_BrowseProjectFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 166 | this.BTN_BrowseProjectFile.Location = new System.Drawing.Point(734, 66); 167 | this.BTN_BrowseProjectFile.Name = "BTN_BrowseProjectFile"; 168 | this.BTN_BrowseProjectFile.Size = new System.Drawing.Size(32, 23); 169 | this.BTN_BrowseProjectFile.TabIndex = 5; 170 | this.BTN_BrowseProjectFile.Text = "..."; 171 | this.TT_ToolTip.SetToolTip(this.BTN_BrowseProjectFile, "Browse UProject file"); 172 | this.BTN_BrowseProjectFile.UseVisualStyleBackColor = true; 173 | this.BTN_BrowseProjectFile.Click += new System.EventHandler(this.BTN_BrowseProjectFile_Click); 174 | // 175 | // OFD_BrowseProjectFile 176 | // 177 | this.OFD_BrowseProjectFile.DefaultExt = "uproject"; 178 | this.OFD_BrowseProjectFile.Filter = "Unreal Project File|*.uproject"; 179 | // 180 | // BTN_RemoveItems 181 | // 182 | this.BTN_RemoveItems.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 183 | this.BTN_RemoveItems.Location = new System.Drawing.Point(644, 315); 184 | this.BTN_RemoveItems.Name = "BTN_RemoveItems"; 185 | this.BTN_RemoveItems.Size = new System.Drawing.Size(90, 30); 186 | this.BTN_RemoveItems.TabIndex = 1; 187 | this.BTN_RemoveItems.Text = "Remove"; 188 | this.TT_ToolTip.SetToolTip(this.BTN_RemoveItems, "Remove selected files."); 189 | this.BTN_RemoveItems.UseVisualStyleBackColor = true; 190 | this.BTN_RemoveItems.Click += new System.EventHandler(this.BTN_RemoveItems_Click); 191 | // 192 | // BTN_CreatePak 193 | // 194 | this.BTN_CreatePak.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 195 | this.BTN_CreatePak.Location = new System.Drawing.Point(644, 395); 196 | this.BTN_CreatePak.Name = "BTN_CreatePak"; 197 | this.BTN_CreatePak.Size = new System.Drawing.Size(90, 30); 198 | this.BTN_CreatePak.TabIndex = 3; 199 | this.BTN_CreatePak.Text = "Create Pak"; 200 | this.TT_ToolTip.SetToolTip(this.BTN_CreatePak, "Start packing!"); 201 | this.BTN_CreatePak.UseVisualStyleBackColor = true; 202 | this.BTN_CreatePak.Click += new System.EventHandler(this.BTN_CreatePak_Click); 203 | // 204 | // OFD_AddFiles 205 | // 206 | this.OFD_AddFiles.Multiselect = true; 207 | // 208 | // BTN_RemoveAll 209 | // 210 | this.BTN_RemoveAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 211 | this.BTN_RemoveAll.Location = new System.Drawing.Point(644, 355); 212 | this.BTN_RemoveAll.Name = "BTN_RemoveAll"; 213 | this.BTN_RemoveAll.Size = new System.Drawing.Size(90, 30); 214 | this.BTN_RemoveAll.TabIndex = 2; 215 | this.BTN_RemoveAll.Text = "Remove All"; 216 | this.TT_ToolTip.SetToolTip(this.BTN_RemoveAll, "Remove all files."); 217 | this.BTN_RemoveAll.UseVisualStyleBackColor = true; 218 | this.BTN_RemoveAll.Click += new System.EventHandler(this.BTN_RemoveAll_Click); 219 | // 220 | // tabControl1 221 | // 222 | this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 223 | | System.Windows.Forms.AnchorStyles.Left) 224 | | System.Windows.Forms.AnchorStyles.Right))); 225 | this.tabControl1.Controls.Add(this.tabPage1); 226 | this.tabControl1.Controls.Add(this.tabPage2); 227 | this.tabControl1.Controls.Add(this.tabPage3); 228 | this.tabControl1.Location = new System.Drawing.Point(12, 100); 229 | this.tabControl1.Name = "tabControl1"; 230 | this.tabControl1.SelectedIndex = 0; 231 | this.tabControl1.Size = new System.Drawing.Size(754, 459); 232 | this.tabControl1.TabIndex = 8; 233 | // 234 | // tabPage1 235 | // 236 | this.tabPage1.Controls.Add(this.LB_FilesToPak); 237 | this.tabPage1.Controls.Add(this.BTN_RemoveItems); 238 | this.tabPage1.Controls.Add(this.BTN_CreatePak); 239 | this.tabPage1.Controls.Add(this.BTN_RemoveAll); 240 | this.tabPage1.Location = new System.Drawing.Point(4, 22); 241 | this.tabPage1.Name = "tabPage1"; 242 | this.tabPage1.Padding = new System.Windows.Forms.Padding(3); 243 | this.tabPage1.Size = new System.Drawing.Size(746, 433); 244 | this.tabPage1.TabIndex = 0; 245 | this.tabPage1.Text = "Single Pak"; 246 | this.tabPage1.UseVisualStyleBackColor = true; 247 | // 248 | // tabPage2 249 | // 250 | this.tabPage2.Controls.Add(this.TV_BatchFiles); 251 | this.tabPage2.Controls.Add(this.BTN_BatchRemove); 252 | this.tabPage2.Controls.Add(this.BTN_BatchCreatePaks); 253 | this.tabPage2.Controls.Add(this.BTN_BatchRemoveAll); 254 | this.tabPage2.Controls.Add(this.BTN_BrowseBatchOutputDir); 255 | this.tabPage2.Controls.Add(this.label3); 256 | this.tabPage2.Controls.Add(this.CKB_FolderPak); 257 | this.tabPage2.Controls.Add(this.CKB_AsPatch); 258 | this.tabPage2.Controls.Add(this.TB_BatchOutputDir); 259 | this.tabPage2.Location = new System.Drawing.Point(4, 22); 260 | this.tabPage2.Name = "tabPage2"; 261 | this.tabPage2.Padding = new System.Windows.Forms.Padding(3); 262 | this.tabPage2.Size = new System.Drawing.Size(746, 433); 263 | this.tabPage2.TabIndex = 1; 264 | this.tabPage2.Text = "Batch Mode"; 265 | this.tabPage2.UseVisualStyleBackColor = true; 266 | // 267 | // TV_BatchFiles 268 | // 269 | this.TV_BatchFiles.AllowDrop = true; 270 | this.TV_BatchFiles.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 271 | | System.Windows.Forms.AnchorStyles.Left) 272 | | System.Windows.Forms.AnchorStyles.Right))); 273 | this.TV_BatchFiles.Location = new System.Drawing.Point(6, 33); 274 | this.TV_BatchFiles.Name = "TV_BatchFiles"; 275 | this.TV_BatchFiles.Size = new System.Drawing.Size(629, 394); 276 | this.TV_BatchFiles.TabIndex = 14; 277 | this.TT_ToolTip.SetToolTip(this.TV_BatchFiles, "Pack each batch into individual pak files. Drag files here."); 278 | this.TV_BatchFiles.DragDrop += new System.Windows.Forms.DragEventHandler(this.TV_BatchFiles_DragDrop); 279 | this.TV_BatchFiles.DragEnter += new System.Windows.Forms.DragEventHandler(this.TV_BatchFiles_DragEnter); 280 | this.TV_BatchFiles.DragOver += new System.Windows.Forms.DragEventHandler(this.TV_BatchFiles_DragEnter); 281 | // 282 | // BTN_BatchRemove 283 | // 284 | this.BTN_BatchRemove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 285 | this.BTN_BatchRemove.Location = new System.Drawing.Point(644, 317); 286 | this.BTN_BatchRemove.Name = "BTN_BatchRemove"; 287 | this.BTN_BatchRemove.Size = new System.Drawing.Size(90, 30); 288 | this.BTN_BatchRemove.TabIndex = 15; 289 | this.BTN_BatchRemove.Text = "Remove"; 290 | this.TT_ToolTip.SetToolTip(this.BTN_BatchRemove, "Remove selected files."); 291 | this.BTN_BatchRemove.UseVisualStyleBackColor = true; 292 | this.BTN_BatchRemove.Click += new System.EventHandler(this.BTN_BatchRemove_Click); 293 | // 294 | // BTN_BatchCreatePaks 295 | // 296 | this.BTN_BatchCreatePaks.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 297 | this.BTN_BatchCreatePaks.Location = new System.Drawing.Point(644, 397); 298 | this.BTN_BatchCreatePaks.Name = "BTN_BatchCreatePaks"; 299 | this.BTN_BatchCreatePaks.Size = new System.Drawing.Size(90, 30); 300 | this.BTN_BatchCreatePaks.TabIndex = 17; 301 | this.BTN_BatchCreatePaks.Text = "Create Paks"; 302 | this.TT_ToolTip.SetToolTip(this.BTN_BatchCreatePaks, "Start batch packing!"); 303 | this.BTN_BatchCreatePaks.UseVisualStyleBackColor = true; 304 | this.BTN_BatchCreatePaks.Click += new System.EventHandler(this.BTN_BatchCreatePaks_Click); 305 | // 306 | // BTN_BatchRemoveAll 307 | // 308 | this.BTN_BatchRemoveAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 309 | this.BTN_BatchRemoveAll.Location = new System.Drawing.Point(644, 357); 310 | this.BTN_BatchRemoveAll.Name = "BTN_BatchRemoveAll"; 311 | this.BTN_BatchRemoveAll.Size = new System.Drawing.Size(90, 30); 312 | this.BTN_BatchRemoveAll.TabIndex = 16; 313 | this.BTN_BatchRemoveAll.Text = "Remove All"; 314 | this.TT_ToolTip.SetToolTip(this.BTN_BatchRemoveAll, "Remove all files."); 315 | this.BTN_BatchRemoveAll.UseVisualStyleBackColor = true; 316 | this.BTN_BatchRemoveAll.Click += new System.EventHandler(this.BTN_BatchRemoveAll_Click); 317 | // 318 | // BTN_BrowseBatchOutputDir 319 | // 320 | this.BTN_BrowseBatchOutputDir.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 321 | this.BTN_BrowseBatchOutputDir.Location = new System.Drawing.Point(708, 6); 322 | this.BTN_BrowseBatchOutputDir.Name = "BTN_BrowseBatchOutputDir"; 323 | this.BTN_BrowseBatchOutputDir.Size = new System.Drawing.Size(32, 23); 324 | this.BTN_BrowseBatchOutputDir.TabIndex = 13; 325 | this.BTN_BrowseBatchOutputDir.Text = "..."; 326 | this.TT_ToolTip.SetToolTip(this.BTN_BrowseBatchOutputDir, "Browse output directory."); 327 | this.BTN_BrowseBatchOutputDir.UseVisualStyleBackColor = true; 328 | this.BTN_BrowseBatchOutputDir.Click += new System.EventHandler(this.BTN_BrowseBatchOutputDir_Click); 329 | // 330 | // label3 331 | // 332 | this.label3.AutoSize = true; 333 | this.label3.Location = new System.Drawing.Point(6, 10); 334 | this.label3.Name = "label3"; 335 | this.label3.Size = new System.Drawing.Size(65, 12); 336 | this.label3.TabIndex = 3; 337 | this.label3.Text = "Output Dir"; 338 | // 339 | // CKB_FolderPak 340 | // 341 | this.CKB_FolderPak.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 342 | this.CKB_FolderPak.AutoSize = true; 343 | this.CKB_FolderPak.Checked = global::UnrealPakGUI.Properties.Settings.Default.bFolderPak; 344 | this.CKB_FolderPak.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::UnrealPakGUI.Properties.Settings.Default, "bFolderPak", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 345 | this.CKB_FolderPak.Location = new System.Drawing.Point(645, 70); 346 | this.CKB_FolderPak.Name = "CKB_FolderPak"; 347 | this.CKB_FolderPak.Size = new System.Drawing.Size(84, 16); 348 | this.CKB_FolderPak.TabIndex = 19; 349 | this.CKB_FolderPak.Text = "Folder Pak"; 350 | this.TT_ToolTip.SetToolTip(this.CKB_FolderPak, "When drag-n-drop, each folder gets packed into its own pak."); 351 | this.CKB_FolderPak.UseVisualStyleBackColor = true; 352 | this.CKB_FolderPak.CheckedChanged += new System.EventHandler(this.CKB_FolderPak_CheckedChanged); 353 | // 354 | // CKB_AsPatch 355 | // 356 | this.CKB_AsPatch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 357 | this.CKB_AsPatch.AutoSize = true; 358 | this.CKB_AsPatch.Checked = global::UnrealPakGUI.Properties.Settings.Default.bAsPatch; 359 | this.CKB_AsPatch.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::UnrealPakGUI.Properties.Settings.Default, "bAsPatch", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 360 | this.CKB_AsPatch.Location = new System.Drawing.Point(645, 46); 361 | this.CKB_AsPatch.Name = "CKB_AsPatch"; 362 | this.CKB_AsPatch.Size = new System.Drawing.Size(72, 16); 363 | this.CKB_AsPatch.TabIndex = 18; 364 | this.CKB_AsPatch.Text = "As Patch"; 365 | this.TT_ToolTip.SetToolTip(this.CKB_AsPatch, "Append \"_p\" to pak filename."); 366 | this.CKB_AsPatch.UseVisualStyleBackColor = true; 367 | this.CKB_AsPatch.CheckedChanged += new System.EventHandler(this.CKB_AsPatch_CheckedChanged); 368 | // 369 | // TB_BatchOutputDir 370 | // 371 | this.TB_BatchOutputDir.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 372 | | System.Windows.Forms.AnchorStyles.Right))); 373 | this.TB_BatchOutputDir.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::UnrealPakGUI.Properties.Settings.Default, "BatchOutputDir", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 374 | this.TB_BatchOutputDir.Location = new System.Drawing.Point(77, 7); 375 | this.TB_BatchOutputDir.Name = "TB_BatchOutputDir"; 376 | this.TB_BatchOutputDir.ReadOnly = true; 377 | this.TB_BatchOutputDir.Size = new System.Drawing.Size(625, 21); 378 | this.TB_BatchOutputDir.TabIndex = 12; 379 | this.TB_BatchOutputDir.Text = global::UnrealPakGUI.Properties.Settings.Default.BatchOutputDir; 380 | this.TT_ToolTip.SetToolTip(this.TB_BatchOutputDir, "Directory to save pak files."); 381 | // 382 | // tabPage3 383 | // 384 | this.tabPage3.Controls.Add(this.label6); 385 | this.tabPage3.Controls.Add(this.BTN_Extract); 386 | this.tabPage3.Controls.Add(this.BTN_BrowseExtractToDir); 387 | this.tabPage3.Controls.Add(this.label5); 388 | this.tabPage3.Controls.Add(this.TB_ExtractToDir); 389 | this.tabPage3.Controls.Add(this.TV_ListPak); 390 | this.tabPage3.Location = new System.Drawing.Point(4, 22); 391 | this.tabPage3.Name = "tabPage3"; 392 | this.tabPage3.Padding = new System.Windows.Forms.Padding(3); 393 | this.tabPage3.Size = new System.Drawing.Size(746, 433); 394 | this.tabPage3.TabIndex = 2; 395 | this.tabPage3.Text = "List & Extract"; 396 | this.tabPage3.UseVisualStyleBackColor = true; 397 | // 398 | // label6 399 | // 400 | this.label6.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 401 | | System.Windows.Forms.AnchorStyles.Right))); 402 | this.label6.AutoSize = true; 403 | this.label6.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Bold); 404 | this.label6.Location = new System.Drawing.Point(641, 33); 405 | this.label6.Name = "label6"; 406 | this.label6.Size = new System.Drawing.Size(96, 24); 407 | this.label6.TabIndex = 19; 408 | this.label6.Text = "Drag pak file\r\n👈 HERE"; 409 | // 410 | // BTN_Extract 411 | // 412 | this.BTN_Extract.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 413 | this.BTN_Extract.Location = new System.Drawing.Point(644, 397); 414 | this.BTN_Extract.Name = "BTN_Extract"; 415 | this.BTN_Extract.Size = new System.Drawing.Size(90, 30); 416 | this.BTN_Extract.TabIndex = 18; 417 | this.BTN_Extract.Text = "Extract"; 418 | this.TT_ToolTip.SetToolTip(this.BTN_Extract, "Start extracting!"); 419 | this.BTN_Extract.UseVisualStyleBackColor = true; 420 | this.BTN_Extract.Click += new System.EventHandler(this.BTN_Extract_Click); 421 | // 422 | // BTN_BrowseExtractToDir 423 | // 424 | this.BTN_BrowseExtractToDir.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 425 | this.BTN_BrowseExtractToDir.Location = new System.Drawing.Point(708, 6); 426 | this.BTN_BrowseExtractToDir.Name = "BTN_BrowseExtractToDir"; 427 | this.BTN_BrowseExtractToDir.Size = new System.Drawing.Size(32, 23); 428 | this.BTN_BrowseExtractToDir.TabIndex = 16; 429 | this.BTN_BrowseExtractToDir.Text = "..."; 430 | this.TT_ToolTip.SetToolTip(this.BTN_BrowseExtractToDir, "Browse extract directory."); 431 | this.BTN_BrowseExtractToDir.UseVisualStyleBackColor = true; 432 | this.BTN_BrowseExtractToDir.Click += new System.EventHandler(this.BTN_BrowseExtractToDir_Click); 433 | // 434 | // label5 435 | // 436 | this.label5.AutoSize = true; 437 | this.label5.Location = new System.Drawing.Point(6, 10); 438 | this.label5.Name = "label5"; 439 | this.label5.Size = new System.Drawing.Size(65, 12); 440 | this.label5.TabIndex = 14; 441 | this.label5.Text = "Extract To"; 442 | // 443 | // TB_ExtractToDir 444 | // 445 | this.TB_ExtractToDir.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 446 | | System.Windows.Forms.AnchorStyles.Right))); 447 | this.TB_ExtractToDir.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::UnrealPakGUI.Properties.Settings.Default, "ExtractToDir", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 448 | this.TB_ExtractToDir.Location = new System.Drawing.Point(77, 7); 449 | this.TB_ExtractToDir.Name = "TB_ExtractToDir"; 450 | this.TB_ExtractToDir.ReadOnly = true; 451 | this.TB_ExtractToDir.Size = new System.Drawing.Size(625, 21); 452 | this.TB_ExtractToDir.TabIndex = 15; 453 | this.TB_ExtractToDir.Text = global::UnrealPakGUI.Properties.Settings.Default.ExtractToDir; 454 | this.TT_ToolTip.SetToolTip(this.TB_ExtractToDir, "Directory to extract pak contet to."); 455 | // 456 | // TV_ListPak 457 | // 458 | this.TV_ListPak.AllowDrop = true; 459 | this.TV_ListPak.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 460 | | System.Windows.Forms.AnchorStyles.Left) 461 | | System.Windows.Forms.AnchorStyles.Right))); 462 | this.TV_ListPak.Location = new System.Drawing.Point(6, 33); 463 | this.TV_ListPak.Name = "TV_ListPak"; 464 | this.TV_ListPak.Size = new System.Drawing.Size(629, 394); 465 | this.TV_ListPak.TabIndex = 0; 466 | this.TT_ToolTip.SetToolTip(this.TV_ListPak, "Drag a pak file here to list its content."); 467 | this.TV_ListPak.DragDrop += new System.Windows.Forms.DragEventHandler(this.TV_ListPak_DragDrop); 468 | this.TV_ListPak.DragEnter += new System.Windows.Forms.DragEventHandler(this.TV_ListPak_DragEnter); 469 | this.TV_ListPak.DragOver += new System.Windows.Forms.DragEventHandler(this.TV_ListPak_DragEnter); 470 | // 471 | // TT_ToolTip 472 | // 473 | this.TT_ToolTip.AutomaticDelay = 0; 474 | this.TT_ToolTip.AutoPopDelay = 30000; 475 | this.TT_ToolTip.InitialDelay = 100; 476 | this.TT_ToolTip.ReshowDelay = 0; 477 | this.TT_ToolTip.UseAnimation = false; 478 | this.TT_ToolTip.UseFading = false; 479 | // 480 | // CKB_ContentOnly 481 | // 482 | this.CKB_ContentOnly.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 483 | this.CKB_ContentOnly.AutoSize = true; 484 | this.CKB_ContentOnly.Checked = global::UnrealPakGUI.Properties.Settings.Default.bContentOnly; 485 | this.CKB_ContentOnly.CheckState = System.Windows.Forms.CheckState.Checked; 486 | this.CKB_ContentOnly.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::UnrealPakGUI.Properties.Settings.Default, "bContentOnly", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 487 | this.CKB_ContentOnly.Location = new System.Drawing.Point(433, 96); 488 | this.CKB_ContentOnly.Name = "CKB_ContentOnly"; 489 | this.CKB_ContentOnly.Size = new System.Drawing.Size(132, 16); 490 | this.CKB_ContentOnly.TabIndex = 6; 491 | this.CKB_ContentOnly.Text = "Content Files Only"; 492 | this.TT_ToolTip.SetToolTip(this.CKB_ContentOnly, resources.GetString("CKB_ContentOnly.ToolTip")); 493 | this.CKB_ContentOnly.UseVisualStyleBackColor = true; 494 | this.CKB_ContentOnly.CheckedChanged += new System.EventHandler(this.CKB_ContentOnly_CheckedChanged); 495 | // 496 | // CKB_Encryption 497 | // 498 | this.CKB_Encryption.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 499 | this.CKB_Encryption.AutoSize = true; 500 | this.CKB_Encryption.Checked = global::UnrealPakGUI.Properties.Settings.Default.bUseEncryption; 501 | this.CKB_Encryption.CheckState = System.Windows.Forms.CheckState.Checked; 502 | this.CKB_Encryption.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::UnrealPakGUI.Properties.Settings.Default, "bUseEncryption", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 503 | this.CKB_Encryption.Location = new System.Drawing.Point(677, 96); 504 | this.CKB_Encryption.Name = "CKB_Encryption"; 505 | this.CKB_Encryption.Size = new System.Drawing.Size(84, 16); 506 | this.CKB_Encryption.TabIndex = 7; 507 | this.CKB_Encryption.Text = "Encryption"; 508 | this.TT_ToolTip.SetToolTip(this.CKB_Encryption, "Encrypt pak file. A valid Crypto file is nessessary."); 509 | this.CKB_Encryption.UseVisualStyleBackColor = true; 510 | this.CKB_Encryption.CheckedChanged += new System.EventHandler(this.CKB_Encryption_CheckedChanged); 511 | // 512 | // TB_ProjectFile 513 | // 514 | this.TB_ProjectFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 515 | | System.Windows.Forms.AnchorStyles.Right))); 516 | this.TB_ProjectFile.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::UnrealPakGUI.Properties.Settings.Default, "ProjectFile", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 517 | this.TB_ProjectFile.Location = new System.Drawing.Point(107, 67); 518 | this.TB_ProjectFile.Name = "TB_ProjectFile"; 519 | this.TB_ProjectFile.ReadOnly = true; 520 | this.TB_ProjectFile.Size = new System.Drawing.Size(621, 21); 521 | this.TB_ProjectFile.TabIndex = 4; 522 | this.TB_ProjectFile.Text = global::UnrealPakGUI.Properties.Settings.Default.ProjectFile; 523 | this.TT_ToolTip.SetToolTip(this.TB_ProjectFile, "Path to uproject file"); 524 | // 525 | // TB_CryptoFile 526 | // 527 | this.TB_CryptoFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 528 | | System.Windows.Forms.AnchorStyles.Right))); 529 | this.TB_CryptoFile.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::UnrealPakGUI.Properties.Settings.Default, "CryptoFile", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 530 | this.TB_CryptoFile.Location = new System.Drawing.Point(107, 39); 531 | this.TB_CryptoFile.Name = "TB_CryptoFile"; 532 | this.TB_CryptoFile.ReadOnly = true; 533 | this.TB_CryptoFile.Size = new System.Drawing.Size(621, 21); 534 | this.TB_CryptoFile.TabIndex = 2; 535 | this.TB_CryptoFile.Text = global::UnrealPakGUI.Properties.Settings.Default.CryptoFile; 536 | this.TT_ToolTip.SetToolTip(this.TB_CryptoFile, "Path to Crypto.json file"); 537 | // 538 | // TB_EngineDir 539 | // 540 | this.TB_EngineDir.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 541 | | System.Windows.Forms.AnchorStyles.Right))); 542 | this.TB_EngineDir.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::UnrealPakGUI.Properties.Settings.Default, "EngineDir", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 543 | this.TB_EngineDir.Location = new System.Drawing.Point(107, 11); 544 | this.TB_EngineDir.Name = "TB_EngineDir"; 545 | this.TB_EngineDir.ReadOnly = true; 546 | this.TB_EngineDir.Size = new System.Drawing.Size(621, 21); 547 | this.TB_EngineDir.TabIndex = 0; 548 | this.TB_EngineDir.Text = global::UnrealPakGUI.Properties.Settings.Default.EngineDir; 549 | this.TT_ToolTip.SetToolTip(this.TB_EngineDir, "Unreal Engine root directory, i.e. \"D:\\UnrealEngine\\UE_4.26\". If UnrealPak.exe is" + 550 | " not found under engine directory, we will try to look for it in the same folder" + 551 | " this tool is in."); 552 | // 553 | // CKB_Compression 554 | // 555 | this.CKB_Compression.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 556 | this.CKB_Compression.AutoSize = true; 557 | this.CKB_Compression.Checked = global::UnrealPakGUI.Properties.Settings.Default.bUseCompression; 558 | this.CKB_Compression.CheckState = System.Windows.Forms.CheckState.Checked; 559 | this.CKB_Compression.DataBindings.Add(new System.Windows.Forms.Binding("Checked", global::UnrealPakGUI.Properties.Settings.Default, "bUseCompression", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 560 | this.CKB_Compression.Location = new System.Drawing.Point(575, 96); 561 | this.CKB_Compression.Name = "CKB_Compression"; 562 | this.CKB_Compression.Size = new System.Drawing.Size(90, 16); 563 | this.CKB_Compression.TabIndex = 7; 564 | this.CKB_Compression.Text = "Compression"; 565 | this.CKB_Compression.UseVisualStyleBackColor = true; 566 | this.CKB_Compression.CheckedChanged += new System.EventHandler(this.CKB_Compression_CheckedChanged); 567 | // 568 | // statusStrip1 569 | // 570 | this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 571 | this.BTN_Logs}); 572 | this.statusStrip1.Location = new System.Drawing.Point(0, 561); 573 | this.statusStrip1.Name = "statusStrip1"; 574 | this.statusStrip1.Size = new System.Drawing.Size(778, 23); 575 | this.statusStrip1.TabIndex = 9; 576 | this.statusStrip1.Text = "statusStrip1"; 577 | // 578 | // BTN_Logs 579 | // 580 | this.BTN_Logs.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; 581 | this.BTN_Logs.ImageTransparentColor = System.Drawing.Color.Magenta; 582 | this.BTN_Logs.Name = "BTN_Logs"; 583 | this.BTN_Logs.ShowDropDownArrow = false; 584 | this.BTN_Logs.Size = new System.Drawing.Size(40, 21); 585 | this.BTN_Logs.Text = "Logs"; 586 | this.BTN_Logs.Click += new System.EventHandler(this.BTN_Logs_Click); 587 | // 588 | // MainForm 589 | // 590 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 591 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 592 | this.ClientSize = new System.Drawing.Size(778, 584); 593 | this.Controls.Add(this.statusStrip1); 594 | this.Controls.Add(this.CKB_ContentOnly); 595 | this.Controls.Add(this.CKB_Compression); 596 | this.Controls.Add(this.CKB_Encryption); 597 | this.Controls.Add(this.tabControl1); 598 | this.Controls.Add(this.label4); 599 | this.Controls.Add(this.label2); 600 | this.Controls.Add(this.label1); 601 | this.Controls.Add(this.BTN_BrowseProjectFile); 602 | this.Controls.Add(this.BTN_BrowseCryptoFile); 603 | this.Controls.Add(this.BTN_BrowseEngineDir); 604 | this.Controls.Add(this.TB_ProjectFile); 605 | this.Controls.Add(this.TB_CryptoFile); 606 | this.Controls.Add(this.TB_EngineDir); 607 | this.MinimumSize = new System.Drawing.Size(500, 400); 608 | this.Name = "MainForm"; 609 | this.ShowIcon = false; 610 | this.Text = "UnrealPakGUI"; 611 | this.tabControl1.ResumeLayout(false); 612 | this.tabPage1.ResumeLayout(false); 613 | this.tabPage2.ResumeLayout(false); 614 | this.tabPage2.PerformLayout(); 615 | this.tabPage3.ResumeLayout(false); 616 | this.tabPage3.PerformLayout(); 617 | this.statusStrip1.ResumeLayout(false); 618 | this.statusStrip1.PerformLayout(); 619 | this.ResumeLayout(false); 620 | this.PerformLayout(); 621 | 622 | } 623 | 624 | #endregion 625 | private System.Windows.Forms.TextBox TB_EngineDir; 626 | private System.Windows.Forms.Button BTN_BrowseEngineDir; 627 | private System.Windows.Forms.Label label1; 628 | private System.Windows.Forms.TextBox TB_CryptoFile; 629 | private System.Windows.Forms.Button BTN_BrowseCryptoFile; 630 | private System.Windows.Forms.Label label2; 631 | private System.Windows.Forms.OpenFileDialog OFD_BrowseCryptoFile; 632 | private System.Windows.Forms.FolderBrowserDialog FBD_BrowseDir; 633 | private System.Windows.Forms.OpenFileDialog OFD_BrowseOutputFile; 634 | private System.Windows.Forms.ListBox LB_FilesToPak; 635 | private System.Windows.Forms.TextBox TB_ProjectFile; 636 | private System.Windows.Forms.Label label4; 637 | private System.Windows.Forms.Button BTN_BrowseProjectFile; 638 | private System.Windows.Forms.OpenFileDialog OFD_BrowseProjectFile; 639 | private System.Windows.Forms.CheckBox CKB_Encryption; 640 | private System.Windows.Forms.Button BTN_RemoveItems; 641 | private System.Windows.Forms.Button BTN_CreatePak; 642 | private System.Windows.Forms.OpenFileDialog OFD_AddFiles; 643 | private System.Windows.Forms.Button BTN_RemoveAll; 644 | private System.Windows.Forms.TabControl tabControl1; 645 | private System.Windows.Forms.TabPage tabPage1; 646 | private System.Windows.Forms.TabPage tabPage2; 647 | private System.Windows.Forms.TreeView TV_BatchFiles; 648 | private System.Windows.Forms.Button BTN_BatchRemove; 649 | private System.Windows.Forms.Button BTN_BatchCreatePaks; 650 | private System.Windows.Forms.Button BTN_BatchRemoveAll; 651 | private System.Windows.Forms.TextBox TB_BatchOutputDir; 652 | private System.Windows.Forms.Button BTN_BrowseBatchOutputDir; 653 | private System.Windows.Forms.Label label3; 654 | private System.Windows.Forms.CheckBox CKB_ContentOnly; 655 | private System.Windows.Forms.ToolTip TT_ToolTip; 656 | private System.Windows.Forms.CheckBox CKB_AsPatch; 657 | private System.Windows.Forms.CheckBox CKB_FolderPak; 658 | private System.Windows.Forms.CheckBox CKB_Compression; 659 | private System.Windows.Forms.TabPage tabPage3; 660 | private System.Windows.Forms.TreeView TV_ListPak; 661 | private System.Windows.Forms.Button BTN_BrowseExtractToDir; 662 | private System.Windows.Forms.Label label5; 663 | private System.Windows.Forms.TextBox TB_ExtractToDir; 664 | private System.Windows.Forms.StatusStrip statusStrip1; 665 | private System.Windows.Forms.ToolStripDropDownButton BTN_Logs; 666 | private System.Windows.Forms.Label label6; 667 | private System.Windows.Forms.Button BTN_Extract; 668 | } 669 | } 670 | 671 | -------------------------------------------------------------------------------- /UnrealPakGUI/Mainform.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading; 11 | using System.Windows.Forms; 12 | 13 | namespace UnrealPakGUI 14 | { 15 | public partial class MainForm : Form 16 | { 17 | private delegate void PassStringDelegate(string Line); 18 | FormLogs Logs; 19 | const string UnrealPakRelativePath = @"Engine\Binaries\Win64\"; 20 | const string UnrealPakExecutable = @"UnrealPak.exe"; 21 | string UnrealPakPath; 22 | string UnrealPakEnginePath; 23 | string UnrealPakCurrentFolderPath; 24 | string CryptoFilePath; 25 | string ProjectFilePath; 26 | string BatchOutputPath; 27 | string ExtractToPath; 28 | string ListedFileName; 29 | bool bContentOnly = false; 30 | bool bCompression = false; 31 | bool bEncryption = false; 32 | bool bAsPatch = false; 33 | 34 | bool bBatchMode = false; 35 | int BatchCount = 0; 36 | int BatchTotal = 0; 37 | 38 | List ListOutput; 39 | 40 | public MainForm() 41 | { 42 | InitializeComponent(); 43 | ListOutput = new List(); 44 | Logs = new FormLogs(); 45 | ApplyConfigs(); 46 | } 47 | 48 | #region Buttons Click 49 | 50 | private void BTN_BrowseEngineDir_Click(object sender, EventArgs e) 51 | { 52 | if (DialogResult.OK == FBD_BrowseDir.ShowDialog()) 53 | { 54 | TB_EngineDir.Text = FBD_BrowseDir.SelectedPath; 55 | SaveConfig("EngineDir", TB_EngineDir.Text); 56 | } 57 | } 58 | 59 | private void BTN_BrowseCryptoFile_Click(object sender, EventArgs e) 60 | { 61 | if (DialogResult.OK == OFD_BrowseCryptoFile.ShowDialog()) 62 | { 63 | TB_CryptoFile.Text = OFD_BrowseCryptoFile.FileName; 64 | SaveConfig("CryptoFile", TB_CryptoFile.Text); 65 | } 66 | } 67 | 68 | private void BTN_BrowseProjectFile_Click(object sender, EventArgs e) 69 | { 70 | if (DialogResult.OK == OFD_BrowseProjectFile.ShowDialog()) 71 | { 72 | TB_ProjectFile.Text = OFD_BrowseProjectFile.FileName; 73 | SaveConfig("ProjectFile", TB_ProjectFile.Text); 74 | } 75 | } 76 | 77 | private void BTN_RemoveItems_Click(object sender, EventArgs e) 78 | { 79 | LB_FilesToPak.BeginUpdate(); 80 | IEnumerable FilesToRemove = LB_FilesToPak.SelectedItems.Cast(); 81 | foreach (string FileName in FilesToRemove) 82 | { 83 | LB_FilesToPak.Items.Remove(FileName); 84 | } 85 | LB_FilesToPak.EndUpdate(); 86 | } 87 | 88 | private void BTN_RemoveAll_Click(object sender, EventArgs e) 89 | { 90 | LB_FilesToPak.Items.Clear(); 91 | } 92 | 93 | private void BTN_CreatePak_Click(object sender, EventArgs e) 94 | { 95 | bBatchMode = false; 96 | ApplyConfigs(); 97 | 98 | if (!ValidateConfigs()) 99 | { 100 | return; 101 | } 102 | 103 | if (bContentOnly && !File.Exists(ProjectFilePath)) 104 | { 105 | MessageBox.Show("Project File does not exist ( requires a valid uproject file)!", "Missing Project File"); 106 | return; 107 | } 108 | 109 | if (LB_FilesToPak.Items.Count == 0) 110 | { 111 | MessageBox.Show("Nothing to Pak!", "Nothing to Pak"); 112 | return; 113 | } 114 | 115 | if (DialogResult.OK != OFD_BrowseOutputFile.ShowDialog()) 116 | { 117 | return; 118 | } 119 | 120 | ShowLog("///////////////////////// START PACKING /////////////////////////"); 121 | 122 | string[] FilesToPak = LB_FilesToPak.Items.Cast().ToArray(); 123 | PakBatch Batch = new PakBatch(FilesToPak); 124 | Batch.OutputPath = OFD_BrowseOutputFile.FileName; 125 | CreateSinglePak(Batch); 126 | } 127 | 128 | private void BTN_BrowseBatchOutputDir_Click(object sender, EventArgs e) 129 | { 130 | if (DialogResult.OK == FBD_BrowseDir.ShowDialog()) 131 | { 132 | TB_BatchOutputDir.Text = FBD_BrowseDir.SelectedPath; 133 | SaveConfig("BatchOutputDir", TB_BatchOutputDir.Text); 134 | } 135 | } 136 | 137 | private void BTN_BatchRemove_Click(object sender, EventArgs e) 138 | { 139 | TreeNode NodeToRemove = TV_BatchFiles.SelectedNode; 140 | while (NodeToRemove.Parent != null) 141 | { 142 | NodeToRemove = NodeToRemove.Parent; 143 | } 144 | TV_BatchFiles.Nodes.Remove(NodeToRemove); 145 | } 146 | 147 | private void BTN_BatchRemoveAll_Click(object sender, EventArgs e) 148 | { 149 | TV_BatchFiles.Nodes.Clear(); 150 | } 151 | 152 | private void BTN_BatchCreatePaks_Click(object sender, EventArgs e) 153 | { 154 | bBatchMode = true; 155 | ApplyConfigs(); 156 | if (!ValidateConfigs()) 157 | { 158 | return; 159 | } 160 | 161 | if (bContentOnly && !File.Exists(ProjectFilePath)) 162 | { 163 | MessageBox.Show("Project File does not exist ( requires a valid uproject file)!", "Missing Project File"); 164 | return; 165 | } 166 | 167 | if (TV_BatchFiles.Nodes.Count == 0) 168 | { 169 | MessageBox.Show("Nothing to Pak!", "Nothing to Pak"); 170 | return; 171 | } 172 | 173 | if (!Directory.Exists(BatchOutputPath)) 174 | { 175 | MessageBox.Show("Output directory does not exist!"); 176 | return; 177 | } 178 | 179 | ShowLog("////////////////////// START BATCH PACKING //////////////////////"); 180 | 181 | BatchCount = BatchTotal = TV_BatchFiles.GetNodeCount(false); 182 | 183 | foreach (TreeNode Node in TV_BatchFiles.Nodes) 184 | { 185 | PakBatch Batch = Node.Tag as PakBatch; 186 | Batch.OutputPath = BatchOutputPath; 187 | if (Batch == null) 188 | { 189 | continue; 190 | } 191 | CreateSinglePak(Batch); 192 | } 193 | } 194 | 195 | private void BTN_BrowseExtractToDir_Click(object sender, EventArgs e) 196 | { 197 | if (DialogResult.OK == FBD_BrowseDir.ShowDialog()) 198 | { 199 | TB_ExtractToDir.Text = FBD_BrowseDir.SelectedPath; 200 | SaveConfig("ExtractToDir", TB_ExtractToDir.Text); 201 | } 202 | } 203 | 204 | private void BTN_Extract_Click(object sender, EventArgs e) 205 | { 206 | if (!File.Exists(ListedFileName)) 207 | { 208 | MessageBox.Show("File does not exist!", "File not found"); 209 | return; 210 | } 211 | 212 | if (Path.GetExtension(ListedFileName) != ".pak") 213 | { 214 | MessageBox.Show("Only supports *.pak file!", "Unsupported file"); 215 | return; 216 | } 217 | 218 | ApplyConfigs(); 219 | if (!ValidateConfigs()) 220 | { 221 | return; 222 | } 223 | 224 | if (!Directory.Exists(ExtractToPath)) 225 | { 226 | MessageBox.Show("Trying to extract to a directory that does not exist!", "Invalid destination directory"); 227 | return; 228 | } 229 | 230 | ShowLog("/////////////////////// START EXTRACTING ////////////////////////"); 231 | ShowLog($"Extracting file {ListedFileName}"); 232 | 233 | Thread Worker = new Thread(() => RunExtractWorker(ListedFileName)); 234 | Worker.IsBackground = true; 235 | Worker.Start(); 236 | } 237 | 238 | private void BTN_Logs_Click(object sender, EventArgs e) 239 | { 240 | Logs.Show(); 241 | } 242 | 243 | #endregion Buttons Click 244 | 245 | #region Checkboxes CheckedChanged 246 | 247 | private void CKB_ContentOnly_CheckedChanged(object sender, EventArgs e) 248 | { 249 | SaveConfig("bContentOnly", CKB_ContentOnly.Checked); 250 | } 251 | 252 | private void CKB_Compression_CheckedChanged(object sender, EventArgs e) 253 | { 254 | SaveConfig("bUseCompression", CKB_Compression.Checked); 255 | } 256 | 257 | private void CKB_Encryption_CheckedChanged(object sender, EventArgs e) 258 | { 259 | SaveConfig("bUseEncryption", CKB_Encryption.Checked); 260 | } 261 | 262 | private void CKB_AsPatch_CheckedChanged(object sender, EventArgs e) 263 | { 264 | Properties.Settings.Default["bAsPatch"] = CKB_AsPatch.Checked; 265 | Properties.Settings.Default.Save(); 266 | } 267 | 268 | private void CKB_FolderPak_CheckedChanged(object sender, EventArgs e) 269 | { 270 | Properties.Settings.Default["bFolderPak"] = CKB_FolderPak.Checked; 271 | Properties.Settings.Default.Save(); 272 | } 273 | 274 | #endregion Checkboxes CheckedChanged 275 | 276 | #region List & Tree DragDrop 277 | 278 | private void LB_FilesToPak_DragEnter(object sender, DragEventArgs e) 279 | { 280 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 281 | { 282 | e.Effect = DragDropEffects.All; 283 | } 284 | else 285 | { 286 | e.Effect = DragDropEffects.None; 287 | } 288 | } 289 | 290 | private void LB_FilesToPak_DragDrop(object sender, DragEventArgs e) 291 | { 292 | LB_FilesToPak.BeginUpdate(); 293 | string[] FileNames = e.Data.GetData(DataFormats.FileDrop, false) as string[]; 294 | foreach (string FileName in FileNames.Where(FileName => !LB_FilesToPak.Items.Contains(FileName))) 295 | { 296 | if (IsDirectory(FileName)) 297 | { 298 | foreach (string SubDirFileName in Directory.EnumerateFiles(FileName, "*.*", SearchOption.AllDirectories) 299 | .Where(SubDirFileName => !LB_FilesToPak.Items.Contains(SubDirFileName))) 300 | { 301 | LB_FilesToPak.Items.Add(SubDirFileName); 302 | } 303 | } 304 | else 305 | { 306 | LB_FilesToPak.Items.Add(FileName); 307 | } 308 | } 309 | LB_FilesToPak.EndUpdate(); 310 | } 311 | 312 | private void TV_BatchFiles_DragEnter(object sender, DragEventArgs e) 313 | { 314 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 315 | { 316 | e.Effect = DragDropEffects.All; 317 | } 318 | else 319 | { 320 | e.Effect = DragDropEffects.None; 321 | } 322 | } 323 | 324 | private void TV_BatchFiles_DragDrop(object sender, DragEventArgs e) 325 | { 326 | TV_BatchFiles.BeginUpdate(); 327 | string[] FileNames = e.Data.GetData(DataFormats.FileDrop, false) as string[]; 328 | if (CKB_FolderPak.Checked) 329 | { 330 | List SingleFiles = new List(); 331 | foreach (string FileName in FileNames) 332 | { 333 | if (IsDirectory(FileName)) 334 | { 335 | PakBatch Batch = new PakBatch(new string[] { FileName }); 336 | TreeNode Node = new TreeNode(Batch.BatchNodeText); 337 | Node.Tag = Batch; 338 | foreach (string SubDirFileName in Batch.Files) 339 | { 340 | Node.Nodes.Add(new TreeNode(SubDirFileName.Substring(Batch.CommonPath.Length))); 341 | } 342 | TV_BatchFiles.Nodes.Add(Node); 343 | } 344 | else 345 | { 346 | SingleFiles.Add(FileName); 347 | } 348 | } 349 | 350 | if (SingleFiles.Count > 0) 351 | { 352 | PakBatch Batch = new PakBatch(SingleFiles.ToArray()); 353 | TreeNode Node = new TreeNode(Batch.BatchNodeText); 354 | Node.Tag = Batch; 355 | TV_BatchFiles.Nodes.Add(Node); 356 | } 357 | } 358 | else 359 | { 360 | PakBatch Batch = new PakBatch(FileNames); 361 | TreeNode Node = new TreeNode(Batch.BatchNodeText); 362 | Node.Tag = Batch; 363 | foreach (string FileName in Batch.Files) 364 | { 365 | Node.Nodes.Add(new TreeNode(FileName.Substring(Batch.CommonPath.Length))); 366 | } 367 | TV_BatchFiles.Nodes.Add(Node); 368 | TV_BatchFiles.CollapseAll(); 369 | Node.Expand(); 370 | } 371 | TV_BatchFiles.EndUpdate(); 372 | } 373 | 374 | private void TV_ListPak_DragEnter(object sender, DragEventArgs e) 375 | { 376 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 377 | { 378 | e.Effect = DragDropEffects.All; 379 | } 380 | else 381 | { 382 | e.Effect = DragDropEffects.None; 383 | } 384 | } 385 | 386 | private void TV_ListPak_DragDrop(object sender, DragEventArgs e) 387 | { 388 | string[] FileNames = e.Data.GetData(DataFormats.FileDrop, false) as string[]; 389 | if (FileNames.Length != 1) 390 | { 391 | MessageBox.Show("No more than one file!", "Too many files"); 392 | return; 393 | } 394 | 395 | ListedFileName = FileNames[0]; 396 | 397 | if (!File.Exists(ListedFileName)) 398 | { 399 | MessageBox.Show("File does not exist!", "File not found"); 400 | return; 401 | } 402 | 403 | if (Path.GetExtension(ListedFileName) != ".pak") 404 | { 405 | MessageBox.Show("Only supports *.pak file!", "Unsupported file"); 406 | return; 407 | } 408 | 409 | ApplyConfigs(); 410 | if (!ValidateConfigs()) 411 | { 412 | return; 413 | } 414 | 415 | ShowLog("//////////////////////// START LISTING //////////////////////////"); 416 | ShowLog($"Listing file {ListedFileName}"); 417 | TV_ListPak.Nodes.Clear(); 418 | ListOutput.Clear(); 419 | 420 | Thread Worker = new Thread(() => RunListWorker(ListedFileName)); 421 | Worker.IsBackground = true; 422 | Worker.Start(); 423 | } 424 | 425 | #endregion List & Tree DragDrop 426 | 427 | #region Configs 428 | 429 | private bool ValidateConfigs() 430 | { 431 | if (File.Exists(UnrealPakEnginePath)) 432 | { 433 | UnrealPakPath = UnrealPakEnginePath; 434 | } 435 | else if (File.Exists(UnrealPakCurrentFolderPath)) 436 | { 437 | UnrealPakPath = UnrealPakCurrentFolderPath; 438 | } 439 | else 440 | { 441 | MessageBox.Show($"Could not find UnrealPak.exe at {UnrealPakEnginePath} or {UnrealPakCurrentFolderPath}!", "UnrealPak.exe Not Found"); 442 | return false; 443 | } 444 | 445 | if (bEncryption && !File.Exists(CryptoFilePath)) 446 | { 447 | MessageBox.Show("Encryption is enabled yet Crypto File does not exist!", "Missing Crypto File"); 448 | return false; 449 | } 450 | 451 | return true; 452 | } 453 | 454 | private void ApplyConfigs() 455 | { 456 | UnrealPakEnginePath = Path.Combine(TB_EngineDir.Text, UnrealPakRelativePath, UnrealPakExecutable); 457 | UnrealPakCurrentFolderPath = Path.Combine(Application.StartupPath, UnrealPakExecutable); 458 | CryptoFilePath = TB_CryptoFile.Text; 459 | ProjectFilePath = TB_ProjectFile.Text; 460 | BatchOutputPath = TB_BatchOutputDir.Text; 461 | ExtractToPath = TB_ExtractToDir.Text; 462 | bContentOnly = CKB_ContentOnly.Checked; 463 | bCompression = CKB_Compression.Checked; 464 | bEncryption = CKB_Encryption.Checked; 465 | bAsPatch = CKB_AsPatch.Checked; 466 | } 467 | 468 | private void SaveConfig(string Name, string Value) 469 | { 470 | Properties.Settings.Default[Name] = Value; 471 | Properties.Settings.Default.Save(); 472 | } 473 | 474 | private void SaveConfig(string Name, bool Value) 475 | { 476 | Properties.Settings.Default[Name] = Value; 477 | Properties.Settings.Default.Save(); 478 | } 479 | 480 | #endregion Configs 481 | 482 | #region Packing 483 | 484 | private void CreateSinglePak(PakBatch Batch) 485 | { 486 | string ResponseFilePath = string.Empty; 487 | List Args = new List(); 488 | 489 | ResponseFilePath = CreateResponseFile(Batch); 490 | 491 | if (!File.Exists(ResponseFilePath)) 492 | { 493 | return; 494 | } 495 | 496 | if (string.IsNullOrEmpty(Batch.OutputPath)) 497 | { 498 | return; 499 | } 500 | 501 | string FileOutputPath = Batch.OutputPath; 502 | if (bAsPatch) 503 | { 504 | FileOutputPath = FileOutputPath.Insert(FileOutputPath.LastIndexOf(".pak"), "_p"); 505 | } 506 | 507 | Args.Add(FileOutputPath); 508 | Args.Add($"-create={ResponseFilePath}"); 509 | 510 | if (bEncryption) 511 | { 512 | Args.Add($"-cryptokeys={CryptoFilePath}"); 513 | Args.Add("-encryptindex"); 514 | } 515 | 516 | if (bCompression) 517 | { 518 | Args.Add("-compress"); 519 | } 520 | 521 | Args.Add("-patchpaddingalign=2048"); 522 | Args.Add("-multiprocess"); 523 | 524 | Thread Worker = new Thread(() => RunPackingWorker(Args.ToArray())); 525 | Worker.IsBackground = true; 526 | Worker.Start(); 527 | } 528 | 529 | private string CreateResponseFile(PakBatch Batch) 530 | { 531 | string[] FilesToPak = Batch.Files; 532 | string ProjectName = Path.GetFileNameWithoutExtension(ProjectFilePath); 533 | string ResponseFileDir = @".\ResponseFiles"; 534 | string ResponseFilePath = Path.Combine(ResponseFileDir, $"{ProjectName}-{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}"); 535 | string MountPoint = bContentOnly ? $"../../../{ProjectName}/" : Batch.CommonPath.Replace(@"\", "/"); 536 | 537 | List Lines = new List(); 538 | 539 | for (int i = 0; i < FilesToPak.Length; i++) 540 | { 541 | string FileName = FilesToPak[i]; 542 | string FileExtension = Path.GetExtension(FileName); 543 | 544 | int RelativeIndex = bContentOnly ? FileName.LastIndexOf(@"Content\") : Batch.CommonPath.Length; 545 | if (RelativeIndex < 0) 546 | { 547 | continue; 548 | } 549 | 550 | string RelativeFilePath = MountPoint + FileName.Substring(RelativeIndex).Replace(@"\", "/"); 551 | string Line = "\"" + FileName + "\" \"" + RelativeFilePath + "\""; 552 | if (bEncryption && FileExtension == ".uasset" || FileExtension == ".ini") 553 | { 554 | Line += " -encrypt"; 555 | } 556 | 557 | Lines.Add(Line); 558 | } 559 | 560 | if (Lines.Count == 0) 561 | { 562 | string ErrMsg = $"ERROR: No eligible file{ (bBatchMode ? $" for batch {Batch.BatchNodeText}!" : "!") }"; 563 | ShowLog(ErrMsg); 564 | return string.Empty; 565 | } 566 | 567 | if (!Directory.Exists(ResponseFileDir)) 568 | { 569 | Directory.CreateDirectory(ResponseFileDir); 570 | } 571 | 572 | if (File.Exists(ResponseFilePath + ".txt")) 573 | { 574 | int DuplicateCount = 1; 575 | while (File.Exists(ResponseFilePath + $"_{DuplicateCount}.txt")) 576 | { 577 | DuplicateCount++; 578 | } 579 | ResponseFilePath += $"_{DuplicateCount}.txt"; 580 | } 581 | else 582 | { 583 | ResponseFilePath += ".txt"; 584 | } 585 | 586 | File.WriteAllLines(ResponseFilePath, Lines); 587 | 588 | return Path.GetFullPath(ResponseFilePath); 589 | } 590 | 591 | private void RunPackingWorker(string[] Args) 592 | { 593 | string CombinedArgs = string.Empty; 594 | foreach (string Arg in Args) 595 | { 596 | CombinedArgs += Arg + " "; 597 | } 598 | CombinedArgs.Trim(); 599 | 600 | ProcessStartInfo StartInfo = new ProcessStartInfo(UnrealPakPath, CombinedArgs); 601 | StartInfo.CreateNoWindow = true; 602 | StartInfo.RedirectStandardOutput = !bBatchMode; 603 | StartInfo.RedirectStandardError = !bBatchMode; 604 | StartInfo.UseShellExecute = false; 605 | Process CmdProc = Process.Start(StartInfo); 606 | 607 | if (!bBatchMode) 608 | { 609 | ShowLog($"Running command: {UnrealPakPath} {CombinedArgs}"); 610 | CmdProc.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived); 611 | CmdProc.BeginOutputReadLine(); 612 | } 613 | 614 | CmdProc.WaitForExit(); 615 | CmdProc.Close(); 616 | 617 | if (bBatchMode) 618 | { 619 | ReportPakCreated(Args[0]); 620 | } 621 | else 622 | { 623 | ShowLog("///////////////////////// DONE PACKING //////////////////////////"); 624 | } 625 | } 626 | 627 | private bool IsDirectory(string FileName) 628 | { 629 | return Directory.Exists(FileName); 630 | } 631 | 632 | #endregion Packing 633 | 634 | #region List & Extract 635 | 636 | private void RunListWorker(string FileName) 637 | { 638 | string Args = FileName + " -list"; 639 | if (bEncryption) 640 | { 641 | Args += $" -cryptokeys={CryptoFilePath}"; 642 | } 643 | ProcessStartInfo StartInfo = new ProcessStartInfo(UnrealPakPath, Args); 644 | StartInfo.CreateNoWindow = true; 645 | StartInfo.RedirectStandardOutput = true; 646 | StartInfo.RedirectStandardError = true; 647 | StartInfo.UseShellExecute = false; 648 | Process CmdProc = Process.Start(StartInfo); 649 | 650 | CmdProc.OutputDataReceived += new DataReceivedEventHandler(OnListOutputReceived); 651 | CmdProc.BeginOutputReadLine(); 652 | 653 | CmdProc.WaitForExit(); 654 | CmdProc.Close(); 655 | 656 | ShowLog("///////////////////////// DONE LISTING //////////////////////////"); 657 | 658 | ProcessListOutput(FileName); 659 | } 660 | 661 | private void OnListOutputReceived(object sender, DataReceivedEventArgs e) 662 | { 663 | if (!string.IsNullOrEmpty(e.Data)) 664 | { 665 | ShowLog(e.Data); 666 | ListOutput.Add(e.Data); 667 | } 668 | } 669 | 670 | private void ProcessListOutput(string FileName) 671 | { 672 | if (TV_ListPak.InvokeRequired) 673 | { 674 | PassStringDelegate Delegate = ProcessListOutput; 675 | string[] Args = { FileName }; 676 | TV_ListPak.Invoke(Delegate, Args); 677 | } 678 | else 679 | { 680 | TV_ListPak.BeginUpdate(); 681 | bool bFoundMountPoint = false; 682 | 683 | TreeNode FileNameNode = new TreeNode("File Name", new TreeNode[] { new TreeNode(FileName) }); 684 | TreeNode MountPointNode = new TreeNode("Mount Point"); 685 | TreeNode FilesNode = new TreeNode("Files"); 686 | TV_ListPak.Nodes.Add(FileNameNode); 687 | TV_ListPak.Nodes.Add(MountPointNode); 688 | TV_ListPak.Nodes.Add(FilesNode); 689 | 690 | foreach (string Line in ListOutput) 691 | { 692 | if (Line.Contains(" Error: ")) 693 | { 694 | MessageBox.Show("An error has occurred during list operation. Please check the logs.", "Error"); 695 | TV_ListPak.EndUpdate(); 696 | return; 697 | } 698 | 699 | if (!bFoundMountPoint) 700 | { 701 | if (Line.Contains("Mount point")) 702 | { 703 | MountPointNode.Nodes.Add(Line.Substring(Line.IndexOf("Mount point") + 11)); 704 | bFoundMountPoint = true; 705 | } 706 | } 707 | else 708 | { 709 | if (Line.StartsWith("LogPakFile: Display: ")) 710 | { 711 | string LineSubStr = Line.Substring(21); 712 | if (LineSubStr.StartsWith("\"")) 713 | { 714 | FilesNode.Nodes.Add(LineSubStr); 715 | } 716 | else if (LineSubStr.StartsWith("Unreal pak executed in")) 717 | { } 718 | else 719 | { 720 | FilesNode.Text += " - " + LineSubStr; 721 | } 722 | } 723 | } 724 | } 725 | FileNameNode.Expand(); 726 | MountPointNode.Expand(); 727 | FilesNode.Collapse(); 728 | TV_ListPak.EndUpdate(); 729 | } 730 | } 731 | 732 | private void RunExtractWorker(string FileToExtract) 733 | { 734 | string Args = FileToExtract + " -extract " + ExtractToPath; 735 | if (bEncryption) 736 | { 737 | Args += $" -cryptokeys={CryptoFilePath}"; 738 | } 739 | ProcessStartInfo StartInfo = new ProcessStartInfo(UnrealPakPath, Args); 740 | StartInfo.CreateNoWindow = true; 741 | StartInfo.RedirectStandardOutput = true; 742 | StartInfo.RedirectStandardError = true; 743 | StartInfo.UseShellExecute = false; 744 | Process CmdProc = Process.Start(StartInfo); 745 | 746 | CmdProc.OutputDataReceived += new DataReceivedEventHandler(OnOutputDataReceived); 747 | CmdProc.BeginOutputReadLine(); 748 | 749 | CmdProc.WaitForExit(); 750 | CmdProc.Close(); 751 | 752 | ShowLog("//////////////////////// DONE EXTRACTING ////////////////////////"); 753 | 754 | OpenOutputDir(ExtractToPath); 755 | } 756 | 757 | private void OpenOutputDir(string OutputDir) 758 | { 759 | if (this.InvokeRequired) 760 | { 761 | PassStringDelegate Delegate = OpenOutputDir; 762 | string[] Args = { OutputDir }; 763 | this.Invoke(Delegate, Args); 764 | } 765 | else 766 | { 767 | if (DialogResult.Yes == MessageBox.Show("Show output folder?", "Show output folder", MessageBoxButtons.YesNo)) 768 | { 769 | Process.Start(OutputDir); 770 | } 771 | } 772 | } 773 | 774 | #endregion List & Extract 775 | 776 | #region Logging 777 | 778 | private void OnOutputDataReceived(object sender, DataReceivedEventArgs e) 779 | { 780 | if (!string.IsNullOrEmpty(e.Data)) 781 | { 782 | ShowLog(e.Data); 783 | } 784 | } 785 | 786 | private void ReportPakCreated(string PakName) 787 | { 788 | if (this.InvokeRequired) 789 | { 790 | PassStringDelegate Delegate = ReportPakCreated; 791 | object[] Args = { PakName }; 792 | this.Invoke(Delegate, Args); 793 | } 794 | else 795 | { 796 | BatchCount--; 797 | ShowLog($"{BatchTotal - BatchCount} of {BatchTotal} - Pak file created: {PakName}"); 798 | if (BatchCount == 0) 799 | { 800 | ShowLog("////////////////////// DONE BATCH PACKING ///////////////////////"); 801 | } 802 | } 803 | } 804 | 805 | private void ShowLog(string Line) 806 | { 807 | if (this.InvokeRequired) 808 | { 809 | PassStringDelegate Delegate = ShowLog; 810 | object[] Args = { Line }; 811 | this.Invoke(Delegate, Args); 812 | } 813 | else 814 | { 815 | if (!Logs.Visible) 816 | { 817 | Logs.Show(); 818 | } 819 | Logs.ShowLog(Line); 820 | } 821 | } 822 | 823 | #endregion Logging 824 | } 825 | } 826 | -------------------------------------------------------------------------------- /UnrealPakGUI/Mainform.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 | 783, 9 122 | 123 | 124 | 145, 8 125 | 126 | 127 | 18, 8 128 | 129 | 130 | 490, 9 131 | 132 | 133 | 317, 9 134 | 135 | 136 | 664, 9 137 | 138 | 139 | If checked, only files under "Content" and its subfolders are packed, so the pak mount point will be set to "../../../<ProjectName>/Content/*". Otherwise mount point is set to the common root directory of the input files. 140 | 141 | 142 | 886, 9 143 | 144 | -------------------------------------------------------------------------------- /UnrealPakGUI/PakBatch.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace UnrealPakGUI 8 | { 9 | class PakBatch 10 | { 11 | public string CommonPath { get; private set; } 12 | 13 | public string BatchNodeText 14 | { 15 | get 16 | { 17 | return CommonPath + $" - {FilesPrivate.Count} Files"; 18 | } 19 | } 20 | 21 | public string[] Files 22 | { 23 | get { return FilesPrivate.ToArray(); } 24 | } 25 | 26 | private string OutputPathPrivate; 27 | public string OutputPath 28 | { 29 | get 30 | { 31 | return OutputPathPrivate; 32 | } 33 | set 34 | { 35 | if (value.EndsWith(".pak")) 36 | { 37 | OutputPathPrivate = value; 38 | } 39 | else 40 | { 41 | OutputPathPrivate = Path.Combine(value, Path.GetFileName(CommonPath) + ".pak"); 42 | } 43 | } 44 | } 45 | 46 | private List FilesPrivate; 47 | 48 | public PakBatch(string[] InFileNames) 49 | { 50 | FilesPrivate = new List(); 51 | foreach (string FileName in InFileNames) 52 | { 53 | if (Directory.Exists(FileName)) 54 | { 55 | foreach (string SubFileName in Directory.EnumerateFiles(FileName, "*.*", SearchOption.AllDirectories)) 56 | { 57 | FilesPrivate.Add(SubFileName); 58 | } 59 | } 60 | else 61 | { 62 | FilesPrivate.Add(FileName); 63 | } 64 | } 65 | CommonPath = GetCommonRootPath(InFileNames); 66 | } 67 | 68 | public static string GetCommonRootPath(string[] FileNames) 69 | { 70 | if (FileNames.Length == 1 && Directory.Exists(FileNames[0])) 71 | { 72 | return FileNames[0]; 73 | } 74 | string Root = GetLongestPath(FileNames).Normalize(); 75 | for (int FileIndex = 0; FileIndex < FileNames.Length && Root.Length > 0; FileIndex++) 76 | { 77 | string FileName = FileNames[FileIndex]; 78 | string FilePath = Path.GetDirectoryName(FileName) + @"\"; 79 | int CommonSeparatorIndex = -1; 80 | int SeparatorIndex = FilePath.IndexOf(@"\"); 81 | while (SeparatorIndex >= 0) 82 | { 83 | if (string.Compare(Root, 0, FilePath, 0, SeparatorIndex + 1) != 0) 84 | { 85 | break; 86 | } 87 | CommonSeparatorIndex = SeparatorIndex; 88 | if (CommonSeparatorIndex + 1 < FilePath.Length) 89 | { 90 | SeparatorIndex = FilePath.IndexOf(@"\", CommonSeparatorIndex + 1); 91 | } 92 | else 93 | { 94 | break; 95 | } 96 | } 97 | if ((CommonSeparatorIndex + 1) < Root.Length) 98 | { 99 | Root = Root.Substring(0, CommonSeparatorIndex + 1); 100 | } 101 | } 102 | return Root.Normalize(); 103 | } 104 | 105 | public static string GetLongestPath(string[] FileNames) 106 | { 107 | string LongestPath = string.Empty; 108 | int MaxNumDirectories = 0; 109 | 110 | for (int FileIndex = 0; FileIndex < FileNames.Length; FileIndex++) 111 | { 112 | string FileName = FileNames[FileIndex]; 113 | int NumDirectories = 0; 114 | for (int Index = 0; Index < FileName.Length; Index++) 115 | { 116 | if (FileName[Index] == '\\') 117 | { 118 | NumDirectories++; 119 | } 120 | } 121 | if (NumDirectories > MaxNumDirectories) 122 | { 123 | LongestPath = FileName; 124 | MaxNumDirectories = NumDirectories; 125 | } 126 | } 127 | return Path.GetDirectoryName(LongestPath) + @"\"; 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /UnrealPakGUI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace UnrealPakGUI 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new MainForm()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /UnrealPakGUI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UnrealPakGUI")] 9 | [assembly: AssemblyDescription("A GUI tool for UnrealPak")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UnrealPakGUI")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("7429bff7-b83b-4006-bd89-e91af9a64378")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /UnrealPakGUI/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 UnrealPakGUI.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", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UnrealPakGUI.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /UnrealPakGUI/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 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /UnrealPakGUI/Properties/Settings.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 UnrealPakGUI.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("")] 29 | public string EngineDir { 30 | get { 31 | return ((string)(this["EngineDir"])); 32 | } 33 | set { 34 | this["EngineDir"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("")] 41 | public string CryptoFile { 42 | get { 43 | return ((string)(this["CryptoFile"])); 44 | } 45 | set { 46 | this["CryptoFile"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("")] 53 | public string ProjectFile { 54 | get { 55 | return ((string)(this["ProjectFile"])); 56 | } 57 | set { 58 | this["ProjectFile"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 65 | public bool bUseEncryption { 66 | get { 67 | return ((bool)(this["bUseEncryption"])); 68 | } 69 | set { 70 | this["bUseEncryption"] = value; 71 | } 72 | } 73 | 74 | [global::System.Configuration.UserScopedSettingAttribute()] 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 76 | [global::System.Configuration.DefaultSettingValueAttribute("")] 77 | public string BatchOutputDir { 78 | get { 79 | return ((string)(this["BatchOutputDir"])); 80 | } 81 | set { 82 | this["BatchOutputDir"] = value; 83 | } 84 | } 85 | 86 | [global::System.Configuration.UserScopedSettingAttribute()] 87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 88 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 89 | public bool bContentOnly { 90 | get { 91 | return ((bool)(this["bContentOnly"])); 92 | } 93 | set { 94 | this["bContentOnly"] = value; 95 | } 96 | } 97 | 98 | [global::System.Configuration.UserScopedSettingAttribute()] 99 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 100 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 101 | public bool bAsPatch { 102 | get { 103 | return ((bool)(this["bAsPatch"])); 104 | } 105 | set { 106 | this["bAsPatch"] = value; 107 | } 108 | } 109 | 110 | [global::System.Configuration.UserScopedSettingAttribute()] 111 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 112 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 113 | public bool bFolderPak { 114 | get { 115 | return ((bool)(this["bFolderPak"])); 116 | } 117 | set { 118 | this["bFolderPak"] = value; 119 | } 120 | } 121 | 122 | [global::System.Configuration.UserScopedSettingAttribute()] 123 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 124 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 125 | public bool bUseCompression { 126 | get { 127 | return ((bool)(this["bUseCompression"])); 128 | } 129 | set { 130 | this["bUseCompression"] = value; 131 | } 132 | } 133 | 134 | [global::System.Configuration.UserScopedSettingAttribute()] 135 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 136 | [global::System.Configuration.DefaultSettingValueAttribute("")] 137 | public string ExtractToDir { 138 | get { 139 | return ((string)(this["ExtractToDir"])); 140 | } 141 | set { 142 | this["ExtractToDir"] = value; 143 | } 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /UnrealPakGUI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | True 16 | 17 | 18 | 19 | 20 | 21 | True 22 | 23 | 24 | False 25 | 26 | 27 | False 28 | 29 | 30 | True 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /UnrealPakGUI/UE4.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tshao4/UnrealPakGUI/94b91f005cfdb5f60b73b9fb3d4e38c41118d9a2/UnrealPakGUI/UE4.ico -------------------------------------------------------------------------------- /UnrealPakGUI/UnrealPakGUI.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {7429BFF7-B83B-4006-BD89-E91AF9A64378} 8 | WinExe 9 | UnrealPakGUI 10 | UnrealPakGUI 11 | v4.0 12 | 512 13 | true 14 | publish\ 15 | true 16 | Disk 17 | false 18 | Foreground 19 | 7 20 | Days 21 | false 22 | false 23 | true 24 | 0 25 | 1.0.0.%2a 26 | false 27 | false 28 | true 29 | 30 | 31 | AnyCPU 32 | true 33 | full 34 | false 35 | bin\Debug\ 36 | DEBUG;TRACE 37 | prompt 38 | 4 39 | false 40 | 41 | 42 | AnyCPU 43 | pdbonly 44 | true 45 | bin\Release\ 46 | TRACE 47 | prompt 48 | 4 49 | 50 | 51 | UE4.ico 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | Form 69 | 70 | 71 | Mainform.cs 72 | 73 | 74 | Form 75 | 76 | 77 | FormLogs.cs 78 | 79 | 80 | 81 | 82 | 83 | Mainform.cs 84 | 85 | 86 | FormLogs.cs 87 | 88 | 89 | ResXFileCodeGenerator 90 | Resources.Designer.cs 91 | Designer 92 | 93 | 94 | True 95 | Resources.resx 96 | True 97 | 98 | 99 | 100 | SettingsSingleFileGenerator 101 | Settings.Designer.cs 102 | 103 | 104 | True 105 | Settings.settings 106 | True 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | False 115 | .NET Framework 3.5 SP1 116 | false 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /UnrealPakGUI/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | True 21 | 22 | 23 | 24 | 25 | 26 | True 27 | 28 | 29 | False 30 | 31 | 32 | False 33 | 34 | 35 | True 36 | 37 | 38 | 39 | 40 | 41 | 42 | --------------------------------------------------------------------------------