Пример #1
0
        public static TaskFunc DownloadFile(string url, string fileName)
        {
            return((Tasker tasker, Object sync) =>
            {
                Debug.WriteLine($"Downloading: {url} to {fileName}");
                Conclusion result = Conclusion.Success;
                var wc = new HakchiWebClient();
                wc.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);

                wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(async(object sender, DownloadProgressChangedEventArgs e) =>
                {
                    tasker.SetProgress(e.BytesReceived, e.TotalBytesToReceive);
                    tasker.SetStatus(String.Format(Resources.DownloadingProgress, Shared.SizeSuffix(e.BytesReceived), Shared.SizeSuffix(e.TotalBytesToReceive)));
                });
                wc.DownloadFileCompleted += (object sender, System.ComponentModel.AsyncCompletedEventArgs e) =>
                {
                    if (e.Error != null)
                    {
                        File.Delete(fileName);
                        result = Conclusion.Error;
                    }
                    else
                    {
                        try
                        {
                            var date = DateTime.ParseExact(wc.ResponseHeaders.Get("Last-Modified"),
                                                           "ddd, dd MMM yyyy HH:mm:ss 'GMT'",
                                                           CultureInfo.InvariantCulture.DateTimeFormat,
                                                           DateTimeStyles.AssumeUniversal);

                            File.SetLastWriteTimeUtc(fileName, date);
                        } catch (Exception) { }
                    }
                };
                var downloadTask = wc.DownloadFileTaskAsync(new Uri(url), fileName);
                new Thread(() =>
                {
                    while (true)
                    {
                        if (tasker.TaskConclusion == Conclusion.Abort)
                        {
                            Debug.WriteLine("Download Aborted");
                            wc.CancelAsync();
                            break;
                        }
                        if (downloadTask.IsCanceled || downloadTask.IsCompleted || downloadTask.IsFaulted)
                        {
                            break;
                        }

                        Thread.Sleep(100);
                    }
                }).Start();
                downloadTask.Wait();
                return result;
            });
        }
