public static XciItem RefreshGame(XciItem xci, bool force = false) { Log($"RefreshGame: {xci.gameName}"); if (force || !IsXciInfoValid(xci)) { if (File.Exists(xci.xciFilePath)) { xci = GetXciInfo(xci.xciFilePath, xci.xciLocation); } } xci.isGameOnSd = (FindXciByIdentifer(xci.uniqueId, xciOnSd) != null); xci.isGameOnPc = (FindXciByIdentifer(xci.uniqueId, xciOnPc) != null); xci.keepInCache = true; //reset any file actions that would have happened with this xci xci.fileAction = new FileHelper.FileStruct(); XciItem oldXci = FindXciByIdentifer(xci.uniqueId); lock (cacheListLock) { xciCache.Remove(oldXci); xciCache.Add(xci); } return(xci); }
public static bool IsXciInTransferList(XciItem xci) { lock (lockObject) { if (xciTransfers.Contains(xci)) { return(true); } } return(false); }
public static bool IsXciInfoValid(XciItem xci) { if (xci == null) { return(false); } if (string.IsNullOrWhiteSpace(xci.titleId)) { return(false); } return(true); }
public static List <XciItem> LoadGamesFromPath(string dirPath, bool recurse = true, bool isSdCard = false) { List <XciItem> pathXciList = new List <XciItem>(); //ulong packageId; string uniqueId; XciItem xciTemp; Log($"LoadGamesFromPath: {dirPath}"); List <string> xciFileList = FindAllFiles(dirPath, recurse); foreach (var item in xciFileList) { uniqueId = XciHelper.GetXciIdentifier(item); //Log($"LoadGamesFromPath: {uniqueId} - {item}"); // Check if this game is in the Cache and Clone the cache XciItem to decouple the objects lock (cacheListLock) xciTemp = Clone(XciHelper.FindXciByIdentifer(uniqueId)); if (xciTemp == null) { xciTemp = new XciItem(); } else { xciTemp.keepInCache = true; } xciTemp.xciFilePath = ""; xciTemp.isGameOnSd = isSdCard; xciTemp.isGameOnPc = !isSdCard; if (isSdCard) { xciTemp.xciLocation = XciLocation.SD; } else { xciTemp.xciLocation = XciLocation.PC; } xciTemp.xciFilePath = item; pathXciList.Add(xciTemp); } return(pathXciList); }
public static void ShowXciCert(XciItem xci) { XCI_Explorer.CertForm certForm; if (xci.gameCert == null) { certForm = new XCI_Explorer.CertForm(xci.gameCert, xci.gameName); } else { certForm = new XCI_Explorer.CertForm(xci.xciFilePath, xci.gameName); } certForm.Show(); }
public static void RemoveXciFromList(XciItem xci, List <XciItem> xciList, bool fromOlvAlso = false) { try { if (fromOlvAlso) { if (xci.xciLocation == Settings.config.defaultView) { formMain.olvList.RemoveObject(xci); } } xciList.Remove(xci); } catch { } }
public static bool UpdateXciCache(XciItem xci) { Log($"UpdateXciCache: {xci.gameName}"); lock (cacheListLock) { XciItem xciTemp = FindXciByIdentifer(xci.uniqueId); if (!IsXciInfoValid(xciTemp)) { if (xciTemp == null) { xciCache.Add(xci); return(true); } } } return(false); }
public static bool TrimXci(XciItem xci) { if (!File.Exists(xci.xciFilePath)) { return(false); } //maybe check this for errors? Maybe copy the file first, then do it on the copy? Needs tested. try { FileStream fileStream = new FileStream(xci.xciFilePath, FileMode.Open, FileAccess.Write); fileStream.SetLength((long)xci.gameUsedSize); fileStream.Close(); } catch { return(false); } return(true); }
public static bool TransferXci(XciItem xci) { if (xci.fileAction.action != FileAction.Copy && xci.fileAction.action != FileAction.Move) { return(false); } if (transferWorker != null && !transferWorker.IsBusy && transferWorker.CancellationPending) { transferWorker.Dispose(); transferWorker = null; } if (transferWorker == null) { transferWorker = new BackgroundWorker(); transferWorker.DoWork += TransferWorker_DoWork; transferWorker.WorkerSupportsCancellation = true; transferWorker.WorkerReportsProgress = true; transferWorker.RunWorkerCompleted += TransferWorker_RunWorkerCompleted; transferWorker.ProgressChanged += TransferWorker_ProgressChanged; } if (string.IsNullOrWhiteSpace(xci.fileAction.sourcePath)) { xci.fileAction.sourcePath = xci.xciFilePath; } if (xci.fileAction.source == XciHelper.XciLocation.SD) { xci.fileAction.destinationPath = Path.Combine(Settings.config.localXciFolders[0], Path.GetFileName(xci.fileAction.sourcePath)); } else { xci.fileAction.destinationPath = Path.Combine(Settings.config.sdDriveLetter, Path.GetFileName(xci.fileAction.sourcePath)); } if (String.IsNullOrWhiteSpace(xci.fileAction.sourcePath) || String.IsNullOrWhiteSpace(xci.fileAction.destinationPath)) { return(false); } if (xci.fileAction.destination == xci.fileAction.source) { return(false); } if (xci.fileAction.destinationPath == xci.fileAction.sourcePath) { return(false); } if (File.Exists(xci.fileAction.destinationPath)) { if (MessageBox.Show($"{xci.fileAction.destinationPath} already exists. Overwrite it?", "Overwrite Destination File", MessageBoxButtons.YesNo) != DialogResult.Yes) { return(false); } File.Delete(xci.fileAction.destinationPath); } lock (lockObject) { xciTransfers.Add(xci); totalFiles++; formMain.UpdateProgressLabel($"Copying {Path.GetFileName(xciTransfers.First().fileAction.sourcePath)} [{transferredFiles}/{totalFiles}]"); } if (!transferWorker.IsBusy) { isTransferInProgress = true; transferWorker.RunWorkerAsync(); } return(true); }
public static void UpdateXci(XciItem xci) { Log($"UpdateXci: {xci.gameName}"); XciItem xciTempSource = new XciItem(); XciItem xciTempDest = new XciItem(); Debug.Assert(xci.fileAction.actionCompleted); if (xci.fileAction.action == FileHelper.FileAction.None) { return; } if (xci.fileAction.source == XciLocation.SD) { xciTempSource = FindXciByIdentifer(xci.uniqueId, xciOnSd); xciTempDest = FindXciByIdentifer(xci.uniqueId, xciOnPc); } else { xciTempSource = FindXciByIdentifer(xci.uniqueId, xciOnPc); xciTempDest = FindXciByIdentifer(xci.uniqueId, xciOnSd); } switch (xci.fileAction.action) { case FileHelper.FileAction.None: break; case FileHelper.FileAction.Copy: xciTempDest = Clone(xci); xciTempDest.xciFilePath = xci.fileAction.destinationPath; xciTempDest.xciLocation = xci.fileAction.destination; xciTempDest = RefreshGame(xciTempDest, true); xciTempSource.isGameOnPc = true; xciTempSource.isGameOnSd = true; xciTempDest.isGameOnPc = true; xciTempDest.isGameOnSd = true; if (xci.fileAction.destination == XciLocation.PC) { xciOnPc.Add(xciTempDest); } else { xciOnSd.Add(xciTempDest); } xciTempDest.fileAction = new FileHelper.FileStruct(); xciTempSource.fileAction = new FileHelper.FileStruct(); if (Settings.config.defaultView == xciTempDest.xciLocation) { formMain.olvList.AddObject(xciTempDest); } else { formMain.olvList.RefreshObject(xciTempSource); } break; case FileHelper.FileAction.Move: if (!File.Exists(xci.fileAction.destinationPath)) { return; } if (File.Exists(xci.fileAction.sourcePath)) { File.Delete(xci.fileAction.sourcePath); } xciTempDest = Clone(xci); xciTempDest.fileAction = new FileHelper.FileStruct(); xciTempDest.xciFilePath = xci.fileAction.destinationPath; xciTempDest.xciLocation = xci.fileAction.destination; xciTempDest = RefreshGame(xciTempDest, true); if (xci.fileAction.destination == XciLocation.PC) { xciTempDest.isGameOnPc = true; xciTempDest.isGameOnSd = false; xciOnPc.Add(xciTempDest); xciOnSd.Remove(xciTempSource); } else { xciTempDest.isGameOnPc = false; xciTempDest.isGameOnSd = true; xciOnSd.Add(xciTempDest); xciOnPc.Remove(xciTempSource); } if (Settings.config.defaultView == xciTempDest.xciLocation) { formMain.olvList.AddObject(xciTempDest); } else { formMain.olvList.RemoveObject(xciTempSource); } break; case FileHelper.FileAction.Delete: //Check if file exists any longer. May not be necessary if we just refresh the xci lists if (!File.Exists(xci.xciFilePath)) { if (xci.xciLocation == XciLocation.PC) { if (xciTempSource != null) { xciOnPc.Remove(xciTempSource); } if (xciTempDest != null) { xciTempDest.isGameOnPc = false; } } else { xciOnSd.Remove(xciTempSource); xciTempDest.isGameOnSd = false; } if (Settings.config.defaultView == xci.xciLocation) { formMain.olvList.RemoveObject(xciTempSource); } else { formMain.olvList.RefreshObject(xciTempDest); } } break; case FileHelper.FileAction.CompletelyDelete: if (!File.Exists(xci.xciFilePath)) { if (Settings.config.defaultView == xci.xciLocation) { formMain.olvList.RemoveObject(xciTempSource); } if (xci.xciLocation == XciLocation.PC) { xciOnPc.Remove(xciTempSource); } else { xciOnSd.Remove(xciTempSource); } } break; case FileHelper.FileAction.Trim: //check if the file size changed, and if it did, get the XCI Info again xciTempSource.gameSize = (double)new FileInfo(xci.xciFilePath).Length; xciTempSource.isXciTrimmed = (xciTempSource.gameSize == xci.gameUsedSize); xciTempSource.fileAction = new FileHelper.FileStruct(); if (Settings.config.defaultView == xci.xciLocation) { formMain.olvList.UpdateObject(xciTempSource); } break; default: break; } }
public static void RefreshXciInBackground(XciItem xci) { Log($"RefreshXciInBackground {xci.gameName}"); isGameLoadingComplete = false; formMain.locationToolStripComboBox.Enabled = isGameLoadingComplete; lock (refreshListLock) xciToRefresh.Add(xci); if (backgroundWorkerSingleLoad == null) { backgroundWorkerSingleLoad = new BackgroundWorker(); backgroundWorkerSingleLoad.RunWorkerCompleted += delegate { formMain.locationToolStripComboBox.Enabled = isGameLoadingComplete; lock (refreshListLock) { XciItem xciRefresh = xciToRefresh.First(); XciItem oldXci; oldXci = FindXciByIdentifer(xciRefresh.uniqueId, xciCache); if (xciRefresh.xciLocation == XciLocation.PC) { oldXci = FindXciByIdentifer(xciRefresh.uniqueId, xciOnPc); xciOnPc.Remove(oldXci); xciOnPc.Add(xciRefresh); } else { oldXci = FindXciByIdentifer(xciRefresh.uniqueId, xciOnSd); xciOnSd.Remove(oldXci); xciOnSd.Add(xciRefresh); } if (xciRefresh.xciLocation == Settings.config.defaultView) { formMain.olvList.RemoveObject(oldXci); oldXci = xciRefresh; formMain.olvList.AddObject(oldXci); } formMain.UpdateToolStripLabel($"Refreshed {xciRefresh.gameName}"); xciToRefresh.Remove(xciRefresh); } if (xciToRefresh.Count > 0) { backgroundWorkerSingleLoad.RunWorkerAsync(); } else { SaveXciCache(); isGameLoadingComplete = true; formMain.locationToolStripComboBox.Enabled = isGameLoadingComplete; } }; backgroundWorkerSingleLoad.DoWork += delegate { XciItem xciRefresh; lock (refreshListLock) { xciRefresh = RefreshGame(xciToRefresh.First(), true); xciToRefresh[0] = xciRefresh; } }; } if (!backgroundWorkerSingleLoad.IsBusy) { backgroundWorkerSingleLoad.RunWorkerAsync(); } }
public static XciItem GetXciInfo(string filePath, XciLocation location) { XciItem xci = new XciItem(filePath); Log($"GetXciInfo {filePath}"); if (!File.Exists(filePath)) { return(null); } XCI_Explorer.MainForm mainForm = new XCI_Explorer.MainForm(false); mainForm.IgnoreFileCorruptErrors = Helpers.Settings.config.ignoreFileCorruptErrors; //xci_header header = hac.GetXCIHeader(xci.xciFilePath); //xci.packageId = header.PackageID; xci.uniqueId = GetXciIdentifier(filePath); mainForm.SGM_ProcessFile(filePath); xci.gameName = mainForm.TB_Name.Text.Trim().TrimEnd('\0'); xci.gameDeveloper = mainForm.TB_Dev.Text.Trim().TrimEnd('\0'); xci.gameCardCapacity = mainForm.TB_Capacity.Text.Trim().TrimEnd('\0'); if ((Bitmap)mainForm.PB_GameIcon.BackgroundImage == null) { xci.gameIcon = GetDefaultIcon(); } else { xci.gameIcon = (Bitmap)mainForm.PB_GameIcon.BackgroundImage; } xci.contentType = mainForm.ContentType; if (xci.contentType == null || xci.contentType.Length == 0) { xci.contentType = "NSP Game"; } xci.gameRevision = mainForm.TB_GameRev.Text.Trim().TrimEnd('\0'); xci.masterKeyRevision = mainForm.TB_MKeyRev.Text.Trim().TrimEnd('\0'); xci.sdkVersion = mainForm.TB_SDKVer.Text.Trim().TrimEnd('\0'); xci.titleId = mainForm.TB_TID.Text.Trim().TrimEnd('\0'); if (xci.titleId.Length != 16) { xci.titleId = 0 + xci.titleId; } xci.gameSize = mainForm.ExactSize; xci.gameUsedSize = mainForm.UsedSize; xci.productCode = mainForm.TB_ProdCode.Text.Trim().TrimEnd('\0'); xci.gameCert = ReadXciCert(xci.xciFilePath); xci.xciFileSize = new System.IO.FileInfo(xci.xciFilePath).Length; if (xci.gameName.Length == 0 && xci.gameUsedSize == 0) { xci.gameName = Path.GetFileName(xci.xciFilePath) + " (Corrupt?)"; } if (location == XciLocation.PC) { xci.xciLocation = XciLocation.PC; xci.isGameOnPc = true; } else { xci.xciLocation = XciLocation.SD; xci.isGameOnSd = true; } // compare the expected size with the actual size xci.isXciTrimmed = (xci.gameSize == xci.gameUsedSize); // compare the first byte of the cert to the rest of the cert if they're all the same, // it's not unique. ex 255 for all xci.isUniqueCert = !xci.gameCert.All(s => s.Equals(xci.gameCert[0])); mainForm.Close(); mainForm = null; return(xci); }