Beispiel #1
0
        public ResultCode SaveScreenShot(byte[] screenshotData, ulong appletResourceUserId, ulong titleId, out ApplicationAlbumEntry applicationAlbumEntry)
        {
            applicationAlbumEntry = default;

            if (screenshotData.Length == 0)
            {
                return(ResultCode.NullInputBuffer);
            }

            /*
             * // NOTE: On our current implementation, appletResourceUserId starts at 0, disable it for now.
             * if (appletResourceUserId == 0)
             * {
             *  return ResultCode.InvalidArgument;
             * }
             */

            /*
             * // Doesn't occur in our case.
             * if (applicationAlbumEntry == null)
             * {
             *  return ResultCode.NullOutputBuffer;
             * }
             */

            if (screenshotData.Length >= 0x384000)
            {
                DateTime currentDateTime = DateTime.Now;

                applicationAlbumEntry = new ApplicationAlbumEntry()
                {
                    Size              = (ulong)Unsafe.SizeOf <ApplicationAlbumEntry>(),
                    TitleId           = titleId,
                    AlbumFileDateTime = new AlbumFileDateTime()
                    {
                        Year     = (ushort)currentDateTime.Year,
                        Month    = (byte)currentDateTime.Month,
                        Day      = (byte)currentDateTime.Day,
                        Hour     = (byte)currentDateTime.Hour,
                        Minute   = (byte)currentDateTime.Minute,
                        Second   = (byte)currentDateTime.Second,
                        UniqueId = 0
                    },
                    AlbumStorage = AlbumStorage.Sd,
                    ContentType  = ContentType.Screenshot,
                    Padding      = new Array5 <byte>(),
                    Unknown0x1f  = 1
                };

                using (SHA256 sha256Hash = SHA256.Create())
                {
                    // NOTE: The hex hash is a HMAC-SHA256 (first 32 bytes) using a hardcoded secret key over the titleId, we can simulate it by hashing the titleId instead.
                    string hash       = BitConverter.ToString(sha256Hash.ComputeHash(BitConverter.GetBytes(titleId))).Replace("-", "").Remove(0x20);
                    string folderPath = Path.Combine(_sdCardPath, "Nintendo", "Album", currentDateTime.Year.ToString("00"), currentDateTime.Month.ToString("00"), currentDateTime.Day.ToString("00"));
                    string filePath   = GenerateFilePath(folderPath, applicationAlbumEntry, currentDateTime, hash);

                    // TODO: Handle that using the FS service implementation and return the right error code instead of throwing exceptions.
                    Directory.CreateDirectory(folderPath);

                    while (File.Exists(filePath))
                    {
                        applicationAlbumEntry.AlbumFileDateTime.UniqueId++;

                        filePath = GenerateFilePath(folderPath, applicationAlbumEntry, currentDateTime, hash);
                    }

                    // NOTE: The saved JPEG file doesn't have the limitation in the extra EXIF data.
                    Image.LoadPixelData <Rgba32>(screenshotData, 1280, 720).SaveAsJpegAsync(filePath);
                }

                return(ResultCode.Success);
            }

            return(ResultCode.NullInputBuffer);
        }
Beispiel #2
0
        private string GenerateFilePath(string folderPath, ApplicationAlbumEntry applicationAlbumEntry, DateTime currentDateTime, string hash)
        {
            string fileName = $"{currentDateTime:yyyyMMddHHmmss}{applicationAlbumEntry.AlbumFileDateTime.UniqueId:00}-{hash}.jpg";

            return(Path.Combine(folderPath, fileName));
        }