Skip to content

Commit dc18bfc

Browse files
committed
Add dependency support, update README to reflect feature-complete state
1 parent 5a754c8 commit dc18bfc

6 files changed

Lines changed: 163 additions & 40 deletions

File tree

README.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Flashpoint Manager
2-
This is a work-in-progress component manager for Flashpoint. When finished, it will serve as an all-in-one solution for downloading Flashpoint and maintaining its individual components.
2+
This is a component manager for [BlueMaxima's Flashpoint](https://bluemaxima.org/flashpoint/). If all goes well, it will eventually become the primary method of downloading Flashpoint and maintaining its individual components.
3+
4+
## Testing
5+
Because the component repository the application depends on does not yet exist, you must download the components.xml file from [here](https://gist.github.com/WumboSpasm/9faf5835d391288805bb7f6c17b8a0e0) and create your own component files in order to test it. However, I will discuss the creation of a comprehensive test repository with other Flashpoint staff and update this section if there are any developments.
36

47
## To-do
5-
* Complete "Remove Flashpoint" tab
6-
* Add more checks to prevent crashes
7-
* Add comments to code
8+
* Add more error checking
9+
* Add more comments to code
10+
* Create a command-line version (probably in another repository)

src/Common.cs

Lines changed: 84 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class Component : Category
1515
{
1616
public string Hash { get; set; }
1717
public long Size { get; set; }
18-
public string[] Depends { get; set; }
18+
public string[] Depends { get; set; } = new string[] {};
1919
public bool Extra { get; set; }
2020

2121
public Component(XmlNode node) : base(node)
@@ -194,7 +194,7 @@ public static class ComponentTracker
194194
{
195195
// Information about components that are available locally
196196
public static List<Component> Downloaded { get; set; } = new List<Component>();
197-
// Information about components that are to be updated
197+
// Information about components that are to be updated or added through the updater
198198
public static List<Component> ToUpdate { get; set; } = new List<Component>();
199199
}
200200

@@ -277,12 +277,12 @@ public static void SyncManager(bool setCheckState = false)
277277

278278
if (File.Exists(infoPath)) ComponentTracker.Downloaded.Add(component);
279279

280-
if (setCheckState) node.Checked = File.Exists(infoPath) ? true : false;
280+
if (setCheckState) node.Checked = File.Exists(infoPath);
281281
}
282282
});
283283

284-
SizeTracker.Downloaded = GetTotalSize(Main.ComponentList2.Nodes);
285-
SizeTracker.Modified = GetTotalSize(Main.ComponentList2.Nodes);
284+
SizeTracker.Downloaded = GetTotalSize(Main.ComponentList2);
285+
SizeTracker.Modified = GetTotalSize(Main.ComponentList2);
286286
}
287287

288288
// Deletes a file as well as any directories made empty by its deletion
@@ -371,16 +371,92 @@ public static bool VerifySourcePath(string path, int textBox = 0)
371371
return false;
372372
}
373373

