├── .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 |
--------------------------------------------------------------------------------