Do migration automatically at startup
This commit is contained in:
parent
8801db5f8d
commit
c965acaa2d
3 changed files with 81 additions and 10 deletions
|
@ -28,7 +28,7 @@ namespace Ryujinx
|
||||||
string userProfilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch", "prod.keys");
|
string userProfilePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".switch", "prod.keys");
|
||||||
if (!File.Exists(appDataPath) && !File.Exists(userProfilePath))
|
if (!File.Exists(appDataPath) && !File.Exists(userProfilePath))
|
||||||
{
|
{
|
||||||
GtkDialog.CreateErrorDialog($"Key file was not found. Please refer to `KEYS.md` for more info");
|
GtkDialog.CreateErrorDialog("Key file was not found. Please refer to `KEYS.md` for more info");
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow mainWindow = new MainWindow();
|
MainWindow mainWindow = new MainWindow();
|
||||||
|
|
|
@ -94,6 +94,12 @@ namespace Ryujinx.Ui
|
||||||
|
|
||||||
_device = new HLE.Switch(_renderer, _audioOut);
|
_device = new HLE.Switch(_renderer, _audioOut);
|
||||||
|
|
||||||
|
bool continueAfterMigration = Migration.TryMigrateForStartup(this, _device);
|
||||||
|
if (!continueAfterMigration)
|
||||||
|
{
|
||||||
|
End();
|
||||||
|
}
|
||||||
|
|
||||||
_treeView = _gameTable;
|
_treeView = _gameTable;
|
||||||
|
|
||||||
Configuration.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
|
Configuration.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json"));
|
||||||
|
|
|
@ -1,18 +1,21 @@
|
||||||
using LibHac;
|
using Gtk;
|
||||||
|
using LibHac;
|
||||||
using LibHac.Common;
|
using LibHac.Common;
|
||||||
using LibHac.Fs;
|
using LibHac.Fs;
|
||||||
using LibHac.Fs.Shim;
|
using LibHac.Fs.Shim;
|
||||||
using LibHac.FsSystem;
|
using LibHac.FsSystem;
|
||||||
using LibHac.FsSystem.Save;
|
using LibHac.FsSystem.Save;
|
||||||
using LibHac.Ncm;
|
using LibHac.Ncm;
|
||||||
using Ryujinx.HLE;
|
|
||||||
using Ryujinx.HLE.Utilities;
|
using Ryujinx.HLE.Utilities;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
using Switch = Ryujinx.HLE.Switch;
|
||||||
|
|
||||||
namespace Ryujinx.Ui
|
namespace Ryujinx.Ui
|
||||||
{
|
{
|
||||||
internal class Migration
|
internal class Migration
|
||||||
|
@ -24,26 +27,85 @@ namespace Ryujinx.Ui
|
||||||
Device = device;
|
Device = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Migrate()
|
public static bool TryMigrateForStartup(Window parentWindow, Switch device)
|
||||||
|
{
|
||||||
|
const int responseYes = -8;
|
||||||
|
|
||||||
|
if (!IsMigrationNeeded(device.FileSystem.GetBasePath()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dialogResponse;
|
||||||
|
|
||||||
|
using (MessageDialog dialog = new MessageDialog(parentWindow, DialogFlags.Modal, MessageType.Question,
|
||||||
|
ButtonsType.YesNo, "What's this?"))
|
||||||
|
{
|
||||||
|
dialog.Title = "Data Migration Needed";
|
||||||
|
dialog.Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png");
|
||||||
|
dialog.Text =
|
||||||
|
"The folder structure of Ryujinx's RyuFs folder has been updated. Your RyuFs folder must be migrated to the new structure. Would you like to do the migration now?\n\n" +
|
||||||
|
"Select \"Yes\" to automatically perform the migration. A backup of your old saves will be placed in your RyuFs folder.\n\n" +
|
||||||
|
"Selecting \"No\" will exit Ryujinx without changing the contents of your RyuFs folder.";
|
||||||
|
|
||||||
|
dialogResponse = dialog.Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dialogResponse != responseYes)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Migration migration = new Migration(device);
|
||||||
|
int saveCount = migration.Migrate();
|
||||||
|
|
||||||
|
using MessageDialog dialogSuccess = new MessageDialog(parentWindow, DialogFlags.Modal, MessageType.Info, ButtonsType.Ok, null)
|
||||||
|
{
|
||||||
|
Title = "Migration Success",
|
||||||
|
Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
|
||||||
|
Text = $"Data migration was successful. {saveCount} saves were migrated.",
|
||||||
|
};
|
||||||
|
|
||||||
|
dialogSuccess.Run();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (HorizonResultException ex)
|
||||||
|
{
|
||||||
|
GtkDialog.CreateErrorDialog(ex.Message);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the number of saves migrated
|
||||||
|
public int Migrate()
|
||||||
{
|
{
|
||||||
string basePath = Device.FileSystem.GetBasePath();
|
string basePath = Device.FileSystem.GetBasePath();
|
||||||
string backupPath = Path.Combine(basePath, "Migration backup (Can delete if successful)");
|
string backupPath = Path.Combine(basePath, "Migration backup (Can delete if successful)");
|
||||||
string backupUserSavePath = Path.Combine(backupPath, "nand/user/save");
|
string backupUserSavePath = Path.Combine(backupPath, "nand/user/save");
|
||||||
|
|
||||||
if (!IsMigrationNeeded(basePath))
|
if (!IsMigrationNeeded(basePath))
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
BackupSaves(basePath, backupPath);
|
BackupSaves(basePath, backupPath);
|
||||||
|
|
||||||
MigrateDirectories(basePath);
|
MigrateDirectories(basePath);
|
||||||
|
|
||||||
MigrateSaves(Device.System.FsClient, backupUserSavePath);
|
return MigrateSaves(Device.System.FsClient, backupUserSavePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsMigrationNeeded(string basePath)
|
private static bool IsMigrationNeeded(string basePath)
|
||||||
{
|
{
|
||||||
return !Directory.Exists(Path.Combine(basePath, "bis")) &&
|
bool missingNewDirs = !Directory.Exists(Path.Combine(basePath, "bis")) &&
|
||||||
!Directory.Exists(Path.Combine(basePath, "sdcard"));
|
!Directory.Exists(Path.Combine(basePath, "sdcard"));
|
||||||
|
|
||||||
|
bool hasOldDirs = Directory.Exists(Path.Combine(basePath, "nand")) ||
|
||||||
|
Directory.Exists(Path.Combine(basePath, "sdmc"));
|
||||||
|
|
||||||
|
return missingNewDirs && hasOldDirs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void MigrateDirectories(string basePath)
|
private static void MigrateDirectories(string basePath)
|
||||||
|
@ -91,11 +153,12 @@ namespace Ryujinx.Ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void MigrateSaves(FileSystemClient fsClient, string rootSaveDir)
|
// Returns the number of saves migrated
|
||||||
|
private static int MigrateSaves(FileSystemClient fsClient, string rootSaveDir)
|
||||||
{
|
{
|
||||||
if (!Directory.Exists(rootSaveDir))
|
if (!Directory.Exists(rootSaveDir))
|
||||||
{
|
{
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveFinder finder = new SaveFinder();
|
SaveFinder finder = new SaveFinder();
|
||||||
|
@ -110,6 +173,8 @@ namespace Ryujinx.Ui
|
||||||
throw new HorizonResultException(migrateResult, $"Error migrating save {save.Path}");
|
throw new HorizonResultException(migrateResult, $"Error migrating save {save.Path}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return finder.Saves.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Result MigrateSave(FileSystemClient fs, SaveToMigrate save)
|
private static Result MigrateSave(FileSystemClient fs, SaveToMigrate save)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue