Skip to content

Commit 54f0d5a

Browse files
committed
Fully re-implement automatic downloading and version picking.
1 parent 2425694 commit 54f0d5a

2 files changed

Lines changed: 169 additions & 5 deletions

File tree

client/src/Ruler.IRule/Backend/UserInputHandler.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ public static async Task HandleInput(bool autoSelect)
1515
{
1616
if (autoSelect)
1717
{
18-
VersionSelector.SelectVersion(autoSelect);
18+
await VersionSelector.SelectVersion(autoSelect);
1919
return;
2020
}
2121

2222
switch (Console.ReadKey().Key)
2323
{
2424
case ConsoleKey.Enter:
25-
VersionSelector.SelectVersion(autoSelect);
25+
await VersionSelector.SelectVersion(autoSelect);
2626
break;
2727

2828
default:
@@ -41,7 +41,7 @@ public static async Task HandleInput(bool autoSelect)
4141
switch (chosen)
4242
{
4343
case "Manually Choose Version":
44-
VersionSelector.SelectVersion(false);
44+
await VersionSelector.SelectVersion(false);
4545
return;
4646

4747
case "Open Config Menu":
Lines changed: 166 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,174 @@
1-
namespace Ruler.IRule.Backend
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Net.Http;
6+
using System.Threading.Tasks;
7+
using Newtonsoft.Json;
8+
using Ruler.Engine.Manifest;
9+
using Ruler.Engine.Platform;
10+
using Spectre.Console;
11+
12+
namespace Ruler.IRule.Backend
213
{
314
public static class VersionSelector
415
{
5-
public static void SelectVersion(bool autoSelect)
16+
public static async Task SelectVersion(bool autoSelect)
617
{
18+
if (!autoSelect)
19+
AnsiConsole.MarkupLine(
20+
"\n[gray]If you know what you're doing, you can change the release branch in the config menu![/]\n"
21+
);
22+
23+
string branch = Program.Endpoint + Program.Config.Branch;
724

25+
HttpResponseMessage resp = await Program.Client.GetAsync(branch + "/versions-manifest.json");
26+
VersionsManifest? vers = JsonConvert.DeserializeObject<VersionsManifest>(
27+
await resp.Content.ReadAsStringAsync()
28+
);
29+
30+
if (vers is null)
31+
throw new InvalidOperationException(
32+
"Could not parse JSON received from: " + branch + "/versions-manifest.json"
33+
);
34+
35+
string version;
36+
37+
if (autoSelect)
38+
version = vers.Latest;
39+
else
40+
{
41+
IEnumerable<string> choices = vers.Versions.Select(x => x.Value.Name);
42+
43+
string sel = AnsiConsole.Prompt(
44+
new SelectionPrompt<string>()
45+
.Title("Select an [red1 bold]I.RULE[/] version:")
46+
.PageSize(5)
47+
.MoreChoicesText("[gray]Scroll up/down for more![/]")
48+
.AddChoices(choices)
49+
);
50+
51+
version = vers.Versions.First(x => x.Value.Name.Equals(sel)).Key;
52+
}
53+
54+
await InstallAndPlayVersion(branch, version, autoSelect);
55+
}
56+
57+
public static async Task InstallAndPlayVersion(string endpoint, string version, bool autoSelect)
58+
{
59+
HttpResponseMessage resp = await Program.Client.GetAsync(endpoint + "/versions/" + version + "/manifest.json");
60+
VersionManifest? vers = JsonConvert.DeserializeObject<VersionManifest>(
61+
await resp.Content.ReadAsStringAsync()
62+
);
63+
64+
if (vers is null)
65+
throw new InvalidOperationException("Could not find version: " + version);
66+
67+
string directory = Path.Combine(DesktopLocationProvider.GetDesktopProvider().GetLocation(), "I.RULE", version);
68+
69+
Directory.CreateDirectory(directory);
70+
71+
if (new DirectoryInfo(directory).EnumerateFiles().Any(x => x.Extension.Equals(".exe")))
72+
{
73+
await GameLauncher.RunGame(directory);
74+
return;
75+
}
76+
77+
AnsiConsole.MarkupLine($"\nSelected version: [b]{vers.Name}[/]");
78+
79+
if (Program.Config.ReviewUpdates && !autoSelect)
80+
{
81+
string desc = vers.Description;
82+
83+
if (desc == "{{ USE_CHANGELOG }}")
84+
{
85+
HttpResponseMessage clResp = await Program.Client.GetAsync(endpoint + "/versions/" + version + "/changelog.txt");
86+
desc = await clResp.Content.ReadAsStringAsync();
87+
}
88+
89+
AnsiConsole.MarkupLine("[b]VERSION OVERVIEW[/]" +
90+
$"\n[u]{vers.Name}[/]" +
91+
"\n" +
92+
$"\n[grey69]{desc}[/]" +
93+
"\n\nPress [u]<ENTER>[/] to confirm this installation. Press [u]<SPACE>[/] to quit," +
94+
"\n[gray]Don't want to see this prompt? Modify \"Update Reviewing\" in the config![/]");
95+
96+
Guh:
97+
ConsoleKey key = Console.ReadKey(true).Key;
98+
99+
switch (key)
100+
{
101+
case ConsoleKey.Enter:
102+
break;
103+
104+
case ConsoleKey.Spacebar:
105+
return;
106+
107+
default:
108+
goto Guh;
109+
}
110+
}
111+
112+
await AnsiConsole.Progress()
113+
.Columns(
114+
new TaskDescriptionColumn(),
115+
new ProgressBarColumn(),
116+
new PercentageColumn(),
117+
new RemainingTimeColumn(),
118+
new SpinnerColumn()
119+
).StartAsync(async x =>
120+
{
121+
var task = x.AddTask("Downloading release.zip", new ProgressTaskSettings
122+
{
123+
AutoStart = false
124+
});
125+
126+
await DownloadRelease(endpoint, directory, version, task);
127+
});
128+
129+
AnsiConsole.MarkupLine("Unzipping (extracting) [u]release.zip[/]...");
130+
ZipImporter.UnzipFile(directory, Path.Combine(directory, "release.zip"));
131+
132+
await GameLauncher.RunGame(directory);
133+
}
134+
135+
public static async Task DownloadRelease(string endpoint, string directory, string version, ProgressTask task)
136+
{
137+
// https://stackoverflow.com/a/56091135
138+
const int bufferSize = 1024;
139+
140+
AnsiConsole.MarkupLine("[i]Preparing to download...[/]");
141+
142+
using HttpResponseMessage resp = await Program.Client.GetAsync(endpoint + "/versions/" + version + "/release.zip");
143+
task.MaxValue(resp.Content.Headers.ContentLength ?? 0);
144+
task.StartTask();
145+
146+
AnsiConsole.MarkupLine(
147+
$"Downloading [u]release.zip[/] according to version [u]{version}[/]! ({task.MaxValue} total bytes)"
148+
);
149+
150+
await using Stream cStream = await resp.Content.ReadAsStreamAsync();
151+
await using FileStream fStream = new(
152+
Path.Combine(directory, "release.zip"),
153+
FileMode.Create,
154+
FileAccess.Write,
155+
FileShare.None,
156+
bufferSize,
157+
true
158+
);
159+
160+
byte[] buf = new byte[bufferSize];
161+
while (true)
162+
{
163+
int read = await cStream.ReadAsync(buf);
164+
165+
if (read == 0)
166+
break;
167+
168+
task.Increment(read);
169+
170+
await fStream.WriteAsync(buf.AsMemory(0, read));
171+
}
8172
}
9173
}
10174
}

0 commit comments

Comments
 (0)