| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- using Gtk;
- using LibHac;
- using LibHac.Fs;
- using LibHac.Fs.Shim;
- using LibHac.Ncm;
- using Ryujinx.HLE.FileSystem;
- using System;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using GUI = Gtk.Builder.ObjectAttribute;
- namespace Ryujinx.Ui
- {
- public class GameTableContextMenu : Menu
- {
- private static ListStore _gameTableStore;
- private static TreeIter _rowIter;
- private FileSystemClient _fsClient;
- #pragma warning disable CS0649
- #pragma warning disable IDE0044
- [GUI] MenuItem _openSaveDir;
- #pragma warning restore CS0649
- #pragma warning restore IDE0044
- public GameTableContextMenu(ListStore gameTableStore, TreeIter rowIter, FileSystemClient fsClient)
- : this(new Builder("Ryujinx.Ui.GameTableContextMenu.glade"), gameTableStore, rowIter, fsClient) { }
- private GameTableContextMenu(Builder builder, ListStore gameTableStore, TreeIter rowIter, FileSystemClient fsClient) : base(builder.GetObject("_contextMenu").Handle)
- {
- builder.Autoconnect(this);
- _openSaveDir.Activated += OpenSaveDir_Clicked;
- _gameTableStore = gameTableStore;
- _rowIter = rowIter;
- _fsClient = fsClient;
- }
- //Events
- private void OpenSaveDir_Clicked(object sender, EventArgs args)
- {
- string titleName = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[0];
- string titleId = _gameTableStore.GetValue(_rowIter, 2).ToString().Split("\n")[1].ToLower();
- if (!TryFindSaveData(titleName, titleId, out ulong saveDataId))
- {
- return;
- }
- string saveDir = GetSaveDataDirectory(saveDataId);
- Process.Start(new ProcessStartInfo()
- {
- FileName = saveDir,
- UseShellExecute = true,
- Verb = "open"
- });
- }
- private bool TryFindSaveData(string titleName, string titleIdText, out ulong saveDataId)
- {
- saveDataId = default;
- if (!ulong.TryParse(titleIdText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out ulong titleId))
- {
- GtkDialog.CreateErrorDialog("UI error: The selected game did not have a valid title ID");
- return false;
- }
- SaveDataFilter filter = new SaveDataFilter();
- filter.SetUserId(new UserId(1, 0));
- filter.SetTitleId(new TitleId(titleId));
- Result result = _fsClient.FindSaveDataWithFilter(out SaveDataInfo saveDataInfo, SaveDataSpaceId.User, ref filter);
- if (result == ResultFs.TargetNotFound)
- {
- // Savedata was not found. Ask the user if they want to create it
- using MessageDialog messageDialog = new MessageDialog(null, DialogFlags.Modal, MessageType.Question, ButtonsType.YesNo, null)
- {
- Title = "Ryujinx",
- Icon = new Gdk.Pixbuf(Assembly.GetExecutingAssembly(), "Ryujinx.Ui.assets.Icon.png"),
- Text = $"There is no savedata for {titleName} [{titleId:x16}]",
- SecondaryText = "Would you like to create savedata for this game?",
- WindowPosition = WindowPosition.Center
- };
- if (messageDialog.Run() != (int)ResponseType.Yes)
- {
- return false;
- }
- result = _fsClient.CreateSaveData(new TitleId(titleId), new UserId(1, 0), new TitleId(titleId), 0, 0, 0);
- if (result.IsFailure())
- {
- GtkDialog.CreateErrorDialog($"There was an error creating the specified savedata: {result.ToStringWithName()}");
- return false;
- }
- // Try to find the savedata again after creating it
- result = _fsClient.FindSaveDataWithFilter(out saveDataInfo, SaveDataSpaceId.User, ref filter);
- }
- if (result.IsSuccess())
- {
- saveDataId = saveDataInfo.SaveDataId;
- return true;
- }
- GtkDialog.CreateErrorDialog($"There was an error finding the specified savedata: {result.ToStringWithName()}");
- return false;
- }
- private string GetSaveDataDirectory(ulong saveDataId)
- {
- string saveRootPath = System.IO.Path.Combine(new VirtualFileSystem().GetNandPath(), $"user/save/{saveDataId:x16}");
- if (!Directory.Exists(saveRootPath))
- {
- // Inconsistent state. Create the directory
- Directory.CreateDirectory(saveRootPath);
- }
- string committedPath = System.IO.Path.Combine(saveRootPath, "0");
- string workingPath = System.IO.Path.Combine(saveRootPath, "1");
- // If the committed directory exists, that path will be loaded the next time the savedata is mounted
- if (Directory.Exists(committedPath))
- {
- return committedPath;
- }
- // If the working directory exists and the committed directory doesn't,
- // the working directory will be loaded the next time the savedata is mounted
- if (!Directory.Exists(workingPath))
- {
- Directory.CreateDirectory(workingPath);
- }
- return workingPath;
- }
- }
- }
|