Skip to content

Commit 12eeca9

Browse files
authored
Merge pull request #175 from MCMrARM/feature-preview-builds
Preview builds feature
2 parents 5bdda3f + 8969534 commit 12eeca9

File tree

3 files changed

+77
-33
lines changed

3 files changed

+77
-33
lines changed

MCLauncher/MainWindow.xaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
x:Key="versionListViewBeta"
1616
IsLiveFilteringRequested="True"
1717
/>
18+
<CollectionViewSource
19+
x:Key="versionListViewPreview"
20+
IsLiveFilteringRequested="True"
21+
/>
1822
<CollectionViewSource
1923
x:Key="versionListViewImported"
2024
IsLiveFilteringRequested="True"
@@ -115,6 +119,9 @@
115119
<TabItem Header="Beta">
116120
<ContentControl x:Name="BetaVersionList" d:DataContext="{d:DesignData /SampleData/Versions.xaml}" Template="{StaticResource templateVersionList}" Margin="5" />
117121
</TabItem>
122+
<TabItem Header="Preview">
123+
<ContentControl x:Name="PreviewVersionList" d:DataContext="{d:DesignData /SampleData/Versions.xaml}" Template="{StaticResource templateVersionList}" Margin="5" />
124+
</TabItem>
118125
<TabItem Header="Imported">
119126
<ContentControl x:Name="ImportedVersionList" d:DataContext="{d:DesignData /SampleData/Versions.xaml}" Template="{StaticResource templateVersionList}" Margin="5" />
120127
</TabItem>

MCLauncher/MainWindow.xaml.cs

