Пример #1
0
        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);
        }
Пример #2
0
        public static bool IsXciInTransferList(XciItem xci)
        {
            lock (lockObject)
            {
                if (xciTransfers.Contains(xci))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #3
0
        public static bool IsXciInfoValid(XciItem xci)
        {
            if (xci == null)
            {
                return(false);
            }

            if (string.IsNullOrWhiteSpace(xci.titleId))
            {
                return(false);
            }

            return(true);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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();
        }
Пример #6
0
        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 { }
        }
Пример #7
0
        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);
        }
Пример #8
0
        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);
        }
Пример #9
0
        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);
        }
Пример #10
0
        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;
            }
        }
Пример #11
0
        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();
            }
        }
Пример #12
0
        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);
        }