@@ -24,7 +24,6 @@ namespace MCLauncher {
24
24
/// </summary>
25
25
public partial class MainWindow : Window , ICommonVersionCommands {
26
26
27
- private static readonly string MINECRAFT_PACKAGE_FAMILY = "Microsoft.MinecraftUWP_8wekyb3d8bbwe" ;
28
27
private static readonly string PREFS_PATH = @"preferences.json" ;
29
28
private static readonly string IMPORTED_VERSIONS_PATH = @"imported_versions" ;
30
29
private static readonly string VERSIONS_API = "https://mrarm.io/r/w10-vdb" ;
@@ -56,7 +55,7 @@ public MainWindow() {
56
55
var versionListViewRelease = Resources [ "versionListViewRelease" ] as CollectionViewSource ;
57
56
versionListViewRelease . Filter += new FilterEventHandler ( ( object sender , FilterEventArgs e ) => {
58
57
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 ) ) ;
60
59
} ) ;
61
60
versionListViewRelease . Source = _versions ;
62
61
ReleaseVersionList . DataContext = versionListViewRelease ;
@@ -65,16 +64,25 @@ public MainWindow() {
65
64
var versionListViewBeta = Resources [ "versionListViewBeta" ] as CollectionViewSource ;
66
65
versionListViewBeta . Filter += new FilterEventHandler ( ( object sender , FilterEventArgs e ) => {
67
66
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 ) ) ;
69
68
} ) ;
70
69
versionListViewBeta . Source = _versions ;
71
70
BetaVersionList . DataContext = versionListViewBeta ;
72
71
_versionListViews . Add ( versionListViewBeta ) ;
73
72
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
+
74
82
var versionListViewImported = Resources [ "versionListViewImported" ] as CollectionViewSource ;
75
83
versionListViewImported . Filter += new FilterEventHandler ( ( object sender , FilterEventArgs e ) => {
76
84
var v = e . Item as Version ;
77
- e . Accepted = v . IsImported ;
85
+ e . Accepted = v . VersionType == VersionType . Imported ;
78
86
} ) ;
79
87
80
88
versionListViewImported . Source = _versions ;
@@ -179,7 +187,7 @@ private void InvokeLaunch(Version v) {
179
187
v . StateChangeInfo = new VersionStateChangeInfo ( VersionState . Registering ) ;
180
188
string gameDir = Path . GetFullPath ( v . GameDirectory ) ;
181
189
try {
182
- await ReRegisterPackage ( gameDir ) ;
190
+ await ReRegisterPackage ( v . GamePackageFamily , gameDir ) ;
183
191
} catch ( Exception e ) {
184
192
Debug . WriteLine ( "App re-register failed:\n " + e . ToString ( ) ) ;
185
193
MessageBox . Show ( "App re-register failed:\n " + e . ToString ( ) ) ;
@@ -189,7 +197,7 @@ private void InvokeLaunch(Version v) {
189
197
}
190
198
v . StateChangeInfo = new VersionStateChangeInfo ( VersionState . Launching ) ;
191
199
try {
192
- var pkg = await AppDiagnosticInfo . RequestInfoForPackageAsync ( MINECRAFT_PACKAGE_FAMILY ) ;
200
+ var pkg = await AppDiagnosticInfo . RequestInfoForPackageAsync ( v . GamePackageFamily ) ;
193
201
if ( pkg . Count > 0 )
194
202
await pkg [ 0 ] . LaunchAsync ( ) ;
195
203
Debug . WriteLine ( "App launch finished!" ) ;
@@ -228,8 +236,8 @@ private string GetBackupMinecraftDataDir() {
228
236
return tmpDir ;
229
237
}
230
238
231
- private void BackupMinecraftDataForRemoval ( ) {
232
- var data = ApplicationDataManager . CreateForPackageFamily ( MINECRAFT_PACKAGE_FAMILY ) ;
239
+ private void BackupMinecraftDataForRemoval ( string packageFamily ) {
240
+ var data = ApplicationDataManager . CreateForPackageFamily ( packageFamily ) ;
233
241
string tmpDir = GetBackupMinecraftDataDir ( ) ;
234
242
if ( Directory . Exists ( tmpDir ) ) {
235
243
Debug . WriteLine ( "BackupMinecraftDataForRemoval error: " + tmpDir + " already exists" ) ;
@@ -262,20 +270,20 @@ private void RestoreMove(string from, string to) {
262
270
}
263
271
}
264
272
265
- private void RestoreMinecraftDataFromReinstall ( ) {
273
+ private void RestoreMinecraftDataFromReinstall ( string packageFamily ) {
266
274
string tmpDir = GetBackupMinecraftDataDir ( ) ;
267
275
if ( ! Directory . Exists ( tmpDir ) )
268
276
return ;
269
- var data = ApplicationDataManager . CreateForPackageFamily ( MINECRAFT_PACKAGE_FAMILY ) ;
277
+ var data = ApplicationDataManager . CreateForPackageFamily ( packageFamily ) ;
270
278
Debug . WriteLine ( "Moving backup Minecraft data to: " + data . LocalFolder . Path ) ;
271
279
RestoreMove ( tmpDir , data . LocalFolder . Path ) ;
272
280
Directory . Delete ( tmpDir , true ) ;
273
281
}
274
282
275
- private async Task RemovePackage ( Package pkg ) {
283
+ private async Task RemovePackage ( Package pkg , string packageFamily ) {
276
284
Debug . WriteLine ( "Removing package: " + pkg . Id . FullName ) ;
277
285
if ( ! pkg . IsDevelopmentMode ) {
278
- BackupMinecraftDataForRemoval ( ) ;
286
+ BackupMinecraftDataForRemoval ( packageFamily ) ;
279
287
await DeploymentProgressWrapper ( new PackageManager ( ) . RemovePackageAsync ( pkg . Id . FullName , 0 ) ) ;
280
288
} else {
281
289
Debug . WriteLine ( "Package is in development mode" ) ;
@@ -292,29 +300,29 @@ private string GetPackagePath(Package pkg) {
292
300
}
293
301
}
294
302
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 ) ) {
297
305
string location = GetPackagePath ( pkg ) ;
298
306
if ( location == "" || location == gameDir ) {
299
- await RemovePackage ( pkg ) ;
307
+ await RemovePackage ( pkg , packageFamily ) ;
300
308
}
301
309
}
302
310
}
303
311
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 ) ) {
306
314
string location = GetPackagePath ( pkg ) ;
307
315
if ( location == gameDir ) {
308
316
Debug . WriteLine ( "Skipping package removal - same path: " + pkg . Id . FullName + " " + location ) ;
309
317
return ;
310
318
}
311
- await RemovePackage ( pkg ) ;
319
+ await RemovePackage ( pkg , packageFamily ) ;
312
320
}
313
321
Debug . WriteLine ( "Registering package" ) ;
314
322
string manifestPath = Path . Combine ( gameDir , "AppxManifest.xml" ) ;
315
323
await DeploymentProgressWrapper ( new PackageManager ( ) . RegisterPackageAsync ( new Uri ( manifestPath ) , null , DeploymentOptions . DevelopmentMode ) ) ;
316
324
Debug . WriteLine ( "App re-register done!" ) ;
317
- RestoreMinecraftDataFromReinstall ( ) ;
325
+ RestoreMinecraftDataFromReinstall ( packageFamily ) ;
318
326
}
319
327
320
328
private void InvokeDownload ( Version v ) {
@@ -325,9 +333,9 @@ private void InvokeDownload(Version v) {
325
333
326
334
Debug . WriteLine ( "Download start" ) ;
327
335
Task . Run ( async ( ) => {
328
- string dlPath = "Minecraft-" + v . Name + ".Appx" ;
336
+ string dlPath = ( v . VersionType == VersionType . Preview ? "Minecraft-Preview-" : "Minecraft-" ) + v . Name + ".Appx" ;
329
337
VersionDownloader downloader = _anonVersionDownloader ;
330
- if ( v . IsBeta ) {
338
+ if ( v . VersionType == VersionType . Beta ) {
331
339
downloader = _userVersionDownloader ;
332
340
if ( Interlocked . CompareExchange ( ref _userVersionDownloaderLoginTaskStarted , 1 , 0 ) == 0 ) {
333
341
_userVersionDownloaderLoginTask . Start ( ) ;
@@ -363,7 +371,7 @@ await downloader.Download(v.UUID, "1", dlPath, (current, total) => {
363
371
Debug . WriteLine ( "Download failed due to failure to fetch download URL" ) ;
364
372
MessageBox . Show (
365
373
"Unable to fetch download URL for version." +
366
- ( v . IsBeta ? "\n For 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 ? "\n For beta versions, please make sure your account is subscribed to the Minecraft beta programme in the Xbox Insider Hub app." : "" )
367
375
) ;
368
376
v . StateChangeInfo = null ;
369
377
return ;
@@ -401,7 +409,7 @@ await downloader.Download(v.UUID, "1", dlPath, (current, total) => {
401
409
402
410
private async Task Remove ( Version v ) {
403
411
v . StateChangeInfo = new VersionStateChangeInfo ( VersionState . Uninstalling ) ;
404
- await UnregisterPackage ( Path . GetFullPath ( v . GameDirectory ) ) ;
412
+ await UnregisterPackage ( v . GamePackageFamily , Path . GetFullPath ( v . GameDirectory ) ) ;
405
413
Directory . Delete ( v . GameDirectory , true ) ;
406
414
v . StateChangeInfo = null ;
407
415
if ( v . IsImported ) {
@@ -474,8 +482,15 @@ private void MenuItemRefreshVersionListClicked(object sender, RoutedEventArgs e)
474
482
}
475
483
}
476
484
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
+
477
491
namespace WPFDataTypes {
478
492
493
+
479
494
public class NotifyPropertyChangedBase : INotifyPropertyChanged {
480
495
481
496
public event PropertyChangedEventHandler PropertyChanged ;
@@ -497,49 +512,68 @@ public interface ICommonVersionCommands {
497
512
498
513
}
499
514
515
+ public enum VersionType : int
516
+ {
517
+ Release = 0 ,
518
+ Beta = 1 ,
519
+ Preview = 2 ,
520
+ Imported = 100
521
+ }
522
+
500
523
public class Version : NotifyPropertyChangedBase {
501
524
public static readonly string UNKNOWN_UUID = "UNKNOWN" ;
502
525
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 ) {
504
527
this . UUID = uuid ;
505
528
this . Name = name ;
506
- this . IsBeta = isBeta ;
529
+ this . VersionType = versionType ;
507
530
this . IsNew = isNew ;
508
531
this . DownloadCommand = commands . DownloadCommand ;
509
532
this . LaunchCommand = commands . LaunchCommand ;
510
533
this . RemoveCommand = commands . RemoveCommand ;
511
- this . GameDirectory = "Minecraft-" + Name ;
534
+ this . GameDirectory = ( versionType == VersionType . Preview ? "Minecraft-Preview-" : "Minecraft-" ) + Name ;
512
535
}
513
536
public Version ( string name , string directory , ICommonVersionCommands commands ) {
514
537
this . UUID = UNKNOWN_UUID ;
515
538
this . Name = name ;
516
- this . IsBeta = false ;
539
+ this . VersionType = VersionType . Imported ;
517
540
this . DownloadCommand = commands . DownloadCommand ;
518
541
this . LaunchCommand = commands . LaunchCommand ;
519
542
this . RemoveCommand = commands . RemoveCommand ;
520
543
this . GameDirectory = directory ;
521
- this . IsImported = true ;
522
544
}
523
545
524
546
public string UUID { get ; set ; }
525
547
public string Name { get ; set ; }
526
- public bool IsBeta { get ; set ; }
548
+ public VersionType VersionType { get ; set ; }
527
549
public bool IsNew {
528
550
get { return _isNew ; }
529
551
set {
530
552
_isNew = value ;
531
553
OnPropertyChanged ( "IsNew" ) ;
532
554
}
533
555
}
534
- public bool IsImported { get ; private set ; }
556
+ public bool IsImported {
557
+ get => VersionType == VersionType . Imported ;
558
+ }
535
559
536
560
public string GameDirectory { get ; set ; }
537
561
562
+ public string GamePackageFamily
563
+ {
564
+ get => VersionType == VersionType . Preview ? MinecraftPackageFamilies . MINECRAFT_PREVIEW : MinecraftPackageFamilies . MINECRAFT ;
565
+ }
566
+
538
567
public bool IsInstalled => Directory . Exists ( GameDirectory ) ;
539
568
540
569
public string DisplayName {
541
570
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!)" : "" ) ;
543
577
}
544
578
}
545
579
public string DisplayInstallStatus {
0 commit comments