├── .github └── FUNDING.yml ├── .gitignore ├── .gitmodules ├── CASCConsole ├── CASCConsole.csproj ├── CASCConsole.csproj.user ├── Program.cs └── Properties │ ├── PublishProfiles │ ├── publish_linux.pubxml │ └── publish_win.pubxml │ └── launchSettings.json ├── CASCExplorer.ViewPlugin ├── CASCExplorer.ViewPlugin.csproj ├── IPreview.cs ├── Previews │ ├── BlpView.Designer.cs │ ├── BlpView.cs │ ├── BlpView.resx │ ├── HexView.Designer.cs │ ├── HexView.cs │ ├── HexView.resx │ ├── TextView.Designer.cs │ ├── TextView.cs │ └── TextView.resx └── Properties │ └── AssemblyInfo.cs ├── CASCExplorer.sln ├── CASCExplorer ├── AboutBox.Designer.cs ├── AboutBox.cs ├── AboutBox.resx ├── App.config ├── Bruteforce.cs ├── BruteforceForm.Designer.cs ├── BruteforceForm.cs ├── BruteforceForm.resx ├── CASCEntrySorter.cs ├── CASCExplorer.csproj ├── CASCViewHelper.cs ├── DB2Reader.cs ├── ExtractProgress.Designer.cs ├── ExtractProgress.cs ├── ExtractProgress.resx ├── FileScanner.cs ├── Icons │ ├── CASCExplorer.ico │ ├── folder.ico │ └── openFolder.ico ├── InitForm.Designer.cs ├── InitForm.cs ├── InitForm.resx ├── MainForm.Designer.cs ├── MainForm.cs ├── MainForm.resx ├── NoFlickerListView.cs ├── OpenStorageForm.Designer.cs ├── OpenStorageForm.cs ├── OpenStorageForm.resx ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── RecentStorage.cs ├── Resources │ ├── logo.png │ └── transparent.png ├── ScanForm.Designer.cs ├── ScanForm.cs ├── ScanForm.resx ├── SearchForm.Designer.cs ├── SearchForm.cs ├── SearchForm.resx ├── SelectBuildForm.Designer.cs ├── SelectBuildForm.cs ├── SelectBuildForm.resx ├── WDB2Reader.cs ├── WDB3Reader.cs ├── WDB5Reader.cs ├── WDB6Reader.cs ├── WDBCReader.cs ├── WDC1Reader.cs ├── WDC2Reader.cs ├── WDC2ReaderGeneric.cs ├── WDC3Reader.cs ├── WDC3ReaderGeneric.cs └── app.manifest └── README.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CFDMAA6ELV2G8 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/* 2 | *.sln.ide 3 | *.suo 4 | [Bb]in 5 | [Oo]bj 6 | *.user 7 | packages/* 8 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "SereniaBLPLib"] 2 | path = SereniaBLPLib 3 | url = https://github.com/WoW-Tools/SereniaBLPLib.git 4 | [submodule "CascLib"] 5 | path = CascLib 6 | url = https://github.com/WoW-Tools/CascLib.git 7 | -------------------------------------------------------------------------------- /CASCConsole/CASCConsole.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net48;net6.0;net7.0;net8.0 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /CASCConsole/CASCConsole.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | <_LastSelectedProfileId>E:\Dev\WoW\tools\CASCExplorer\CASCConsole\Properties\PublishProfiles\publish_win.pubxml 5 | net48 6 | 7 | -------------------------------------------------------------------------------- /CASCConsole/Properties/PublishProfiles/publish_linux.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\publish_linux-x64\ 10 | FileSystem 11 | net6.0 12 | linux-x64 13 | true 14 | true 15 | true 16 | 17 | -------------------------------------------------------------------------------- /CASCConsole/Properties/PublishProfiles/publish_win.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | Release 8 | Any CPU 9 | bin\Release\publish_win-x64\ 10 | FileSystem 11 | net6.0 12 | win-x64 13 | true 14 | true 15 | false 16 | true 17 | 18 | -------------------------------------------------------------------------------- /CASCConsole/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "CASCConsole": { 4 | "commandName": "Project", 5 | "commandLineArgs": "-m pattern -o -e *.cur -d test -l enUS -p fenris" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/CASCExplorer.ViewPlugin.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {63C32AC8-2EE2-4DB7-99C5-84FD815AADC3} 8 | Library 9 | Properties 10 | CASCExplorer.ViewPlugin 11 | CASCExplorer.ViewPlugin 12 | v4.8 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | UserControl 41 | 42 | 43 | BlpView.cs 44 | 45 | 46 | UserControl 47 | 48 | 49 | HexView.cs 50 | 51 | 52 | 53 | UserControl 54 | 55 | 56 | TextView.cs 57 | 58 | 59 | 60 | 61 | 62 | BlpView.cs 63 | 64 | 65 | HexView.cs 66 | 67 | 68 | TextView.cs 69 | 70 | 71 | 72 | 73 | {4ed9f877-a9bb-470f-b35c-694147472080} 74 | SereniaBLPLib 75 | 76 | 77 | 78 | 79 | 1.6.1 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/IPreview.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Windows.Forms; 3 | 4 | namespace CASCExplorer.ViewPlugin 5 | { 6 | public interface IExtensions 7 | { 8 | string[] Extensions { get; } 9 | } 10 | 11 | public interface IPreview 12 | { 13 | Control Show(Stream stream, string fileName); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/BlpView.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer.DefaultViews.Previews 2 | { 3 | partial class BlpView 4 | { 5 | /// 6 | /// Обязательная переменная конструктора. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Освободить все используемые ресурсы. 12 | /// 13 | /// истинно, если управляемый ресурс должен быть удален; иначе ложно. 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 Код, автоматически созданный конструктором компонентов 24 | 25 | /// 26 | /// Требуемый метод для поддержки конструктора — не изменяйте 27 | /// содержимое этого метода с помощью редактора кода. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.cbMipIndex = new System.Windows.Forms.ComboBox(); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.bSave = new System.Windows.Forms.Button(); 34 | this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); 35 | this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); 36 | this.pictureBox1 = new System.Windows.Forms.PictureBox(); 37 | this.flowLayoutPanel1.SuspendLayout(); 38 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit(); 39 | this.SuspendLayout(); 40 | // 41 | // cbMipIndex 42 | // 43 | this.cbMipIndex.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 44 | this.cbMipIndex.FormattingEnabled = true; 45 | this.cbMipIndex.Location = new System.Drawing.Point(79, 3); 46 | this.cbMipIndex.Name = "cbMipIndex"; 47 | this.cbMipIndex.Size = new System.Drawing.Size(121, 21); 48 | this.cbMipIndex.TabIndex = 1; 49 | this.cbMipIndex.SelectedIndexChanged += new System.EventHandler(this.cbMipIndex_SelectedIndexChanged); 50 | // 51 | // label1 52 | // 53 | this.label1.AutoSize = true; 54 | this.label1.Location = new System.Drawing.Point(10, 6); 55 | this.label1.Name = "label1"; 56 | this.label1.Size = new System.Drawing.Size(55, 13); 57 | this.label1.TabIndex = 2; 58 | this.label1.Text = "Mip index:"; 59 | // 60 | // bSave 61 | // 62 | this.bSave.Location = new System.Drawing.Point(217, 3); 63 | this.bSave.Name = "bSave"; 64 | this.bSave.Size = new System.Drawing.Size(75, 21); 65 | this.bSave.TabIndex = 3; 66 | this.bSave.Text = "Save"; 67 | this.bSave.UseVisualStyleBackColor = true; 68 | this.bSave.Click += new System.EventHandler(this.bSave_Click); 69 | // 70 | // saveFileDialog1 71 | // 72 | this.saveFileDialog1.Filter = "BMP Files (*.bmp)|*.bmp|JPEG Files (*.jpeg)|*.jpeg|PNG Files (*.png)|*.png"; 73 | // 74 | // flowLayoutPanel1 75 | // 76 | this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 77 | | System.Windows.Forms.AnchorStyles.Left) 78 | | System.Windows.Forms.AnchorStyles.Right))); 79 | this.flowLayoutPanel1.AutoScroll = true; 80 | this.flowLayoutPanel1.Controls.Add(this.pictureBox1); 81 | this.flowLayoutPanel1.Location = new System.Drawing.Point(3, 30); 82 | this.flowLayoutPanel1.Name = "flowLayoutPanel1"; 83 | this.flowLayoutPanel1.Size = new System.Drawing.Size(396, 310); 84 | this.flowLayoutPanel1.TabIndex = 4; 85 | // 86 | // pictureBox1 87 | // 88 | this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill; 89 | this.pictureBox1.Location = new System.Drawing.Point(3, 3); 90 | this.pictureBox1.Name = "pictureBox1"; 91 | this.pictureBox1.Size = new System.Drawing.Size(73, 55); 92 | this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; 93 | this.pictureBox1.TabIndex = 1; 94 | this.pictureBox1.TabStop = false; 95 | this.pictureBox1.WaitOnLoad = true; 96 | // 97 | // BlpView 98 | // 99 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 100 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 101 | this.AutoSize = true; 102 | this.Controls.Add(this.flowLayoutPanel1); 103 | this.Controls.Add(this.bSave); 104 | this.Controls.Add(this.label1); 105 | this.Controls.Add(this.cbMipIndex); 106 | this.Name = "BlpView"; 107 | this.Size = new System.Drawing.Size(402, 343); 108 | this.flowLayoutPanel1.ResumeLayout(false); 109 | this.flowLayoutPanel1.PerformLayout(); 110 | ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit(); 111 | this.ResumeLayout(false); 112 | this.PerformLayout(); 113 | 114 | } 115 | 116 | #endregion 117 | private System.Windows.Forms.ComboBox cbMipIndex; 118 | private System.Windows.Forms.Label label1; 119 | private System.Windows.Forms.Button bSave; 120 | private System.Windows.Forms.SaveFileDialog saveFileDialog1; 121 | private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; 122 | private System.Windows.Forms.PictureBox pictureBox1; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/BlpView.cs: -------------------------------------------------------------------------------- 1 | using CASCExplorer.ViewPlugin; 2 | using SereniaBLPLib; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.Composition; 5 | using System.Drawing; 6 | using System.Drawing.Imaging; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Windows.Forms; 10 | 11 | namespace CASCExplorer.DefaultViews.Previews 12 | { 13 | [Export(typeof(IPreview))] 14 | [ExportMetadata("Extensions", new string[] { ".blp" })] 15 | public partial class BlpView : UserControl, IPreview 16 | { 17 | List m_mips = new List(); 18 | string m_fileName; 19 | 20 | public BlpView() 21 | { 22 | InitializeComponent(); 23 | } 24 | 25 | public Control Show(Stream stream, string fileName) 26 | { 27 | m_fileName = fileName; 28 | m_mips.Clear(); 29 | try 30 | { 31 | using (var blp = new BlpFile(stream)) 32 | { 33 | for (int i = 0; i < blp.MipMapCount; ++i) 34 | { 35 | var bmp = blp.GetBitmap(i); 36 | if (bmp.Width > 0 && bmp.Height > 0) 37 | { 38 | m_mips.Add(bmp); 39 | } 40 | } 41 | } 42 | } 43 | catch// (System.Exception ex) 44 | { 45 | //MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 46 | } 47 | 48 | cbMipIndex.Items.Clear(); 49 | cbMipIndex.Items.AddRange(Enumerable.Range(0, m_mips.Count).Select(m => m.ToString()).ToArray()); 50 | if (cbMipIndex.Items.Count > 0) 51 | cbMipIndex.SelectedIndex = 0; 52 | return this; 53 | } 54 | 55 | private void cbMipIndex_SelectedIndexChanged(object sender, System.EventArgs e) 56 | { 57 | pictureBox1.Image = m_mips[cbMipIndex.SelectedIndex]; 58 | } 59 | 60 | private void bSave_Click(object sender, System.EventArgs e) 61 | { 62 | saveFileDialog1.FileName = Path.GetFileNameWithoutExtension(m_fileName); 63 | if (saveFileDialog1.ShowDialog() == DialogResult.OK) 64 | { 65 | var format = ImageFormat.Bmp; 66 | switch (saveFileDialog1.FilterIndex) 67 | { 68 | case 2: format = ImageFormat.Jpeg; break; 69 | case 3: format = ImageFormat.Png; break; 70 | } 71 | pictureBox1.Image.Save(saveFileDialog1.FileName, format); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/BlpView.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/HexView.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer.DefaultViews.Previews 2 | { 3 | partial class HexView 4 | { 5 | /// 6 | /// Обязательная переменная конструктора. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Освободить все используемые ресурсы. 12 | /// 13 | /// истинно, если управляемый ресурс должен быть удален; иначе ложно. 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 Код, автоматически созданный конструктором компонентов 24 | 25 | /// 26 | /// Требуемый метод для поддержки конструктора — не изменяйте 27 | /// содержимое этого метода с помощью редактора кода. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.hexBox1 = new Be.Windows.Forms.HexBox(); 32 | this.cbEncoding = new System.Windows.Forms.ComboBox(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.SuspendLayout(); 35 | // 36 | // hexBox1 37 | // 38 | this.hexBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 39 | | System.Windows.Forms.AnchorStyles.Left) 40 | | System.Windows.Forms.AnchorStyles.Right))); 41 | this.hexBox1.ColumnInfoVisible = true; 42 | this.hexBox1.Font = new System.Drawing.Font("Segoe UI", 9F); 43 | this.hexBox1.GroupSize = 8; 44 | this.hexBox1.LineInfoVisible = true; 45 | this.hexBox1.Location = new System.Drawing.Point(0, 29); 46 | this.hexBox1.Name = "hexBox1"; 47 | this.hexBox1.ReadOnly = true; 48 | this.hexBox1.ShadowSelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(60)))), ((int)(((byte)(188)))), ((int)(((byte)(255))))); 49 | this.hexBox1.Size = new System.Drawing.Size(575, 371); 50 | this.hexBox1.StringViewVisible = true; 51 | this.hexBox1.TabIndex = 0; 52 | this.hexBox1.VScrollBarVisible = true; 53 | // 54 | // cbEncoding 55 | // 56 | this.cbEncoding.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 57 | this.cbEncoding.FormattingEnabled = true; 58 | this.cbEncoding.Location = new System.Drawing.Point(78, 4); 59 | this.cbEncoding.Name = "cbEncoding"; 60 | this.cbEncoding.Size = new System.Drawing.Size(126, 21); 61 | this.cbEncoding.TabIndex = 3; 62 | this.cbEncoding.SelectedIndexChanged += new System.EventHandler(this.cbEncoding_SelectedIndexChanged); 63 | // 64 | // label1 65 | // 66 | this.label1.AutoSize = true; 67 | this.label1.Location = new System.Drawing.Point(22, 8); 68 | this.label1.Name = "label1"; 69 | this.label1.Size = new System.Drawing.Size(55, 13); 70 | this.label1.TabIndex = 4; 71 | this.label1.Text = "Encoding:"; 72 | // 73 | // HexView 74 | // 75 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 76 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 77 | this.Controls.Add(this.label1); 78 | this.Controls.Add(this.cbEncoding); 79 | this.Controls.Add(this.hexBox1); 80 | this.Name = "HexView"; 81 | this.Size = new System.Drawing.Size(575, 400); 82 | this.ResumeLayout(false); 83 | this.PerformLayout(); 84 | 85 | } 86 | 87 | #endregion 88 | 89 | private Be.Windows.Forms.HexBox hexBox1; 90 | private System.Windows.Forms.ComboBox cbEncoding; 91 | private System.Windows.Forms.Label label1; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/HexView.cs: -------------------------------------------------------------------------------- 1 | using Be.Windows.Forms; 2 | using CASCExplorer.ViewPlugin; 3 | using System; 4 | using System.ComponentModel.Composition; 5 | using System.IO; 6 | using System.Windows.Forms; 7 | 8 | namespace CASCExplorer.DefaultViews.Previews 9 | { 10 | [Export(typeof(IPreview))] 11 | [ExportMetadata("Extensions", null)] 12 | public partial class HexView : UserControl, IPreview 13 | { 14 | byte[] m_bytes; 15 | 16 | public HexView() 17 | { 18 | InitializeComponent(); 19 | 20 | cbEncoding.Items.Clear(); 21 | cbEncoding.Items.Add(new DefaultByteCharConverter()); 22 | cbEncoding.Items.Add(new EbcdicByteCharProvider()); 23 | cbEncoding.SelectedIndex = 0; 24 | } 25 | 26 | public Control Show(Stream stream, string fileName) 27 | { 28 | int size = (int)Math.Min(1_000_000, stream.Length); 29 | 30 | m_bytes = new byte[size]; 31 | stream.Read(m_bytes, 0, size); 32 | 33 | hexBox1.ByteProvider = new DynamicByteProvider(m_bytes); 34 | 35 | return this; 36 | } 37 | 38 | private void cbEncoding_SelectedIndexChanged(object sender, EventArgs e) 39 | { 40 | hexBox1.ByteCharConverter = cbEncoding.SelectedItem as IByteCharConverter; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/HexView.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/TextView.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer.DefaultViews.Previews 2 | { 3 | partial class TextView 4 | { 5 | /// 6 | /// Обязательная переменная конструктора. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Освободить все используемые ресурсы. 12 | /// 13 | /// истинно, если управляемый ресурс должен быть удален; иначе ложно. 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 Код, автоматически созданный конструктором компонентов 24 | 25 | /// 26 | /// Требуемый метод для поддержки конструктора — не изменяйте 27 | /// содержимое этого метода с помощью редактора кода. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.richTextBox1 = new System.Windows.Forms.RichTextBox(); 32 | this.cbWordWrap = new System.Windows.Forms.CheckBox(); 33 | this.comboBox1 = new System.Windows.Forms.ComboBox(); 34 | this.label1 = new System.Windows.Forms.Label(); 35 | this.SuspendLayout(); 36 | // 37 | // richTextBox1 38 | // 39 | this.richTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 40 | | System.Windows.Forms.AnchorStyles.Left) 41 | | System.Windows.Forms.AnchorStyles.Right))); 42 | this.richTextBox1.Location = new System.Drawing.Point(0, 31); 43 | this.richTextBox1.Name = "richTextBox1"; 44 | this.richTextBox1.ReadOnly = true; 45 | this.richTextBox1.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedBoth; 46 | this.richTextBox1.Size = new System.Drawing.Size(309, 269); 47 | this.richTextBox1.TabIndex = 0; 48 | this.richTextBox1.Text = ""; 49 | this.richTextBox1.WordWrap = false; 50 | // 51 | // cbWordWrap 52 | // 53 | this.cbWordWrap.AutoSize = true; 54 | this.cbWordWrap.Location = new System.Drawing.Point(3, 6); 55 | this.cbWordWrap.Name = "cbWordWrap"; 56 | this.cbWordWrap.Size = new System.Drawing.Size(78, 17); 57 | this.cbWordWrap.TabIndex = 1; 58 | this.cbWordWrap.Text = "Word wrap"; 59 | this.cbWordWrap.UseVisualStyleBackColor = true; 60 | this.cbWordWrap.CheckedChanged += new System.EventHandler(this.cbWordWrap_CheckedChanged); 61 | // 62 | // comboBox1 63 | // 64 | this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 65 | this.comboBox1.FormattingEnabled = true; 66 | this.comboBox1.Items.AddRange(new object[] { 67 | "utf-8", 68 | "us-ascii", 69 | "utf-7", 70 | "utf-16", 71 | "utf-16BE", 72 | "cp1025", 73 | "koi8-u", 74 | "windows-1251", 75 | "cp866"}); 76 | this.comboBox1.Location = new System.Drawing.Point(154, 4); 77 | this.comboBox1.Name = "comboBox1"; 78 | this.comboBox1.Size = new System.Drawing.Size(137, 21); 79 | this.comboBox1.TabIndex = 2; 80 | this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); 81 | // 82 | // label1 83 | // 84 | this.label1.AutoSize = true; 85 | this.label1.Location = new System.Drawing.Point(93, 7); 86 | this.label1.Name = "label1"; 87 | this.label1.Size = new System.Drawing.Size(55, 13); 88 | this.label1.TabIndex = 3; 89 | this.label1.Text = "Encoding:"; 90 | // 91 | // TextView 92 | // 93 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 94 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 95 | this.Controls.Add(this.label1); 96 | this.Controls.Add(this.comboBox1); 97 | this.Controls.Add(this.cbWordWrap); 98 | this.Controls.Add(this.richTextBox1); 99 | this.Name = "TextView"; 100 | this.Size = new System.Drawing.Size(309, 300); 101 | this.ResumeLayout(false); 102 | this.PerformLayout(); 103 | 104 | } 105 | 106 | #endregion 107 | 108 | private System.Windows.Forms.RichTextBox richTextBox1; 109 | private System.Windows.Forms.CheckBox cbWordWrap; 110 | private System.Windows.Forms.ComboBox comboBox1; 111 | private System.Windows.Forms.Label label1; 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/TextView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Text; 4 | using System.Windows.Forms; 5 | using CASCExplorer.ViewPlugin; 6 | using System.IO; 7 | using System.ComponentModel.Composition; 8 | 9 | namespace CASCExplorer.DefaultViews.Previews 10 | { 11 | [Export(typeof(IPreview))] 12 | [ExportMetadata("Extensions", new string[] { ".txt", ".ini", ".wtf", ".lua", ".toc", ".xml", ".htm", ".html", ".lst", ".signed", ".anim", ".plist" })] 13 | public partial class TextView : UserControl, IPreview 14 | { 15 | byte[] m_bytes; 16 | 17 | public TextView() 18 | { 19 | InitializeComponent(); 20 | comboBox1.SelectedIndex = 0; 21 | } 22 | 23 | private void GetText() 24 | { 25 | richTextBox1.Clear(); 26 | if (m_bytes != null) 27 | { 28 | var enc_name = (string)comboBox1.SelectedItem ?? "utf-8"; 29 | var enc = Encoding.GetEncoding(enc_name); 30 | richTextBox1.Text = enc.GetString(m_bytes); 31 | } 32 | } 33 | 34 | private void GetAnim() 35 | { 36 | richTextBox1.Clear(); 37 | if (m_bytes?.Length > 8) 38 | { 39 | var sig = BitConverter.ToUInt64(m_bytes, 0); 40 | var text = Encoding.UTF8.GetString(m_bytes, 8, m_bytes.Length - 8); 41 | 42 | richTextBox1.AppendText($"Signature: 0x{sig:X08}"); 43 | richTextBox1.AppendText(Environment.NewLine); 44 | richTextBox1.AppendText(Environment.NewLine); 45 | richTextBox1.AppendText(text); 46 | 47 | richTextBox1.WordWrap = true; 48 | } 49 | } 50 | 51 | public Control Show(Stream stream, string fileName) 52 | { 53 | m_bytes = new byte[stream.Length]; 54 | stream.Read(m_bytes, 0, (int)stream.Length); 55 | if (fileName.EndsWith(".anim")) 56 | { 57 | GetAnim(); 58 | } 59 | else 60 | { 61 | GetText(); 62 | } 63 | return this; 64 | } 65 | 66 | private void cbWordWrap_CheckedChanged(object sender, System.EventArgs e) 67 | { 68 | richTextBox1.WordWrap = cbWordWrap.Checked; 69 | } 70 | 71 | private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 72 | { 73 | GetText(); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Previews/TextView.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /CASCExplorer.ViewPlugin/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Общие сведения об этой сборке предоставляются следующим набором 6 | // набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения, 7 | // связанные со сборкой. 8 | [assembly: AssemblyTitle("CommonViewPlugin")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CommonViewPlugin")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми 18 | // для компонентов COM. Если необходимо обратиться к типу в этой сборке через 19 | // COM, задайте атрибуту ComVisible значение TRUE для этого типа. 20 | [assembly: ComVisible(false)] 21 | 22 | // Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM 23 | [assembly: Guid("63c32ac8-2ee2-4db7-99c5-84fd815aadc3")] 24 | 25 | // Сведения о версии сборки состоят из следующих четырех значений: 26 | // 27 | // Основной номер версии 28 | // Дополнительный номер версии 29 | // Номер сборки 30 | // Редакция 31 | // 32 | // Можно задать все значения или принять номер сборки и номер редакции по умолчанию. 33 | // используя "*", как показано ниже: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /CASCExplorer.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.28902.138 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CASCExplorer", "CASCExplorer\CASCExplorer.csproj", "{CB208F91-B1E8-4319-B4C0-2F4E15A4BFBC}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CASCConsole", "CASCConsole\CASCConsole.csproj", "{85502A7B-1B1B-4A02-B37F-11600B6194FD}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SereniaBLPLib", "SereniaBLPLib\SereniaBLPLib\SereniaBLPLib.csproj", "{4ED9F877-A9BB-470F-B35C-694147472080}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CASCExplorer.ViewPlugin", "CASCExplorer.ViewPlugin\CASCExplorer.ViewPlugin.csproj", "{63C32AC8-2EE2-4DB7-99C5-84FD815AADC3}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CascLib", "CascLib\CascLib\CascLib.csproj", "{D91852FA-206F-4790-87F0-345248E4A588}" 15 | EndProject 16 | Global 17 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 18 | Debug|Any CPU = Debug|Any CPU 19 | Release|Any CPU = Release|Any CPU 20 | EndGlobalSection 21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 22 | {CB208F91-B1E8-4319-B4C0-2F4E15A4BFBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {CB208F91-B1E8-4319-B4C0-2F4E15A4BFBC}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {CB208F91-B1E8-4319-B4C0-2F4E15A4BFBC}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {CB208F91-B1E8-4319-B4C0-2F4E15A4BFBC}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {85502A7B-1B1B-4A02-B37F-11600B6194FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {85502A7B-1B1B-4A02-B37F-11600B6194FD}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {85502A7B-1B1B-4A02-B37F-11600B6194FD}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {85502A7B-1B1B-4A02-B37F-11600B6194FD}.Release|Any CPU.Build.0 = Release|Any CPU 30 | {4ED9F877-A9BB-470F-B35C-694147472080}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {4ED9F877-A9BB-470F-B35C-694147472080}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {4ED9F877-A9BB-470F-B35C-694147472080}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {4ED9F877-A9BB-470F-B35C-694147472080}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {63C32AC8-2EE2-4DB7-99C5-84FD815AADC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {63C32AC8-2EE2-4DB7-99C5-84FD815AADC3}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {63C32AC8-2EE2-4DB7-99C5-84FD815AADC3}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {63C32AC8-2EE2-4DB7-99C5-84FD815AADC3}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {D91852FA-206F-4790-87F0-345248E4A588}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {D91852FA-206F-4790-87F0-345248E4A588}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {D91852FA-206F-4790-87F0-345248E4A588}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {D91852FA-206F-4790-87F0-345248E4A588}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | GlobalSection(ExtensibilityGlobals) = postSolution 47 | SolutionGuid = {ACCA6FD1-0ACF-4D0D-A70A-DC4BC0AECA68} 48 | EndGlobalSection 49 | EndGlobal 50 | -------------------------------------------------------------------------------- /CASCExplorer/AboutBox.cs: -------------------------------------------------------------------------------- 1 | using System.Diagnostics; 2 | using System.Reflection; 3 | using System.Windows.Forms; 4 | 5 | namespace CASCExplorer 6 | { 7 | sealed partial class AboutBox : Form 8 | { 9 | public AboutBox() 10 | { 11 | InitializeComponent(); 12 | Text = string.Format("About {0}", AssemblyTitle); 13 | labelProductName.Text = AssemblyProduct; 14 | labelVersion.Text = string.Format("Version {0}", AssemblyVersion); 15 | labelCopyright.Text = AssemblyCopyright; 16 | var link = new LinkLabel.Link {LinkData = Properties.Resources.donateURL}; 17 | labelDonate.Links.Add(link); 18 | textBoxDescription.Text = AssemblyDescription; 19 | } 20 | 21 | #region Assembly Attribute Accessors 22 | 23 | public string AssemblyTitle 24 | { 25 | get 26 | { 27 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); 28 | if (attributes.Length > 0) 29 | { 30 | AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; 31 | if (titleAttribute.Title != "") 32 | { 33 | return titleAttribute.Title; 34 | } 35 | } 36 | return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); 37 | } 38 | } 39 | 40 | public string AssemblyVersion 41 | { 42 | get 43 | { 44 | return Assembly.GetExecutingAssembly().GetName().Version.ToString(); 45 | } 46 | } 47 | 48 | public string AssemblyDescription 49 | { 50 | get 51 | { 52 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); 53 | if (attributes.Length == 0) 54 | { 55 | return ""; 56 | } 57 | return ((AssemblyDescriptionAttribute)attributes[0]).Description; 58 | } 59 | } 60 | 61 | public string AssemblyProduct 62 | { 63 | get 64 | { 65 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); 66 | if (attributes.Length == 0) 67 | { 68 | return ""; 69 | } 70 | return ((AssemblyProductAttribute)attributes[0]).Product; 71 | } 72 | } 73 | 74 | public string AssemblyCopyright 75 | { 76 | get 77 | { 78 | object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); 79 | if (attributes.Length == 0) 80 | { 81 | return ""; 82 | } 83 | return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; 84 | } 85 | } 86 | #endregion 87 | 88 | private void labelDonate_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 89 | { 90 | Process.Start(e.Link?.LinkData as string); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /CASCExplorer/AboutBox.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /CASCExplorer/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | enUS 20 | 21 | 22 | False 23 | 24 | 25 | 26 | 27 | 28 | True 29 | 30 | 31 | listfile.csv 32 | 33 | 34 | False 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /CASCExplorer/Bruteforce.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.Text; 6 | 7 | namespace CASCExplorer 8 | { 9 | class PassEnumerator 10 | { 11 | private int length; 12 | private char[] chars; 13 | private int[] indexes; 14 | private StringBuilder result; 15 | 16 | public long TotalCount; 17 | public long Processed; 18 | 19 | public PassEnumerator(string charStr, int length) 20 | { 21 | this.length = length; 22 | chars = charStr.ToCharArray(); 23 | result = new StringBuilder(length); 24 | indexes = new int[length]; 25 | 26 | TotalCount = 1; 27 | 28 | for (var j = 0; j < length; j++) 29 | { 30 | result.Insert(j, chars[0]); 31 | TotalCount *= chars.Length; 32 | } 33 | } 34 | 35 | public IEnumerable Enumerate() 36 | { 37 | int i = 0; 38 | 39 | do 40 | { 41 | yield return result.ToString(); 42 | 43 | Processed++; 44 | 45 | for (i = 0; i < length; i++) 46 | { 47 | var ind = indexes[i]; 48 | ind++; 49 | if (ind >= chars.Length) 50 | { 51 | indexes[i] = 0; 52 | result[i] = chars[0]; 53 | } 54 | else 55 | { 56 | indexes[i] = ind; 57 | result[i] = chars[ind]; 58 | break; 59 | } 60 | } 61 | } while (i < length); 62 | } 63 | } 64 | 65 | public class Bruteforce : IEnumerable 66 | { 67 | private StringBuilder sb = new StringBuilder(); 68 | public string charset = "abcdefghijklmnopqrstuvwxyz-_ "; 69 | private uint len; 70 | private Stopwatch sw = new Stopwatch(); 71 | public int max { get; set; } 72 | public int min { get; set; } 73 | public ulong total { get; set; } 74 | public ulong done { get; set; } 75 | 76 | public ulong speed 77 | { 78 | get 79 | { 80 | ulong totalSec = (ulong)sw.Elapsed.TotalSeconds; 81 | if (totalSec == 0 || done == 0) 82 | return 0; 83 | return done / totalSec; 84 | } 85 | } 86 | 87 | public TimeSpan eta 88 | { 89 | get 90 | { 91 | if (speed == 0) 92 | return TimeSpan.Zero; 93 | return TimeSpan.FromSeconds((total - done) / speed); 94 | } 95 | } 96 | 97 | public IEnumerator GetEnumerator() 98 | { 99 | sw.Start(); 100 | 101 | len = (uint)charset.Length; 102 | 103 | for (int x = min; x <= max; x++) 104 | { 105 | ulong c = (ulong)Math.Pow(len, x); 106 | total += c; 107 | 108 | for (ulong i = 0; i < c; ++i, ++done) 109 | { 110 | yield return Factoradic(i, x - 1); 111 | } 112 | } 113 | 114 | sw.Stop(); 115 | } 116 | 117 | private string Factoradic(ulong l, int power) 118 | { 119 | sb.Clear(); 120 | while (power >= 0) 121 | { 122 | sb = sb.Append(charset[(int)(l % len)]); 123 | l /= len; 124 | power--; 125 | } 126 | return sb.ToString(); 127 | } 128 | 129 | IEnumerator IEnumerable.GetEnumerator() 130 | { 131 | return GetEnumerator(); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /CASCExplorer/BruteforceForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer 2 | { 3 | partial class BruteforceForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); 32 | this.progressBar1 = new System.Windows.Forms.ProgressBar(); 33 | this.button1 = new System.Windows.Forms.Button(); 34 | this.textBox1 = new System.Windows.Forms.TextBox(); 35 | this.label1 = new System.Windows.Forms.Label(); 36 | this.SuspendLayout(); 37 | // 38 | // backgroundWorker1 39 | // 40 | this.backgroundWorker1.WorkerReportsProgress = true; 41 | this.backgroundWorker1.WorkerSupportsCancellation = true; 42 | this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); 43 | this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); 44 | this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); 45 | // 46 | // progressBar1 47 | // 48 | this.progressBar1.Location = new System.Drawing.Point(49, 172); 49 | this.progressBar1.Name = "progressBar1"; 50 | this.progressBar1.Size = new System.Drawing.Size(265, 23); 51 | this.progressBar1.TabIndex = 0; 52 | // 53 | // button1 54 | // 55 | this.button1.Location = new System.Drawing.Point(320, 172); 56 | this.button1.Name = "button1"; 57 | this.button1.Size = new System.Drawing.Size(75, 23); 58 | this.button1.TabIndex = 1; 59 | this.button1.Text = "Start"; 60 | this.button1.UseVisualStyleBackColor = true; 61 | this.button1.Click += new System.EventHandler(this.button1_Click); 62 | // 63 | // textBox1 64 | // 65 | this.textBox1.Location = new System.Drawing.Point(49, 102); 66 | this.textBox1.Name = "textBox1"; 67 | this.textBox1.Size = new System.Drawing.Size(265, 20); 68 | this.textBox1.TabIndex = 2; 69 | // 70 | // label1 71 | // 72 | this.label1.Location = new System.Drawing.Point(46, 154); 73 | this.label1.Name = "label1"; 74 | this.label1.Size = new System.Drawing.Size(268, 15); 75 | this.label1.TabIndex = 3; 76 | this.label1.Text = "label1"; 77 | // 78 | // BruteforceForm 79 | // 80 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 81 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 82 | this.ClientSize = new System.Drawing.Size(547, 261); 83 | this.Controls.Add(this.label1); 84 | this.Controls.Add(this.textBox1); 85 | this.Controls.Add(this.button1); 86 | this.Controls.Add(this.progressBar1); 87 | this.Name = "BruteforceForm"; 88 | this.Text = "BruteforceForm"; 89 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.BruteforceForm_FormClosing); 90 | this.ResumeLayout(false); 91 | this.PerformLayout(); 92 | 93 | } 94 | 95 | #endregion 96 | 97 | private System.ComponentModel.BackgroundWorker backgroundWorker1; 98 | private System.Windows.Forms.ProgressBar progressBar1; 99 | private System.Windows.Forms.Button button1; 100 | private System.Windows.Forms.TextBox textBox1; 101 | private System.Windows.Forms.Label label1; 102 | } 103 | } -------------------------------------------------------------------------------- /CASCExplorer/BruteforceForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using System.Windows.Forms; 5 | 6 | namespace CASCExplorer 7 | { 8 | public partial class BruteforceForm : Form 9 | { 10 | bool running; 11 | 12 | public BruteforceForm() 13 | { 14 | InitializeComponent(); 15 | } 16 | 17 | private void button1_Click(object sender, EventArgs e) 18 | { 19 | if (!running) 20 | { 21 | if (!backgroundWorker1.IsBusy) 22 | { 23 | backgroundWorker1.RunWorkerAsync(); 24 | button1.Text = "Stop"; 25 | running = true; 26 | } 27 | } 28 | else 29 | { 30 | backgroundWorker1.CancelAsync(); 31 | button1.Text = "Start"; 32 | running = false; 33 | } 34 | } 35 | 36 | private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 37 | { 38 | PassEnumerator en = new PassEnumerator("abcdefghijklmnopqrstuvwxyz", 7); 39 | 40 | IEnumerable variations = en.Enumerate(); 41 | 42 | Parallel.ForEach(variations, (val, ps) => 43 | { 44 | if (backgroundWorker1.CancellationPending) 45 | { 46 | ps.Stop(); 47 | return; 48 | } 49 | 50 | int pct = (int)(en.Processed / (double)en.TotalCount * 100.0f); 51 | 52 | if (en.Processed % 2000 == 0) 53 | { 54 | backgroundWorker1.ReportProgress(pct, val); 55 | } 56 | }); 57 | } 58 | 59 | private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) 60 | { 61 | MessageBox.Show("Done!"); 62 | } 63 | 64 | private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) 65 | { 66 | progressBar1.Value = e.ProgressPercentage; 67 | 68 | if (e.UserState != null) 69 | label1.Text = (string)e.UserState; 70 | } 71 | 72 | private void BruteforceForm_FormClosing(object sender, FormClosingEventArgs e) 73 | { 74 | backgroundWorker1.CancelAsync(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /CASCExplorer/BruteforceForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /CASCExplorer/CASCEntrySorter.cs: -------------------------------------------------------------------------------- 1 | using CASCLib; 2 | using System.Collections.Generic; 3 | using System.Windows.Forms; 4 | 5 | namespace CASCExplorer 6 | { 7 | class CASCEntrySorter : IComparer 8 | { 9 | public int SortColumn { get; set; } 10 | public SortOrder Order { get; set; } 11 | public CASCHandler CASC { get; set; } 12 | 13 | public CASCEntrySorter() 14 | { 15 | SortColumn = 0; 16 | Order = SortOrder.Ascending; 17 | } 18 | 19 | public int Compare(ICASCEntry x, ICASCEntry y) 20 | { 21 | int result = x.CompareTo(y, SortColumn, CASC); 22 | 23 | if (Order == SortOrder.Ascending) 24 | return result; 25 | else 26 | return -result; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /CASCExplorer/ExtractProgress.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer 2 | { 3 | partial class ExtractProgress 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | this.progressBar1 = new System.Windows.Forms.ProgressBar(); 33 | this.textBox1 = new System.Windows.Forms.TextBox(); 34 | this.button1 = new System.Windows.Forms.Button(); 35 | this.button2 = new System.Windows.Forms.Button(); 36 | this.button3 = new System.Windows.Forms.Button(); 37 | this.folderBrowserDialog1 = new System.Windows.Forms.FolderBrowserDialog(); 38 | this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker(); 39 | this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); 40 | this.SuspendLayout(); 41 | // 42 | // progressBar1 43 | // 44 | this.progressBar1.Location = new System.Drawing.Point(12, 39); 45 | this.progressBar1.Name = "progressBar1"; 46 | this.progressBar1.Size = new System.Drawing.Size(368, 23); 47 | this.progressBar1.Step = 1; 48 | this.progressBar1.TabIndex = 0; 49 | // 50 | // textBox1 51 | // 52 | this.textBox1.Location = new System.Drawing.Point(12, 12); 53 | this.textBox1.Name = "textBox1"; 54 | this.textBox1.Size = new System.Drawing.Size(337, 20); 55 | this.textBox1.TabIndex = 1; 56 | this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged); 57 | // 58 | // button1 59 | // 60 | this.button1.Location = new System.Drawing.Point(355, 10); 61 | this.button1.Name = "button1"; 62 | this.button1.Size = new System.Drawing.Size(25, 23); 63 | this.button1.TabIndex = 2; 64 | this.button1.Text = "..."; 65 | this.button1.UseVisualStyleBackColor = true; 66 | this.button1.Click += new System.EventHandler(this.button1_Click); 67 | // 68 | // button2 69 | // 70 | this.button2.Enabled = false; 71 | this.button2.Location = new System.Drawing.Point(122, 68); 72 | this.button2.Name = "button2"; 73 | this.button2.Size = new System.Drawing.Size(75, 23); 74 | this.button2.TabIndex = 3; 75 | this.button2.Text = "OK"; 76 | this.button2.UseVisualStyleBackColor = true; 77 | this.button2.Click += new System.EventHandler(this.button2_Click); 78 | // 79 | // button3 80 | // 81 | this.button3.DialogResult = System.Windows.Forms.DialogResult.Cancel; 82 | this.button3.Location = new System.Drawing.Point(203, 68); 83 | this.button3.Name = "button3"; 84 | this.button3.Size = new System.Drawing.Size(75, 23); 85 | this.button3.TabIndex = 4; 86 | this.button3.Text = "Cancel"; 87 | this.button3.UseVisualStyleBackColor = true; 88 | this.button3.Click += new System.EventHandler(this.button3_Click); 89 | // 90 | // backgroundWorker1 91 | // 92 | this.backgroundWorker1.WorkerReportsProgress = true; 93 | this.backgroundWorker1.WorkerSupportsCancellation = true; 94 | this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); 95 | this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); 96 | this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); 97 | // 98 | // ExtractProgress 99 | // 100 | this.AcceptButton = this.button2; 101 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 102 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 103 | this.CancelButton = this.button3; 104 | this.ClientSize = new System.Drawing.Size(393, 102); 105 | this.Controls.Add(this.button3); 106 | this.Controls.Add(this.button2); 107 | this.Controls.Add(this.button1); 108 | this.Controls.Add(this.textBox1); 109 | this.Controls.Add(this.progressBar1); 110 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 111 | this.MaximizeBox = false; 112 | this.MinimizeBox = false; 113 | this.Name = "ExtractProgress"; 114 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 115 | this.Text = "Extract Files"; 116 | this.ResumeLayout(false); 117 | this.PerformLayout(); 118 | 119 | } 120 | 121 | #endregion 122 | 123 | private System.Windows.Forms.ProgressBar progressBar1; 124 | private System.Windows.Forms.TextBox textBox1; 125 | private System.Windows.Forms.Button button1; 126 | private System.Windows.Forms.Button button2; 127 | private System.Windows.Forms.Button button3; 128 | private System.Windows.Forms.FolderBrowserDialog folderBrowserDialog1; 129 | private System.ComponentModel.BackgroundWorker backgroundWorker1; 130 | private System.Windows.Forms.ToolTip toolTip1; 131 | } 132 | } -------------------------------------------------------------------------------- /CASCExplorer/ExtractProgress.cs: -------------------------------------------------------------------------------- 1 | using CASCLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.IO; 6 | using System.Windows.Forms; 7 | 8 | namespace CASCExplorer 9 | { 10 | public partial class ExtractProgress : Form 11 | { 12 | private string ExtractPath 13 | { 14 | get => textBox1.Text; 15 | set => textBox1.Text = value; 16 | } 17 | 18 | private int NumExtracted; 19 | private ICollection files; 20 | private CASCHandler CASC; 21 | 22 | public ExtractProgress() 23 | { 24 | InitializeComponent(); 25 | } 26 | 27 | public void SetExtractData(CASCHandler handler, ICollection files) 28 | { 29 | NumExtracted = 0; 30 | progressBar1.Value = 0; 31 | CASC = handler; 32 | this.files = files; 33 | ExtractPath = ExtractPath; 34 | } 35 | 36 | private void button1_Click(object sender, EventArgs e) 37 | { 38 | var result = folderBrowserDialog1.ShowDialog(); 39 | 40 | if (result != DialogResult.OK) 41 | return; 42 | 43 | var path = folderBrowserDialog1.SelectedPath; 44 | 45 | if (path == null) 46 | return; 47 | 48 | ExtractPath = path; 49 | } 50 | 51 | private void button3_Click(object sender, EventArgs e) 52 | { 53 | if (backgroundWorker1.IsBusy) 54 | { 55 | backgroundWorker1.CancelAsync(); 56 | return; 57 | } 58 | 59 | Close(); 60 | } 61 | 62 | private void button2_Click(object sender, EventArgs e) 63 | { 64 | button2.Enabled = false; 65 | textBox1.ReadOnly = true; 66 | backgroundWorker1.RunWorkerAsync(); 67 | } 68 | 69 | private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 70 | { 71 | foreach (var file in files) 72 | { 73 | if (backgroundWorker1.CancellationPending) 74 | { 75 | e.Cancel = true; 76 | break; 77 | } 78 | 79 | try 80 | { 81 | backgroundWorker1.ReportProgress((int)(++NumExtracted / (float)files.Count * 100.0f)); 82 | 83 | CASC.SaveFileTo(file.Hash, ExtractPath, file.FullName); 84 | } 85 | catch (Exception exc) 86 | { 87 | Logger.WriteLine("Unable to extract file {0}: {1}", file.FullName, exc.Message); 88 | } 89 | } 90 | } 91 | 92 | private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 93 | { 94 | progressBar1.Value = e.ProgressPercentage; 95 | } 96 | 97 | private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 98 | { 99 | button2.Enabled = true; 100 | textBox1.ReadOnly = false; 101 | 102 | if (e.Cancelled) 103 | { 104 | NumExtracted = 0; 105 | progressBar1.Value = 0; 106 | MessageBox.Show("Operation cancelled!"); 107 | return; 108 | } 109 | 110 | Hide(); 111 | } 112 | 113 | private void textBox1_TextChanged(object sender, EventArgs e) 114 | { 115 | button2.Enabled = Directory.Exists(ExtractPath); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /CASCExplorer/ExtractProgress.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | 124 | 186, 17 125 | 126 | 127 | 350, 17 128 | 129 | -------------------------------------------------------------------------------- /CASCExplorer/Icons/CASCExplorer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WoW-Tools/CASCExplorer/b06833ff112b4f0ca36083d17e4723460ec2c7f1/CASCExplorer/Icons/CASCExplorer.ico -------------------------------------------------------------------------------- /CASCExplorer/Icons/folder.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WoW-Tools/CASCExplorer/b06833ff112b4f0ca36083d17e4723460ec2c7f1/CASCExplorer/Icons/folder.ico -------------------------------------------------------------------------------- /CASCExplorer/Icons/openFolder.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WoW-Tools/CASCExplorer/b06833ff112b4f0ca36083d17e4723460ec2c7f1/CASCExplorer/Icons/openFolder.ico -------------------------------------------------------------------------------- /CASCExplorer/InitForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer 2 | { 3 | partial class InitForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.label1 = new System.Windows.Forms.Label(); 32 | this.progressBar1 = new System.Windows.Forms.ProgressBar(); 33 | this.backgroundWorker1 = new CASCLib.BackgroundWorkerEx(); 34 | this.SuspendLayout(); 35 | // 36 | // label1 37 | // 38 | this.label1.AutoSize = true; 39 | this.label1.Location = new System.Drawing.Point(12, 38); 40 | this.label1.Name = "label1"; 41 | this.label1.Size = new System.Drawing.Size(54, 13); 42 | this.label1.TabIndex = 0; 43 | this.label1.Text = "Loading..."; 44 | // 45 | // progressBar1 46 | // 47 | this.progressBar1.Location = new System.Drawing.Point(12, 12); 48 | this.progressBar1.Name = "progressBar1"; 49 | this.progressBar1.Size = new System.Drawing.Size(313, 23); 50 | this.progressBar1.TabIndex = 1; 51 | // 52 | // backgroundWorker1 53 | // 54 | this.backgroundWorker1.WorkerReportsProgress = true; 55 | this.backgroundWorker1.WorkerSupportsCancellation = true; 56 | this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork); 57 | this.backgroundWorker1.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.backgroundWorker1_ProgressChanged); 58 | this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted); 59 | // 60 | // InitForm 61 | // 62 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 63 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 64 | this.ClientSize = new System.Drawing.Size(337, 62); 65 | this.Controls.Add(this.progressBar1); 66 | this.Controls.Add(this.label1); 67 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 68 | this.MaximizeBox = false; 69 | this.MinimizeBox = false; 70 | this.Name = "InitForm"; 71 | this.ShowInTaskbar = false; 72 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 73 | this.Text = "Loading..."; 74 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.InitForm_FormClosing); 75 | this.ResumeLayout(false); 76 | this.PerformLayout(); 77 | 78 | } 79 | 80 | #endregion 81 | 82 | private System.Windows.Forms.Label label1; 83 | private System.Windows.Forms.ProgressBar progressBar1; 84 | private CASCLib.BackgroundWorkerEx backgroundWorker1; 85 | } 86 | } -------------------------------------------------------------------------------- /CASCExplorer/InitForm.cs: -------------------------------------------------------------------------------- 1 | using CASCExplorer.Properties; 2 | using CASCLib; 3 | using System; 4 | using System.ComponentModel; 5 | using System.IO; 6 | using System.Windows.Forms; 7 | 8 | namespace CASCExplorer 9 | { 10 | public partial class InitForm : Form 11 | { 12 | public CASCHandler CASC { get; set; } 13 | public CASCFolder Root { get; set; } 14 | 15 | private bool _onlineMode; 16 | 17 | public InitForm() 18 | { 19 | InitializeComponent(); 20 | } 21 | 22 | private void InitForm_FormClosing(object sender, FormClosingEventArgs e) 23 | { 24 | if (e.CloseReason != CloseReason.None) 25 | backgroundWorker1.CancelAsync(); 26 | } 27 | 28 | private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 29 | { 30 | (bool online, string path, string product) = ((bool online, string path, string product))e.Argument; 31 | CASCConfig.LoadFlags |= LoadFlags.Install; 32 | CASCConfig.LoadFlags |= LoadFlags.FileIndex; 33 | CASCConfig config = _onlineMode ? CASCConfig.LoadOnlineStorageConfig(product, "eu") : CASCConfig.LoadLocalStorageConfig(path, product); 34 | 35 | if (_onlineMode) 36 | { 37 | using (SelectBuildForm sb = new SelectBuildForm(config)) 38 | { 39 | var result = sb.ShowDialog(); 40 | 41 | if (result != DialogResult.OK || sb.SelectedIndex == -1) 42 | { 43 | e.Cancel = true; 44 | return; 45 | } 46 | 47 | config.ActiveBuild = sb.SelectedIndex; 48 | } 49 | } 50 | 51 | var casc = CASCHandler.OpenStorage(config, backgroundWorker1); 52 | 53 | casc.Root.SetFlags(Settings.Default.LocaleFlags, Settings.Default.OverrideArchive, Settings.Default.PreferHighResTextures, false); 54 | 55 | LoadFileDataComplete(casc); 56 | 57 | using (var _ = new PerfCounter("LoadListFile()")) 58 | { 59 | casc.Root.LoadListFile(Settings.Default.ListFilePath, backgroundWorker1); 60 | } 61 | 62 | var fldr = casc.Root.SetFlags(Settings.Default.LocaleFlags, Settings.Default.OverrideArchive, Settings.Default.PreferHighResTextures); 63 | casc.Root.MergeInstall(casc.Install); 64 | GC.Collect(); 65 | 66 | e.Result = new object[] { casc, fldr }; 67 | } 68 | 69 | public void LoadFileDataComplete(CASCHandler casc) 70 | { 71 | if (!casc.FileExists("DBFilesClient\\FileDataComplete.db2")) 72 | return; 73 | 74 | Logger.WriteLine("WowRootHandler: loading file names from FileDataComplete.db2..."); 75 | 76 | using (var s = casc.OpenFile("DBFilesClient\\FileDataComplete.db2")) 77 | { 78 | WDC1Reader fd = new WDC1Reader(s); 79 | 80 | Jenkins96 hasher = new Jenkins96(); 81 | 82 | foreach (var row in fd) 83 | { 84 | string path = row.Value.GetField(0); 85 | string name = row.Value.GetField(1); 86 | 87 | string fullname = path + name; 88 | 89 | ulong fileHash = hasher.ComputeHash(fullname); 90 | 91 | // skip invalid names 92 | if (!casc.FileExists(fileHash)) 93 | { 94 | //Logger.WriteLine("Invalid file name: {0}", fullname); 95 | continue; 96 | } 97 | 98 | CASCFile.Files[fileHash] = new CASCFile(fileHash, fullname); 99 | } 100 | } 101 | } 102 | 103 | private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) 104 | { 105 | progressBar1.Value = e.ProgressPercentage; 106 | 107 | string arg = (string)e.UserState; 108 | 109 | if (arg != null) 110 | label1.Text = arg; 111 | } 112 | 113 | private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 114 | { 115 | DialogResult = DialogResult.Cancel; 116 | 117 | if (e.Cancelled) 118 | { 119 | MessageBox.Show("Loading cancelled", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 120 | //Application.Exit(); 121 | return; 122 | } 123 | 124 | if (e.Error != null) 125 | { 126 | MessageBox.Show("Loading failed due to:\n" + e.Error.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 127 | //Application.Exit(); 128 | return; 129 | } 130 | 131 | if (e.Result == null) 132 | { 133 | MessageBox.Show("Loading failed: Result is null", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 134 | //Application.Exit(); 135 | return; 136 | } 137 | 138 | var result = (object[])e.Result; 139 | CASC = (CASCHandler)result[0]; 140 | Root = (CASCFolder)result[1]; 141 | 142 | DialogResult = DialogResult.OK; 143 | } 144 | 145 | public void LoadStorage((bool online, string path, string product) options) 146 | { 147 | _onlineMode = options.online; 148 | backgroundWorker1.RunWorkerAsync(options); 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /CASCExplorer/InitForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /CASCExplorer/NoFlickerListView.cs: -------------------------------------------------------------------------------- 1 | using System.Windows.Forms; 2 | using System.Linq; 3 | 4 | namespace CASCExplorer 5 | { 6 | public class NoFlickerListView : ListView 7 | { 8 | public NoFlickerListView() 9 | { 10 | DoubleBuffered = true; 11 | } 12 | 13 | public bool HasSingleSelection 14 | { 15 | get { return SelectedIndices.Count == 1; } 16 | } 17 | 18 | public bool HasSelection 19 | { 20 | get { return SelectedIndices.Count >= 1; } 21 | } 22 | 23 | public int SelectedIndex 24 | { 25 | get 26 | { 27 | int selCount = SelectedIndices.Count; 28 | 29 | if (selCount == 0) 30 | return -1; 31 | else if (selCount == 1) 32 | return SelectedIndices[0]; 33 | else 34 | return SelectedIndices.Cast().Max(); 35 | } 36 | set 37 | { 38 | SelectedIndices.Clear(); 39 | 40 | if (value >= 0) 41 | { 42 | SelectedIndices.Add(value); 43 | Items[value].Selected = true; 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /CASCExplorer/OpenStorageForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer 2 | { 3 | partial class OpenStorageForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.button1 = new System.Windows.Forms.Button(); 32 | this.textBox1 = new System.Windows.Forms.TextBox(); 33 | this.label1 = new System.Windows.Forms.Label(); 34 | this.productComboBox = new System.Windows.Forms.ComboBox(); 35 | this.storageFolderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog(); 36 | this.button2 = new System.Windows.Forms.Button(); 37 | this.label2 = new System.Windows.Forms.Label(); 38 | this.SuspendLayout(); 39 | // 40 | // button1 41 | // 42 | this.button1.Location = new System.Drawing.Point(590, 31); 43 | this.button1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); 44 | this.button1.Name = "button1"; 45 | this.button1.Size = new System.Drawing.Size(39, 35); 46 | this.button1.TabIndex = 0; 47 | this.button1.Text = "..."; 48 | this.button1.UseVisualStyleBackColor = true; 49 | this.button1.Click += new System.EventHandler(this.Button1_Click); 50 | // 51 | // textBox1 52 | // 53 | this.textBox1.Location = new System.Drawing.Point(81, 34); 54 | this.textBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); 55 | this.textBox1.Name = "textBox1"; 56 | this.textBox1.Size = new System.Drawing.Size(498, 26); 57 | this.textBox1.TabIndex = 1; 58 | // 59 | // label1 60 | // 61 | this.label1.AutoSize = true; 62 | this.label1.Location = new System.Drawing.Point(27, 38); 63 | this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 64 | this.label1.Name = "label1"; 65 | this.label1.Size = new System.Drawing.Size(46, 20); 66 | this.label1.TabIndex = 2; 67 | this.label1.Text = "Path:"; 68 | // 69 | // productComboBox 70 | // 71 | this.productComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 72 | this.productComboBox.FormattingEnabled = true; 73 | this.productComboBox.Location = new System.Drawing.Point(81, 89); 74 | this.productComboBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); 75 | this.productComboBox.Name = "productComboBox"; 76 | this.productComboBox.Size = new System.Drawing.Size(498, 28); 77 | this.productComboBox.TabIndex = 3; 78 | // 79 | // button2 80 | // 81 | this.button2.Location = new System.Drawing.Point(254, 149); 82 | this.button2.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); 83 | this.button2.Name = "button2"; 84 | this.button2.Size = new System.Drawing.Size(202, 35); 85 | this.button2.TabIndex = 4; 86 | this.button2.Text = "Open Storage"; 87 | this.button2.UseVisualStyleBackColor = true; 88 | this.button2.Click += new System.EventHandler(this.Button2_Click); 89 | // 90 | // label2 91 | // 92 | this.label2.AutoSize = true; 93 | this.label2.Location = new System.Drawing.Point(27, 92); 94 | this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); 95 | this.label2.Name = "label2"; 96 | this.label2.Size = new System.Drawing.Size(57, 20); 97 | this.label2.TabIndex = 5; 98 | this.label2.Text = "Game:"; 99 | // 100 | // OpenStorageForm 101 | // 102 | this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F); 103 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 104 | this.ClientSize = new System.Drawing.Size(657, 211); 105 | this.Controls.Add(this.label2); 106 | this.Controls.Add(this.button2); 107 | this.Controls.Add(this.productComboBox); 108 | this.Controls.Add(this.label1); 109 | this.Controls.Add(this.textBox1); 110 | this.Controls.Add(this.button1); 111 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 112 | this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); 113 | this.Name = "OpenStorageForm"; 114 | this.Text = "Open Storage"; 115 | this.ResumeLayout(false); 116 | this.PerformLayout(); 117 | 118 | } 119 | 120 | #endregion 121 | 122 | private System.Windows.Forms.Button button1; 123 | private System.Windows.Forms.TextBox textBox1; 124 | private System.Windows.Forms.Label label1; 125 | private System.Windows.Forms.ComboBox productComboBox; 126 | private System.Windows.Forms.FolderBrowserDialog storageFolderBrowserDialog; 127 | private System.Windows.Forms.Button button2; 128 | private System.Windows.Forms.Label label2; 129 | } 130 | } -------------------------------------------------------------------------------- /CASCExplorer/OpenStorageForm.cs: -------------------------------------------------------------------------------- 1 | using CASCLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Collections.Specialized; 5 | using System.Configuration; 6 | using System.Windows.Forms; 7 | 8 | namespace CASCExplorer 9 | { 10 | public partial class OpenStorageForm : Form 11 | { 12 | public string StoragePath { get; private set; } 13 | public string Product { get; private set; } 14 | 15 | private List products = new List(); 16 | 17 | public OpenStorageForm() 18 | { 19 | InitializeComponent(); 20 | 21 | NameValueCollection onlineStorageList = (NameValueCollection)ConfigurationManager.GetSection("OnlineStorageList"); 22 | 23 | if (onlineStorageList != null) 24 | { 25 | foreach (string game in onlineStorageList) 26 | { 27 | products.Add(new TACTProduct { Id = game, Name = onlineStorageList[game] }); 28 | } 29 | } 30 | 31 | productComboBox.DataSource = products; 32 | } 33 | 34 | private void Button1_Click(object sender, EventArgs e) 35 | { 36 | if (storageFolderBrowserDialog.ShowDialog() != DialogResult.OK) 37 | { 38 | DialogResult = DialogResult.Cancel; 39 | return; 40 | } 41 | 42 | string path = storageFolderBrowserDialog.SelectedPath; 43 | 44 | textBox1.Text = path; 45 | } 46 | 47 | private void Button2_Click(object sender, EventArgs e) 48 | { 49 | if (productComboBox.SelectedIndex == -1) 50 | { 51 | MessageBox.Show("Must select type of game product!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); 52 | return; 53 | } 54 | 55 | TACTProduct selectedProduct = productComboBox.SelectedItem as TACTProduct; 56 | try 57 | { 58 | CASCConfig.LoadLocalStorageConfig(textBox1.Text, selectedProduct.Id); 59 | } 60 | catch (Exception ex) 61 | { 62 | MessageBox.Show(ex.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error); 63 | return; 64 | } 65 | 66 | StoragePath = textBox1.Text; 67 | Product = selectedProduct.Id; 68 | 69 | DialogResult = DialogResult.OK; 70 | Close(); 71 | } 72 | 73 | class TACTProduct 74 | { 75 | public string Id { get; set; } 76 | public string Name { get; set; } 77 | 78 | public override string ToString() => $"{Name} ({Id})"; 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /CASCExplorer/OpenStorageForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /CASCExplorer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace CASCExplorer 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 MainForm()); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /CASCExplorer/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("CASCExplorer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("CASCExplorer")] 13 | [assembly: AssemblyCopyright("Copyright © TOM_RUS 2014-2022")] 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("5c5b095e-c651-44a8-b8f2-50f8996197eb")] 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 | -------------------------------------------------------------------------------- /CASCExplorer/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 CASCExplorer.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", "15.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("CASCExplorer.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CFDMAA6ELV2G8. 65 | /// 66 | internal static string donateURL { 67 | get { 68 | return ResourceManager.GetString("donateURL", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 74 | /// 75 | internal static System.Drawing.Icon folder { 76 | get { 77 | object obj = ResourceManager.GetObject("folder", resourceCulture); 78 | return ((System.Drawing.Icon)(obj)); 79 | } 80 | } 81 | 82 | /// 83 | /// Looks up a localized resource of type System.Drawing.Bitmap. 84 | /// 85 | internal static System.Drawing.Bitmap logo { 86 | get { 87 | object obj = ResourceManager.GetObject("logo", resourceCulture); 88 | return ((System.Drawing.Bitmap)(obj)); 89 | } 90 | } 91 | 92 | /// 93 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 94 | /// 95 | internal static System.Drawing.Icon openFolder { 96 | get { 97 | object obj = ResourceManager.GetObject("openFolder", resourceCulture); 98 | return ((System.Drawing.Icon)(obj)); 99 | } 100 | } 101 | 102 | /// 103 | /// Looks up a localized resource of type System.Drawing.Bitmap. 104 | /// 105 | internal static System.Drawing.Bitmap transparent { 106 | get { 107 | object obj = ResourceManager.GetObject("transparent", resourceCulture); 108 | return ((System.Drawing.Bitmap)(obj)); 109 | } 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /CASCExplorer/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Icons\openFolder.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CFDMAA6ELV2G8 126 | 127 | 128 | ..\Icons\folder.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\transparent.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\logo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | -------------------------------------------------------------------------------- /CASCExplorer/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 CASCExplorer.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("enUS")] 29 | public global::CASCLib.LocaleFlags LocaleFlags { 30 | get { 31 | return ((global::CASCLib.LocaleFlags)(this["LocaleFlags"])); 32 | } 33 | set { 34 | this["LocaleFlags"] = value; 35 | } 36 | } 37 | 38 | [global::System.Configuration.UserScopedSettingAttribute()] 39 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 40 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 41 | public bool OverrideArchive { 42 | get { 43 | return ((bool)(this["OverrideArchive"])); 44 | } 45 | set { 46 | this["OverrideArchive"] = value; 47 | } 48 | } 49 | 50 | [global::System.Configuration.UserScopedSettingAttribute()] 51 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 52 | [global::System.Configuration.DefaultSettingValueAttribute("")] 53 | public string RecentStorages { 54 | get { 55 | return ((string)(this["RecentStorages"])); 56 | } 57 | set { 58 | this["RecentStorages"] = value; 59 | } 60 | } 61 | 62 | [global::System.Configuration.UserScopedSettingAttribute()] 63 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 64 | [global::System.Configuration.DefaultSettingValueAttribute("True")] 65 | public bool PreviewVisible { 66 | get { 67 | return ((bool)(this["PreviewVisible"])); 68 | } 69 | set { 70 | this["PreviewVisible"] = value; 71 | } 72 | } 73 | 74 | [global::System.Configuration.UserScopedSettingAttribute()] 75 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 76 | [global::System.Configuration.DefaultSettingValueAttribute("listfile.csv")] 77 | public string ListFilePath { 78 | get { 79 | return ((string)(this["ListFilePath"])); 80 | } 81 | set { 82 | this["ListFilePath"] = value; 83 | } 84 | } 85 | 86 | [global::System.Configuration.UserScopedSettingAttribute()] 87 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 88 | [global::System.Configuration.DefaultSettingValueAttribute("False")] 89 | public bool PreferHighResTextures { 90 | get { 91 | return ((bool)(this["PreferHighResTextures"])); 92 | } 93 | set { 94 | this["PreferHighResTextures"] = value; 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /CASCExplorer/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | enUS 7 | 8 | 9 | False 10 | 11 | 12 | 13 | 14 | 15 | True 16 | 17 | 18 | listfile.csv 19 | 20 | 21 | False 22 | 23 | 24 | -------------------------------------------------------------------------------- /CASCExplorer/RecentStorage.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace CASCExplorer 5 | { 6 | class RecentStorage 7 | { 8 | public string Path { get; set; } 9 | public string Product { get; set; } 10 | 11 | public static List Storages { get; private set; } 12 | 13 | public static bool Load(string json) 14 | { 15 | if (string.IsNullOrWhiteSpace(json)) 16 | { 17 | Storages = new List(); 18 | return true; 19 | } 20 | else 21 | { 22 | try 23 | { 24 | Storages = JsonConvert.DeserializeObject>(json); 25 | return true; 26 | } 27 | catch 28 | { 29 | Storages = new List(); 30 | return false; 31 | } 32 | } 33 | } 34 | 35 | public static string Save() 36 | { 37 | return JsonConvert.SerializeObject(Storages); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /CASCExplorer/Resources/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WoW-Tools/CASCExplorer/b06833ff112b4f0ca36083d17e4723460ec2c7f1/CASCExplorer/Resources/logo.png -------------------------------------------------------------------------------- /CASCExplorer/Resources/transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WoW-Tools/CASCExplorer/b06833ff112b4f0ca36083d17e4723460ec2c7f1/CASCExplorer/Resources/transparent.png -------------------------------------------------------------------------------- /CASCExplorer/ScanForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer 2 | { 3 | partial class ScanForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.scanProgressBar = new System.Windows.Forms.ProgressBar(); 32 | this.scanButton = new System.Windows.Forms.Button(); 33 | this.scanLabel = new System.Windows.Forms.Label(); 34 | this.scanBackgroundWorker = new System.ComponentModel.BackgroundWorker(); 35 | this.progressLabel = new System.Windows.Forms.Label(); 36 | this.filenameTextBox = new System.Windows.Forms.TextBox(); 37 | this.missingFilesLabel = new System.Windows.Forms.Label(); 38 | this.SuspendLayout(); 39 | // 40 | // scanProgressBar 41 | // 42 | this.scanProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 43 | | System.Windows.Forms.AnchorStyles.Right))); 44 | this.scanProgressBar.Location = new System.Drawing.Point(12, 25); 45 | this.scanProgressBar.Name = "scanProgressBar"; 46 | this.scanProgressBar.Size = new System.Drawing.Size(731, 23); 47 | this.scanProgressBar.TabIndex = 0; 48 | // 49 | // scanButton 50 | // 51 | this.scanButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 52 | this.scanButton.Location = new System.Drawing.Point(749, 25); 53 | this.scanButton.Name = "scanButton"; 54 | this.scanButton.Size = new System.Drawing.Size(73, 23); 55 | this.scanButton.TabIndex = 1; 56 | this.scanButton.Text = "Start"; 57 | this.scanButton.UseVisualStyleBackColor = true; 58 | this.scanButton.Click += new System.EventHandler(this.scanButton_Click); 59 | // 60 | // scanLabel 61 | // 62 | this.scanLabel.AutoSize = true; 63 | this.scanLabel.Location = new System.Drawing.Point(9, 9); 64 | this.scanLabel.Name = "scanLabel"; 65 | this.scanLabel.Size = new System.Drawing.Size(38, 13); 66 | this.scanLabel.TabIndex = 3; 67 | this.scanLabel.Text = "Ready"; 68 | // 69 | // scanBackgroundWorker 70 | // 71 | this.scanBackgroundWorker.WorkerReportsProgress = true; 72 | this.scanBackgroundWorker.WorkerSupportsCancellation = true; 73 | this.scanBackgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.scanBackgroundWorker_DoWork); 74 | this.scanBackgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(this.scanBackgroundWorker_ProgressChanged); 75 | this.scanBackgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.scanBackgroundWorker_RunWorkerCompleted); 76 | // 77 | // progressLabel 78 | // 79 | this.progressLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 80 | this.progressLabel.Location = new System.Drawing.Point(625, 9); 81 | this.progressLabel.Name = "progressLabel"; 82 | this.progressLabel.Size = new System.Drawing.Size(121, 13); 83 | this.progressLabel.TabIndex = 4; 84 | this.progressLabel.Text = "0/0"; 85 | this.progressLabel.TextAlign = System.Drawing.ContentAlignment.TopRight; 86 | // 87 | // filenameTextBox 88 | // 89 | this.filenameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 90 | | System.Windows.Forms.AnchorStyles.Left) 91 | | System.Windows.Forms.AnchorStyles.Right))); 92 | this.filenameTextBox.Font = new System.Drawing.Font("Consolas", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 93 | this.filenameTextBox.Location = new System.Drawing.Point(12, 78); 94 | this.filenameTextBox.MaxLength = 33554432; 95 | this.filenameTextBox.Multiline = true; 96 | this.filenameTextBox.Name = "filenameTextBox"; 97 | this.filenameTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; 98 | this.filenameTextBox.Size = new System.Drawing.Size(810, 289); 99 | this.filenameTextBox.TabIndex = 5; 100 | // 101 | // missingFilesLabel 102 | // 103 | this.missingFilesLabel.AutoSize = true; 104 | this.missingFilesLabel.Location = new System.Drawing.Point(9, 62); 105 | this.missingFilesLabel.Name = "missingFilesLabel"; 106 | this.missingFilesLabel.Size = new System.Drawing.Size(125, 13); 107 | this.missingFilesLabel.TabIndex = 6; 108 | this.missingFilesLabel.Text = "Missing file names found:"; 109 | // 110 | // ScanForm 111 | // 112 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 113 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 114 | this.ClientSize = new System.Drawing.Size(834, 379); 115 | this.Controls.Add(this.missingFilesLabel); 116 | this.Controls.Add(this.filenameTextBox); 117 | this.Controls.Add(this.progressLabel); 118 | this.Controls.Add(this.scanLabel); 119 | this.Controls.Add(this.scanButton); 120 | this.Controls.Add(this.scanProgressBar); 121 | this.MaximizeBox = false; 122 | this.MinimizeBox = false; 123 | this.MinimumSize = new System.Drawing.Size(350, 250); 124 | this.Name = "ScanForm"; 125 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 126 | this.Text = "Scan all files for missing file names"; 127 | this.ResumeLayout(false); 128 | this.PerformLayout(); 129 | 130 | } 131 | 132 | #endregion 133 | 134 | private System.Windows.Forms.ProgressBar scanProgressBar; 135 | private System.Windows.Forms.Button scanButton; 136 | private System.Windows.Forms.Label scanLabel; 137 | private System.ComponentModel.BackgroundWorker scanBackgroundWorker; 138 | private System.Windows.Forms.Label progressLabel; 139 | private System.Windows.Forms.TextBox filenameTextBox; 140 | private System.Windows.Forms.Label missingFilesLabel; 141 | } 142 | } -------------------------------------------------------------------------------- /CASCExplorer/ScanForm.cs: -------------------------------------------------------------------------------- 1 | using CASCLib; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Windows.Forms; 7 | 8 | namespace CASCExplorer 9 | { 10 | public partial class ScanForm : Form 11 | { 12 | private static readonly Jenkins96 Hasher = new Jenkins96(); 13 | 14 | private FileScanner scanner; 15 | private HashSet uniqueFileNames = new HashSet(); 16 | 17 | private CASCHandler CASC; 18 | private CASCFolder Root; 19 | 20 | private int NumFiles; 21 | private int NumScanned; 22 | private bool running; 23 | 24 | private class ScanResult 25 | { 26 | public string NewFile { get; set; } 27 | public string FoundInFile { get; set; } 28 | 29 | public ScanResult(string newFileName, string foundInFileName) 30 | { 31 | NewFile = newFileName; 32 | FoundInFile = foundInFileName; 33 | } 34 | 35 | public override int GetHashCode() 36 | { 37 | return NewFile.ToLower().GetHashCode(); 38 | } 39 | 40 | public override bool Equals(object obj) 41 | { 42 | if (obj == null) 43 | return false; 44 | if (!(obj is ScanResult)) 45 | return false; 46 | ScanResult res = (ScanResult)obj; 47 | if (!res.NewFile.ToLower().Equals(NewFile.ToLower())) 48 | return false; 49 | return true; 50 | } 51 | 52 | public override string ToString() 53 | { 54 | return NewFile + " (in: " + FoundInFile + ")"; 55 | } 56 | } 57 | 58 | public ScanForm() 59 | { 60 | InitializeComponent(); 61 | } 62 | 63 | public void Initialize(CASCHandler casc, CASCFolder root) 64 | { 65 | CASC = casc; 66 | Root = root; 67 | scanner = new FileScanner(CASC, Root); 68 | } 69 | 70 | public void Reset() 71 | { 72 | running = false; 73 | NumScanned = 0; 74 | NumFiles = CASC.Root.CountSelect; 75 | scanButton.Enabled = true; 76 | scanButton.Text = "Start"; 77 | scanProgressBar.Value = 0; 78 | scanLabel.Text = "Ready"; 79 | progressLabel.Text = ""; 80 | filenameTextBox.Clear(); 81 | uniqueFileNames.Clear(); 82 | } 83 | 84 | private void UpdateFileNames(string newFileName, string foundInFileName) 85 | { 86 | ScanResult res = new ScanResult(newFileName.Replace("/", "\\"), foundInFileName); 87 | uniqueFileNames.Add(res); 88 | filenameTextBox.AppendText(res.ToString() + Environment.NewLine); 89 | } 90 | 91 | private void scanButton_Click(object sender, EventArgs e) 92 | { 93 | running = !running; 94 | if (running) 95 | { 96 | Reset(); 97 | running = true; 98 | scanButton.Text = "Cancel"; 99 | scanBackgroundWorker.RunWorkerAsync(); 100 | } 101 | else 102 | { 103 | scanButton.Enabled = false; 104 | scanBackgroundWorker.CancelAsync(); 105 | } 106 | } 107 | 108 | private void scanBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) 109 | { 110 | try 111 | { 112 | ScanFolder(Root); 113 | } 114 | catch (OperationCanceledException) 115 | { 116 | e.Cancel = true; 117 | } 118 | } 119 | 120 | private void scanBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 121 | { 122 | scanProgressBar.Value = e.ProgressPercentage; 123 | scanLabel.Text = string.Format("Scanning '{0}' ...", e.UserState); 124 | progressLabel.Text = NumScanned + "/" + NumFiles; 125 | } 126 | 127 | private void scanBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 128 | { 129 | running = false; 130 | scanButton.Text = "Start"; 131 | scanButton.Enabled = true; 132 | scanLabel.Text = "Scan completed."; 133 | scanProgressBar.Value = 100; 134 | 135 | // display unique file names without finding place 136 | filenameTextBox.Clear(); 137 | 138 | foreach (var uniqueFileName in uniqueFileNames) 139 | filenameTextBox.AppendText(uniqueFileName.NewFile + Environment.NewLine); 140 | 141 | if (e.Cancelled) 142 | { 143 | Reset(); 144 | scanLabel.Text = "Scan cancelled."; 145 | } 146 | } 147 | 148 | private void ScanFolder(CASCFolder folder) 149 | { 150 | foreach (var entry in folder.Files) 151 | { 152 | ScanFile(entry.Value); 153 | } 154 | foreach (var entry in folder.Folders) 155 | { 156 | ScanFolder(entry.Value); 157 | } 158 | } 159 | 160 | private void ScanFile(CASCFile file) 161 | { 162 | if (scanBackgroundWorker.CancellationPending) 163 | throw new OperationCanceledException(); 164 | 165 | NumScanned++; 166 | 167 | var fileNames = scanner.ScanFile(file); 168 | 169 | if (fileNames.Any()) 170 | { 171 | // only report progress when not skipping a file, it's faster that way 172 | int progress = (int)(NumScanned / (float)NumFiles * 100); 173 | 174 | scanBackgroundWorker.ReportProgress(progress, file.FullName); 175 | 176 | foreach (var fileName in fileNames) 177 | { 178 | ulong hash = Hasher.ComputeHash(fileName); 179 | 180 | if ((CASC.Root as WowRootHandler).IsUnknownFile(hash)) 181 | { 182 | BeginInvoke((MethodInvoker)(() => UpdateFileNames(fileName, file.FullName))); 183 | } 184 | } 185 | } 186 | } 187 | } 188 | } 189 | -------------------------------------------------------------------------------- /CASCExplorer/ScanForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /CASCExplorer/SearchForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer 2 | { 3 | partial class SearchForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.button1 = new System.Windows.Forms.Button(); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.textBox1 = new System.Windows.Forms.TextBox(); 34 | this.button2 = new System.Windows.Forms.Button(); 35 | this.SuspendLayout(); 36 | // 37 | // button1 38 | // 39 | this.button1.Location = new System.Drawing.Point(274, 10); 40 | this.button1.Name = "button1"; 41 | this.button1.Size = new System.Drawing.Size(75, 23); 42 | this.button1.TabIndex = 1; 43 | this.button1.Text = "Find Next"; 44 | this.button1.UseVisualStyleBackColor = true; 45 | this.button1.Click += new System.EventHandler(this.button1_Click); 46 | // 47 | // label1 48 | // 49 | this.label1.AutoSize = true; 50 | this.label1.Location = new System.Drawing.Point(11, 15); 51 | this.label1.Name = "label1"; 52 | this.label1.Size = new System.Drawing.Size(59, 13); 53 | this.label1.TabIndex = 1; 54 | this.label1.Text = "Find What:"; 55 | // 56 | // textBox1 57 | // 58 | this.textBox1.Location = new System.Drawing.Point(76, 12); 59 | this.textBox1.Name = "textBox1"; 60 | this.textBox1.Size = new System.Drawing.Size(192, 20); 61 | this.textBox1.TabIndex = 0; 62 | // 63 | // button2 64 | // 65 | this.button2.DialogResult = System.Windows.Forms.DialogResult.Cancel; 66 | this.button2.Location = new System.Drawing.Point(274, 35); 67 | this.button2.Name = "button2"; 68 | this.button2.Size = new System.Drawing.Size(75, 23); 69 | this.button2.TabIndex = 2; 70 | this.button2.Text = "Cancel"; 71 | this.button2.UseVisualStyleBackColor = true; 72 | this.button2.Click += new System.EventHandler(this.button2_Click); 73 | // 74 | // SearchForm 75 | // 76 | this.AcceptButton = this.button1; 77 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 78 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 79 | this.CancelButton = this.button2; 80 | this.ClientSize = new System.Drawing.Size(369, 100); 81 | this.Controls.Add(this.button2); 82 | this.Controls.Add(this.textBox1); 83 | this.Controls.Add(this.label1); 84 | this.Controls.Add(this.button1); 85 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; 86 | this.Name = "SearchForm"; 87 | this.ShowInTaskbar = false; 88 | this.Text = "Find"; 89 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.SearchForm_FormClosing); 90 | this.ResumeLayout(false); 91 | this.PerformLayout(); 92 | 93 | } 94 | 95 | #endregion 96 | 97 | private System.Windows.Forms.Button button1; 98 | private System.Windows.Forms.Label label1; 99 | private System.Windows.Forms.TextBox textBox1; 100 | private System.Windows.Forms.Button button2; 101 | } 102 | } -------------------------------------------------------------------------------- /CASCExplorer/SearchForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace CASCExplorer 5 | { 6 | public partial class SearchForm : Form 7 | { 8 | private NoFlickerListView filelist; 9 | 10 | public SearchForm(NoFlickerListView filelist) 11 | { 12 | this.filelist = filelist; 13 | 14 | InitializeComponent(); 15 | } 16 | 17 | private void button1_Click(object sender, EventArgs e) 18 | { 19 | if (filelist.SelectedIndex < 0) 20 | return; 21 | 22 | var item = filelist.FindItemWithText(textBox1.Text, false, filelist.SelectedIndex, true); 23 | 24 | if (item != null) 25 | { 26 | filelist.EnsureVisible(item.Index); 27 | filelist.SelectedIndex = item.Index; 28 | filelist.FocusedItem = item; 29 | } 30 | else 31 | { 32 | MessageBox.Show(string.Format("Can't find:'{0}'", textBox1.Text), 33 | "CASCExplorer", 34 | MessageBoxButtons.OK, 35 | MessageBoxIcon.Information); 36 | } 37 | } 38 | 39 | private void SearchForm_FormClosing(object sender, FormClosingEventArgs e) 40 | { 41 | if (e.CloseReason == CloseReason.UserClosing) 42 | { 43 | e.Cancel = true; 44 | Hide(); 45 | Owner.Activate(); 46 | } 47 | } 48 | 49 | private void button2_Click(object sender, EventArgs e) 50 | { 51 | Hide(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /CASCExplorer/SearchForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /CASCExplorer/SelectBuildForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace CASCExplorer 2 | { 3 | partial class SelectBuildForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.listBox1 = new System.Windows.Forms.ListBox(); 32 | this.SuspendLayout(); 33 | // 34 | // listBox1 35 | // 36 | this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 37 | | System.Windows.Forms.AnchorStyles.Left) 38 | | System.Windows.Forms.AnchorStyles.Right))); 39 | this.listBox1.FormattingEnabled = true; 40 | this.listBox1.Location = new System.Drawing.Point(12, 12); 41 | this.listBox1.Name = "listBox1"; 42 | this.listBox1.Size = new System.Drawing.Size(391, 290); 43 | this.listBox1.TabIndex = 0; 44 | this.listBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDoubleClick); 45 | // 46 | // SelectBuildForm 47 | // 48 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 49 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 50 | this.ClientSize = new System.Drawing.Size(415, 315); 51 | this.Controls.Add(this.listBox1); 52 | this.Name = "SelectBuildForm"; 53 | this.Text = "Select CDN Build"; 54 | this.ResumeLayout(false); 55 | 56 | } 57 | 58 | #endregion 59 | 60 | private System.Windows.Forms.ListBox listBox1; 61 | } 62 | } -------------------------------------------------------------------------------- /CASCExplorer/SelectBuildForm.cs: -------------------------------------------------------------------------------- 1 | using CASCLib; 2 | using System.Windows.Forms; 3 | 4 | namespace CASCExplorer 5 | { 6 | public partial class SelectBuildForm : Form 7 | { 8 | public int SelectedIndex { get; private set; } 9 | 10 | public SelectBuildForm(CASCConfig config) 11 | { 12 | InitializeComponent(); 13 | 14 | foreach (var cfg in config.Builds) 15 | { 16 | listBox1.Items.Add(cfg["build-name"][0]); 17 | } 18 | 19 | //if (config.Builds.Count > 1) 20 | //{ 21 | // foreach (var cfg in config.Builds) 22 | // { 23 | // listBox1.Items.Add(cfg["build-name"][0]); 24 | // } 25 | //} 26 | //else 27 | // listBox1.Items.Add(config.BuildName); 28 | 29 | listBox1.SelectedIndex = 0; 30 | } 31 | 32 | private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e) 33 | { 34 | SelectedIndex = listBox1.SelectedIndex; 35 | DialogResult = DialogResult.OK; 36 | Close(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /CASCExplorer/SelectBuildForm.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /CASCExplorer/WDB2Reader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Text; 6 | 7 | namespace CASCLib 8 | { 9 | public class DB2Row 10 | { 11 | private readonly byte[] m_data; 12 | private readonly WDB2Reader m_reader; 13 | 14 | public byte[] Data => m_data; 15 | 16 | public DB2Row(WDB2Reader reader, byte[] data) 17 | { 18 | m_reader = reader; 19 | m_data = data; 20 | } 21 | 22 | public T GetField(int field) 23 | { 24 | object retVal; 25 | 26 | switch (Type.GetTypeCode(typeof(T))) 27 | { 28 | case TypeCode.String: 29 | int start = BitConverter.ToInt32(m_data, field * 4), len = 0; 30 | while (m_reader.StringTable[start + len] != 0) 31 | len++; 32 | retVal = Encoding.UTF8.GetString(m_reader.StringTable, start, len); 33 | return (T)retVal; 34 | case TypeCode.Int32: 35 | retVal = BitConverter.ToInt32(m_data, field * 4); 36 | return (T)retVal; 37 | case TypeCode.Single: 38 | retVal = BitConverter.ToSingle(m_data, field * 4); 39 | return (T)retVal; 40 | default: 41 | return default(T); 42 | } 43 | } 44 | } 45 | 46 | public class WDB2Reader : IEnumerable> 47 | { 48 | private const int HeaderSize = 48; 49 | private const uint DB2FmtSig = 0x32424457; // WDB2 50 | 51 | public int RecordsCount { get; private set; } 52 | public int FieldsCount { get; private set; } 53 | public int RecordSize { get; private set; } 54 | public int StringTableSize { get; private set; } 55 | public int MinIndex { get; private set; } 56 | public int MaxIndex { get; private set; } 57 | 58 | private readonly DB2Row[] m_rows; 59 | public byte[] StringTable { get; private set; } 60 | 61 | readonly Dictionary m_index = new Dictionary(); 62 | 63 | public WDB2Reader(string dbcFile) : this(new FileStream(dbcFile, FileMode.Open)) { } 64 | 65 | public WDB2Reader(Stream stream) 66 | { 67 | using (var reader = new BinaryReader(stream, Encoding.UTF8)) 68 | { 69 | if (reader.BaseStream.Length < HeaderSize) 70 | { 71 | throw new InvalidDataException(string.Format("DB2 file is corrupted!")); 72 | } 73 | 74 | if (reader.ReadUInt32() != DB2FmtSig) 75 | { 76 | throw new InvalidDataException(string.Format("DB2 file is corrupted!")); 77 | } 78 | 79 | RecordsCount = reader.ReadInt32(); 80 | FieldsCount = reader.ReadInt32(); 81 | RecordSize = reader.ReadInt32(); 82 | StringTableSize = reader.ReadInt32(); 83 | 84 | // WDB2 specific fields 85 | uint tableHash = reader.ReadUInt32(); // new field in WDB2 86 | uint build = reader.ReadUInt32(); // new field in WDB2 87 | uint unk1 = reader.ReadUInt32(); // new field in WDB2 88 | 89 | if (build > 12880) // new extended header 90 | { 91 | int MinId = reader.ReadInt32(); // new field in WDB2 92 | int MaxId = reader.ReadInt32(); // new field in WDB2 93 | int locale = reader.ReadInt32(); // new field in WDB2 94 | int unk5 = reader.ReadInt32(); // new field in WDB2 95 | 96 | if (MaxId != 0) 97 | { 98 | var diff = MaxId - MinId + 1; // blizzard is weird people... 99 | reader.ReadBytes(diff * 4); // an index for rows 100 | reader.ReadBytes(diff * 2); // a memory allocation bank 101 | } 102 | } 103 | 104 | m_rows = new DB2Row[RecordsCount]; 105 | 106 | for (int i = 0; i < RecordsCount; i++) 107 | { 108 | m_rows[i] = new DB2Row(this, reader.ReadBytes(RecordSize)); 109 | 110 | int idx = BitConverter.ToInt32(m_rows[i].Data, 0); 111 | 112 | if (idx < MinIndex) 113 | MinIndex = idx; 114 | 115 | if (idx > MaxIndex) 116 | MaxIndex = idx; 117 | 118 | m_index[idx] = m_rows[i]; 119 | } 120 | 121 | StringTable = reader.ReadBytes(StringTableSize); 122 | } 123 | } 124 | 125 | public bool HasRow(int index) 126 | { 127 | return m_index.ContainsKey(index); 128 | } 129 | 130 | public DB2Row GetRow(int index) 131 | { 132 | m_index.TryGetValue(index, out DB2Row row); 133 | return row; 134 | } 135 | 136 | public IEnumerator> GetEnumerator() 137 | { 138 | return m_index.GetEnumerator(); 139 | } 140 | 141 | IEnumerator IEnumerable.GetEnumerator() 142 | { 143 | return m_index.GetEnumerator(); 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /CASCExplorer/WDB3Reader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Text; 6 | 7 | namespace CASCLib 8 | { 9 | public class DB3Row 10 | { 11 | private byte[] m_data; 12 | private WDB3Reader m_reader; 13 | 14 | public byte[] Data { get { return m_data; } } 15 | 16 | public DB3Row(WDB3Reader reader, byte[] data) 17 | { 18 | m_reader = reader; 19 | m_data = data; 20 | } 21 | 22 | public unsafe T GetField(int offset) 23 | { 24 | object retVal; 25 | 26 | fixed (byte* ptr = m_data) 27 | { 28 | switch (Type.GetTypeCode(typeof(T))) 29 | { 30 | case TypeCode.String: 31 | string str; 32 | int start = BitConverter.ToInt32(m_data, offset); 33 | if (m_reader.StringTable.TryGetValue(start, out str)) 34 | retVal = str; 35 | else 36 | retVal = string.Empty; 37 | return (T)retVal; 38 | case TypeCode.SByte: 39 | retVal = ptr[offset]; 40 | return (T)retVal; 41 | case TypeCode.Byte: 42 | retVal = ptr[offset]; 43 | return (T)retVal; 44 | case TypeCode.Int16: 45 | retVal = *(short*)(ptr + offset); 46 | return (T)retVal; 47 | case TypeCode.UInt16: 48 | retVal = *(ushort*)(ptr + offset); 49 | return (T)retVal; 50 | case TypeCode.Int32: 51 | retVal = *(int*)(ptr + offset); 52 | return (T)retVal; 53 | case TypeCode.UInt32: 54 | retVal = *(uint*)(ptr + offset); 55 | return (T)retVal; 56 | case TypeCode.Single: 57 | retVal = *(float*)(ptr + offset); 58 | return (T)retVal; 59 | default: 60 | return default(T); 61 | } 62 | } 63 | } 64 | } 65 | 66 | public class WDB3Reader : IEnumerable> 67 | { 68 | private readonly int HeaderSize; 69 | private const uint DB3FmtSig = 0x33424457; // WDB3 70 | private const uint DB4FmtSig = 0x34424457; // WDB4 71 | 72 | public int RecordsCount { get; private set; } 73 | public int FieldsCount { get; private set; } 74 | public int RecordSize { get; private set; } 75 | public int StringTableSize { get; private set; } 76 | public int MinIndex { get; private set; } 77 | public int MaxIndex { get; private set; } 78 | 79 | public Dictionary StringTable { get; private set; } 80 | 81 | private SortedDictionary m_index = new SortedDictionary(); 82 | 83 | public WDB3Reader(string dbcFile) : this(new FileStream(dbcFile, FileMode.Open)) { } 84 | 85 | public WDB3Reader(Stream stream) 86 | { 87 | using (var reader = new BinaryReader(stream, Encoding.UTF8)) 88 | { 89 | if (reader.BaseStream.Length < HeaderSize) 90 | { 91 | throw new InvalidDataException(string.Format("DB3 file is corrupted!")); 92 | } 93 | 94 | uint magic = reader.ReadUInt32(); 95 | 96 | if (magic != DB3FmtSig && magic != DB4FmtSig) 97 | { 98 | throw new InvalidDataException(string.Format("DB3 file is corrupted!")); 99 | } 100 | 101 | if (magic == DB3FmtSig) 102 | HeaderSize = 48; 103 | else if (magic == DB4FmtSig) 104 | HeaderSize = 52; 105 | else 106 | HeaderSize = 56; 107 | 108 | RecordsCount = reader.ReadInt32(); 109 | FieldsCount = reader.ReadInt32(); 110 | RecordSize = reader.ReadInt32(); 111 | StringTableSize = reader.ReadInt32(); 112 | 113 | uint tableHash = reader.ReadUInt32(); 114 | uint build = reader.ReadUInt32(); 115 | 116 | uint unk1 = reader.ReadUInt32(); // timemodified 117 | 118 | int MinId = reader.ReadInt32(); 119 | int MaxId = reader.ReadInt32(); 120 | int locale = reader.ReadInt32(); 121 | int CopyTableSize = reader.ReadInt32(); 122 | 123 | if (magic == DB4FmtSig) 124 | { 125 | int metaFlags = reader.ReadInt32(); 126 | } 127 | 128 | int stringTableStart = HeaderSize + RecordsCount * RecordSize; 129 | int stringTableEnd = stringTableStart + StringTableSize; 130 | 131 | // Index table 132 | int[] m_indexes = null; 133 | bool hasIndex = stringTableEnd + CopyTableSize < reader.BaseStream.Length; 134 | 135 | if (hasIndex) 136 | { 137 | reader.BaseStream.Position = stringTableEnd; 138 | 139 | m_indexes = new int[RecordsCount]; 140 | 141 | for (int i = 0; i < RecordsCount; i++) 142 | m_indexes[i] = reader.ReadInt32(); 143 | } 144 | 145 | // Records table 146 | reader.BaseStream.Position = HeaderSize; 147 | 148 | for (int i = 0; i < RecordsCount; i++) 149 | { 150 | byte[] recordBytes = reader.ReadBytes(RecordSize); 151 | 152 | if (hasIndex) 153 | { 154 | byte[] newRecordBytes = new byte[RecordSize + 4]; 155 | 156 | Array.Copy(BitConverter.GetBytes(m_indexes[i]), newRecordBytes, 4); 157 | Array.Copy(recordBytes, 0, newRecordBytes, 4, recordBytes.Length); 158 | 159 | m_index.Add(m_indexes[i], new DB3Row(this, newRecordBytes)); 160 | } 161 | else 162 | { 163 | m_index.Add(BitConverter.ToInt32(recordBytes, 0), new DB3Row(this, recordBytes)); 164 | } 165 | } 166 | 167 | // Strings table 168 | reader.BaseStream.Position = stringTableStart; 169 | 170 | StringTable = new Dictionary(); 171 | 172 | while (reader.BaseStream.Position != stringTableEnd) 173 | { 174 | int index = (int)reader.BaseStream.Position - stringTableStart; 175 | StringTable[index] = reader.ReadCString(); 176 | } 177 | 178 | // Copy index table 179 | long copyTablePos = stringTableEnd + (hasIndex ? 4 * RecordsCount : 0); 180 | 181 | if (copyTablePos != reader.BaseStream.Length && CopyTableSize != 0) 182 | { 183 | reader.BaseStream.Position = copyTablePos; 184 | 185 | while (reader.BaseStream.Position != reader.BaseStream.Length) 186 | { 187 | int id = reader.ReadInt32(); 188 | int idcopy = reader.ReadInt32(); 189 | 190 | RecordsCount++; 191 | 192 | DB3Row copyRow = m_index[idcopy]; 193 | byte[] newRowData = new byte[copyRow.Data.Length]; 194 | Array.Copy(copyRow.Data, newRowData, newRowData.Length); 195 | Array.Copy(BitConverter.GetBytes(id), newRowData, 4); 196 | 197 | m_index.Add(id, new DB3Row(this, newRowData)); 198 | } 199 | } 200 | } 201 | } 202 | 203 | public bool HasRow(int index) 204 | { 205 | return m_index.ContainsKey(index); 206 | } 207 | 208 | public DB3Row GetRow(int index) 209 | { 210 | m_index.TryGetValue(index, out DB3Row row); 211 | return row; 212 | } 213 | 214 | public IEnumerator> GetEnumerator() 215 | { 216 | return m_index.GetEnumerator(); 217 | } 218 | 219 | IEnumerator IEnumerable.GetEnumerator() 220 | { 221 | return m_index.GetEnumerator(); 222 | } 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /CASCExplorer/WDBCReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Text; 6 | 7 | namespace CASCLib 8 | { 9 | class DBCRow 10 | { 11 | private byte[] m_data; 12 | private WDBCReader m_reader; 13 | 14 | public byte[] Data { get { return m_data; } } 15 | 16 | public DBCRow(WDBCReader reader, byte[] data) 17 | { 18 | m_reader = reader; 19 | m_data = data; 20 | } 21 | 22 | public T GetField(int field) 23 | { 24 | object retVal; 25 | 26 | switch (Type.GetTypeCode(typeof(T))) 27 | { 28 | case TypeCode.String: 29 | int start = BitConverter.ToInt32(m_data, field * 4), len = 0; 30 | while (m_reader.StringTable[start + len] != 0) 31 | len++; 32 | retVal = Encoding.UTF8.GetString(m_reader.StringTable, start, len); 33 | return (T)retVal; 34 | case TypeCode.Int32: 35 | retVal = BitConverter.ToInt32(m_data, field * 4); 36 | return (T)retVal; 37 | case TypeCode.Single: 38 | retVal = BitConverter.ToSingle(m_data, field * 4); 39 | return (T)retVal; 40 | default: 41 | return default(T); 42 | } 43 | } 44 | } 45 | 46 | class WDBCReader : IEnumerable> 47 | { 48 | private const uint HeaderSize = 20; 49 | private const uint DBCFmtSig = 0x43424457; // WDBC 50 | 51 | public int RecordsCount { get; private set; } 52 | public int FieldsCount { get; private set; } 53 | public int RecordSize { get; private set; } 54 | public int StringTableSize { get; private set; } 55 | public int MinIndex { get; private set; } = int.MaxValue; 56 | public int MaxIndex { get; private set; } = int.MinValue; 57 | 58 | private readonly DBCRow[] m_rows; 59 | private readonly byte[] m_stringTable; 60 | 61 | public byte[] StringTable { get { return m_stringTable; } } 62 | 63 | Dictionary m_index = new Dictionary(); 64 | 65 | public WDBCReader(string dbcFile) : this(new FileStream(dbcFile, FileMode.Open)) { } 66 | 67 | public WDBCReader(Stream stream) 68 | { 69 | using (var reader = new BinaryReader(stream, Encoding.UTF8)) 70 | { 71 | if (reader.BaseStream.Length < HeaderSize) 72 | { 73 | throw new InvalidDataException("File DBC is corrupted!"); 74 | } 75 | 76 | if (reader.ReadUInt32() != DBCFmtSig) 77 | { 78 | throw new InvalidDataException("File DBC is corrupted!"); 79 | } 80 | 81 | RecordsCount = reader.ReadInt32(); 82 | FieldsCount = reader.ReadInt32(); 83 | RecordSize = reader.ReadInt32(); 84 | StringTableSize = reader.ReadInt32(); 85 | 86 | m_rows = new DBCRow[RecordsCount]; 87 | 88 | for (int i = 0; i < RecordsCount; i++) 89 | { 90 | m_rows[i] = new DBCRow(this, reader.ReadBytes(RecordSize)); 91 | 92 | int idx = BitConverter.ToInt32(m_rows[i].Data, 0); 93 | 94 | if (idx < MinIndex) 95 | MinIndex = idx; 96 | 97 | if (idx > MaxIndex) 98 | MaxIndex = idx; 99 | 100 | m_index[idx] = m_rows[i]; 101 | } 102 | 103 | m_stringTable = reader.ReadBytes(StringTableSize); 104 | } 105 | } 106 | 107 | public bool HasRow(int index) 108 | { 109 | return m_index.ContainsKey(index); 110 | } 111 | 112 | public DBCRow GetRow(int index) 113 | { 114 | if (!m_index.ContainsKey(index)) 115 | return null; 116 | 117 | return m_index[index]; 118 | } 119 | 120 | public IEnumerator> GetEnumerator() 121 | { 122 | return m_index.GetEnumerator(); 123 | } 124 | 125 | IEnumerator IEnumerable.GetEnumerator() 126 | { 127 | return m_index.GetEnumerator(); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /CASCExplorer/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | true 57 | true 58 | 59 | 60 | 61 | 62 | 63 | 64 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CASCExplorer 2 | ============ 3 | 4 | You can download compiled binaries [here][Binaries]. 5 | 6 | Make sure to edit path to wow folder in config file before use. 7 | 8 | [Donate][Donate] to support developer! 9 | 10 | [Binaries]: https://github.com/WoW-Tools/CASCExplorer/releases 11 | [Donate]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=CFDMAA6ELV2G8 12 | 13 | # Build instructions 14 | First grab the code using git: 15 | 16 | ``` 17 | git clone https://github.com/WoW-Tools/CASCExplorer.git 18 | cd CASCExplorer 19 | git submodule update --init --recursive 20 | ``` 21 | 22 | Use Visual Studio 2017 15.7.0 or higher to build it once you have all dependencies. 23 | --------------------------------------------------------------------------------