Skip to content

Commit 446666b

Browse files
committed
Version 1.3
Final release. New features: Highlighter, SHA-256 hash, duplicate contents with same offset.
1 parent 2208ac7 commit 446666b

15 files changed

+312
-286
lines changed

HPIZ Archiver/App.config

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace HPIZArchiver
88
{
9-
static class FolderExtension
9+
static class DirectoryExtensionPair
1010
{
1111
static readonly Dictionary<string, string[]> folderExtensionPairs = new Dictionary<string, string[]>()
1212
{
@@ -45,7 +45,7 @@ static class FolderExtension
4545
{ @"weapons", new string[] { "tdf" } }
4646
};
4747

48-
public static bool CheckKnow(string path)
48+
public static bool IsDirectoryExtensionKnow(string path)
4949
{
5050
path = path.ToLower();
5151
foreach (var folder in folderExtensionPairs.Keys)

HPIZ Archiver/HPIZ Archiver.csproj

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@
7272
<PropertyGroup>
7373
<TargetZone>LocalIntranet</TargetZone>
7474
</PropertyGroup>
75+
<PropertyGroup>
76+
<ApplicationManifest>app.manifest</ApplicationManifest>
77+
</PropertyGroup>
7578
<ItemGroup>
7679
<Reference Include="System" />
7780
<Reference Include="System.Core" />
@@ -89,7 +92,7 @@
8992
<Compile Include="CollapsibleListView.cs">
9093
<SubType>Component</SubType>
9194
</Compile>
92-
<Compile Include="FolderExtension.cs" />
95+
<Compile Include="DirectoryExtensionPair.cs" />
9396
<Compile Include="ListViewItemComparer.cs" />
9497
<Compile Include="MainForm.cs">
9598
<SubType>Form</SubType>
@@ -109,7 +112,7 @@
109112
<SubType>Designer</SubType>
110113
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
111114
</EmbeddedResource>
112-
<None Include="app.config" />
115+
<None Include="app.manifest" />
113116
<None Include="Properties\Settings.settings">
114117
<Generator>SettingsSingleFileGenerator</Generator>
115118
<LastGenOutput>Settings.Designer.cs</LastGenOutput>

HPIZ Archiver/MainForm.Designer.cs

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

HPIZ Archiver/MainForm.cs

Lines changed: 87 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using System.Security.Policy;
99
using System.Threading.Tasks;
1010
using System.Windows.Forms;
11-
using static System.Net.WebRequestMethods;
1211

1312
namespace HPIZArchiver
1413
{
@@ -20,6 +19,8 @@ public partial class MainForm : Form
2019
Dictionary<int, List<ListViewItem>> toHashCandidates = new Dictionary<int, List<ListViewItem>>();
2120
Dictionary<string, List<ListViewItem>> sameContent = new Dictionary<string, List<ListViewItem>>();
2221

22+
Dictionary<string, HpiArchive> cachedHPI = new Dictionary<string, HpiArchive>(StringComparer.OrdinalIgnoreCase);
23+
2324
Stopwatch timer = new Stopwatch();
2425

2526
long totalSize = 0;
@@ -62,6 +63,7 @@ private void closeAllToolStripMenuItem_Click(object sender, EventArgs e)
6263
listViewFiles.Groups.Clear();
6364
uniqueSources.Clear();
6465
uniqueNames.Clear();
66+
cachedHPI.Clear();
6567
toHashCandidates.Clear();
6668
sameContent.Clear();
6769
totalSize = 0;
@@ -95,30 +97,18 @@ private void AddToListViewFiles(List<ListViewItem> itemList)
9597
}
9698

9799
foreach (ListViewGroup group in listViewFiles.Groups)
98-
if (Directory.Exists(group.Name))
99-
{
100100
foreach (var candidate in toHashCandidates.Values)
101101
if (candidate.Count > 1 && candidate[0].Group == group && candidate[0].SubItems[8].Text == string.Empty)
102102
{
103-
candidate[0].SubItems[8].Text = Utils.CalculateSha256((string)candidate[0].SubItems[1].Tag);
104-
if (sameContent.ContainsKey(candidate[0].SubItems[8].Text))
105-
sameContent[candidate[0].SubItems[8].Text].Add(candidate[0]);
106-
else sameContent.Add(candidate[0].SubItems[8].Text, new List<ListViewItem>() { candidate[0] });
107-
}
108-
}
109-
else
110-
using (HpiArchive hpia = HpiFile.Open(group.Name))
111-
foreach (var candidate in toHashCandidates.Values)
112-
if (candidate.Count > 1 && candidate[0].Group == group && candidate[0].SubItems[8].Text == string.Empty)
113-
{
114-
candidate[0].SubItems[8].Text = Utils.CalculateSha256(hpia.Entries[candidate[0].SubItems[1].Text].Uncompress());
103+
if (Directory.Exists(group.Name))
104+
candidate[0].SubItems[8].Text = Utils.CalculateSha256( Path.Combine(group.Name, candidate[0].SubItems[1].Text) );
105+
else
106+
candidate[0].SubItems[8].Text = Utils.CalculateSha256(cachedHPI[group.Name].Entries[candidate[0].SubItems[1].Text].Uncompress());
115107
if (sameContent.ContainsKey(candidate[0].SubItems[8].Text))
116108
sameContent[candidate[0].SubItems[8].Text].Add(candidate[0]);
117109
else sameContent.Add(candidate[0].SubItems[8].Text, new List<ListViewItem>() { candidate[0] });
118110
}
119111

120-
121-
122112
SetRule(dRules);
123113
SetHighliths();
124114
showHideColumns();
@@ -163,6 +153,7 @@ internal async void openFilesStripMenuItem_Click(object sender, EventArgs e)
163153
if(!uniqueSources.Contains(file))
164154
{
165155
uniqueSources.Add(file);
156+
cachedHPI.Add(file, HpiFile.Open(file));
166157
var filesInfo = await Task.Run(() => GetListViewGroupItens(file));
167158
AddToListViewFiles(filesInfo);
168159
}
@@ -247,48 +238,45 @@ public List<ListViewItem> GetListViewGroupItens(string fullPath)
247238
else //HPI Files
248239
{
249240
var group = new ListViewGroup(fullPath, Path.GetExtension(fullPath).ToUpper() + " File - " + fullPath);
250-
using (HpiArchive hpia = HpiFile.Open(fullPath))
241+
foreach (var entry in cachedHPI[fullPath].Entries)
251242
{
252-
foreach (var entry in hpia.Entries)
253-
{
254-
totalSize += entry.Value.UncompressedSize;
255-
totalCompressedSize += entry.Value.CompressedSizeCount();
256-
257-
ListViewItem lvItem = new ListViewItem(new string[] {
258-
String.Empty,
259-
entry.Key,
260-
Path.GetExtension(entry.Key).ToUpper(),
261-
entry.Value.UncompressedSize.ToString("N0"),
262-
entry.Value.CompressedSizeCount().ToString("N0"),
263-
entry.Value.Ratio().ToString("P1"),
264-
entry.Value.FlagCompression.ToString(),
265-
entry.Value.OffsetOfCompressedData.ToString("X8"),
266-
String.Empty
267-
}, group);
243+
totalSize += entry.Value.UncompressedSize;
244+
totalCompressedSize += entry.Value.CompressedSizeCount();
268245

269-
lvItem.SubItems[1].Tag = fullPath;
270-
lvItem.SubItems[3].Tag = entry.Value.UncompressedSize;
271-
lvItem.SubItems[4].Tag = entry.Value.CompressedSizeCount();
272-
lvItem.SubItems[5].Tag = entry.Value.Ratio();
273-
lvItem.SubItems[6].Tag = entry.Value.FlagCompression;
274-
lvItem.Tag = fullPath;
275-
listColection.Add(lvItem);
246+
ListViewItem lvItem = new ListViewItem(new string[] {
247+
String.Empty,
248+
entry.Key,
249+
Path.GetExtension(entry.Key).ToUpper(),
250+
entry.Value.UncompressedSize.ToString("N0"),
251+
entry.Value.CompressedSizeCount().ToString("N0"),
252+
entry.Value.Ratio().ToString("P1"),
253+
entry.Value.FlagCompression.ToString(),
254+
entry.Value.CompressedDataOffset.ToString("X8"),
255+
String.Empty
256+
}, group);
276257

277-
if (sha256ToolStripMenuItem.Checked || toHashCandidates.ContainsKey(entry.Value.UncompressedSize))
278-
{
279-
var hash = Utils.CalculateSha256(entry.Value.Uncompress());
280-
lvItem.SubItems[8].Text = hash;
258+
lvItem.SubItems[1].Tag = fullPath;
259+
lvItem.SubItems[3].Tag = entry.Value.UncompressedSize;
260+
lvItem.SubItems[4].Tag = entry.Value.CompressedSizeCount();
261+
lvItem.SubItems[5].Tag = entry.Value.Ratio();
262+
lvItem.SubItems[6].Tag = entry.Value.FlagCompression;
263+
lvItem.Tag = fullPath;
264+
listColection.Add(lvItem);
281265

282-
if(!sha256ToolStripMenuItem.Checked)
283-
toHashCandidates[entry.Value.UncompressedSize].Add(lvItem);
266+
if (sha256ToolStripMenuItem.Checked || toHashCandidates.ContainsKey(entry.Value.UncompressedSize))
267+
{
268+
var hash = Utils.CalculateSha256(entry.Value.Uncompress());
269+
lvItem.SubItems[8].Text = hash;
284270

285-
if (sameContent.ContainsKey(hash))
286-
sameContent[hash].Add(lvItem);
287-
else sameContent.Add(hash, new List<ListViewItem>() { lvItem });
288-
}
289-
else
290-
toHashCandidates.Add(entry.Value.UncompressedSize, new List<ListViewItem>() { lvItem });
271+
if(!sha256ToolStripMenuItem.Checked)
272+
toHashCandidates[entry.Value.UncompressedSize].Add(lvItem);
273+
274+
if (sameContent.ContainsKey(hash))
275+
sameContent[hash].Add(lvItem);
276+
else sameContent.Add(hash, new List<ListViewItem>() { lvItem });
291277
}
278+
else
279+
toHashCandidates.Add(entry.Value.UncompressedSize, new List<ListViewItem>() { lvItem });
292280
}
293281
}
294282
return listColection;
@@ -316,7 +304,7 @@ private async void toolStripExtractButton_Click(object sender, EventArgs e)
316304

317305
timer.Restart();
318306

319-
await Task.Run(() => HpiFile.DoExtraction(sources, dialogExtractToFolder.SelectedPath, progress));
307+
await Task.Run(() => HpiFile.DoExtraction(sources, dialogExtractToFolder.SelectedPath, progress, cachedHPI));
320308

321309
timer.Stop();
322310

@@ -330,33 +318,25 @@ private async void toolStripExtractButton_Click(object sender, EventArgs e)
330318
}
331319
}
332320

333-
public PathCollection GetCheckedFileNames()
321+
public FilePathCollection GetCheckedFileNames()
334322
{
335-
PathCollection fileList = new PathCollection();
323+
FilePathCollection fileList = new FilePathCollection();
336324

337325
foreach (ListViewItem item in listViewFiles.CheckedItems)
338-
{
339-
if (fileList.ContainsKey(item.Group.Name))
340-
fileList[item.Group.Name].Add(item.SubItems[1].Text);
341-
else
342-
fileList.Add(item.Group.Name, new SortedSet<string>() { item.SubItems[1].Text });
343-
}
326+
fileList.AddOrReplace(item.SubItems[1].Text, item.Group.Name);
344327

345328
return fileList;
346329
}
347330

348-
private async void compressCheckedFilesToolStripMenuItem_Click(object sender, EventArgs e)
331+
public async void compressOrRepackCheckedFiles()
349332
{
350-
if (listViewFiles.CheckedItems.Count == 0)
351-
MessageBox.Show("Can't Compress: No files have been checked in the list.");
352-
353-
else if (dialogSaveHpi.ShowDialog() == DialogResult.OK)
333+
if (dialogSaveHpi.ShowDialog() == DialogResult.OK)
354334
{
355335
SetMode(ArchiverMode.Busy);
356336

357337
firstStatusLabel.Text = "Compressing... Last processed:";
358338

359-
//Calculate total size and number of chunks
339+
//Calculate total size and number of chunks to max progressbar
360340
foreach (ListViewItem item in listViewFiles.CheckedItems)
361341
progressBar.Maximum += FileEntry.CalculateChunkQuantity((int)item.SubItems[3].Tag);
362342

@@ -372,9 +352,29 @@ private async void compressCheckedFilesToolStripMenuItem_Click(object sender, Ev
372352

373353
var sources = GetCheckedFileNames();
374354

375-
timer.Restart();
355+
var duplicateResults = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
356+
357+
foreach (var sames in sameContent.Values)
358+
{
359+
string first = string.Empty;
360+
SortedSet<string> orderedSames = new SortedSet<string>(StringComparer.OrdinalIgnoreCase);
361+
foreach (var item in sames)
362+
if(item.Checked == true)
363+
orderedSames.Add(item.SubItems[1].Text);
364+
365+
foreach (var item in orderedSames)
366+
if (first == string.Empty)
367+
first = item;
368+
else if (!duplicateResults.ContainsKey(item))
369+
duplicateResults.Add(item, first);
370+
}
371+
376372

377-
await Task.Run(() => HpiFile.CreateFromManySources(sources, dialogSaveHpi.FileName, flavor, progress));
373+
duplicateResults = null;
374+
375+
timer.Restart();
376+
377+
await Task.Run(() => HpiFile.CreateFromManySources(sources, dialogSaveHpi.FileName, flavor, progress, cachedHPI, duplicateResults));
378378

379379
timer.Stop();
380380

@@ -388,6 +388,22 @@ private async void compressCheckedFilesToolStripMenuItem_Click(object sender, Ev
388388
}
389389
}
390390

391+
private void compressCheckedFilesToolStripMenuItem_Click(object sender, EventArgs e)
392+
{
393+
if (listViewFiles.CheckedItems.Count == 0)
394+
MessageBox.Show("Can't Compress: No files have been checked in the list.");
395+
else
396+
compressOrRepackCheckedFiles();
397+
}
398+
399+
private void mergeRepackCheckedFilesToolStripMenuItem_Click(object sender, EventArgs e)
400+
{
401+
if (listViewFiles.CheckedItems.Count == 0)
402+
MessageBox.Show("Can't Merge/Repack: No files have been checked in the list.");
403+
else
404+
compressOrRepackCheckedFiles();
405+
}
406+
391407
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
392408
{
393409
for (int i = 0; i < listViewFiles.Items.Count; i++)
@@ -429,49 +445,6 @@ private void listViewFiles_ColumnClick(object sender, ColumnClickEventArgs e)
429445
}
430446
}
431447

432-
private async void mergeRepackCheckedFilesToolStripMenuItem_Click(object sender, EventArgs e)
433-
{
434-
if(listViewFiles.CheckedItems.Count == 0)
435-
MessageBox.Show("Can't Merge/Repack: No files have been checked in the list.");
436-
437-
else if (dialogSaveHpi.ShowDialog() == DialogResult.OK)
438-
{
439-
SetMode(ArchiverMode.Busy);
440-
441-
firstStatusLabel.Text = "Compressing... Last processed:";
442-
443-
CompressionMethod flavor;
444-
Enum.TryParse(flavorLevelComboBox.Text, out flavor);
445-
446-
//Calculate total size and number of chunks to max progressbar
447-
foreach (ListViewItem item in listViewFiles.CheckedItems)
448-
progressBar.Maximum += FileEntry.CalculateChunkQuantity((int)item.SubItems[3].Tag);
449-
450-
var progress = new Progress<string>(last =>
451-
{
452-
secondStatusLabel.Text = last;
453-
progressBar.PerformStep();
454-
TaskbarProgress.SetValue(this.Handle, progressBar.Value, progressBar.Maximum);
455-
});
456-
457-
var sources = GetCheckedFileNames();
458-
459-
timer.Restart();
460-
461-
await Task.Run(() => HpiFile.CreateFromManySources(sources, dialogSaveHpi.FileName, flavor, progress));
462-
463-
timer.Stop();
464-
465-
firstStatusLabel.Text = String.Format("Done! Elapsed time: {0}h {1}m {2}s {3}ms", timer.Elapsed.Hours, timer.Elapsed.Minutes,
466-
timer.Elapsed.Seconds, timer.Elapsed.Milliseconds);
467-
progressBar.Value = progressBar.Maximum;
468-
secondStatusLabel.Text = dialogSaveHpi.FileName;
469-
secondStatusLabel.IsLink = true;
470-
TaskbarProgress.FlashWindow(this.Handle, true);
471-
SetMode(ArchiverMode.Finish);
472-
}
473-
}
474-
475448
private void SetRule(DuplicateRules rule)
476449
{
477450
dRules = rule;
@@ -589,7 +562,7 @@ void SetHighliths()
589562

590563

591564
foreach (ListViewItem item in listViewFiles.Items)
592-
if (!FolderExtension.CheckKnow(item.SubItems[1].Text))
565+
if (!DirectoryExtensionPair.IsDirectoryExtensionKnow(item.SubItems[1].Text))
593566
if (unknowFoldersExtensionToolStripMenuItem.Checked)
594567
item.BackColor = unknowFoldersExtensionToolStripMenuItem.BackColor;
595568
else if (item.BackColor == unknowFoldersExtensionToolStripMenuItem.BackColor)

HPIZ Archiver/Utils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public static string SizeSuffix(long byteCount, int decimalPlaces = 1)
2525
public static string CalculateSha256(string filename)
2626
{
2727
using (SHA256 mySHA256 = SHA256.Create())
28-
return BitConverter.ToString(mySHA256.ComputeHash(File.Open(filename, FileMode.Open))).ToLower().Replace("-", string.Empty);
28+
return BitConverter.ToString(mySHA256.ComputeHash(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))).ToLower().Replace("-", string.Empty);
2929
}
3030

3131
public static string CalculateSha256(byte[] data)

0 commit comments

Comments
 (0)