374+
// Checks if any dependencies were not marked for download by the user, and marks them accordingly
375+
public static bool CheckDependencies(TreeView sourceTree)
376+
{
377+
List<string> requiredDepends = new List<string>();
378+
List<string> persistDepends = new List<string>();
379+
List<string> missingDepends = new List<string>();
380+
381+
// First, fill out a list of dependencies
382+
Iterate(sourceTree.Nodes, node =>
383+
{
384+
if (node.Checked && node.Tag.GetType().ToString().EndsWith("Component"))
385+
{
386+
Component component = node.Tag as Component;
387+
string infoPath = Path.Combine(SourcePath, "Components", $"{component.ID}.txt");
388+
389+
if (sourceTree.Name == "ComponentList2" && File.Exists(infoPath))
390+
{
391+
requiredDepends.AddRange(File.ReadLines(infoPath).First().Split(' ').Skip(2).ToArray());
392+
}
393+
else
394+
{
395+
requiredDepends.AddRange((node.Tag as Component).Depends);
396+
}
397+
}
398+
});
399+
400+
// Then make sure they're all marked for installation
401+
Iterate(sourceTree.Nodes, node =>
402+
{
403+
if (node.Tag.GetType().ToString().EndsWith("Component"))
404+
{
405+
Component component = node.Tag as Component;
406+
407+
if (requiredDepends.Any(depend => depend == component.ID) && !node.Checked)
408+
{
409+
node.Checked = true;
410+
411+
if (ComponentTracker.Downloaded.Any(depend => depend.ID == component.ID))
412+
{
413+
persistDepends.Add(component.Title);
414+
}
415+
else
416+
{
417+
missingDepends.Add(component.Title);
418+
}
419+
}
420+
}
421+
});
422+
423+
if (persistDepends.Count > 0)
424+
{
425+
MessageBox.Show(
426+
"The following components cannot be removed because one or more components depend on them:\n\n" +
427+
string.Join(", ", persistDepends), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error
428+
);
429+
430+
return false;
431+
}
432+
433+
if (missingDepends.Count > 0)
434+
{
435+
MessageBox.Show(
436+
"The following dependencies will also be installed:\n\n" +
437+
string.Join(", ", missingDepends) + "\n\nClick the OK button to proceed.",
438+
"Notice", MessageBoxButtons.OK, MessageBoxIcon.Information
439+
);
440+
}
441+
442+
return true;
443+
}
444+
374445
// Gets total size in bytes of all checked components in the specified TreeView
375-
public static long GetTotalSize(TreeNodeCollection sourceNodes)
446+
public static long GetTotalSize(TreeView sourceTree)
376447
{
377448
long size = 0;
378449

379-
Iterate(sourceNodes, node =>
450+
Iterate(sourceTree.Nodes, node =>
380451
{
381452
if (node.Checked && node.Tag.GetType().ToString().EndsWith("Component"))
382453
{
383-
size += (node.Tag as Component).Size;
454+
Component component = node.Tag as Component;
455+
string infoPath = Path.Combine(SourcePath, "Components", $"{component.ID}.txt");
456+
457+
size += sourceTree.Name == "ComponentList2" && File.Exists(infoPath)
458+
? long.Parse(File.ReadLines(infoPath).First().Split(' ')[1])
459+
: component.Size;
384460
}
385461
});
386462

src/Forms/MainDownload.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private void ComponentList_BeforeCheck(object sender, TreeViewCancelEventArgs e)
4343

4444
private void ComponentList_AfterCheck(object sender, TreeViewEventArgs e)
4545
{
46-
FPM.SizeTracker.ToDownload = FPM.GetTotalSize(ComponentList.Nodes);
46+
FPM.SizeTracker.ToDownload = FPM.GetTotalSize(ComponentList);
4747
}
4848

4949
private void ComponentList_BeforeSelect(object _, TreeViewCancelEventArgs e)
@@ -70,6 +70,10 @@ private void DestinationPath_KeyPress(object sender, KeyPressEventArgs e)
7070

7171
private void DownloadButton_Click(object sender, EventArgs e)
7272
{
73+
if (!FPM.VerifyDestinationPath(FPM.DestinationPath, false)) return;
74+
75+
FPM.CheckDependencies(ComponentList);
76+
7377
if (FPM.SizeTracker.ToDownload >= 1000000000000)
7478
{
7579
var terabyteWarning = MessageBox.Show(
@@ -81,13 +85,10 @@ private void DownloadButton_Click(object sender, EventArgs e)
8185
if (terabyteWarning == DialogResult.No) return;
8286
}
8387

84-
if (FPM.VerifyDestinationPath(FPM.DestinationPath, false))
85-
{
86-
FPM.OperateMode = 0;
88+
FPM.OperateMode = 0;
8789

88-
var operationWindow = new Operation();
89-
operationWindow.ShowDialog();
90-
}
90+
var operationWindow = new Operation();
91+
operationWindow.ShowDialog();
9192
}
9293
}
9394
}

src/Forms/MainManage.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ private void SourcePathBrowse_Click(object sender, EventArgs e)
3535

3636
private void ComponentList2_AfterCheck(object sender, TreeViewEventArgs e)
3737
{
38-
FPM.SizeTracker.Modified = FPM.GetTotalSize(ComponentList2.Nodes);
38+
FPM.SizeTracker.Modified = FPM.GetTotalSize(ComponentList2);
3939
}
4040

4141
private void ComponentList2_BeforeSelect(object sender, TreeViewCancelEventArgs e)
@@ -58,6 +58,8 @@ private void ChangeButton_Click(object sender, EventArgs e)
5858
{
5959
if (FPM.VerifySourcePath(FPM.SourcePath))
6060
{
61+
if (!FPM.CheckDependencies(ComponentList2)) return;
62+
6163
FPM.OperateMode = 1;
6264

6365
var operationWindow = new Operation();

src/Forms/Operation.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ private async void Operation_Load(object sender, EventArgs e)
7878
{
7979
foreach (var component in FPM.ComponentTracker.ToUpdate)
8080
{
81-
removedComponents.Add(component);
81+
if (FPM.ComponentTracker.Downloaded.Contains(component))
82+
{
83+
removedComponents.Add(component);
84+
}
85+
8286
addedComponents.Add(component);
8387
}
8488
}
@@ -167,7 +171,10 @@ private void ExtractComponents()
167171

168172
using (TextWriter writer = File.CreateText(infoFile))
169173
{
170-
writer.WriteLine($"{workingComponent.Hash} {workingComponent.Size} {workingComponent.GetURL()}");
174+
string[] header = new string[] { workingComponent.Hash, workingComponent.Size.ToString() }
175+
.Concat(workingComponent.Depends).ToArray();
176+
177+
writer.WriteLine(string.Join(" ", header));
171178
}
172179

173180
while (cancelStatus == 0 && reader.MoveToNextEntry())

src/Forms/UpdateCheck.cs

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,66 @@ private void UpdateCheck_Load(object sender, System.EventArgs e)
2121
FPM.SyncManager();
2222
FPM.ComponentTracker.ToUpdate.Clear();
2323

24+
void AddToQueue(Component component, long oldSize)
25+
{
26+
long sizeChange = component.Size - oldSize;
27+
totalSizeChange += sizeChange;
28+
29+
string displayedSize = FPM.GetFormattedBytes(sizeChange);
30+
if (displayedSize[0] != '-') displayedSize = "+" + displayedSize;
31+
32+
ListViewItem item = new ListViewItem();
33+
item.Text = component.Title;
34+
item.SubItems.Add(component.Description);
35+
item.SubItems.Add(displayedSize);
36+
UpdateList.Items.Add(item);
37+
38+
FPM.ComponentTracker.ToUpdate.Add(component);
39+
}
40+
2441
void IterateXML(XmlNode sourceNode)
2542
{
2643
foreach (XmlNode node in sourceNode.ChildNodes)
2744
{
28-
var query = FPM.ComponentTracker.Downloaded.FirstOrDefault(item => item.ID == new Category(node).ID);
29-
30-
if (query != null)
45+
if (node.Name == "component")
3146
{
32-
string infoFile = Path.Combine(FPM.SourcePath, "Components", $"{query.ID}.txt");
33-
string[] componentData = File.ReadLines(infoFile).First().Split(' ');
47+
Component component = new Component(node);
3448

35-
if (componentData[0] != query.Hash)
36-
{
37-
long sizeChange = query.Size - long.Parse(componentData[1]);
38-
totalSizeChange += sizeChange;
49+
bool update = false;
50+
long oldSize = 0;
3951

40-
string displayedSize = FPM.GetFormattedBytes(sizeChange);
41-
if (displayedSize[0] != '-') displayedSize = "+" + displayedSize;
52+
if (FPM.ComponentTracker.Downloaded.Any(item => item.ID == component.ID))
53+
{
54+
string infoFile = Path.Combine(FPM.SourcePath, "Components", $"{component.ID}.txt");
55+
string[] componentData = File.ReadLines(infoFile).First().Split(' ');
4256

43-
ListViewItem item = new ListViewItem();
44-
item.Text = query.Title;
45-
item.SubItems.Add(query.Description);
46-
item.SubItems.Add(displayedSize);
47-
UpdateList.Items.Add(item);
57+
update = componentData[0] != component.Hash;
58+
oldSize = long.Parse(componentData[1]);
59+
}
60+
else if (component.ID.StartsWith("required"))
61+
{
62+
update = true;
63+
}
4864

49-
FPM.ComponentTracker.ToUpdate.Add(query);
65+
if (update)
66+
{
67+
AddToQueue(component, oldSize);
68+
69+
foreach (string dependID in component.Depends)
70+
{
71+
if (!FPM.ComponentTracker.Downloaded.Any(item => item.ID == dependID))
72+
{
73+
FPM.Iterate(FPM.Main.ComponentList.Nodes, treeNode =>
74+
{
75+
if (treeNode.Tag.GetType().ToString().EndsWith("Component"))
76+
{
77+
Component treeComponent = treeNode.Tag as Component;
78+
79+
if (treeComponent.ID == dependID) AddToQueue(treeComponent, 0);
80+
}
81+
});
82+
}
83+
}
5084

5185
UpdateButton.Enabled = true;
5286
}
@@ -74,7 +108,7 @@ private void UpdateButton_Click(object sender, System.EventArgs e)
74108
var downloadWindow = new Operation();
75109
downloadWindow.ShowDialog();
76110

77-
FPM.SyncManager();
111+
FPM.SyncManager(true);
78112

79113
Close();
80114
}

0 commit comments

Comments
 (0)