Пример #2
0
        public Tasker.Conclusion ScrapeGames(Tasker tasker, Object syncObject = null)
        {
            if (Program.TheGamesDBAPI == null)
            {
                return(Tasker.Conclusion.Success);
            }

            try
            {
                var idList = new Dictionary <UInt32, int>();

                foreach (var app in NewGames)
                {
                    if (app.Metadata.OriginalCrc32 != 0 &&
                        data.GamesDB.HashLookup.ContainsKey(app.Metadata.OriginalCrc32) &&
                        data.GamesDB.HashLookup[app.Metadata.OriginalCrc32].TgdbId.Count > 0)
                    {
                        if (!idList.ContainsKey(app.Metadata.OriginalCrc32))
                        {
                            idList.Add(app.Metadata.OriginalCrc32, data.GamesDB.HashLookup[app.Metadata.OriginalCrc32].TgdbId.First());
                        }
                    }
                }

                var api      = Program.TheGamesDBAPI;
                var infoList = new Dictionary <int, IScraperData>();

                foreach (var chunk in idList.Values.Distinct().ToList().ChunkBy(20))
                {
                    var apiResponse = api.GetInfoByID(chunk.ToArray());

                    while (true)
                    {
                        apiResponse.Wait();
                        foreach (var result in apiResponse.Result.Items)
                        {
                            infoList.Add(int.Parse(result.ID), result);
                        }

                        if (apiResponse.Result.HasNextPage)
                        {
                            apiResponse = apiResponse.Result.GetNextPage();
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                var counter = 0;

                foreach (var app in NewGames)
                {
                    tasker.SetProgress(++counter, NewGames.Count);
                    tasker.SetStatus(string.Format(Resources.Scraping0, app.Name));

                    int tgdbId;
                    if (app.Metadata.OriginalCrc32 != 0 &&
                        data.GamesDB.HashLookup.ContainsKey(app.Metadata.OriginalCrc32) &&
                        data.GamesDB.HashLookup[app.Metadata.OriginalCrc32].TgdbId.Count > 0 &&
                        infoList.ContainsKey(tgdbId = data.GamesDB.HashLookup[app.Metadata.OriginalCrc32].TgdbId.First()))
                    {
                        try
                        {
                            var apiResult = infoList[tgdbId];

                            if (apiResult.Name != null)
                            {
                                var name = GamesDB.HashLookup[app.Metadata.OriginalCrc32].Name;

                                if (name != null)
                                {
                                    name = Shared.CleanName(name, true);
                                }

                                app.Desktop.Name     = name ?? apiResult.Name;
                                app.Desktop.SortName = Shared.GetSortName(app.Desktop.Name);
                            }

                            if (apiResult.Publishers != null && apiResult.Publishers.Length > 0)
                            {
                                app.Desktop.Publisher = String.Join(", ", apiResult.Publishers).ToUpper();
                            }
                            else if (apiResult.Developers != null && apiResult.Developers.Length > 0)
                            {
                                if (apiResult.ReleaseDate != null)
                                {
                                    app.Desktop.Copyright = $"© {apiResult.ReleaseDate.Year} {String.Join(", ", apiResult.Developers)}";
                                }
                                else
                                {
                                    app.Desktop.Copyright = $"© {String.Join(", ", apiResult.Developers)}";
                                }
                            }

                            if (apiResult.Description != null)
                            {
                                app.Desktop.Description = apiResult.Description;
                            }

                            if (apiResult.ReleaseDate != null)
                            {
                                app.Desktop.ReleaseDate = apiResult.ReleaseDate.ToString("yyyy-MM-dd");
                            }

                            if (apiResult.PlayerCount > 0)
                            {
                                app.Desktop.Players      = Convert.ToByte(apiResult.PlayerCount);
                                app.Desktop.Simultaneous = apiResult.PlayerCount == 2;
                            }

                            if (apiResult.Genres != null && apiResult.Genres.Length > 0)
                            {
                                foreach (var genre in apiResult.Genres)
                                {
                                    var match = Genre.GenreList.Where(g => g.GamesDbId.Contains(genre.ID)).Select(g => g);

                                    if (match.Count() > 0)
                                    {
                                        var firstGenre = match.First();

                                        app.Desktop.Genre = firstGenre.DesktopName;
                                        break;
                                    }
                                }
                            }

                            using (var wc = new HakchiWebClient())
                            {
                                try
                                {
                                    var front = apiResult.Images.Where(i => i.Type == TeamShinkansen.Scrapers.Enums.ArtType.Front).ToArray();

                                    if (front.Length > 0 && !app.CoverArtMatchSuccess)
                                    {
                                        tasker.SetStatus(string.Format(Resources.DownloadingFrontArtFor0, apiResult.Name));
                                        var data = wc.DownloadData(front[0].Url);
                                        using (var ms = new MemoryStream(data))
                                            using (var bm = new Bitmap(ms))
                                            {
                                                app.SetImage(bm);
                                            }
                                    }
                                }
                                catch (WebException ex) { }

                                try
                                {
                                    tasker.SetStatus(string.Format(Resources.DownloadingClearLogoFor0, apiResult.Name));
                                    var imageData = wc.DownloadData($"https://cdn.thegamesdb.net/images/original/clearlogo/{apiResult.ID}.png");

                                    using (var ms = new MemoryStream(imageData))
                                        using (var clearLogo = File.OpenWrite(Path.Combine(app.BasePath, $"{app.Code}_logo.png")))
                                        {
                                            ms.Seek(0, SeekOrigin.Begin);
                                            ms.CopyTo(clearLogo);
                                            ms.Seek(0, SeekOrigin.Begin);

                                            tasker.SetStatus(string.Format(Resources.GeneratingSpineFor0, apiResult.Name));
                                            using (var bm = new Bitmap(ms))
                                                using (var cl = new SystemDrawingBitmap(bm))
                                                    using (var spineImage = (Program.SpineTemplates.Where(e => e.Value.Name == "Custom (Black Grid)").First().Value as SpineTemplate <Bitmap>).Process(cl).Bitmap)
                                                    {
                                                        app.SetMdMini(spineImage, NesMenuElementBase.GameImageType.MdSpine);
                                                    }
                                        }
                                }
                                catch (WebException ex) { }
                            }
                        }
                        catch (Exception innerEx) { }
                    }
                }
            }
            catch (Exception ex) { }

            return(Tasker.Conclusion.Success);
        }
Пример #3
0
        public Tasker.Conclusion AddGames(Tasker tasker, Object syncObject = null)
        {
            tasker.SetProgress(-1, -1, Tasker.State.Running, Resources.AddingGames);
            tasker.SetTitle(Resources.AddingGames);
            tasker.SetStatusImage(Resources.sign_cogs);

            // static presets
            NesApplication.ParentForm           = tasker.HostForm;
            NesApplication.NeedPatch            = null;
            NesApplication.Need3rdPartyEmulator = null;
            NesApplication.CachedCoverFiles     = null;
            NesGame.IgnoreMapper           = null;
            SnesGame.NeedAutoDownloadCover = null;

            int total = files.Count();
            int count = 0;
            var gamesWithMultipleArt = new List <NesApplication>();

            foreach (var sourceFileName in files)
            {
                NesApplication app = null;
                try
                {
                    tasker.SetStatus(string.Format(Resources.AddingGame, Path.GetFileName(sourceFileName)));
                    var    fileName = sourceFileName;
                    var    ext      = Path.GetExtension(sourceFileName).ToLower();
                    byte[] rawData  = null;
                    string tmp      = null;
                    if (!asIs && (ext == ".7z" || ext == ".zip" || ext == ".rar" || ext == ".clvg"))
                    {
                        if (ext == ".clvg")
                        {
                            tmp = TempHelpers.getUniqueTempPath();
                            Directory.CreateDirectory(tmp);

                            using (var file = File.OpenRead(sourceFileName))
                                using (var reader = ReaderFactory.Open(file))
                                {
                                    reader.WriteAllToDirectory(tmp, new ExtractionOptions()
                                    {
                                        ExtractFullPath = true, PreserveFileTime = true
                                    });
                                }

                            var gameFilesInArchive = Directory.GetFiles(tmp, "*.desktop").Select(o => new DirectoryInfo(o)).Cast <DirectoryInfo>().ToArray();

                            switch (gameFilesInArchive.LongLength)
                            {
                            case 0:
                                // no files found
                                break;

                            case 1:
                                // one file found
                                fileName = gameFilesInArchive[0].FullName;
                                break;

                            default:
                                // multiple files found
                                var r = SelectFile(tasker, gameFilesInArchive.Select(o => o.FullName).ToArray());
                                if (r == DialogResult.OK)
                                {
                                    fileName = selectedFile;
                                }
                                else if (r == DialogResult.Ignore)
                                {
                                    fileName = sourceFileName;
                                }
                                else
                                {
                                    continue;
                                }
                                break;
                            }
                        }
                        else
                        {
                            using (var extractor = ArchiveFactory.Open(sourceFileName))
                            {
                                var filesInArchive     = extractor.Entries;
                                var gameFilesInArchive = new List <string>();
                                foreach (var f in extractor.Entries)
                                {
                                    if (!f.IsDirectory)
                                    {
                                        var e = Path.GetExtension(f.Key).ToLower();
                                        if (e == ".desktop")
                                        {
                                            gameFilesInArchive.Clear();
                                            gameFilesInArchive.Add(f.Key);
                                            break;
                                        }
                                        else if (CoreCollection.Extensions.Contains(e))
                                        {
                                            gameFilesInArchive.Add(f.Key);
                                        }
                                    }
                                }
                                if (gameFilesInArchive.Count == 1) // Only one known file (or app)
                                {
                                    fileName = gameFilesInArchive[0];
                                }
                                else if (gameFilesInArchive.Count > 1) // Many known files, need to select
                                {
                                    var r = SelectFile(tasker, gameFilesInArchive.ToArray());
                                    if (r == DialogResult.OK)
                                    {
                                        fileName = selectedFile;
                                    }
                                    else if (r == DialogResult.Ignore)
                                    {
                                        fileName = sourceFileName;
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }
                                else if (filesInArchive.Count() == 1) // No known files but only one another file
                                {
                                    fileName = filesInArchive.First().Key;
                                }
                                else // Need to select
                                {
                                    var r = SelectFile(tasker, filesInArchive.Select(f => f.Key).ToArray());
                                    if (r == DialogResult.OK)
                                    {
                                        fileName = selectedFile;
                                    }
                                    else if (r == DialogResult.Ignore)
                                    {
                                        fileName = sourceFileName;
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }
                                if (fileName != sourceFileName)
                                {
                                    var o = new MemoryStream();
                                    if (Path.GetExtension(fileName).ToLower() == ".desktop" || // App in archive, need the whole directory
                                        filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".jpg") || // Or it has cover in archive
                                        filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".png") ||
                                        filesInArchive.Select(f => f.Key).Contains(Path.GetFileNameWithoutExtension(fileName) + ".ips")    // Or IPS file
                                        )
                                    {
                                        tmp = Path.Combine(tempDirectory, fileName);
                                        Directory.CreateDirectory(tmp);
                                        extractor.WriteToDirectory(tmp, new ExtractionOptions()
                                        {
                                            ExtractFullPath = true, Overwrite = true
                                        });
                                        fileName = Path.Combine(tmp, fileName);
                                    }
                                    else
                                    {
                                        extractor.Entries.Where(f => f.Key == fileName).First().WriteTo(o);
                                        rawData = new byte[o.Length];
                                        o.Seek(0, SeekOrigin.Begin);
                                        o.Read(rawData, 0, (int)o.Length);
                                    }
                                }
                            }
                        }
                    }
                    app = NesApplication.Import(fileName, sourceFileName, rawData, asIs);

                    if (ext == ".clvg")
                    {
                        app.SkipCoreSelect = true;
                    }
                    else
                    {
                        if (app.CoverArtMatches != null && app.CoverArtMatches.Count() > 1)
                        {
                            gamesWithMultipleArt.Add(app);
                        }
                        if (ConfigIni.Instance.EnableImportScraper && Program.TheGamesDBAPI != null &&
                            app.Metadata.OriginalCrc32 != 0 &&
                            data.GamesDB.HashLookup.ContainsKey(app.Metadata.OriginalCrc32) &&
                            data.GamesDB.HashLookup[app.Metadata.OriginalCrc32].Length > 0)
                        {
                            var api  = Program.TheGamesDBAPI;
                            var task = api.GetInfoByID(data.GamesDB.HashLookup[app.Metadata.OriginalCrc32]);
                            try
                            {
                                task.Wait();
                                var result = task.Result;

                                if (result.Items.Count() > 0)
                                {
                                    var first = result.Items.First();

                                    if (first.Name != null)
                                    {
                                        app.Desktop.Name     = first.Name;
                                        app.Desktop.SortName = Shared.GetSortName(first.Name);
                                    }

                                    if (first.Publishers != null && first.Publishers.Length > 0)
                                    {
                                        app.Desktop.Publisher = String.Join(", ", first.Publishers).ToUpper();
                                    }
                                    else if (first.Developers != null && first.Developers.Length > 0)
                                    {
                                        if (first.ReleaseDate != null)
                                        {
                                            app.Desktop.Copyright = $"© {first.ReleaseDate.Year} {String.Join(", ", first.Developers)}";
                                        }
                                        else
                                        {
                                            app.Desktop.Copyright = $"© {String.Join(", ", first.Developers)}";
                                        }
                                    }

                                    if (first.Description != null)
                                    {
                                        app.Desktop.Description = first.Description;
                                    }

                                    if (first.ReleaseDate != null)
                                    {
                                        app.Desktop.ReleaseDate = first.ReleaseDate.ToString("yyyy-MM-dd");
                                    }

                                    if (first.PlayerCount > 0)
                                    {
                                        app.Desktop.Players      = Convert.ToByte(first.PlayerCount);
                                        app.Desktop.Simultaneous = first.PlayerCount == 2;
                                    }

                                    if (first.Genres != null && first.Genres.Length > 0)
                                    {
                                        foreach (var genre in first.Genres)
                                        {
                                            var match = ScraperForm.TheGamesDBGenreLookup.Where(g => g.Value.Contains(genre.ID)).Select(g => g.Key);

                                            if (match.Count() > 0)
                                            {
                                                var firstGenre = match.First();

                                                app.Desktop.Genre = firstGenre;
                                                break;
                                            }
                                        }
                                    }

                                    using (var wc = new HakchiWebClient())
                                    {
                                        try
                                        {
                                            var front = first.Images.Where(i => i.Type == TeamShinkansen.Scrapers.Enums.ArtType.Front).ToArray();

                                            if (front.Length > 0 && !app.CoverArtMatchSuccess)
                                            {
                                                var data = wc.DownloadData(front[0].Url);
                                                using (var ms = new MemoryStream(data))
                                                    using (var bm = new Bitmap(ms))
                                                    {
                                                        app.SetImage(bm);
                                                    }
                                            }
                                        }
                                        catch (WebException ex) { }

                                        try
                                        {
                                            var imageData = wc.DownloadData($"https://cdn.thegamesdb.net/images/original/clearlogo/{first.ID}.png");

                                            using (var ms = new MemoryStream(imageData))
                                                using (var clearLogo = File.OpenWrite(Path.Combine(app.BasePath, $"{app.Code}_logo.png")))
                                                {
                                                    ms.Seek(0, SeekOrigin.Begin);
                                                    ms.CopyTo(clearLogo);
                                                }
                                        }
                                        catch (WebException ex) { }
                                    }
                                }
                            }
                            catch (Exception) { }
                        }
                    }

                    if (app is ISupportsGameGenie && Path.GetExtension(fileName).ToLower() == ".nes")
                    {
                        var lGameGeniePath = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".xml");
                        if (File.Exists(lGameGeniePath))
                        {
                            GameGenieDataBase lGameGenieDataBase = new GameGenieDataBase(app);
                            lGameGenieDataBase.ImportCodes(lGameGeniePath, true);
                            lGameGenieDataBase.Save();
                        }
                    }

                    if (!string.IsNullOrEmpty(tmp) && Directory.Exists(tmp))
                    {
                        Directory.Delete(tmp, true);
                    }
                }
                catch (Exception ex)
                {
                    if (ex is ThreadAbortException)
                    {
                        return(Tasker.Conclusion.Abort);
                    }
                    if (ex.InnerException != null && !string.IsNullOrEmpty(ex.InnerException.Message))
                    {
                        Trace.WriteLine(ex.InnerException.Message + ex.InnerException.StackTrace);
                        tasker.ShowError(ex.InnerException, Path.GetFileName(sourceFileName));
                    }
                    else
                    {
                        Trace.WriteLine(ex.Message + ex.StackTrace, Path.GetFileName(sourceFileName));
                        tasker.ShowError(ex);
                    }
                    return(Tasker.Conclusion.Error);
                }
                if (app != null)
                {
                    addedApps.Add(app);
                }
                tasker.SetProgress(++count, total);
            }
            if (gamesWithMultipleArt.Count > 0)
            {
                tasker.HostForm.Invoke(new Action(() => {
                    using (SelectCoverDialog selectCoverDialog = new SelectCoverDialog())
                    {
                        selectCoverDialog.Games.AddRange(gamesWithMultipleArt);
                        selectCoverDialog.ShowDialog(tasker.HostForm);
                    }
                }));
            }
            return(Tasker.Conclusion.Success);
        }