Lines changed: 65 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ namespace MCLauncher {
2424
/// </summary>
2525
public partial class MainWindow : Window, ICommonVersionCommands {
2626

27-
private static readonly string MINECRAFT_PACKAGE_FAMILY = "Microsoft.MinecraftUWP_8wekyb3d8bbwe";
2827
private static readonly string PREFS_PATH = @"preferences.json";
2928
private static readonly string IMPORTED_VERSIONS_PATH = @"imported_versions";
3029
private static readonly string VERSIONS_API = "https://mrarm.io/r/w10-vdb";
@@ -56,7 +55,7 @@ public MainWindow() {
5655
var versionListViewRelease = Resources["versionListViewRelease"] as CollectionViewSource;
5756
versionListViewRelease.Filter += new FilterEventHandler((object sender, FilterEventArgs e) => {
5857
var v = e.Item as Version;
59-
e.Accepted = !v.IsImported && !v.IsBeta && (v.IsInstalled || v.IsStateChanging || !(ShowInstalledVersionsOnlyCheckbox.IsChecked ?? false));
58+
e.Accepted = v.VersionType == VersionType.Release && (v.IsInstalled || v.IsStateChanging || !(ShowInstalledVersionsOnlyCheckbox.IsChecked ?? false));
6059
});
6160
versionListViewRelease.Source = _versions;
6261
ReleaseVersionList.DataContext = versionListViewRelease;
@@ -65,16 +64,25 @@ public MainWindow() {
6564
var versionListViewBeta = Resources["versionListViewBeta"] as CollectionViewSource;
6665
versionListViewBeta.Filter += new FilterEventHandler((object sender, FilterEventArgs e) => {
6766
var v = e.Item as Version;
68-
e.Accepted = !v.IsImported && v.IsBeta && (v.IsInstalled || v.IsStateChanging || !(ShowInstalledVersionsOnlyCheckbox.IsChecked ?? false));
67+
e.Accepted = v.VersionType == VersionType.Beta && (v.IsInstalled || v.IsStateChanging || !(ShowInstalledVersionsOnlyCheckbox.IsChecked ?? false));
6968
});
7069
versionListViewBeta.Source = _versions;
7170
BetaVersionList.DataContext = versionListViewBeta;
7271
_versionListViews.Add(versionListViewBeta);
7372

73+
var versionListViewPreview = Resources["versionListViewPreview"] as CollectionViewSource;
74+
versionListViewPreview.Filter += new FilterEventHandler((object sender, FilterEventArgs e) => {
75+
var v = e.Item as Version;
76+
e.Accepted = v.VersionType == VersionType.Preview && (v.IsInstalled || v.IsStateChanging || !(ShowInstalledVersionsOnlyCheckbox.IsChecked ?? false));
77+
});
78+
versionListViewPreview.Source = _versions;
79+
PreviewVersionList.DataContext = versionListViewPreview;
80+
_versionListViews.Add(versionListViewPreview);
81+
7482
var versionListViewImported = Resources["versionListViewImported"] as CollectionViewSource;
7583
versionListViewImported.Filter += new FilterEventHandler((object sender, FilterEventArgs e) => {
7684
var v = e.Item as Version;
77-
e.Accepted = v.IsImported;
85+
e.Accepted = v.VersionType == VersionType.Imported;
7886
});
7987

8088
versionListViewImported.Source = _versions;
@@ -179,7 +187,7 @@ private void InvokeLaunch(Version v) {
179187
v.StateChangeInfo = new VersionStateChangeInfo(VersionState.Registering);
180188
string gameDir = Path.GetFullPath(v.GameDirectory);
181189
try {
182-
await ReRegisterPackage(gameDir);
190+
await ReRegisterPackage(v.GamePackageFamily, gameDir);
183191
} catch (Exception e) {
184192
Debug.WriteLine("App re-register failed:\n" + e.ToString());
185193
MessageBox.Show("App re-register failed:\n" + e.ToString());
@@ -189,7 +197,7 @@ private void InvokeLaunch(Version v) {
189197
}
190198
v.StateChangeInfo = new VersionStateChangeInfo(VersionState.Launching);
191199
try {
192-
var pkg = await AppDiagnosticInfo.RequestInfoForPackageAsync(MINECRAFT_PACKAGE_FAMILY);
200+
var pkg = await AppDiagnosticInfo.RequestInfoForPackageAsync(v.GamePackageFamily);
193201
if (pkg.Count > 0)
194202
await pkg[0].LaunchAsync();
195203
Debug.WriteLine("App launch finished!");
@@ -228,8 +236,8 @@ private string GetBackupMinecraftDataDir() {
228236
return tmpDir;
229237
}
230238

231-
private void BackupMinecraftDataForRemoval() {
232-
var data = ApplicationDataManager.CreateForPackageFamily(MINECRAFT_PACKAGE_FAMILY);
239+
private void BackupMinecraftDataForRemoval(string packageFamily) {
240+
var data = ApplicationDataManager.CreateForPackageFamily(packageFamily);
233241
string tmpDir = GetBackupMinecraftDataDir();
234242
if (Directory.Exists(tmpDir)) {
235243
Debug.WriteLine("BackupMinecraftDataForRemoval error: " + tmpDir + " already exists");
@@ -262,20 +270,20 @@ private void RestoreMove(string from, string to) {
262270
}
263271
}
264272

265-
private void RestoreMinecraftDataFromReinstall() {
273+
private void RestoreMinecraftDataFromReinstall(string packageFamily) {
266274
string tmpDir = GetBackupMinecraftDataDir();
267275
if (!Directory.Exists(tmpDir))
268276
return;
269-
var data = ApplicationDataManager.CreateForPackageFamily(MINECRAFT_PACKAGE_FAMILY);
277+
var data = ApplicationDataManager.CreateForPackageFamily(packageFamily);
270278
Debug.WriteLine("Moving backup Minecraft data to: " + data.LocalFolder.Path);
271279
RestoreMove(tmpDir, data.LocalFolder.Path);
272280
Directory.Delete(tmpDir, true);
273281
}
274282

275-
private async Task RemovePackage(Package pkg) {
283+
private async Task RemovePackage(Package pkg, string packageFamily) {
276284
Debug.WriteLine("Removing package: " + pkg.Id.FullName);
277285
if (!pkg.IsDevelopmentMode) {
278-
BackupMinecraftDataForRemoval();
286+
BackupMinecraftDataForRemoval(packageFamily);
279287
await DeploymentProgressWrapper(new PackageManager().RemovePackageAsync(pkg.Id.FullName, 0));
280288
} else {
281289
Debug.WriteLine("Package is in development mode");
@@ -292,29 +300,29 @@ private string GetPackagePath(Package pkg) {
292300
}
293301
}
294302

295-
private async Task UnregisterPackage(string gameDir) {
296-
foreach (var pkg in new PackageManager().FindPackages(MINECRAFT_PACKAGE_FAMILY)) {
303+
private async Task UnregisterPackage(string packageFamily, string gameDir) {
304+
foreach (var pkg in new PackageManager().FindPackages(packageFamily)) {
297305
string location = GetPackagePath(pkg);
298306
if (location == "" || location == gameDir) {
299-
await RemovePackage(pkg);
307+
await RemovePackage(pkg, packageFamily);
300308
}
301309
}
302310
}
303311

304-
private async Task ReRegisterPackage(string gameDir) {
305-
foreach (var pkg in new PackageManager().FindPackages(MINECRAFT_PACKAGE_FAMILY)) {
312+
private async Task ReRegisterPackage(string packageFamily, string gameDir) {
313+
foreach (var pkg in new PackageManager().FindPackages(packageFamily)) {
306314
string location = GetPackagePath(pkg);
307315
if (location == gameDir) {
308316
Debug.WriteLine("Skipping package removal - same path: " + pkg.Id.FullName + " " + location);
309317
return;
310318
}
311-
await RemovePackage(pkg);
319+
await RemovePackage(pkg, packageFamily);
312320
}
313321
Debug.WriteLine("Registering package");
314322
string manifestPath = Path.Combine(gameDir, "AppxManifest.xml");
315323
await DeploymentProgressWrapper(new PackageManager().RegisterPackageAsync(new Uri(manifestPath), null, DeploymentOptions.DevelopmentMode));
316324
Debug.WriteLine("App re-register done!");
317-
RestoreMinecraftDataFromReinstall();
325+
RestoreMinecraftDataFromReinstall(packageFamily);
318326
}
319327

320328
private void InvokeDownload(Version v) {
@@ -325,9 +333,9 @@ private void InvokeDownload(Version v) {
325333

326334
Debug.WriteLine("Download start");
327335
Task.Run(async () => {
328-
string dlPath = "Minecraft-" + v.Name + ".Appx";
336+
string dlPath = (v.VersionType == VersionType.Preview ? "Minecraft-Preview-" : "Minecraft-") + v.Name + ".Appx";
329337
VersionDownloader downloader = _anonVersionDownloader;
330-
if (v.IsBeta) {
338+
if (v.VersionType == VersionType.Beta) {
331339
downloader = _userVersionDownloader;
332340
if (Interlocked.CompareExchange(ref _userVersionDownloaderLoginTaskStarted, 1, 0) == 0) {
333341
_userVersionDownloaderLoginTask.Start();
@@ -363,7 +371,7 @@ await downloader.Download(v.UUID, "1", dlPath, (current, total) => {
363371
Debug.WriteLine("Download failed due to failure to fetch download URL");
364372
MessageBox.Show(
365373
"Unable to fetch download URL for version." +
366-
(v.IsBeta ? "\nFor beta versions, please make sure your account is subscribed to the Minecraft beta programme in the Xbox Insider Hub app." : "")
374+
(v.VersionType == VersionType.Beta ? "\nFor beta versions, please make sure your account is subscribed to the Minecraft beta programme in the Xbox Insider Hub app." : "")
367375
);
368376
v.StateChangeInfo = null;
369377
return;
@@ -401,7 +409,7 @@ await downloader.Download(v.UUID, "1", dlPath, (current, total) => {
401409

402410
private async Task Remove(Version v) {
403411
v.StateChangeInfo = new VersionStateChangeInfo(VersionState.Uninstalling);
404-
await UnregisterPackage(Path.GetFullPath(v.GameDirectory));
412+
await UnregisterPackage(v.GamePackageFamily, Path.GetFullPath(v.GameDirectory));
405413
Directory.Delete(v.GameDirectory, true);
406414
v.StateChangeInfo = null;
407415
if (v.IsImported) {
@@ -474,8 +482,15 @@ private void MenuItemRefreshVersionListClicked(object sender, RoutedEventArgs e)
474482
}
475483
}
476484

485+
struct MinecraftPackageFamilies
486+
{
487+
public static readonly string MINECRAFT = "Microsoft.MinecraftUWP_8wekyb3d8bbwe";
488+
public static readonly string MINECRAFT_PREVIEW = "Microsoft.MinecraftWindowsBeta_8wekyb3d8bbwe";
489+
}
490+
477491
namespace WPFDataTypes {
478492

493+
479494
public class NotifyPropertyChangedBase : INotifyPropertyChanged {
480495

481496
public event PropertyChangedEventHandler PropertyChanged;
@@ -497,49 +512,68 @@ public interface ICommonVersionCommands {
497512

498513
}
499514

515+
public enum VersionType : int
516+
{
517+
Release = 0,
518+
Beta = 1,
519+
Preview = 2,
520+
Imported = 100
521+
}
522+
500523
public class Version : NotifyPropertyChangedBase {
501524
public static readonly string UNKNOWN_UUID = "UNKNOWN";
502525

503-
public Version(string uuid, string name, bool isBeta, bool isNew, ICommonVersionCommands commands) {
526+
public Version(string uuid, string name, VersionType versionType, bool isNew, ICommonVersionCommands commands) {
504527
this.UUID = uuid;
505528
this.Name = name;
506-
this.IsBeta = isBeta;
529+
this.VersionType = versionType;
507530
this.IsNew = isNew;
508531
this.DownloadCommand = commands.DownloadCommand;
509532
this.LaunchCommand = commands.LaunchCommand;
510533
this.RemoveCommand = commands.RemoveCommand;
511-
this.GameDirectory = "Minecraft-" + Name;
534+
this.GameDirectory = (versionType == VersionType.Preview ? "Minecraft-Preview-" : "Minecraft-") + Name;
512535
}
513536
public Version(string name, string directory, ICommonVersionCommands commands) {
514537
this.UUID = UNKNOWN_UUID;
515538
this.Name = name;
516-
this.IsBeta = false;
539+
this.VersionType = VersionType.Imported;
517540
this.DownloadCommand = commands.DownloadCommand;
518541
this.LaunchCommand = commands.LaunchCommand;
519542
this.RemoveCommand = commands.RemoveCommand;
520543
this.GameDirectory = directory;
521-
this.IsImported = true;
522544
}
523545

524546
public string UUID { get; set; }
525547
public string Name { get; set; }
526-
public bool IsBeta { get; set; }
548+
public VersionType VersionType { get; set; }
527549
public bool IsNew {
528550
get { return _isNew; }
529551
set {
530552
_isNew = value;
531553
OnPropertyChanged("IsNew");
532554
}
533555
}
534-
public bool IsImported { get; private set; }
556+
public bool IsImported {
557+
get => VersionType == VersionType.Imported;
558+
}
535559

536560
public string GameDirectory { get; set; }
537561

562+
public string GamePackageFamily
563+
{
564+
get => VersionType == VersionType.Preview ? MinecraftPackageFamilies.MINECRAFT_PREVIEW : MinecraftPackageFamilies.MINECRAFT;
565+
}
566+
538567
public bool IsInstalled => Directory.Exists(GameDirectory);
539568

540569
public string DisplayName {
541570
get {
542-
return Name + (IsBeta ? " (beta)" : "") + (IsNew ? " (NEW!)" : "");
571+
string typeTag = "";
572+
if (VersionType == VersionType.Beta)
573+
typeTag = "(beta)";
574+
else if (VersionType == VersionType.Preview)
575+
typeTag = "(preview)";
576+
return Name + (typeTag.Length > 0 ? " " + typeTag : "") + (IsNew ? " (NEW!)" : "");
543577
}
544578
}
545579
public string DisplayInstallStatus {

MCLauncher/VersionList.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,13 @@ private void versionListOnCollectionChanged(object sender, NotifyCollectionChang
4646

4747
private void ParseList(JArray data, bool isCache) {
4848
Clear();
49-
// ([name, uuid, isBeta])[]
49+
// ([name, uuid, versionType])[]
5050
foreach (JArray o in data.AsEnumerable().Reverse()) {
5151
bool isNew = dbVersions.Add(o[0].Value<string>()) && !isCache;
52-
Add(new WPFDataTypes.Version(o[1].Value<string>(), o[0].Value<string>(), o[2].Value<int>() == 1, isNew, _commands));
52+
int versionType = o[2].Value<int>();
53+
if (!Enum.IsDefined(typeof(WPFDataTypes.VersionType), versionType) || versionType == (int) WPFDataTypes.VersionType.Imported)
54+
continue;
55+
Add(new WPFDataTypes.Version(o[1].Value<string>(), o[0].Value<string>(), (WPFDataTypes.VersionType) versionType, isNew, _commands));
5356
}
5457
}
5558

0 commit comments

Comments
 (0)