├── .gitattributes ├── .gitignore ├── FileMonolith ├── ArchiveTransferrer │ ├── App.config │ ├── ArchiveTransferrer.csproj │ ├── FormProcessingTransfer.Designer.cs │ ├── FormProcessingTransfer.cs │ ├── FormProcessingTransfer.resx │ ├── FormTransferrer.Designer.cs │ ├── FormTransferrer.cs │ ├── FormTransferrer.resx │ ├── ProcessingWindow │ │ └── ProcessingWindow.cs │ ├── Program.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ └── TransferManager.cs ├── FileMonolith.sln ├── FileMonolith │ ├── App.config │ ├── ArchiveUnpacker.csproj │ ├── FolderSelectDialog │ │ ├── FolderSelectDialog.cs │ │ └── Reflector.cs │ ├── FormProcessesingUnpack.Designer.cs │ ├── FormProcessesingUnpack.cs │ ├── FormProcessesingUnpack.resx │ ├── FormUnpacker.Designer.cs │ ├── FormUnpacker.cs │ ├── FormUnpacker.resx │ ├── ProcessingWindow │ │ └── ProcessingWindow.cs │ ├── Program.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── UnpackManager.cs │ └── packages.config ├── FileProliferator │ ├── App.config │ ├── AutoPftxsTool │ │ └── ArchiveHandler.cs │ ├── FileProliferator.csproj │ ├── FolderSelectDialog │ │ ├── FolderSelectDialog.cs │ │ └── Reflector.cs │ ├── FormProcessingProliferation.Designer.cs │ ├── FormProcessingProliferation.cs │ ├── FormProcessingProliferation.resx │ ├── FormProliferator.Designer.cs │ ├── FormProliferator.cs │ ├── FormProliferator.resx │ ├── GzsTool │ │ └── Hashing.cs │ ├── ProcessingWindow │ │ └── ProcessingWindow.cs │ ├── Program.cs │ ├── ProliferateManager.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── TextureManager.cs │ └── UpdateManager.cs ├── FilenameUpdater │ ├── App.config │ ├── FilenameUpdater.csproj │ ├── FolderSelectDialog │ │ ├── FolderSelectDialog.cs │ │ └── Reflector.cs │ ├── FormProcessingUpdate.Designer.cs │ ├── FormProcessingUpdate.cs │ ├── FormProcessingUpdate.resx │ ├── FormUpdater.Designer.cs │ ├── FormUpdater.cs │ ├── FormUpdater.resx │ ├── GzsTool │ │ └── Hashing.cs │ ├── ProcessingWindow │ │ └── ProcessingWindow.cs │ ├── Program.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ └── UpdateManager.cs ├── MassTextureConverter │ ├── App.config │ ├── ConvertManager.cs │ ├── FolderSelectDialog │ │ ├── FolderSelectDialog.cs │ │ └── Reflector.cs │ ├── FormMassTexConverter.Designer.cs │ ├── FormMassTexConverter.cs │ ├── FormMassTexConverter.resx │ ├── FormProcessingConversion.Designer.cs │ ├── FormProcessingConversion.cs │ ├── FormProcessingConversion.resx │ ├── MassTextureConverter.csproj │ ├── ProcessingWindow │ │ └── ProcessingWindow.cs │ ├── Program.cs │ └── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings ├── RegexFileCopier │ ├── App.config │ ├── CopyManager.cs │ ├── FormProcessing.Designer.cs │ ├── FormProcessing.cs │ ├── FormProcessing.resx │ ├── FormRegexFileCopier.Designer.cs │ ├── FormRegexFileCopier.cs │ ├── FormRegexFileCopier.resx │ ├── ProcessingWindow │ │ └── ProcessingWindow.cs │ ├── Program.cs │ ├── Properties │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ └── RegexFileCopier.csproj └── TextureAggregator │ ├── AggregateManager.cs │ ├── App.config │ ├── ConvertManager.cs │ ├── FolderSelectDialog │ ├── FolderSelectDialog.cs │ └── Reflector.cs │ ├── FormAggregator.Designer.cs │ ├── FormAggregator.cs │ ├── FormAggregator.resx │ ├── FormProcessing.Designer.cs │ ├── FormProcessing.cs │ ├── FormProcessing.resx │ ├── ProcessingWindow │ └── ProcessingWindow.cs │ ├── Program.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings │ ├── TextureAggregator.csproj │ └── UnpackManager.cs ├── README.md └── lib ├── CityHash.dll ├── FtexTool.dll └── GzsTool.Core.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/ArchiveTransferrer.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {1A8742A5-A5AC-4059-9906-4A1C4AA79539} 8 | WinExe 9 | Properties 10 | ArchiveTransferrer 11 | ArchiveTransferrer 12 | v4.8 13 | 512 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\..\lib\GzsTool.Core.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Form 55 | 56 | 57 | FormProcessingTransfer.cs 58 | 59 | 60 | Form 61 | 62 | 63 | FormTransferrer.cs 64 | 65 | 66 | 67 | 68 | 69 | 70 | FormProcessingTransfer.cs 71 | 72 | 73 | FormTransferrer.cs 74 | 75 | 76 | ResXFileCodeGenerator 77 | Resources.Designer.cs 78 | Designer 79 | 80 | 81 | True 82 | Resources.resx 83 | True 84 | 85 | 86 | SettingsSingleFileGenerator 87 | Settings.Designer.cs 88 | 89 | 90 | True 91 | Settings.settings 92 | True 93 | 94 | 95 | 96 | 97 | 98 | 99 | 106 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/FormProcessingTransfer.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ArchiveTransferrer 2 | { 3 | partial class FormProcessingTransfer 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(FormProcessingTransfer)); 32 | this.pictureSpiral = new System.Windows.Forms.PictureBox(); 33 | this.labelCurrentWork = new System.Windows.Forms.Label(); 34 | this.labelUpdate = new System.Windows.Forms.Label(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // pictureSpiral 39 | // 40 | this.pictureSpiral.Image = ((System.Drawing.Image)(resources.GetObject("pictureSpiral.Image"))); 41 | this.pictureSpiral.Location = new System.Drawing.Point(12, 8); 42 | this.pictureSpiral.Name = "pictureSpiral"; 43 | this.pictureSpiral.Size = new System.Drawing.Size(36, 35); 44 | this.pictureSpiral.TabIndex = 8; 45 | this.pictureSpiral.TabStop = false; 46 | // 47 | // labelCurrentWork 48 | // 49 | this.labelCurrentWork.Location = new System.Drawing.Point(12, 46); 50 | this.labelCurrentWork.Name = "labelCurrentWork"; 51 | this.labelCurrentWork.Size = new System.Drawing.Size(306, 43); 52 | this.labelCurrentWork.TabIndex = 7; 53 | this.labelCurrentWork.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 54 | // 55 | // labelUpdate 56 | // 57 | this.labelUpdate.Location = new System.Drawing.Point(12, 8); 58 | this.labelUpdate.Name = "labelUpdate"; 59 | this.labelUpdate.Size = new System.Drawing.Size(306, 23); 60 | this.labelUpdate.TabIndex = 6; 61 | this.labelUpdate.Text = "Transferring, please wait..."; 62 | this.labelUpdate.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 63 | // 64 | // FormProcessingTransfer 65 | // 66 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 67 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 68 | this.ClientSize = new System.Drawing.Size(318, 86); 69 | this.ControlBox = false; 70 | this.Controls.Add(this.pictureSpiral); 71 | this.Controls.Add(this.labelCurrentWork); 72 | this.Controls.Add(this.labelUpdate); 73 | this.Cursor = System.Windows.Forms.Cursors.WaitCursor; 74 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 75 | this.MaximizeBox = false; 76 | this.MinimizeBox = false; 77 | this.Name = "FormProcessingTransfer"; 78 | this.ShowIcon = false; 79 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 80 | this.Text = "Processing..."; 81 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).EndInit(); 82 | this.ResumeLayout(false); 83 | 84 | } 85 | 86 | #endregion 87 | 88 | private System.Windows.Forms.PictureBox pictureSpiral; 89 | private System.Windows.Forms.Label labelCurrentWork; 90 | private System.Windows.Forms.Label labelUpdate; 91 | } 92 | } -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/FormProcessingTransfer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ArchiveTransferrer 5 | { 6 | public partial class FormProcessingTransfer : Form 7 | { 8 | public FormProcessingTransfer() 9 | { 10 | InitializeComponent(); 11 | } 12 | 13 | public void OnSendFeedback(object source, FeedbackEventArgs e) 14 | { 15 | try 16 | { 17 | labelCurrentWork.Invoke(new Action(() => labelCurrentWork.Text = (string)e.Feedback)); 18 | } 19 | catch 20 | { 21 | MessageBox.Show("Exception occurred during transfer: \n" + (Exception)e.Feedback); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/FormTransferrer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | using ProcessWindow; 12 | 13 | namespace ArchiveTransferrer 14 | { 15 | public partial class FormTransferrer : Form 16 | { 17 | string gzTextureG0s; 18 | string mgoTextureDat; 19 | string tppMasterDir; 20 | 21 | string GZExe; 22 | string TPPExe; 23 | 24 | public FormTransferrer() 25 | { 26 | InitializeComponent(); 27 | /* 28 | string defaultGZExe = Properties.Settings.Default.GZExe; 29 | if (!string.IsNullOrEmpty(defaultGZExe)) 30 | { 31 | if (Directory.Exists(defaultGZExe)) 32 | { 33 | GZExe = defaultGZExe; 34 | textGZEXE.Text = defaultGZExe; 35 | } 36 | } 37 | string defaultTPPExe = Properties.Settings.Default.TPPExe; 38 | if (!string.IsNullOrEmpty(defaultTPPExe)) 39 | { 40 | if (Directory.Exists(defaultTPPExe)) 41 | { 42 | TPPExe = defaultTPPExe; 43 | textTPPEXE.Text = defaultTPPExe; 44 | } 45 | } 46 | 47 | updateTransferButton(); 48 | */ 49 | } 50 | 51 | private void buttonStart_Click(object sender, EventArgs e) 52 | { 53 | 54 | TransferManager transferrer = new TransferManager(); 55 | FormProcessingTransfer processWindow = new FormProcessingTransfer(); 56 | transferrer.SendFeedback += processWindow.OnSendFeedback; 57 | 58 | ProcessingWindow.Show(processWindow, new Action((MethodInvoker)delegate { transferrer.Transfer(gzTextureG0s, mgoTextureDat, tppMasterDir); })); 59 | 60 | if (transferrer.errorOccurred != "") 61 | { 62 | MessageBox.Show("An error occurred while attempting to transfer data:\n" + transferrer.errorOccurred); 63 | } 64 | if (transferrer.successfulTransfers.Count > 0) 65 | { 66 | MessageBox.Show("The following archives were transferred successfully: " + transferrer.GetSuccessfulTransfers()); 67 | } 68 | else 69 | { 70 | MessageBox.Show("No archives were transferred."); 71 | } 72 | } 73 | 74 | private void buttonGZEXE_Click(object sender, EventArgs e) 75 | { 76 | OpenFileDialog inputDialog = new OpenFileDialog(); 77 | inputDialog.Filter = "GZ Executable|MgsGroundZeroes.exe"; 78 | inputDialog.Multiselect = false; 79 | 80 | DialogResult selectionResult = inputDialog.ShowDialog(); 81 | if (selectionResult != DialogResult.OK) return; 82 | textGZEXE.Text = inputDialog.FileName; 83 | 84 | string filename = "data_01.g0s"; 85 | gzTextureG0s = Path.Combine(Path.GetDirectoryName(textGZEXE.Text), filename); 86 | checkForArchive(gzTextureG0s, filename, labelGZFOUND); 87 | 88 | updateTransferButton(); 89 | } 90 | 91 | private void buttonTPPEXE_Click(object sender, EventArgs e) 92 | { 93 | OpenFileDialog inputDialog = new OpenFileDialog(); 94 | inputDialog.Filter = "TPP Executable|mgsvtpp.exe"; 95 | inputDialog.Multiselect = false; 96 | 97 | DialogResult selectionResult = inputDialog.ShowDialog(); 98 | if (selectionResult != DialogResult.OK) return; 99 | textTPPEXE.Text = inputDialog.FileName; 100 | 101 | string filename = "mgo\\texture0.dat"; 102 | mgoTextureDat = Path.Combine(Path.GetDirectoryName(textTPPEXE.Text), filename); 103 | checkForArchive(mgoTextureDat, filename, labelMGOFOUND); 104 | 105 | tppMasterDir = Path.Combine(Path.GetDirectoryName(textTPPEXE.Text), "master"); 106 | updateTransferButton(); 107 | } 108 | 109 | private void checkForArchive(string archivePath, string filename, Label statusLabel) 110 | { 111 | if (File.Exists(archivePath)) 112 | { 113 | statusLabel.Text = string.Format("'{0}' Found!", filename); 114 | statusLabel.ForeColor = Color.ForestGreen; 115 | } 116 | else 117 | { 118 | statusLabel.Text = string.Format("'{0}' Not Found!", filename); 119 | statusLabel.ForeColor = Color.Red; 120 | } 121 | } 122 | 123 | private void updateTransferButton() 124 | { 125 | bool g0sReady = textGZEXE.Text != "" && File.Exists(gzTextureG0s); 126 | bool mgoReady = textTPPEXE.Text != "" && File.Exists(mgoTextureDat); 127 | bool masterExists = Directory.Exists(tppMasterDir); 128 | 129 | buttonStart.Enabled = g0sReady && mgoReady && masterExists; 130 | Console.WriteLine(gzTextureG0s + " | " + mgoTextureDat + " | " + tppMasterDir); 131 | } 132 | 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/ProcessingWindow/ProcessingWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | 5 | namespace ProcessWindow 6 | { 7 | public static class ProcessingWindow 8 | { 9 | public static void Show(Form processWindow, Action WorkerFunction) 10 | { 11 | BackgroundWorker processWorker = new BackgroundWorker(); 12 | 13 | processWorker.DoWork += (obj, var) => { 14 | WorkerFunction(); 15 | }; 16 | processWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object sender, RunWorkerCompletedEventArgs e) 17 | { 18 | processWindow.Invoke((MethodInvoker)delegate 19 | { 20 | processWindow.Close(); 21 | }); 22 | processWorker.Dispose(); 23 | }); 24 | 25 | processWorker.RunWorkerAsync(); 26 | processWindow.ShowDialog(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace ArchiveTransferrer 8 | { 9 | public class FeedbackEventArgs : EventArgs { public object Feedback { get; set; } } 10 | 11 | static class Program 12 | { 13 | /// 14 | /// The main entry point for the application. 15 | /// 16 | [STAThread] 17 | static void Main() 18 | { 19 | Application.EnableVisualStyles(); 20 | Application.SetCompatibleTextRenderingDefault(false); 21 | Application.Run(new FormTransferrer()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/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("ArchiveTransferrer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ArchiveTransferrer")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 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("1a8742a5-a5ac-4059-9906-4a1c4aa79539")] 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 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/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 ArchiveTransferrer.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ArchiveTransferrer.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/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 ArchiveTransferrer.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.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 GZExe { 30 | get { 31 | return ((string)(this["GZExe"])); 32 | } 33 | set { 34 | this["GZExe"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("")] 41 | public string TPPExe { 42 | get { 43 | return ((string)(this["TPPExe"])); 44 | } 45 | set { 46 | this["TPPExe"] = value; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /FileMonolith/ArchiveTransferrer/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.10.35122.118 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchiveUnpacker", "FileMonolith\ArchiveUnpacker.csproj", "{E40EC0B4-4232-417D-B041-97AC71381EA3}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileProliferator", "FileProliferator\FileProliferator.csproj", "{D78BED57-43D5-49C8-8087-49FFC48DAD3D}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MassTextureConverter", "MassTextureConverter\MassTextureConverter.csproj", "{021E8ABB-26CF-4D0B-9494-EC26B6EB0866}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FilenameUpdater", "FilenameUpdater\FilenameUpdater.csproj", "{CEAB3C59-361F-4A88-AA2E-4496D44708EC}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchiveTransferrer", "ArchiveTransferrer\ArchiveTransferrer.csproj", "{1A8742A5-A5AC-4059-9906-4A1C4AA79539}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TextureAggregator", "TextureAggregator\TextureAggregator.csproj", "{6E60F497-0669-450B-BAA0-9E80E8B93739}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RegexFileCopier", "RegexFileCopier\RegexFileCopier.csproj", "{38D3A9A0-1B4F-4D48-85CF-AD18DB2C861E}" 19 | EndProject 20 | Global 21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 22 | Debug|Any CPU = Debug|Any CPU 23 | Release|Any CPU = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 26 | {E40EC0B4-4232-417D-B041-97AC71381EA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {E40EC0B4-4232-417D-B041-97AC71381EA3}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {E40EC0B4-4232-417D-B041-97AC71381EA3}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {E40EC0B4-4232-417D-B041-97AC71381EA3}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {D78BED57-43D5-49C8-8087-49FFC48DAD3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {D78BED57-43D5-49C8-8087-49FFC48DAD3D}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {D78BED57-43D5-49C8-8087-49FFC48DAD3D}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {D78BED57-43D5-49C8-8087-49FFC48DAD3D}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {021E8ABB-26CF-4D0B-9494-EC26B6EB0866}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {021E8ABB-26CF-4D0B-9494-EC26B6EB0866}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {021E8ABB-26CF-4D0B-9494-EC26B6EB0866}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {021E8ABB-26CF-4D0B-9494-EC26B6EB0866}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {CEAB3C59-361F-4A88-AA2E-4496D44708EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {CEAB3C59-361F-4A88-AA2E-4496D44708EC}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {CEAB3C59-361F-4A88-AA2E-4496D44708EC}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {CEAB3C59-361F-4A88-AA2E-4496D44708EC}.Release|Any CPU.Build.0 = Release|Any CPU 42 | {1A8742A5-A5AC-4059-9906-4A1C4AA79539}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 43 | {1A8742A5-A5AC-4059-9906-4A1C4AA79539}.Debug|Any CPU.Build.0 = Debug|Any CPU 44 | {1A8742A5-A5AC-4059-9906-4A1C4AA79539}.Release|Any CPU.ActiveCfg = Release|Any CPU 45 | {1A8742A5-A5AC-4059-9906-4A1C4AA79539}.Release|Any CPU.Build.0 = Release|Any CPU 46 | {6E60F497-0669-450B-BAA0-9E80E8B93739}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 47 | {6E60F497-0669-450B-BAA0-9E80E8B93739}.Debug|Any CPU.Build.0 = Debug|Any CPU 48 | {6E60F497-0669-450B-BAA0-9E80E8B93739}.Release|Any CPU.ActiveCfg = Release|Any CPU 49 | {6E60F497-0669-450B-BAA0-9E80E8B93739}.Release|Any CPU.Build.0 = Release|Any CPU 50 | {38D3A9A0-1B4F-4D48-85CF-AD18DB2C861E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 51 | {38D3A9A0-1B4F-4D48-85CF-AD18DB2C861E}.Debug|Any CPU.Build.0 = Debug|Any CPU 52 | {38D3A9A0-1B4F-4D48-85CF-AD18DB2C861E}.Release|Any CPU.ActiveCfg = Release|Any CPU 53 | {38D3A9A0-1B4F-4D48-85CF-AD18DB2C861E}.Release|Any CPU.Build.0 = Release|Any CPU 54 | EndGlobalSection 55 | GlobalSection(SolutionProperties) = preSolution 56 | HideSolutionNode = FALSE 57 | EndGlobalSection 58 | GlobalSection(ExtensibilityGlobals) = postSolution 59 | SolutionGuid = {D7E3BB46-93A5-4C96-B922-B5FA96B055E9} 60 | EndGlobalSection 61 | EndGlobal 62 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/FolderSelectDialog/FolderSelectDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | // ------------------------------------------------------------------ 5 | // Wraps System.Windows.Forms.OpenFileDialog to make it present 6 | // a vista-style dialog. 7 | // ------------------------------------------------------------------ 8 | 9 | namespace FolderSelect 10 | { 11 | /// 12 | /// Wraps System.Windows.Forms.OpenFileDialog to make it present 13 | /// a vista-style dialog. 14 | /// 15 | public class FolderSelectDialog 16 | { 17 | // Wrapped dialog 18 | private System.Windows.Forms.OpenFileDialog ofd = null; 19 | 20 | /// 21 | /// Default constructor 22 | /// 23 | public FolderSelectDialog() 24 | { 25 | ofd = new System.Windows.Forms.OpenFileDialog(); 26 | 27 | ofd.Filter = "Folders|\n"; 28 | ofd.AddExtension = false; 29 | ofd.CheckFileExists = false; 30 | ofd.DereferenceLinks = true; 31 | ofd.Multiselect = false; 32 | } 33 | 34 | #region Properties 35 | 36 | /// 37 | /// Gets/Sets the initial folder to be selected. A null value selects the current directory. 38 | /// 39 | public string InitialDirectory 40 | { 41 | get { return ofd.InitialDirectory; } 42 | set { ofd.InitialDirectory = value == null || value.Length == 0 ? Environment.CurrentDirectory : value; } 43 | } 44 | 45 | /// 46 | /// Gets/Sets the title to show in the dialog 47 | /// 48 | public string Title 49 | { 50 | get { return ofd.Title; } 51 | set { ofd.Title = value == null ? "Select a folder" : value; } 52 | } 53 | 54 | /// 55 | /// Gets the selected folder 56 | /// 57 | public string FileName 58 | { 59 | get { return ofd.FileName; } 60 | } 61 | 62 | #endregion Properties 63 | 64 | #region Methods 65 | 66 | /// 67 | /// Shows the dialog 68 | /// 69 | /// True if the user presses OK else false 70 | public bool ShowDialog() 71 | { 72 | return ShowDialog(IntPtr.Zero); 73 | } 74 | 75 | /// 76 | /// Shows the dialog 77 | /// 78 | /// Handle of the control to be parent 79 | /// True if the user presses OK else false 80 | public bool ShowDialog(IntPtr hWndOwner) 81 | { 82 | bool flag = false; 83 | 84 | if (Environment.OSVersion.Version.Major >= 6) 85 | { 86 | var r = new Reflector("System.Windows.Forms"); 87 | 88 | uint num = 0; 89 | Type typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); 90 | object dialog = r.Call(ofd, "CreateVistaDialog"); 91 | r.Call(ofd, "OnBeforeVistaDialog", dialog); 92 | 93 | uint options = (uint)r.CallAs(typeof(System.Windows.Forms.FileDialog), ofd, "GetOptions"); 94 | options |= (uint)r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); 95 | r.CallAs(typeIFileDialog, dialog, "SetOptions", options); 96 | 97 | object pfde = r.New("FileDialog.VistaDialogEvents", ofd); 98 | object[] parameters = new object[] { pfde, num }; 99 | r.CallAs2(typeIFileDialog, dialog, "Advise", parameters); 100 | num = (uint)parameters[1]; 101 | try 102 | { 103 | int num2 = (int)r.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); 104 | flag = 0 == num2; 105 | } 106 | finally 107 | { 108 | r.CallAs(typeIFileDialog, dialog, "Unadvise", num); 109 | GC.KeepAlive(pfde); 110 | } 111 | } 112 | else 113 | { 114 | var fbd = new FolderBrowserDialog(); 115 | fbd.Description = this.Title; 116 | fbd.SelectedPath = this.InitialDirectory; 117 | fbd.ShowNewFolderButton = false; 118 | if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK) return false; 119 | ofd.FileName = fbd.SelectedPath; 120 | flag = true; 121 | } 122 | 123 | return flag; 124 | } 125 | 126 | #endregion Methods 127 | } 128 | 129 | /// 130 | /// Creates IWin32Window around an IntPtr 131 | /// 132 | public class WindowWrapper : System.Windows.Forms.IWin32Window 133 | { 134 | /// 135 | /// Constructor 136 | /// 137 | /// Handle to wrap 138 | public WindowWrapper(IntPtr handle) 139 | { 140 | _hwnd = handle; 141 | } 142 | 143 | /// 144 | /// Original ptr 145 | /// 146 | public IntPtr Handle 147 | { 148 | get { return _hwnd; } 149 | } 150 | 151 | private IntPtr _hwnd; 152 | } 153 | } -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/FormProcessesingUnpack.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ArchiveUnpacker 2 | { 3 | partial class FormProcessesingUnpack 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(FormProcessesingUnpack)); 32 | this.labelUnpack = new System.Windows.Forms.Label(); 33 | this.labelCurrentFile = new System.Windows.Forms.Label(); 34 | this.pictureSpiral = new System.Windows.Forms.PictureBox(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // labelUnpack 39 | // 40 | this.labelUnpack.Location = new System.Drawing.Point(12, 8); 41 | this.labelUnpack.Name = "labelUnpack"; 42 | this.labelUnpack.Size = new System.Drawing.Size(306, 23); 43 | this.labelUnpack.TabIndex = 0; 44 | this.labelUnpack.Text = "Unpacking, please wait..."; 45 | this.labelUnpack.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 46 | // 47 | // labelCurrentFile 48 | // 49 | this.labelCurrentFile.Location = new System.Drawing.Point(12, 46); 50 | this.labelCurrentFile.Name = "labelCurrentFile"; 51 | this.labelCurrentFile.Size = new System.Drawing.Size(306, 43); 52 | this.labelCurrentFile.TabIndex = 1; 53 | this.labelCurrentFile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 54 | // 55 | // pictureSpiral 56 | // 57 | this.pictureSpiral.Image = ((System.Drawing.Image)(resources.GetObject("pictureSpiral.Image"))); 58 | this.pictureSpiral.Location = new System.Drawing.Point(12, 8); 59 | this.pictureSpiral.Name = "pictureSpiral"; 60 | this.pictureSpiral.Size = new System.Drawing.Size(36, 35); 61 | this.pictureSpiral.TabIndex = 2; 62 | this.pictureSpiral.TabStop = false; 63 | // 64 | // FormProcessesingUnpack 65 | // 66 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 67 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 68 | this.ClientSize = new System.Drawing.Size(326, 94); 69 | this.ControlBox = false; 70 | this.Controls.Add(this.pictureSpiral); 71 | this.Controls.Add(this.labelCurrentFile); 72 | this.Controls.Add(this.labelUnpack); 73 | this.Cursor = System.Windows.Forms.Cursors.WaitCursor; 74 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 75 | this.MaximizeBox = false; 76 | this.MinimizeBox = false; 77 | this.Name = "FormProcessesingUnpack"; 78 | this.ShowIcon = false; 79 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 80 | this.Text = "Processing..."; 81 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).EndInit(); 82 | this.ResumeLayout(false); 83 | 84 | } 85 | 86 | #endregion 87 | 88 | private System.Windows.Forms.Label labelUnpack; 89 | private System.Windows.Forms.Label labelCurrentFile; 90 | private System.Windows.Forms.PictureBox pictureSpiral; 91 | } 92 | } -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/FormProcessesingUnpack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ArchiveUnpacker 5 | { 6 | public partial class FormProcessesingUnpack : Form 7 | { 8 | public FormProcessesingUnpack() 9 | { 10 | InitializeComponent(); 11 | } 12 | public void OnSendFeedback(object source, FeedbackEventArgs e) 13 | { 14 | if (e.Feedback is string) 15 | { 16 | if (labelCurrentFile.InvokeRequired) 17 | { 18 | labelCurrentFile.Invoke(new Action(() => labelCurrentFile.Text = (string)e.Feedback)); 19 | } 20 | else 21 | { 22 | labelCurrentFile.Text = (string)e.Feedback; 23 | } 24 | } 25 | else if (e.Feedback is Exception) 26 | { 27 | MessageBox.Show("Exception occurred during unpack: \n" + (Exception)e.Feedback); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/FormUnpacker.cs: -------------------------------------------------------------------------------- 1 | using FolderSelect; 2 | using ProcessWindow; 3 | using System; 4 | using System.IO; 5 | using System.Windows.Forms; 6 | 7 | namespace ArchiveUnpacker 8 | { 9 | public partial class FormUnpacker : Form 10 | { 11 | public FormUnpacker() 12 | { 13 | InitializeComponent(); 14 | checkCondenseDir.Checked = true; 15 | } 16 | 17 | private string[] archivePaths { get; set; } 18 | 19 | private string outputDir { get; set; } 20 | 21 | private void buttonArchives_Click(object sender, EventArgs e) 22 | { 23 | OpenFileDialog inputDialog = new OpenFileDialog(); 24 | inputDialog.Filter = "Archive Files (*.dat)|*.dat|Mod Files (*.mgsv)|*.mgsv"; 25 | inputDialog.Multiselect = true; 26 | 27 | DialogResult selectionResult = inputDialog.ShowDialog(); 28 | if (selectionResult != DialogResult.OK) return; 29 | 30 | archivePaths = inputDialog.FileNames; 31 | Array.Sort(archivePaths); Array.Reverse(archivePaths); 32 | 33 | string archiveText = ""; 34 | foreach (string archivePath in archivePaths) 35 | { 36 | string archiveName = Path.GetFileName(archivePath); 37 | string archiveDir = Path.GetFileName(Path.GetDirectoryName(archivePath)); 38 | archiveText += string.Format("\"{0}/{1}\" ", archiveDir, archiveName); 39 | } 40 | textArchives.Text = archiveText; 41 | } 42 | 43 | private void buttonOutDir_Click(object sender, EventArgs e) 44 | { 45 | FolderSelectDialog selectionDialog = new FolderSelectDialog(); 46 | selectionDialog.Title = "Choose a folder where the .dat files will unpack into. Making a new folder is highly recommended."; 47 | 48 | if (textOutDir.Text != "") 49 | selectionDialog.InitialDirectory = textOutDir.Text; 50 | else if (textArchives.Text != "") 51 | selectionDialog.InitialDirectory = Path.GetDirectoryName(archivePaths[0]); 52 | 53 | if (selectionDialog.ShowDialog() != true) return; 54 | string directoryPath = selectionDialog.FileName; 55 | 56 | outputDir = directoryPath; 57 | textOutDir.Text = directoryPath; 58 | } 59 | 60 | private void buttonStart_Click(object sender, EventArgs e) 61 | { 62 | UnpackManager archiveUnpacker = new UnpackManager(); 63 | FormProcessesingUnpack processWindow = new FormProcessesingUnpack(); 64 | archiveUnpacker.SendFeedback += processWindow.OnSendFeedback; 65 | 66 | if (archivePaths != null) 67 | if (outputDir != null) 68 | { 69 | ProcessingWindow.Show(processWindow, new Action((MethodInvoker)delegate { archiveUnpacker.DoUnpack(archivePaths, outputDir, checkCondenseDir.Checked); })); 70 | MessageBox.Show("Done!","Process Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); 71 | } 72 | else 73 | MessageBox.Show("Please select an output folder.", "Missing Output Directory", MessageBoxButtons.OK, MessageBoxIcon.Information); 74 | else 75 | MessageBox.Show("Please choose which archives to unpack.", "No Archives Selected", MessageBoxButtons.OK, MessageBoxIcon.Information); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/ProcessingWindow/ProcessingWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | 5 | namespace ProcessWindow 6 | { 7 | public static class ProcessingWindow 8 | { 9 | public static void Show(Form processWindow, Action WorkerFunction) 10 | { 11 | BackgroundWorker processWorker = new BackgroundWorker(); 12 | 13 | processWorker.DoWork += (obj, var) => { 14 | WorkerFunction(); 15 | }; 16 | processWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object sender, RunWorkerCompletedEventArgs e) 17 | { 18 | processWindow.Invoke((MethodInvoker)delegate 19 | { 20 | processWindow.Close(); 21 | }); 22 | processWorker.Dispose(); 23 | }); 24 | 25 | processWorker.RunWorkerAsync(); 26 | processWindow.ShowDialog(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ArchiveUnpacker 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new FormUnpacker()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/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("ArchiveUnpacker")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ArchiveUnpacker")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 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("e40ec0b4-4232-417d-b041-97ac71381ea3")] 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 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/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 ArchiveUnpacker.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ArchiveUnpacker.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/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 ArchiveUnpacker.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.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 | } 27 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FileMonolith/FileMonolith/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/FileProliferator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D78BED57-43D5-49C8-8087-49FFC48DAD3D} 8 | WinExe 9 | Properties 10 | FileProliferator 11 | File Proliferator 12 | v4.8 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | False 38 | ..\..\lib\CityHash.dll 39 | 40 | 41 | ..\..\lib\FtexTool.dll 42 | 43 | 44 | False 45 | ..\..\lib\GzsTool.Core.dll 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | Form 65 | 66 | 67 | FormProcessingProliferation.cs 68 | 69 | 70 | Form 71 | 72 | 73 | FormProliferator.cs 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | FormProcessingProliferation.cs 84 | 85 | 86 | FormProliferator.cs 87 | 88 | 89 | ResXFileCodeGenerator 90 | Resources.Designer.cs 91 | Designer 92 | 93 | 94 | True 95 | Resources.resx 96 | True 97 | 98 | 99 | SettingsSingleFileGenerator 100 | Settings.Designer.cs 101 | 102 | 103 | True 104 | Settings.settings 105 | True 106 | 107 | 108 | 109 | 110 | 111 | 112 | 119 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/FolderSelectDialog/FolderSelectDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | // ------------------------------------------------------------------ 5 | // Wraps System.Windows.Forms.OpenFileDialog to make it present 6 | // a vista-style dialog. 7 | // ------------------------------------------------------------------ 8 | 9 | namespace FolderSelect 10 | { 11 | /// 12 | /// Wraps System.Windows.Forms.OpenFileDialog to make it present 13 | /// a vista-style dialog. 14 | /// 15 | public class FolderSelectDialog 16 | { 17 | // Wrapped dialog 18 | private System.Windows.Forms.OpenFileDialog ofd = null; 19 | 20 | /// 21 | /// Default constructor 22 | /// 23 | public FolderSelectDialog() 24 | { 25 | ofd = new System.Windows.Forms.OpenFileDialog(); 26 | 27 | ofd.Filter = "Folders|\n"; 28 | ofd.AddExtension = false; 29 | ofd.CheckFileExists = false; 30 | ofd.DereferenceLinks = true; 31 | ofd.Multiselect = false; 32 | } 33 | 34 | #region Properties 35 | 36 | /// 37 | /// Gets/Sets the initial folder to be selected. A null value selects the current directory. 38 | /// 39 | public string InitialDirectory 40 | { 41 | get { return ofd.InitialDirectory; } 42 | set { ofd.InitialDirectory = value == null || value.Length == 0 ? Environment.CurrentDirectory : value; } 43 | } 44 | 45 | /// 46 | /// Gets/Sets the title to show in the dialog 47 | /// 48 | public string Title 49 | { 50 | get { return ofd.Title; } 51 | set { ofd.Title = value == null ? "Select a folder" : value; } 52 | } 53 | 54 | /// 55 | /// Gets the selected folder 56 | /// 57 | public string FileName 58 | { 59 | get { return ofd.FileName; } 60 | } 61 | 62 | #endregion Properties 63 | 64 | #region Methods 65 | 66 | /// 67 | /// Shows the dialog 68 | /// 69 | /// True if the user presses OK else false 70 | public bool ShowDialog() 71 | { 72 | return ShowDialog(IntPtr.Zero); 73 | } 74 | 75 | /// 76 | /// Shows the dialog 77 | /// 78 | /// Handle of the control to be parent 79 | /// True if the user presses OK else false 80 | public bool ShowDialog(IntPtr hWndOwner) 81 | { 82 | bool flag = false; 83 | 84 | if (Environment.OSVersion.Version.Major >= 6) 85 | { 86 | var r = new Reflector("System.Windows.Forms"); 87 | 88 | uint num = 0; 89 | Type typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); 90 | object dialog = r.Call(ofd, "CreateVistaDialog"); 91 | r.Call(ofd, "OnBeforeVistaDialog", dialog); 92 | 93 | uint options = (uint)r.CallAs(typeof(System.Windows.Forms.FileDialog), ofd, "GetOptions"); 94 | options |= (uint)r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); 95 | r.CallAs(typeIFileDialog, dialog, "SetOptions", options); 96 | 97 | object pfde = r.New("FileDialog.VistaDialogEvents", ofd); 98 | object[] parameters = new object[] { pfde, num }; 99 | r.CallAs2(typeIFileDialog, dialog, "Advise", parameters); 100 | num = (uint)parameters[1]; 101 | try 102 | { 103 | int num2 = (int)r.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); 104 | flag = 0 == num2; 105 | } 106 | finally 107 | { 108 | r.CallAs(typeIFileDialog, dialog, "Unadvise", num); 109 | GC.KeepAlive(pfde); 110 | } 111 | } 112 | else 113 | { 114 | var fbd = new FolderBrowserDialog(); 115 | fbd.Description = this.Title; 116 | fbd.SelectedPath = this.InitialDirectory; 117 | fbd.ShowNewFolderButton = false; 118 | if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK) return false; 119 | ofd.FileName = fbd.SelectedPath; 120 | flag = true; 121 | } 122 | 123 | return flag; 124 | } 125 | 126 | #endregion Methods 127 | } 128 | 129 | /// 130 | /// Creates IWin32Window around an IntPtr 131 | /// 132 | public class WindowWrapper : System.Windows.Forms.IWin32Window 133 | { 134 | /// 135 | /// Constructor 136 | /// 137 | /// Handle to wrap 138 | public WindowWrapper(IntPtr handle) 139 | { 140 | _hwnd = handle; 141 | } 142 | 143 | /// 144 | /// Original ptr 145 | /// 146 | public IntPtr Handle 147 | { 148 | get { return _hwnd; } 149 | } 150 | 151 | private IntPtr _hwnd; 152 | } 153 | } -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/FormProcessingProliferation.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FileProliferator 2 | { 3 | partial class FormProcessingProliferation 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(FormProcessingProliferation)); 32 | this.pictureSpiral = new System.Windows.Forms.PictureBox(); 33 | this.labelCurrentFile = new System.Windows.Forms.Label(); 34 | this.labelProliferate = new System.Windows.Forms.Label(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // pictureSpiral 39 | // 40 | this.pictureSpiral.Image = ((System.Drawing.Image)(resources.GetObject("pictureSpiral.Image"))); 41 | this.pictureSpiral.Location = new System.Drawing.Point(12, 8); 42 | this.pictureSpiral.Name = "pictureSpiral"; 43 | this.pictureSpiral.Size = new System.Drawing.Size(36, 35); 44 | this.pictureSpiral.TabIndex = 5; 45 | this.pictureSpiral.TabStop = false; 46 | // 47 | // labelCurrentFile 48 | // 49 | this.labelCurrentFile.Location = new System.Drawing.Point(12, 46); 50 | this.labelCurrentFile.Name = "labelCurrentFile"; 51 | this.labelCurrentFile.Size = new System.Drawing.Size(306, 43); 52 | this.labelCurrentFile.TabIndex = 4; 53 | this.labelCurrentFile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 54 | // 55 | // labelProliferate 56 | // 57 | this.labelProliferate.Location = new System.Drawing.Point(12, 8); 58 | this.labelProliferate.Name = "labelProliferate"; 59 | this.labelProliferate.Size = new System.Drawing.Size(306, 23); 60 | this.labelProliferate.TabIndex = 3; 61 | this.labelProliferate.Text = "Building, please wait..."; 62 | this.labelProliferate.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 63 | // 64 | // FormProcessingProliferation 65 | // 66 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 67 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 68 | this.ClientSize = new System.Drawing.Size(326, 94); 69 | this.ControlBox = false; 70 | this.Controls.Add(this.pictureSpiral); 71 | this.Controls.Add(this.labelCurrentFile); 72 | this.Controls.Add(this.labelProliferate); 73 | this.Cursor = System.Windows.Forms.Cursors.WaitCursor; 74 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 75 | this.MaximizeBox = false; 76 | this.MinimizeBox = false; 77 | this.Name = "FormProcessingProliferation"; 78 | this.ShowIcon = false; 79 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 80 | this.Text = "Processing..."; 81 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).EndInit(); 82 | this.ResumeLayout(false); 83 | 84 | } 85 | 86 | #endregion 87 | 88 | private System.Windows.Forms.PictureBox pictureSpiral; 89 | private System.Windows.Forms.Label labelCurrentFile; 90 | private System.Windows.Forms.Label labelProliferate; 91 | } 92 | } -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/FormProcessingProliferation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace FileProliferator 5 | { 6 | public partial class FormProcessingProliferation : Form 7 | { 8 | public FormProcessingProliferation() 9 | { 10 | InitializeComponent(); 11 | } 12 | 13 | public void OnSendFeedback(object source, FeedbackEventArgs e) 14 | { 15 | try 16 | { 17 | labelCurrentFile.Invoke(new Action(() => labelCurrentFile.Text = (string)e.Feedback)); 18 | } 19 | catch 20 | { 21 | MessageBox.Show("Exception occurred during proliferation: \n" + (Exception)e.Feedback); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/GzsTool/Hashing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace FileProliferator.GzsTool 6 | { 7 | class Hashing 8 | { 9 | private static readonly Dictionary HashNameDictionary = new Dictionary(); 10 | 11 | public const ulong MetaFlag = 0x4000000000000; 12 | 13 | public static void ReadDictionary(string path) 14 | { 15 | foreach (var line in File.ReadAllLines(path)) 16 | { 17 | ulong hash = HashFileName(line) & 0x3FFFFFFFFFFFF; 18 | if (HashNameDictionary.ContainsKey(hash) == false) 19 | { 20 | HashNameDictionary.Add(hash, line); 21 | } 22 | } 23 | } 24 | 25 | public static ulong HashFileName(string text, bool removeExtension = true) 26 | { 27 | if (removeExtension) 28 | { 29 | int index = text.IndexOf('.'); 30 | text = index == -1 ? text : text.Substring(0, index); 31 | } 32 | 33 | bool metaFlag = false; 34 | const string assetsConstant = "/Assets/"; 35 | if (text.StartsWith(assetsConstant)) 36 | { 37 | text = text.Substring(assetsConstant.Length); 38 | 39 | if (text.StartsWith("tpptest")) 40 | { 41 | metaFlag = true; 42 | } 43 | } 44 | else 45 | { 46 | metaFlag = true; 47 | } 48 | 49 | text = text.TrimStart('/'); 50 | 51 | const ulong seed0 = 0x9ae16a3b2f90404f; 52 | byte[] seed1Bytes = new byte[sizeof(ulong)]; 53 | for (int i = text.Length - 1, j = 0; i >= 0 && j < sizeof(ulong); i--, j++) 54 | { 55 | seed1Bytes[j] = Convert.ToByte(text[i]); 56 | } 57 | ulong seed1 = BitConverter.ToUInt64(seed1Bytes, 0); 58 | ulong maskedHash = CityHash.CityHash.CityHash64WithSeeds(text, seed0, seed1) & 0x3FFFFFFFFFFFF; 59 | 60 | return metaFlag 61 | ? maskedHash | MetaFlag 62 | : maskedHash; 63 | } 64 | 65 | internal static bool TryGetFilePathFromHash(ulong hash, out string filePath) 66 | { 67 | bool foundFileName = true; 68 | ulong pathHash = hash & 0x3FFFFFFFFFFFF; 69 | 70 | if (!HashNameDictionary.TryGetValue(pathHash, out filePath)) 71 | { 72 | foundFileName = false; 73 | } 74 | 75 | return foundFileName; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/ProcessingWindow/ProcessingWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | 5 | namespace ProcessWindow 6 | { 7 | public static class ProcessingWindow 8 | { 9 | public static void Show(Form processWindow, Action WorkerFunction) 10 | { 11 | BackgroundWorker processWorker = new BackgroundWorker(); 12 | 13 | processWorker.DoWork += (obj, var) => { 14 | WorkerFunction(); 15 | }; 16 | processWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object sender, RunWorkerCompletedEventArgs e) 17 | { 18 | processWindow.Invoke((MethodInvoker)delegate 19 | { 20 | processWindow.Close(); 21 | }); 22 | processWorker.Dispose(); 23 | }); 24 | 25 | processWorker.RunWorkerAsync(); 26 | processWindow.ShowDialog(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace FileProliferator 8 | { 9 | 10 | public class FeedbackEventArgs : EventArgs { public object Feedback { get; set; } } 11 | 12 | static class Program 13 | { 14 | /// 15 | /// The main entry point for the application. 16 | /// 17 | [STAThread] 18 | static void Main() 19 | { 20 | Application.EnableVisualStyles(); 21 | Application.SetCompatibleTextRenderingDefault(false); 22 | Application.Run(new FormProliferator()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/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("FileProliferator")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FileProliferator")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 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("d78bed57-43d5-49c8-8087-49ffc48dad3d")] 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 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/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 FileProliferator.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FileProliferator.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/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 FileProliferator.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.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 inputDirectory { 30 | get { 31 | return ((string)(this["inputDirectory"])); 32 | } 33 | set { 34 | this["inputDirectory"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("")] 41 | public string outputDirectory { 42 | get { 43 | return ((string)(this["outputDirectory"])); 44 | } 45 | set { 46 | this["outputDirectory"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("")] 53 | public string textureDirectory { 54 | get { 55 | return ((string)(this["textureDirectory"])); 56 | } 57 | set { 58 | this["textureDirectory"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("")] 65 | public string refDirectory { 66 | get { 67 | return ((string)(this["refDirectory"])); 68 | } 69 | set { 70 | this["refDirectory"] = value; 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /FileMonolith/FileProliferator/UpdateManager.cs: -------------------------------------------------------------------------------- 1 | using FileProliferator.GzsTool; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace FileProliferator 11 | { 12 | class UpdateManager 13 | { 14 | private int successfulUpdateCount = 0; 15 | public string errorMsg = ""; 16 | private int totalCount = 0; 17 | 18 | public event EventHandler SendFeedback; 19 | 20 | protected virtual void OnSendFeedback(string feedback) 21 | { 22 | SendFeedback?.Invoke(this, new FeedbackEventArgs() { Feedback = feedback }); 23 | } 24 | 25 | public string[] DoUpdates(string[] inputFilePaths) 26 | { 27 | try 28 | { 29 | ReadDictionary(); 30 | return UpdateFilePaths(inputFilePaths); 31 | } 32 | catch (Exception e) 33 | { 34 | errorMsg = e.Message; 35 | return new string[0]; 36 | } 37 | } 38 | 39 | private string[] UpdateFilePaths(string[] inputFilePaths) 40 | { 41 | 42 | totalCount = inputFilePaths.Length; 43 | for (int i = 0; i < inputFilePaths.Length; i++) 44 | { 45 | string inputFilePath = inputFilePaths[i]; 46 | string filename = Path.GetFileNameWithoutExtension(inputFilePath); 47 | string ext = Path.GetExtension(inputFilePath); 48 | string extInner = ""; 49 | if (filename.Contains(".")) // Ex: .1.ftexs, .eng.lng 50 | { 51 | extInner = Path.GetExtension(filename); 52 | filename = Path.GetFileNameWithoutExtension(filename); 53 | } 54 | bool isUpdated = false; 55 | ulong fileNameHash; 56 | 57 | OnSendFeedback(filename); 58 | 59 | if (TryGetFileNameHash(filename, out fileNameHash)) 60 | { 61 | string foundFilePathNoExt; 62 | string dirPath = Path.GetDirectoryName(inputFilePath); 63 | string outputFilePath; 64 | 65 | if (Hashing.TryGetFilePathFromHash(fileNameHash, out foundFilePathNoExt)) 66 | { 67 | foundFilePathNoExt = foundFilePathNoExt.Remove(0, 1); 68 | outputFilePath = Path.Combine(dirPath, Path.GetFileNameWithoutExtension(foundFilePathNoExt) + extInner + ext); 69 | 70 | 71 | string outputFilePathDir = Path.GetDirectoryName(outputFilePath); 72 | if (!Directory.Exists(outputFilePathDir)) 73 | { 74 | Directory.CreateDirectory(outputFilePathDir); 75 | } 76 | 77 | File.Copy(inputFilePath, outputFilePath, true); 78 | inputFilePaths[i] = outputFilePath; 79 | 80 | isUpdated = true; 81 | } 82 | } 83 | 84 | if (isUpdated) 85 | { 86 | successfulUpdateCount++; 87 | } 88 | else 89 | { 90 | OnSendFeedback(filename + " Update Failed"); 91 | } 92 | 93 | } 94 | return inputFilePaths; 95 | } 96 | 97 | private bool TryGetFileNameHash(string filename, out ulong fileNameHash) 98 | { 99 | bool isConverted = true; 100 | try 101 | { 102 | fileNameHash = Convert.ToUInt64(filename, 16); 103 | } 104 | catch (FormatException) 105 | { 106 | isConverted = false; 107 | fileNameHash = 0; 108 | } 109 | return isConverted; 110 | } 111 | 112 | private static void ReadDictionary() 113 | { 114 | string executingAssemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 115 | const string qarDictionaryName = "qar_dictionary.txt"; 116 | try 117 | { 118 | Hashing.ReadDictionary(Path.Combine(executingAssemblyLocation, qarDictionaryName)); 119 | } 120 | catch (Exception e) 121 | { 122 | Console.WriteLine("Error reading {0}: {1}", qarDictionaryName, e.Message); 123 | } 124 | } 125 | 126 | internal int getSuccessCount() 127 | { 128 | return successfulUpdateCount; 129 | } 130 | 131 | internal int getTotalCount() 132 | { 133 | return totalCount; 134 | } 135 | 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/FilenameUpdater.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CEAB3C59-361F-4A88-AA2E-4496D44708EC} 8 | WinExe 9 | Properties 10 | FilenameUpdater 11 | Filename Updater 12 | v4.8 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\..\lib\CityHash.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Form 56 | 57 | 58 | FormProcessingUpdate.cs 59 | 60 | 61 | Form 62 | 63 | 64 | FormUpdater.cs 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | FormProcessingUpdate.cs 73 | 74 | 75 | FormUpdater.cs 76 | 77 | 78 | ResXFileCodeGenerator 79 | Resources.Designer.cs 80 | Designer 81 | 82 | 83 | True 84 | Resources.resx 85 | True 86 | 87 | 88 | SettingsSingleFileGenerator 89 | Settings.Designer.cs 90 | 91 | 92 | True 93 | Settings.settings 94 | True 95 | 96 | 97 | 98 | 99 | 100 | 101 | 108 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/FolderSelectDialog/FolderSelectDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | // ------------------------------------------------------------------ 5 | // Wraps System.Windows.Forms.OpenFileDialog to make it present 6 | // a vista-style dialog. 7 | // ------------------------------------------------------------------ 8 | 9 | namespace FolderSelect 10 | { 11 | /// 12 | /// Wraps System.Windows.Forms.OpenFileDialog to make it present 13 | /// a vista-style dialog. 14 | /// 15 | public class FolderSelectDialog 16 | { 17 | // Wrapped dialog 18 | private System.Windows.Forms.OpenFileDialog ofd = null; 19 | 20 | /// 21 | /// Default constructor 22 | /// 23 | public FolderSelectDialog() 24 | { 25 | ofd = new System.Windows.Forms.OpenFileDialog(); 26 | 27 | ofd.Filter = "Folders|\n"; 28 | ofd.AddExtension = false; 29 | ofd.CheckFileExists = false; 30 | ofd.DereferenceLinks = true; 31 | ofd.Multiselect = false; 32 | } 33 | 34 | #region Properties 35 | 36 | /// 37 | /// Gets/Sets the initial folder to be selected. A null value selects the current directory. 38 | /// 39 | public string InitialDirectory 40 | { 41 | get { return ofd.InitialDirectory; } 42 | set { ofd.InitialDirectory = value == null || value.Length == 0 ? Environment.CurrentDirectory : value; } 43 | } 44 | 45 | /// 46 | /// Gets/Sets the title to show in the dialog 47 | /// 48 | public string Title 49 | { 50 | get { return ofd.Title; } 51 | set { ofd.Title = value == null ? "Select a folder" : value; } 52 | } 53 | 54 | /// 55 | /// Gets the selected folder 56 | /// 57 | public string FileName 58 | { 59 | get { return ofd.FileName; } 60 | } 61 | 62 | #endregion Properties 63 | 64 | #region Methods 65 | 66 | /// 67 | /// Shows the dialog 68 | /// 69 | /// True if the user presses OK else false 70 | public bool ShowDialog() 71 | { 72 | return ShowDialog(IntPtr.Zero); 73 | } 74 | 75 | /// 76 | /// Shows the dialog 77 | /// 78 | /// Handle of the control to be parent 79 | /// True if the user presses OK else false 80 | public bool ShowDialog(IntPtr hWndOwner) 81 | { 82 | bool flag = false; 83 | 84 | if (Environment.OSVersion.Version.Major >= 6) 85 | { 86 | var r = new Reflector("System.Windows.Forms"); 87 | 88 | uint num = 0; 89 | Type typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); 90 | object dialog = r.Call(ofd, "CreateVistaDialog"); 91 | r.Call(ofd, "OnBeforeVistaDialog", dialog); 92 | 93 | uint options = (uint)r.CallAs(typeof(System.Windows.Forms.FileDialog), ofd, "GetOptions"); 94 | options |= (uint)r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); 95 | r.CallAs(typeIFileDialog, dialog, "SetOptions", options); 96 | 97 | object pfde = r.New("FileDialog.VistaDialogEvents", ofd); 98 | object[] parameters = new object[] { pfde, num }; 99 | r.CallAs2(typeIFileDialog, dialog, "Advise", parameters); 100 | num = (uint)parameters[1]; 101 | try 102 | { 103 | int num2 = (int)r.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); 104 | flag = 0 == num2; 105 | } 106 | finally 107 | { 108 | r.CallAs(typeIFileDialog, dialog, "Unadvise", num); 109 | GC.KeepAlive(pfde); 110 | } 111 | } 112 | else 113 | { 114 | var fbd = new FolderBrowserDialog(); 115 | fbd.Description = this.Title; 116 | fbd.SelectedPath = this.InitialDirectory; 117 | fbd.ShowNewFolderButton = false; 118 | if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK) return false; 119 | ofd.FileName = fbd.SelectedPath; 120 | flag = true; 121 | } 122 | 123 | return flag; 124 | } 125 | 126 | #endregion Methods 127 | } 128 | 129 | /// 130 | /// Creates IWin32Window around an IntPtr 131 | /// 132 | public class WindowWrapper : System.Windows.Forms.IWin32Window 133 | { 134 | /// 135 | /// Constructor 136 | /// 137 | /// Handle to wrap 138 | public WindowWrapper(IntPtr handle) 139 | { 140 | _hwnd = handle; 141 | } 142 | 143 | /// 144 | /// Original ptr 145 | /// 146 | public IntPtr Handle 147 | { 148 | get { return _hwnd; } 149 | } 150 | 151 | private IntPtr _hwnd; 152 | } 153 | } -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/FormProcessingUpdate.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace FilenameUpdater 2 | { 3 | partial class FormProcessingUpdate 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(FormProcessingUpdate)); 32 | this.pictureSpiral = new System.Windows.Forms.PictureBox(); 33 | this.labelCurrentFile = new System.Windows.Forms.Label(); 34 | this.labelUpdate = new System.Windows.Forms.Label(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // pictureSpiral 39 | // 40 | this.pictureSpiral.Image = ((System.Drawing.Image)(resources.GetObject("pictureSpiral.Image"))); 41 | this.pictureSpiral.Location = new System.Drawing.Point(12, 8); 42 | this.pictureSpiral.Name = "pictureSpiral"; 43 | this.pictureSpiral.Size = new System.Drawing.Size(36, 35); 44 | this.pictureSpiral.TabIndex = 8; 45 | this.pictureSpiral.TabStop = false; 46 | // 47 | // labelCurrentFile 48 | // 49 | this.labelCurrentFile.Location = new System.Drawing.Point(12, 46); 50 | this.labelCurrentFile.Name = "labelCurrentFile"; 51 | this.labelCurrentFile.Size = new System.Drawing.Size(306, 43); 52 | this.labelCurrentFile.TabIndex = 7; 53 | this.labelCurrentFile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 54 | // 55 | // labelUpdate 56 | // 57 | this.labelUpdate.Location = new System.Drawing.Point(12, 8); 58 | this.labelUpdate.Name = "labelUpdate"; 59 | this.labelUpdate.Size = new System.Drawing.Size(306, 23); 60 | this.labelUpdate.TabIndex = 6; 61 | this.labelUpdate.Text = "Updating, please wait..."; 62 | this.labelUpdate.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 63 | // 64 | // FormProcessingUpdate 65 | // 66 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 67 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 68 | this.ClientSize = new System.Drawing.Size(322, 90); 69 | this.ControlBox = false; 70 | this.Controls.Add(this.pictureSpiral); 71 | this.Controls.Add(this.labelCurrentFile); 72 | this.Controls.Add(this.labelUpdate); 73 | this.Cursor = System.Windows.Forms.Cursors.WaitCursor; 74 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 75 | this.MaximizeBox = false; 76 | this.MinimizeBox = false; 77 | this.Name = "FormProcessingUpdate"; 78 | this.ShowIcon = false; 79 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 80 | this.Text = "Processing..."; 81 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).EndInit(); 82 | this.ResumeLayout(false); 83 | 84 | } 85 | 86 | #endregion 87 | 88 | private System.Windows.Forms.PictureBox pictureSpiral; 89 | private System.Windows.Forms.Label labelCurrentFile; 90 | private System.Windows.Forms.Label labelUpdate; 91 | } 92 | } -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/FormProcessingUpdate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace FilenameUpdater 5 | { 6 | public partial class FormProcessingUpdate : Form 7 | { 8 | public FormProcessingUpdate() 9 | { 10 | InitializeComponent(); 11 | } 12 | 13 | public void OnSendFeedback(object source, FeedbackEventArgs e) 14 | { 15 | try 16 | { 17 | labelCurrentFile.Invoke(new Action(() => labelCurrentFile.Text = (string)e.Feedback)); 18 | } 19 | catch 20 | { 21 | MessageBox.Show("Exception occurred during update: \n" + (Exception)e.Feedback); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/FormUpdater.cs: -------------------------------------------------------------------------------- 1 | using FolderSelect; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Data; 6 | using System.Drawing; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Text; 10 | using System.Threading.Tasks; 11 | using System.Windows.Forms; 12 | using ProcessWindow; 13 | 14 | namespace FilenameUpdater 15 | { 16 | public partial class FormUpdater : Form 17 | { 18 | public FormUpdater() 19 | { 20 | InitializeComponent(); 21 | 22 | if (!File.Exists("qar_dictionary.txt")) 23 | { 24 | MessageBox.Show("qar_dictionary.txt is missing from the application folder. This tool cannot update filenames without qar_dictionary.txt", "Missing qar_dictionary.txt", MessageBoxButtons.OK, MessageBoxIcon.Warning); 25 | } 26 | } 27 | 28 | private string[] selectedFilePaths { get; set; } 29 | 30 | private string outputDirectory { get; set; } 31 | 32 | private void buttonInFiles_Click(object sender, EventArgs e) 33 | { 34 | OpenFileDialog inputFileDialog = new OpenFileDialog(); 35 | inputFileDialog.Filter = "All files (*.*)|*.*"; 36 | inputFileDialog.Multiselect = true; 37 | 38 | DialogResult selectionResult = inputFileDialog.ShowDialog(); 39 | if (selectionResult != DialogResult.OK) return; 40 | 41 | selectedFilePaths = inputFileDialog.FileNames; 42 | 43 | string filesText = ""; 44 | foreach (string filePath in selectedFilePaths) 45 | { 46 | filesText += string.Format("\"{0}\" ", Path.GetFileName(filePath)); 47 | } 48 | textInFiles.Text = filesText; 49 | } 50 | 51 | private void buttonOutDir_Click(object sender, EventArgs e) 52 | { 53 | FolderSelectDialog selectionDialog = new FolderSelectDialog(); 54 | selectionDialog.Title = "Choose a folder where the updated files will be sent. Making a new folder is highly recommended."; 55 | 56 | if (textOutDir.Text != "") 57 | selectionDialog.InitialDirectory = textOutDir.Text; 58 | else if (textInFiles.Text != "") 59 | selectionDialog.InitialDirectory = Path.GetDirectoryName(selectedFilePaths[0]); 60 | 61 | if (selectionDialog.ShowDialog() != true) return; 62 | string directoryPath = selectionDialog.FileName; 63 | 64 | outputDirectory = directoryPath; 65 | textOutDir.Text = directoryPath; 66 | } 67 | 68 | private void buttonUpdate_Click(object sender, EventArgs e) 69 | { 70 | if (selectedFilePaths == null) 71 | { 72 | MessageBox.Show("Please choose file(s) to update their names.", "No Files Selected", MessageBoxButtons.OK, MessageBoxIcon.Information); 73 | return; 74 | } 75 | if (outputDirectory == null) 76 | { 77 | MessageBox.Show("Please select an output folder.", "No Directory Selected", MessageBoxButtons.OK, MessageBoxIcon.Information); 78 | return; 79 | } 80 | 81 | UpdateManager updater = new UpdateManager(); 82 | FormProcessingUpdate processWindow = new FormProcessingUpdate(); 83 | updater.SendFeedback += processWindow.OnSendFeedback; 84 | 85 | ProcessingWindow.Show(processWindow, new Action((MethodInvoker)delegate { updater.DoUpdates(selectedFilePaths, outputDirectory, checkIncludeDirs.Checked); })); 86 | 87 | int successfulUpdatesCount = updater.getSuccessCount(); 88 | int totalFileCount = updater.getTotalCount(); 89 | if (successfulUpdatesCount > 0) 90 | { 91 | MessageBox.Show(string.Format("{0} of {1} Filename(s) successfully updated.", successfulUpdatesCount, totalFileCount), "Update Results", MessageBoxButtons.OK, MessageBoxIcon.Information); 92 | } 93 | else 94 | { 95 | MessageBox.Show("No filename updates were found.", "Process Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); 96 | } 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/GzsTool/Hashing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace FilenameUpdater.GzsTool 6 | { 7 | class Hashing 8 | { 9 | private static readonly Dictionary HashNameDictionary = new Dictionary(); 10 | 11 | public const ulong MetaFlag = 0x4000000000000; 12 | 13 | public static void ReadDictionary(string path) 14 | { 15 | foreach (var line in File.ReadAllLines(path)) 16 | { 17 | ulong hash = HashFileName(line) & 0x3FFFFFFFFFFFF; 18 | if (HashNameDictionary.ContainsKey(hash) == false) 19 | { 20 | HashNameDictionary.Add(hash, line); 21 | } 22 | } 23 | } 24 | 25 | public static ulong HashFileName(string text, bool removeExtension = true) 26 | { 27 | if (removeExtension) 28 | { 29 | int index = text.IndexOf('.'); 30 | text = index == -1 ? text : text.Substring(0, index); 31 | } 32 | 33 | bool metaFlag = false; 34 | const string assetsConstant = "/Assets/"; 35 | if (text.StartsWith(assetsConstant)) 36 | { 37 | text = text.Substring(assetsConstant.Length); 38 | 39 | if (text.StartsWith("tpptest")) 40 | { 41 | metaFlag = true; 42 | } 43 | } 44 | else 45 | { 46 | metaFlag = true; 47 | } 48 | 49 | text = text.TrimStart('/'); 50 | 51 | const ulong seed0 = 0x9ae16a3b2f90404f; 52 | byte[] seed1Bytes = new byte[sizeof(ulong)]; 53 | for (int i = text.Length - 1, j = 0; i >= 0 && j < sizeof(ulong); i--, j++) 54 | { 55 | seed1Bytes[j] = Convert.ToByte(text[i]); 56 | } 57 | ulong seed1 = BitConverter.ToUInt64(seed1Bytes, 0); 58 | ulong maskedHash = CityHash.CityHash.CityHash64WithSeeds(text, seed0, seed1) & 0x3FFFFFFFFFFFF; 59 | 60 | return metaFlag 61 | ? maskedHash | MetaFlag 62 | : maskedHash; 63 | } 64 | 65 | internal static bool TryGetFilePathFromHash(ulong hash, out string filePath) 66 | { 67 | bool foundFileName = true; 68 | ulong pathHash = hash & 0x3FFFFFFFFFFFF; 69 | 70 | if (!HashNameDictionary.TryGetValue(pathHash, out filePath)) 71 | { 72 | foundFileName = false; 73 | } 74 | 75 | return foundFileName; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/ProcessingWindow/ProcessingWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | 5 | namespace ProcessWindow 6 | { 7 | public static class ProcessingWindow 8 | { 9 | public static void Show(Form processWindow, Action WorkerFunction) 10 | { 11 | BackgroundWorker processWorker = new BackgroundWorker(); 12 | 13 | processWorker.DoWork += (obj, var) => { 14 | WorkerFunction(); 15 | }; 16 | processWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object sender, RunWorkerCompletedEventArgs e) 17 | { 18 | processWindow.Invoke((MethodInvoker)delegate 19 | { 20 | processWindow.Close(); 21 | }); 22 | processWorker.Dispose(); 23 | }); 24 | 25 | processWorker.RunWorkerAsync(); 26 | processWindow.ShowDialog(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace FilenameUpdater 8 | { 9 | 10 | public class FeedbackEventArgs : EventArgs { public object Feedback { get; set; } } 11 | 12 | static class Program 13 | { 14 | /// 15 | /// The main entry point for the application. 16 | /// 17 | [STAThread] 18 | static void Main() 19 | { 20 | Application.EnableVisualStyles(); 21 | Application.SetCompatibleTextRenderingDefault(false); 22 | Application.Run(new FormUpdater()); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/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("FilenameUpdater")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FilenameUpdater")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 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("ceab3c59-361f-4a88-aa2e-4496d44708ec")] 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 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/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 FilenameUpdater.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("FilenameUpdater.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/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 FilenameUpdater.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.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 | } 27 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FileMonolith/FilenameUpdater/UpdateManager.cs: -------------------------------------------------------------------------------- 1 | using FilenameUpdater.GzsTool; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace FilenameUpdater 11 | { 12 | class UpdateManager 13 | { 14 | private int successfulUpdateCount = 0; 15 | private int totalCount = 0; 16 | 17 | public event EventHandler SendFeedback; 18 | 19 | protected virtual void OnSendFeedback(object feedback) 20 | { 21 | SendFeedback?.Invoke(this, new FeedbackEventArgs() { Feedback = feedback }); 22 | } 23 | 24 | public void DoUpdates(string[] inputFilePaths, string outputDir, bool includeDirs) 25 | { 26 | try 27 | { 28 | ReadDictionary(); 29 | UpdateFilePaths(inputFilePaths, outputDir, includeDirs); 30 | } 31 | catch (Exception e) 32 | { 33 | OnSendFeedback(e); 34 | } 35 | } 36 | 37 | private void UpdateFilePaths(string[] inputFilePaths, string outputDir, bool includeDirs) 38 | { 39 | foreach (string inputFilePath in inputFilePaths) 40 | { 41 | totalCount++; 42 | string filename = Path.GetFileNameWithoutExtension(inputFilePath); 43 | string ext = Path.GetExtension(inputFilePath); 44 | string extInner = ""; 45 | if (filename.Contains(".")) // Ex: .1.ftexs, .eng.lng 46 | { 47 | extInner = Path.GetExtension(filename); 48 | filename = Path.GetFileNameWithoutExtension(filename); 49 | } 50 | bool isUpdated = false; 51 | ulong fileNameHash; 52 | 53 | OnSendFeedback(filename); 54 | 55 | if (TryGetFileNameHash(filename, out fileNameHash)) 56 | { 57 | string foundFilePathNoExt; 58 | string outputFilePath; 59 | 60 | if (Hashing.TryGetFilePathFromHash(fileNameHash, out foundFilePathNoExt)) 61 | { 62 | foundFilePathNoExt = foundFilePathNoExt.Remove(0, 1); 63 | if (includeDirs) 64 | { 65 | outputFilePath = Path.Combine(outputDir, foundFilePathNoExt + extInner + ext); 66 | } 67 | else 68 | { 69 | outputFilePath = Path.Combine(outputDir, Path.GetFileNameWithoutExtension(foundFilePathNoExt) + extInner + ext); 70 | } 71 | 72 | string outputFilePathDir = Path.GetDirectoryName(outputFilePath); 73 | if (!Directory.Exists(outputFilePathDir)) 74 | { 75 | Directory.CreateDirectory(outputFilePathDir); 76 | } 77 | File.Copy(inputFilePath, outputFilePath, true); 78 | 79 | isUpdated = true; 80 | } 81 | } 82 | 83 | if (isUpdated) 84 | { 85 | successfulUpdateCount++; 86 | } 87 | else 88 | { 89 | OnSendFeedback(filename + " update not found"); 90 | } 91 | 92 | } 93 | } 94 | 95 | private bool TryGetFileNameHash(string filename, out ulong fileNameHash) 96 | { 97 | bool isConverted = true; 98 | try 99 | { 100 | fileNameHash = Convert.ToUInt64(filename, 16); 101 | } 102 | catch (FormatException) 103 | { 104 | isConverted = false; 105 | fileNameHash = 0; 106 | } 107 | return isConverted; 108 | } 109 | 110 | private static void ReadDictionary() 111 | { 112 | string executingAssemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 113 | const string qarDictionaryName = "qar_dictionary.txt"; 114 | try 115 | { 116 | Hashing.ReadDictionary(Path.Combine(executingAssemblyLocation, qarDictionaryName)); 117 | } 118 | catch (Exception e) 119 | { 120 | Console.WriteLine("Error reading {0}: {1}", qarDictionaryName, e.Message); 121 | } 122 | } 123 | 124 | internal int getSuccessCount() 125 | { 126 | return successfulUpdateCount; 127 | } 128 | 129 | internal int getTotalCount() 130 | { 131 | return totalCount; 132 | } 133 | 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/ConvertManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace MassTextureConverter 5 | { 6 | public class FeedbackEventArgs : EventArgs { public string Feedback { get; set; } } 7 | 8 | public class ConvertManager 9 | { 10 | public event EventHandler SendFeedback; 11 | 12 | private int conversionFailedCount = 0; 13 | private int conversionTryCount = 0; 14 | 15 | protected virtual void OnSendFeedback(string feedback) 16 | { 17 | SendFeedback?.Invoke(this, new FeedbackEventArgs() { Feedback = feedback }); 18 | } 19 | 20 | public void DoMassConversion(string inputDirectory, string outputDirectory, bool subFolders) 21 | { 22 | ConvertTextures(inputDirectory, subFolders, outputDirectory); 23 | } 24 | 25 | private void ConvertTextures(string inputRootDir, bool searchSubFolders, string outputRootDir) 26 | { 27 | int numRemoveRootDir = inputRootDir.Length + 1; 28 | SearchOption searchOpt = new SearchOption(); 29 | if (searchSubFolders) 30 | searchOpt = SearchOption.AllDirectories; 31 | else 32 | searchOpt = SearchOption.TopDirectoryOnly; 33 | 34 | foreach (var ftexFileInfo in new DirectoryInfo(inputRootDir).EnumerateFiles("*.ftex", searchOpt)) 35 | { 36 | conversionTryCount++; 37 | string ddsOutputDir = ftexFileInfo.FullName.Remove(0, numRemoveRootDir); 38 | 39 | OnSendFeedback(ddsOutputDir); 40 | 41 | ddsOutputDir = Path.GetDirectoryName(ddsOutputDir); 42 | ddsOutputDir = Path.Combine(outputRootDir, ddsOutputDir); 43 | 44 | if (!Directory.Exists(ddsOutputDir)) 45 | Directory.CreateDirectory(ddsOutputDir); 46 | 47 | try 48 | { 49 | //string[] ftexArgs = { ftexFileInfo.FullName, ddsOutputDir }; Same outcome, but using UnpackFtexFile directly saves on processing. UnpackFtexFile is private by default, so I made it public in the dll I'm using. 50 | //FtexTool.Program.Main(ftexArgs); 51 | FtexTool.Program.UnpackFtexFile(ftexFileInfo.FullName, ddsOutputDir); 52 | } 53 | catch (FtexTool.Exceptions.MissingFtexsFileException) 54 | { 55 | conversionFailedCount++; 56 | } 57 | } 58 | } 59 | 60 | public int GetFailureCount() 61 | { 62 | return conversionFailedCount; 63 | } 64 | 65 | public int GetTryCount() 66 | { 67 | return conversionTryCount; 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/FolderSelectDialog/FolderSelectDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | // ------------------------------------------------------------------ 5 | // Wraps System.Windows.Forms.OpenFileDialog to make it present 6 | // a vista-style dialog. 7 | // ------------------------------------------------------------------ 8 | 9 | namespace FolderSelect 10 | { 11 | /// 12 | /// Wraps System.Windows.Forms.OpenFileDialog to make it present 13 | /// a vista-style dialog. 14 | /// 15 | public class FolderSelectDialog 16 | { 17 | // Wrapped dialog 18 | private System.Windows.Forms.OpenFileDialog ofd = null; 19 | 20 | /// 21 | /// Default constructor 22 | /// 23 | public FolderSelectDialog() 24 | { 25 | ofd = new System.Windows.Forms.OpenFileDialog(); 26 | 27 | ofd.Filter = "Folders|\n"; 28 | ofd.AddExtension = false; 29 | ofd.CheckFileExists = false; 30 | ofd.DereferenceLinks = true; 31 | ofd.Multiselect = false; 32 | } 33 | 34 | #region Properties 35 | 36 | /// 37 | /// Gets/Sets the initial folder to be selected. A null value selects the current directory. 38 | /// 39 | public string InitialDirectory 40 | { 41 | get { return ofd.InitialDirectory; } 42 | set { ofd.InitialDirectory = value == null || value.Length == 0 ? Environment.CurrentDirectory : value; } 43 | } 44 | 45 | /// 46 | /// Gets/Sets the title to show in the dialog 47 | /// 48 | public string Title 49 | { 50 | get { return ofd.Title; } 51 | set { ofd.Title = value == null ? "Select a folder" : value; } 52 | } 53 | 54 | /// 55 | /// Gets the selected folder 56 | /// 57 | public string FileName 58 | { 59 | get { return ofd.FileName; } 60 | } 61 | 62 | #endregion Properties 63 | 64 | #region Methods 65 | 66 | /// 67 | /// Shows the dialog 68 | /// 69 | /// True if the user presses OK else false 70 | public bool ShowDialog() 71 | { 72 | return ShowDialog(IntPtr.Zero); 73 | } 74 | 75 | /// 76 | /// Shows the dialog 77 | /// 78 | /// Handle of the control to be parent 79 | /// True if the user presses OK else false 80 | public bool ShowDialog(IntPtr hWndOwner) 81 | { 82 | bool flag = false; 83 | 84 | if (Environment.OSVersion.Version.Major >= 6) 85 | { 86 | var r = new Reflector("System.Windows.Forms"); 87 | 88 | uint num = 0; 89 | Type typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); 90 | object dialog = r.Call(ofd, "CreateVistaDialog"); 91 | r.Call(ofd, "OnBeforeVistaDialog", dialog); 92 | 93 | uint options = (uint)r.CallAs(typeof(System.Windows.Forms.FileDialog), ofd, "GetOptions"); 94 | options |= (uint)r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); 95 | r.CallAs(typeIFileDialog, dialog, "SetOptions", options); 96 | 97 | object pfde = r.New("FileDialog.VistaDialogEvents", ofd); 98 | object[] parameters = new object[] { pfde, num }; 99 | r.CallAs2(typeIFileDialog, dialog, "Advise", parameters); 100 | num = (uint)parameters[1]; 101 | try 102 | { 103 | int num2 = (int)r.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); 104 | flag = 0 == num2; 105 | } 106 | finally 107 | { 108 | r.CallAs(typeIFileDialog, dialog, "Unadvise", num); 109 | GC.KeepAlive(pfde); 110 | } 111 | } 112 | else 113 | { 114 | var fbd = new FolderBrowserDialog(); 115 | fbd.Description = this.Title; 116 | fbd.SelectedPath = this.InitialDirectory; 117 | fbd.ShowNewFolderButton = false; 118 | if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK) return false; 119 | ofd.FileName = fbd.SelectedPath; 120 | flag = true; 121 | } 122 | 123 | return flag; 124 | } 125 | 126 | #endregion Methods 127 | } 128 | 129 | /// 130 | /// Creates IWin32Window around an IntPtr 131 | /// 132 | public class WindowWrapper : System.Windows.Forms.IWin32Window 133 | { 134 | /// 135 | /// Constructor 136 | /// 137 | /// Handle to wrap 138 | public WindowWrapper(IntPtr handle) 139 | { 140 | _hwnd = handle; 141 | } 142 | 143 | /// 144 | /// Original ptr 145 | /// 146 | public IntPtr Handle 147 | { 148 | get { return _hwnd; } 149 | } 150 | 151 | private IntPtr _hwnd; 152 | } 153 | } -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/FormMassTexConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using FolderSelect; 4 | using ProcessWindow; 5 | using System.IO; 6 | 7 | namespace MassTextureConverter 8 | { 9 | public partial class FormMassTexConverter : Form 10 | { 11 | private string inputDirectory { get; set; } 12 | 13 | private string outputDirectory { get; set; } 14 | 15 | public FormMassTexConverter() 16 | { 17 | InitializeComponent(); 18 | checkConvertSubfolders.Checked = true; 19 | } 20 | 21 | private void buttonInDir_Click(object sender, EventArgs e) 22 | { 23 | FolderSelectDialog selectionDialog = new FolderSelectDialog(); 24 | selectionDialog.Title = "Select a folder containing .ftex and .ftexs files."; 25 | if (textInDir.Text != null) 26 | selectionDialog.InitialDirectory = textInDir.Text; 27 | if (selectionDialog.ShowDialog() != true) return; 28 | string directoryPath = selectionDialog.FileName; 29 | 30 | textInDir.Text = directoryPath; 31 | inputDirectory = directoryPath; 32 | 33 | } 34 | 35 | private void buttonOutDir_Click(object sender, EventArgs e) 36 | { 37 | FolderSelectDialog selectionDialog = new FolderSelectDialog(); 38 | selectionDialog.Title = "Choose an output folder. Making a new folder is highly recommended."; 39 | 40 | if (textOutDir.Text != "") 41 | selectionDialog.InitialDirectory = textOutDir.Text; 42 | else if (textInDir.Text != "") 43 | selectionDialog.InitialDirectory = inputDirectory; 44 | 45 | if (selectionDialog.ShowDialog() != true) return; 46 | string directoryPath = selectionDialog.FileName; 47 | 48 | textOutDir.Text = directoryPath; 49 | outputDirectory = directoryPath; 50 | } 51 | 52 | private void buttonStart_Click(object sender, EventArgs e) 53 | { 54 | ConvertManager converter = new ConvertManager(); 55 | FormProcessingConversion processWindow = new FormProcessingConversion(); 56 | converter.SendFeedback += processWindow.OnSendFeedback; 57 | 58 | if (inputDirectory != null) 59 | if (outputDirectory != null) 60 | { 61 | ProcessingWindow.Show(processWindow, new Action((MethodInvoker)delegate { converter.DoMassConversion(inputDirectory, outputDirectory, checkConvertSubfolders.Checked); })); 62 | int conversionFailedCount = converter.GetFailureCount(); 63 | int conversionTryCount = converter.GetTryCount(); 64 | if (conversionFailedCount > 0) 65 | MessageBox.Show(string.Format("Process Complete.\n\n{0} of {1} file(s) could not be converted (missing .ftexs).", conversionFailedCount, conversionTryCount), "Process Complete", MessageBoxButtons.OK, MessageBoxIcon.Warning); 66 | else 67 | MessageBox.Show(string.Format("{0} file(s) converted.", conversionTryCount), "Process Complete", MessageBoxButtons.OK, MessageBoxIcon.Information); 68 | } 69 | else 70 | MessageBox.Show("Please select an output folder.", "Missing Output Directory", MessageBoxButtons.OK, MessageBoxIcon.Information); 71 | else 72 | MessageBox.Show("Please select an input folder.", "Missing Input Directory", MessageBoxButtons.OK, MessageBoxIcon.Information); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/FormProcessingConversion.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace MassTextureConverter 2 | { 3 | partial class FormProcessingConversion 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(FormProcessingConversion)); 32 | this.pictureSpiral = new System.Windows.Forms.PictureBox(); 33 | this.labelCurrentFile = new System.Windows.Forms.Label(); 34 | this.labelUnpack = new System.Windows.Forms.Label(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // pictureSpiral 39 | // 40 | this.pictureSpiral.Image = ((System.Drawing.Image)(resources.GetObject("pictureSpiral.Image"))); 41 | this.pictureSpiral.Location = new System.Drawing.Point(12, 8); 42 | this.pictureSpiral.Name = "pictureSpiral"; 43 | this.pictureSpiral.Size = new System.Drawing.Size(36, 35); 44 | this.pictureSpiral.TabIndex = 5; 45 | this.pictureSpiral.TabStop = false; 46 | // 47 | // labelCurrentFile 48 | // 49 | this.labelCurrentFile.Location = new System.Drawing.Point(12, 46); 50 | this.labelCurrentFile.Name = "labelCurrentFile"; 51 | this.labelCurrentFile.Size = new System.Drawing.Size(306, 43); 52 | this.labelCurrentFile.TabIndex = 4; 53 | this.labelCurrentFile.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 54 | // 55 | // labelUnpack 56 | // 57 | this.labelUnpack.Location = new System.Drawing.Point(12, 8); 58 | this.labelUnpack.Name = "labelUnpack"; 59 | this.labelUnpack.Size = new System.Drawing.Size(306, 23); 60 | this.labelUnpack.TabIndex = 3; 61 | this.labelUnpack.Text = "Unpacking, please wait..."; 62 | this.labelUnpack.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 63 | // 64 | // FormProcessingConversion 65 | // 66 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 67 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 68 | this.ClientSize = new System.Drawing.Size(326, 94); 69 | this.ControlBox = false; 70 | this.Controls.Add(this.pictureSpiral); 71 | this.Controls.Add(this.labelCurrentFile); 72 | this.Controls.Add(this.labelUnpack); 73 | this.Cursor = System.Windows.Forms.Cursors.WaitCursor; 74 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 75 | this.MaximizeBox = false; 76 | this.MinimizeBox = false; 77 | this.Name = "FormProcessingConversion"; 78 | this.ShowIcon = false; 79 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 80 | this.Text = "Processing..."; 81 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).EndInit(); 82 | this.ResumeLayout(false); 83 | 84 | } 85 | 86 | #endregion 87 | 88 | private System.Windows.Forms.PictureBox pictureSpiral; 89 | private System.Windows.Forms.Label labelCurrentFile; 90 | private System.Windows.Forms.Label labelUnpack; 91 | } 92 | } -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/FormProcessingConversion.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace MassTextureConverter 5 | { 6 | public partial class FormProcessingConversion : Form 7 | { 8 | public FormProcessingConversion() 9 | { 10 | InitializeComponent(); 11 | } 12 | public void OnSendFeedback(object source, FeedbackEventArgs e) 13 | { 14 | labelCurrentFile.Invoke(new Action(() => labelCurrentFile.Text = e.Feedback)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/MassTextureConverter.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {021E8ABB-26CF-4D0B-9494-EC26B6EB0866} 8 | WinExe 9 | Properties 10 | MassTextureConverter 11 | Mass Texture Converter 12 | v4.8 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\..\lib\FtexTool.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Form 57 | 58 | 59 | FormMassTexConverter.cs 60 | 61 | 62 | Form 63 | 64 | 65 | FormProcessingConversion.cs 66 | 67 | 68 | 69 | 70 | 71 | FormMassTexConverter.cs 72 | 73 | 74 | FormProcessingConversion.cs 75 | 76 | 77 | ResXFileCodeGenerator 78 | Resources.Designer.cs 79 | Designer 80 | 81 | 82 | True 83 | Resources.resx 84 | True 85 | 86 | 87 | SettingsSingleFileGenerator 88 | Settings.Designer.cs 89 | 90 | 91 | True 92 | Settings.settings 93 | True 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 108 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/ProcessingWindow/ProcessingWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | 5 | namespace ProcessWindow 6 | { 7 | public static class ProcessingWindow 8 | { 9 | public static void Show(Form processWindow, Action WorkerFunction) 10 | { 11 | BackgroundWorker processWorker = new BackgroundWorker(); 12 | 13 | processWorker.DoWork += (obj, var) => { 14 | WorkerFunction(); 15 | }; 16 | processWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object sender, RunWorkerCompletedEventArgs e) 17 | { 18 | processWindow.Invoke((MethodInvoker)delegate 19 | { 20 | processWindow.Close(); 21 | }); 22 | processWorker.Dispose(); 23 | }); 24 | 25 | processWorker.RunWorkerAsync(); 26 | processWindow.ShowDialog(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace MassTextureConverter 5 | { 6 | static class Program 7 | { 8 | /// 9 | /// The main entry point for the application. 10 | /// 11 | [STAThread] 12 | static void Main() 13 | { 14 | Application.EnableVisualStyles(); 15 | Application.SetCompatibleTextRenderingDefault(false); 16 | Application.Run(new FormMassTexConverter()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/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("Mass Texture Converter")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Mass Texture Converter")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 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("021e8abb-26cf-4d0b-9494-ec26b6eb0866")] 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 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/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 MassTextureConverter.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MassTextureConverter.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/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 MassTextureConverter.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.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 | } 27 | -------------------------------------------------------------------------------- /FileMonolith/MassTextureConverter/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/CopyManager.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace RegexFileCopier 4 | { 5 | public class FeedbackEventArgs : EventArgs { public object Feedback { get; set; } } 6 | 7 | public class CopyManager 8 | { 9 | public event EventHandler SendFeedback; 10 | 11 | private List files = new List(); 12 | 13 | protected virtual void OnSendFeedback(object feedback) 14 | { 15 | SendFeedback?.Invoke(this, new FeedbackEventArgs() { Feedback = feedback }); 16 | } 17 | 18 | public List DoScan(string inputDir, string strRegex) 19 | { 20 | OnSendFeedback("Scanning files..."); 21 | if (!Directory.Exists(inputDir)) 22 | { 23 | return new List(); 24 | } 25 | 26 | var regex = new Regex(strRegex, RegexOptions.Compiled); 27 | 28 | files = Directory.EnumerateFiles(inputDir, "*", SearchOption.AllDirectories) 29 | .Select(file => Path.GetRelativePath(inputDir, file)) 30 | .Where(file => regex.IsMatch(Path.GetFileName(file))) 31 | .ToList(); 32 | 33 | return files; 34 | } 35 | 36 | public void DoCopy(string inputDir, string outputDir) 37 | { 38 | try 39 | { 40 | if (!Directory.Exists(inputDir)) 41 | { 42 | throw new DirectoryNotFoundException($"The directory '{inputDir}' does not exist."); 43 | } 44 | 45 | if (!Directory.Exists(outputDir)) 46 | { 47 | Directory.CreateDirectory(outputDir); 48 | } 49 | 50 | foreach (var file in files) 51 | { 52 | var sourcePath = Path.Combine(inputDir, file); 53 | var destinationPath = Path.Combine(outputDir, file); 54 | 55 | try 56 | { 57 | var destinationDir = Path.GetDirectoryName(destinationPath); 58 | if (!string.IsNullOrEmpty(destinationDir) && !Directory.Exists(destinationDir)) 59 | { 60 | Directory.CreateDirectory(destinationDir); 61 | } 62 | 63 | OnSendFeedback($"Copying {sourcePath} to {destinationPath}"); 64 | File.Copy(sourcePath, destinationPath, true); 65 | } 66 | catch (Exception fileEx) 67 | { 68 | OnSendFeedback($"Error copying {sourcePath} -> {destinationPath}: {fileEx.Message}"); 69 | } 70 | } 71 | } 72 | catch (Exception e) 73 | { 74 | OnSendFeedback($"Critical Error: {e.Message}"); 75 | } 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/FormProcessing.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace RegexFileCopier 2 | { 3 | partial class FormProcessing 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(FormProcessing)); 32 | labelProcessing = new Label(); 33 | labelCurrentFile = new Label(); 34 | pictureSpiral = new PictureBox(); 35 | ((System.ComponentModel.ISupportInitialize)pictureSpiral).BeginInit(); 36 | SuspendLayout(); 37 | // 38 | // labelProcessing 39 | // 40 | labelProcessing.Location = new Point(14, 9); 41 | labelProcessing.Margin = new Padding(4, 0, 4, 0); 42 | labelProcessing.Name = "labelProcessing"; 43 | labelProcessing.Size = new Size(357, 27); 44 | labelProcessing.TabIndex = 0; 45 | labelProcessing.Text = "Processing, please wait..."; 46 | labelProcessing.TextAlign = ContentAlignment.MiddleCenter; 47 | // 48 | // labelCurrentFile 49 | // 50 | labelCurrentFile.Location = new Point(14, 53); 51 | labelCurrentFile.Margin = new Padding(4, 0, 4, 0); 52 | labelCurrentFile.Name = "labelCurrentFile"; 53 | labelCurrentFile.Size = new Size(357, 50); 54 | labelCurrentFile.TabIndex = 1; 55 | labelCurrentFile.TextAlign = ContentAlignment.MiddleCenter; 56 | // 57 | // pictureSpiral 58 | // 59 | pictureSpiral.Image = (Image)resources.GetObject("pictureSpiral.Image"); 60 | pictureSpiral.Location = new Point(12, 8); 61 | pictureSpiral.Margin = new Padding(4, 3, 4, 3); 62 | pictureSpiral.Name = "pictureSpiral"; 63 | pictureSpiral.Size = new Size(36, 35); 64 | pictureSpiral.TabIndex = 2; 65 | pictureSpiral.TabStop = false; 66 | // 67 | // FormProcessing 68 | // 69 | AutoScaleDimensions = new SizeF(7F, 15F); 70 | AutoScaleMode = AutoScaleMode.Font; 71 | ClientSize = new Size(376, 104); 72 | ControlBox = false; 73 | Controls.Add(pictureSpiral); 74 | Controls.Add(labelCurrentFile); 75 | Controls.Add(labelProcessing); 76 | Cursor = Cursors.WaitCursor; 77 | FormBorderStyle = FormBorderStyle.FixedSingle; 78 | Margin = new Padding(4, 3, 4, 3); 79 | MaximizeBox = false; 80 | MinimizeBox = false; 81 | Name = "FormProcessing"; 82 | ShowIcon = false; 83 | StartPosition = FormStartPosition.CenterParent; 84 | Text = "Processing..."; 85 | ((System.ComponentModel.ISupportInitialize)pictureSpiral).EndInit(); 86 | ResumeLayout(false); 87 | } 88 | 89 | #endregion 90 | 91 | private System.Windows.Forms.Label labelProcessing; 92 | private System.Windows.Forms.Label labelCurrentFile; 93 | private System.Windows.Forms.PictureBox pictureSpiral; 94 | } 95 | } -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/FormProcessing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace RegexFileCopier 12 | { 13 | public partial class FormProcessing : Form 14 | { 15 | public FormProcessing() 16 | { 17 | InitializeComponent(); 18 | } 19 | 20 | public void OnSendFeedback(object source, FeedbackEventArgs e) 21 | { 22 | if (e.Feedback is string) 23 | { 24 | if (labelCurrentFile.InvokeRequired) 25 | { 26 | labelCurrentFile.Invoke(new Action(() => labelCurrentFile.Text = (string)e.Feedback)); 27 | } 28 | else 29 | { 30 | labelCurrentFile.Text = (string)e.Feedback; 31 | } 32 | } 33 | else if (e.Feedback is Exception) 34 | { 35 | MessageBox.Show("Exception occurred during processing: \n" + (Exception)e.Feedback); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/ProcessingWindow/ProcessingWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | 5 | namespace ProcessWindow 6 | { 7 | public static class ProcessingWindow 8 | { 9 | public static void Show(Form processWindow, Action WorkerFunction) 10 | { 11 | BackgroundWorker processWorker = new BackgroundWorker(); 12 | 13 | processWorker.DoWork += (obj, var) => { 14 | WorkerFunction(); 15 | }; 16 | processWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object sender, RunWorkerCompletedEventArgs e) 17 | { 18 | processWindow.Invoke((MethodInvoker)delegate 19 | { 20 | processWindow.Close(); 21 | }); 22 | processWorker.Dispose(); 23 | }); 24 | 25 | processWorker.RunWorkerAsync(); 26 | processWindow.ShowDialog(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/Program.cs: -------------------------------------------------------------------------------- 1 | namespace RegexFileCopier 2 | { 3 | internal static class Program 4 | { 5 | /// 6 | /// The main entry point for the application. 7 | /// 8 | [STAThread] 9 | static void Main() 10 | { 11 | // To customize application configuration such as set high DPI settings or default font, 12 | // see https://aka.ms/applicationconfiguration. 13 | ApplicationConfiguration.Initialize(); 14 | Application.Run(new FormRegexFileCopier()); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/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 RegexFileCopier.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RegexFileCopier.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/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 RegexFileCopier.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.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 inputDirectory { 30 | get { 31 | return ((string)(this["inputDirectory"])); 32 | } 33 | set { 34 | this["inputDirectory"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("")] 41 | public string outputDirectory { 42 | get { 43 | return ((string)(this["outputDirectory"])); 44 | } 45 | set { 46 | this["outputDirectory"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("")] 53 | public string regexText { 54 | get { 55 | return ((string)(this["regexText"])); 56 | } 57 | set { 58 | this["regexText"] = value; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /FileMonolith/RegexFileCopier/RegexFileCopier.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | WinExe 5 | net8.0-windows 6 | enable 7 | true 8 | enable 9 | 10 | 11 | 12 | 13 | True 14 | True 15 | Resources.resx 16 | 17 | 18 | True 19 | True 20 | Settings.settings 21 | 22 | 23 | 24 | 25 | 26 | ResXFileCodeGenerator 27 | Resources.Designer.cs 28 | 29 | 30 | 31 | 32 | 33 | SettingsSingleFileGenerator 34 | Settings.Designer.cs 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/AggregateManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace TextureAggregator 9 | { 10 | class AggregateManager 11 | { 12 | public event EventHandler SendFeedback; 13 | public List errorList = new List(); 14 | 15 | protected virtual void OnSendFeedback(object feedback) 16 | { 17 | SendFeedback?.Invoke(this, new FeedbackEventArgs() { Feedback = feedback }); 18 | } 19 | 20 | public string[] DoAggregate(string[] ftexpaths, string archivePath, string outputDir, bool condense) 21 | { 22 | IEnumerable textures = ftexpaths.Select(file => file.Substring(0, file.Length - 5)); 23 | 24 | OnSendFeedback("Reading TppMasterFileList..."); 25 | string[] TppFileList = File.ReadAllLines("TppMasterFileList.txt"); 26 | IEnumerable ftexsEntries = TppFileList.Where(entry => entry.EndsWith(".ftexs") && !entry.EndsWith(".1.ftexs")); 27 | 28 | OnSendFeedback("Scanning for .pftxs Textures..."); 29 | List pullFiles = new List(); 30 | foreach (string ftexsEntry in ftexsEntries) 31 | { 32 | if (textures.Any(texture => ftexsEntry.StartsWith(texture))) 33 | { 34 | pullFiles.Add(ftexsEntry); 35 | } 36 | } 37 | 38 | foreach (string textureFile in pullFiles) 39 | { 40 | PullFile(Path.Combine(archivePath, textureFile), Path.Combine(outputDir, condense ? Path.GetFileName(textureFile) : textureFile)); 41 | } 42 | 43 | return pullFiles.ToArray(); 44 | } 45 | 46 | 47 | internal void PullFile(string srcPath, string dstPath) 48 | { 49 | if (!File.Exists(dstPath)) // all original .2+.ftexs live outside packs, so the monolith can be condensed or uncondensed 50 | { 51 | if (File.Exists(srcPath)) 52 | { 53 | OnSendFeedback("Copying...\n" + Path.GetFileName(srcPath)); 54 | File.Copy(srcPath, dstPath); 55 | } 56 | else 57 | { 58 | errorList.Add("[Pull file]: Could not find " + srcPath + "\nPerhaps the archives are incomplete?"); 59 | } 60 | } 61 | } 62 | 63 | internal void DeleteFoxTextures(string[] ftexPaths, string[] pulledFtexsPaths, string outputDir, bool condense) 64 | { 65 | IEnumerable ftexRelativePath = condense ? ftexPaths.Select(entry => Path.GetFileNameWithoutExtension(entry)) : ftexPaths.Select(file => file.Substring(0, file.Length - 5)); 66 | OnSendFeedback("Deleting Leftover Fox Textures..."); 67 | foreach (string ftexFile in ftexRelativePath) 68 | { 69 | try 70 | { 71 | string outFile = Path.Combine(outputDir, ftexFile); 72 | 73 | string outdds = outFile + ".dds"; 74 | if (File.Exists(outdds)) 75 | { 76 | string outftex = outFile + ".ftex"; 77 | if (File.Exists(outftex)) 78 | File.Delete(outftex); 79 | 80 | string out1ftexs = outFile + ".1.ftexs"; 81 | if (File.Exists(out1ftexs)) 82 | File.Delete(out1ftexs); 83 | } 84 | } 85 | catch { } 86 | } 87 | 88 | IEnumerable ftexsRelativePath = condense ? pulledFtexsPaths.Select(entry => Path.GetFileName(entry)) : pulledFtexsPaths; 89 | foreach (string ftexsFile in ftexsRelativePath) 90 | { 91 | try 92 | { 93 | string outfile = Path.Combine(outputDir, ftexsFile); 94 | if (File.Exists(outfile)) 95 | File.Delete(outfile); 96 | } 97 | catch { } 98 | } 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/ConvertManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace TextureAggregator 6 | { 7 | public class ConvertManager 8 | { 9 | public event EventHandler SendFeedback; 10 | public List errorList = new List(); 11 | 12 | protected virtual void OnSendFeedback(string feedback) 13 | { 14 | SendFeedback?.Invoke(this, new FeedbackEventArgs() { Feedback = feedback }); 15 | } 16 | 17 | public void DoMassConversion(string inputDirectory, string outputDirectory, bool subFolders) 18 | { 19 | ConvertTextures(inputDirectory, subFolders, outputDirectory); 20 | } 21 | 22 | private void ConvertTextures(string inputRootDir, bool searchSubFolders, string outputRootDir) 23 | { 24 | int numRemoveRootDir = inputRootDir.Length + 1; 25 | SearchOption searchOpt = new SearchOption(); 26 | if (searchSubFolders) 27 | searchOpt = SearchOption.AllDirectories; 28 | else 29 | searchOpt = SearchOption.TopDirectoryOnly; 30 | 31 | foreach (var ftexFileInfo in new DirectoryInfo(inputRootDir).EnumerateFiles("*.ftex", searchOpt)) 32 | { 33 | string ddsOutputDir = ftexFileInfo.FullName.Remove(0, numRemoveRootDir); 34 | string texturename = Path.GetFileName(ftexFileInfo.FullName); 35 | OnSendFeedback("Converting to .dds...\n" + texturename); 36 | 37 | ddsOutputDir = Path.GetDirectoryName(ddsOutputDir); 38 | ddsOutputDir = Path.Combine(outputRootDir, ddsOutputDir); 39 | 40 | if (!Directory.Exists(ddsOutputDir)) 41 | Directory.CreateDirectory(ddsOutputDir); 42 | 43 | try 44 | { 45 | //string[] ftexArgs = { ftexFileInfo.FullName, ddsOutputDir }; Same outcome, but using UnpackFtexFile directly saves on processing. UnpackFtexFile is private by default, so I made it public in the dll I'm using. 46 | //FtexTool.Program.Main(ftexArgs); 47 | FtexTool.Program.UnpackFtexFile(ftexFileInfo.FullName, ddsOutputDir); 48 | } 49 | catch (FtexTool.Exceptions.MissingFtexsFileException) 50 | { 51 | errorList.Add("[Convert .dds]: Failed to convert " + texturename + "\nMissing .ftexs files, likely due to a custom (new) texture."); 52 | } 53 | catch (ArgumentOutOfRangeException) 54 | { 55 | errorList.Add("[Convert .dds]: Failed to convert " + texturename + "\nLikely mismatching .ftexs due to a modded (existing) texture."); 56 | } 57 | catch (Exception e) 58 | { 59 | errorList.Add("[Convert .dds]: Mysteriously failed to convert " + texturename + "\nError message: " + e.Message); 60 | } 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/FolderSelectDialog/FolderSelectDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | // ------------------------------------------------------------------ 5 | // Wraps System.Windows.Forms.OpenFileDialog to make it present 6 | // a vista-style dialog. 7 | // ------------------------------------------------------------------ 8 | 9 | namespace FolderSelect 10 | { 11 | /// 12 | /// Wraps System.Windows.Forms.OpenFileDialog to make it present 13 | /// a vista-style dialog. 14 | /// 15 | public class FolderSelectDialog 16 | { 17 | // Wrapped dialog 18 | private System.Windows.Forms.OpenFileDialog ofd = null; 19 | 20 | /// 21 | /// Default constructor 22 | /// 23 | public FolderSelectDialog() 24 | { 25 | ofd = new System.Windows.Forms.OpenFileDialog(); 26 | 27 | ofd.Filter = "Folders|\n"; 28 | ofd.AddExtension = false; 29 | ofd.CheckFileExists = false; 30 | ofd.DereferenceLinks = true; 31 | ofd.Multiselect = false; 32 | } 33 | 34 | #region Properties 35 | 36 | /// 37 | /// Gets/Sets the initial folder to be selected. A null value selects the current directory. 38 | /// 39 | public string InitialDirectory 40 | { 41 | get { return ofd.InitialDirectory; } 42 | set { ofd.InitialDirectory = value == null || value.Length == 0 ? Environment.CurrentDirectory : value; } 43 | } 44 | 45 | /// 46 | /// Gets/Sets the title to show in the dialog 47 | /// 48 | public string Title 49 | { 50 | get { return ofd.Title; } 51 | set { ofd.Title = value == null ? "Select a folder" : value; } 52 | } 53 | 54 | /// 55 | /// Gets the selected folder 56 | /// 57 | public string FileName 58 | { 59 | get { return ofd.FileName; } 60 | } 61 | 62 | #endregion Properties 63 | 64 | #region Methods 65 | 66 | /// 67 | /// Shows the dialog 68 | /// 69 | /// True if the user presses OK else false 70 | public bool ShowDialog() 71 | { 72 | return ShowDialog(IntPtr.Zero); 73 | } 74 | 75 | /// 76 | /// Shows the dialog 77 | /// 78 | /// Handle of the control to be parent 79 | /// True if the user presses OK else false 80 | public bool ShowDialog(IntPtr hWndOwner) 81 | { 82 | bool flag = false; 83 | 84 | if (Environment.OSVersion.Version.Major >= 6) 85 | { 86 | var r = new Reflector("System.Windows.Forms"); 87 | 88 | uint num = 0; 89 | Type typeIFileDialog = r.GetType("FileDialogNative.IFileDialog"); 90 | object dialog = r.Call(ofd, "CreateVistaDialog"); 91 | r.Call(ofd, "OnBeforeVistaDialog", dialog); 92 | 93 | uint options = (uint)r.CallAs(typeof(System.Windows.Forms.FileDialog), ofd, "GetOptions"); 94 | options |= (uint)r.GetEnum("FileDialogNative.FOS", "FOS_PICKFOLDERS"); 95 | r.CallAs(typeIFileDialog, dialog, "SetOptions", options); 96 | 97 | object pfde = r.New("FileDialog.VistaDialogEvents", ofd); 98 | object[] parameters = new object[] { pfde, num }; 99 | r.CallAs2(typeIFileDialog, dialog, "Advise", parameters); 100 | num = (uint)parameters[1]; 101 | try 102 | { 103 | int num2 = (int)r.CallAs(typeIFileDialog, dialog, "Show", hWndOwner); 104 | flag = 0 == num2; 105 | } 106 | finally 107 | { 108 | r.CallAs(typeIFileDialog, dialog, "Unadvise", num); 109 | GC.KeepAlive(pfde); 110 | } 111 | } 112 | else 113 | { 114 | var fbd = new FolderBrowserDialog(); 115 | fbd.Description = this.Title; 116 | fbd.SelectedPath = this.InitialDirectory; 117 | fbd.ShowNewFolderButton = false; 118 | if (fbd.ShowDialog(new WindowWrapper(hWndOwner)) != DialogResult.OK) return false; 119 | ofd.FileName = fbd.SelectedPath; 120 | flag = true; 121 | } 122 | 123 | return flag; 124 | } 125 | 126 | #endregion Methods 127 | } 128 | 129 | /// 130 | /// Creates IWin32Window around an IntPtr 131 | /// 132 | public class WindowWrapper : System.Windows.Forms.IWin32Window 133 | { 134 | /// 135 | /// Constructor 136 | /// 137 | /// Handle to wrap 138 | public WindowWrapper(IntPtr handle) 139 | { 140 | _hwnd = handle; 141 | } 142 | 143 | /// 144 | /// Original ptr 145 | /// 146 | public IntPtr Handle 147 | { 148 | get { return _hwnd; } 149 | } 150 | 151 | private IntPtr _hwnd; 152 | } 153 | } -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/FormProcessing.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TextureAggregator 2 | { 3 | partial class FormProcessing 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(FormProcessing)); 32 | this.pictureSpiral = new System.Windows.Forms.PictureBox(); 33 | this.labelCurrentWork = new System.Windows.Forms.Label(); 34 | this.labelUpdate = new System.Windows.Forms.Label(); 35 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).BeginInit(); 36 | this.SuspendLayout(); 37 | // 38 | // pictureSpiral 39 | // 40 | this.pictureSpiral.Image = ((System.Drawing.Image)(resources.GetObject("pictureSpiral.Image"))); 41 | this.pictureSpiral.Location = new System.Drawing.Point(12, 8); 42 | this.pictureSpiral.Name = "pictureSpiral"; 43 | this.pictureSpiral.Size = new System.Drawing.Size(36, 35); 44 | this.pictureSpiral.TabIndex = 8; 45 | this.pictureSpiral.TabStop = false; 46 | // 47 | // labelCurrentWork 48 | // 49 | this.labelCurrentWork.Location = new System.Drawing.Point(12, 46); 50 | this.labelCurrentWork.Name = "labelCurrentWork"; 51 | this.labelCurrentWork.Size = new System.Drawing.Size(306, 43); 52 | this.labelCurrentWork.TabIndex = 7; 53 | this.labelCurrentWork.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 54 | // 55 | // labelUpdate 56 | // 57 | this.labelUpdate.Location = new System.Drawing.Point(12, 8); 58 | this.labelUpdate.Name = "labelUpdate"; 59 | this.labelUpdate.Size = new System.Drawing.Size(306, 23); 60 | this.labelUpdate.TabIndex = 6; 61 | this.labelUpdate.Text = "Processing, please wait..."; 62 | this.labelUpdate.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 63 | // 64 | // FormProcessing 65 | // 66 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 67 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 68 | this.ClientSize = new System.Drawing.Size(314, 82); 69 | this.ControlBox = false; 70 | this.Controls.Add(this.pictureSpiral); 71 | this.Controls.Add(this.labelCurrentWork); 72 | this.Controls.Add(this.labelUpdate); 73 | this.Cursor = System.Windows.Forms.Cursors.WaitCursor; 74 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 75 | this.MaximizeBox = false; 76 | this.MinimizeBox = false; 77 | this.Name = "FormProcessing"; 78 | this.ShowIcon = false; 79 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 80 | this.Text = "Processing..."; 81 | ((System.ComponentModel.ISupportInitialize)(this.pictureSpiral)).EndInit(); 82 | this.ResumeLayout(false); 83 | 84 | } 85 | 86 | #endregion 87 | 88 | private System.Windows.Forms.PictureBox pictureSpiral; 89 | private System.Windows.Forms.Label labelCurrentWork; 90 | private System.Windows.Forms.Label labelUpdate; 91 | } 92 | } -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/FormProcessing.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace TextureAggregator 5 | { 6 | public partial class FormProcessing : Form 7 | { 8 | public FormProcessing() 9 | { 10 | InitializeComponent(); 11 | } 12 | 13 | public void OnSendFeedback(object source, FeedbackEventArgs e) 14 | { 15 | try 16 | { 17 | labelCurrentWork.Invoke(new Action(() => labelCurrentWork.Text = (string)e.Feedback)); 18 | } 19 | catch 20 | { 21 | MessageBox.Show("Exception occurred during transfer: \n" + e.Feedback); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/ProcessingWindow/ProcessingWindow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Windows.Forms; 4 | 5 | namespace ProcessWindow 6 | { 7 | public static class ProcessingWindow 8 | { 9 | public static void Show(Form processWindow, Action WorkerFunction) 10 | { 11 | BackgroundWorker processWorker = new BackgroundWorker(); 12 | 13 | processWorker.DoWork += (obj, var) => { 14 | WorkerFunction(); 15 | }; 16 | processWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate (object sender, RunWorkerCompletedEventArgs e) 17 | { 18 | processWindow.Invoke((MethodInvoker)delegate 19 | { 20 | processWindow.Close(); 21 | }); 22 | processWorker.Dispose(); 23 | }); 24 | 25 | processWorker.RunWorkerAsync(); 26 | processWindow.ShowDialog(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace TextureAggregator 8 | { 9 | public class FeedbackEventArgs : EventArgs { public object Feedback { get; set; } } 10 | 11 | static class Program 12 | { 13 | /// 14 | /// The main entry point for the application. 15 | /// 16 | [STAThread] 17 | static void Main() 18 | { 19 | Application.EnableVisualStyles(); 20 | Application.SetCompatibleTextRenderingDefault(false); 21 | Application.Run(new FormAggregator()); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/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("TextureAggregator")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TextureAggregator")] 13 | [assembly: AssemblyCopyright("Copyright © 2020")] 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("6e60f497-0669-450b-baa0-9e80e8b93739")] 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 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/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 TextureAggregator.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TextureAggregator.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/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 TextureAggregator.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.10.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 textureDirectory { 30 | get { 31 | return ((string)(this["textureDirectory"])); 32 | } 33 | set { 34 | this["textureDirectory"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("")] 41 | public string outputDirectory { 42 | get { 43 | return ((string)(this["outputDirectory"])); 44 | } 45 | set { 46 | this["outputDirectory"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("")] 53 | public string inputPftxs { 54 | get { 55 | return ((string)(this["inputPftxs"])); 56 | } 57 | set { 58 | this["inputPftxs"] = value; 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/TextureAggregator.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6E60F497-0669-450B-BAA0-9E80E8B93739} 8 | WinExe 9 | Properties 10 | TextureAggregator 11 | TextureAggregator 12 | v4.8 13 | 512 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\..\lib\FtexTool.dll 39 | 40 | 41 | ..\..\lib\GzsTool.Core.dll 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | Form 62 | 63 | 64 | FormAggregator.cs 65 | 66 | 67 | Form 68 | 69 | 70 | FormProcessing.cs 71 | 72 | 73 | 74 | 75 | 76 | 77 | FormAggregator.cs 78 | 79 | 80 | FormProcessing.cs 81 | 82 | 83 | ResXFileCodeGenerator 84 | Resources.Designer.cs 85 | Designer 86 | 87 | 88 | True 89 | Resources.resx 90 | True 91 | 92 | 93 | SettingsSingleFileGenerator 94 | Settings.Designer.cs 95 | 96 | 97 | True 98 | Settings.settings 99 | True 100 | 101 | 102 | 103 | 104 | 105 | 106 | 113 | -------------------------------------------------------------------------------- /FileMonolith/TextureAggregator/UnpackManager.cs: -------------------------------------------------------------------------------- 1 | using GzsTool.Core.Common; 2 | using GzsTool.Core.Common.Interfaces; 3 | using GzsTool.Core.Fpk; 4 | using GzsTool.Core.Pftxs; 5 | using GzsTool.Core.Qar; 6 | using GzsTool.Core.Sbp; 7 | using GzsTool.Core.Utility; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.IO; 11 | using System.Linq; 12 | using System.Reflection; 13 | using System.Windows.Forms; 14 | 15 | namespace TextureAggregator 16 | { 17 | 18 | public class UnpackManager 19 | { 20 | 21 | public event EventHandler SendFeedback; 22 | public string err = ""; 23 | 24 | protected virtual void OnSendFeedback(object feedback) 25 | { 26 | SendFeedback?.Invoke(this, new FeedbackEventArgs() { Feedback = feedback }); 27 | } 28 | 29 | public string[] DoUnpack(string pftxsPath, string outputDir, bool condense) 30 | { 31 | try 32 | { 33 | OnSendFeedback("Reading Dictionaries..."); 34 | ReadDictionaries(); 35 | } catch (Exception e) 36 | { 37 | err = "[Unpack .pftxs]: Failed to read qar_dictionary.txt"; 38 | } 39 | 40 | OnSendFeedback(string.Format("Unpacking {0}...", Path.GetFileName(pftxsPath))); 41 | try 42 | { 43 | var unpackedFiles = ReadArchive(pftxsPath, outputDir, condense); 44 | return unpackedFiles.Where(file => file.EndsWith(".ftex")).ToArray(); 45 | } catch (Exception e) 46 | { 47 | err = "[Unpack .pftxs]: Failed to unpack .pftxs file"; 48 | } 49 | return new string[] { }; 50 | } 51 | 52 | private void ReadDictionaries() 53 | { 54 | string executingAssemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 55 | const string qarDictionaryName = "qar_dictionary.txt"; 56 | try 57 | { 58 | Hashing.ReadDictionary(Path.Combine(executingAssemblyLocation, qarDictionaryName)); 59 | } 60 | catch (Exception e) 61 | { 62 | Console.WriteLine("Error reading {0}: {1}", qarDictionaryName, e.Message); 63 | } 64 | } 65 | 66 | public List ReadArchive(string filePath, string outputDir, bool condense) where T : ArchiveFile, new() 67 | { 68 | IDirectory iDir = new FileSystemDirectory(outputDir); 69 | List fileNames = new List(); 70 | 71 | using (FileStream input = new FileStream(filePath, FileMode.Open)) 72 | { 73 | T file = new T(); 74 | file.Read(input); 75 | foreach (var exportedFile in file.ExportFiles(input)) 76 | { 77 | fileNames.Add(exportedFile.FileName); 78 | 79 | string name = condense ? Path.GetFileName(exportedFile.FileName) : exportedFile.FileName; 80 | 81 | string exportedFileFullName = Path.Combine(outputDir, name); 82 | if (!File.Exists(exportedFileFullName)) 83 | { 84 | iDir.WriteFile(name, exportedFile.DataStream); 85 | } 86 | } 87 | } 88 | return fileNames; 89 | } 90 | 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /lib/CityHash.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morbidslinky/FileMonolith/4a60718ad41465e195cb568395eac871fffcfc0d/lib/CityHash.dll -------------------------------------------------------------------------------- /lib/FtexTool.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morbidslinky/FileMonolith/4a60718ad41465e195cb568395eac871fffcfc0d/lib/FtexTool.dll -------------------------------------------------------------------------------- /lib/GzsTool.Core.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/morbidslinky/FileMonolith/4a60718ad41465e195cb568395eac871fffcfc0d/lib/GzsTool.Core.dll --------------------------------------------------------------------------------