using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows.Threading; using auto_creamapi.Model; using auto_creamapi.Utils; using HttpProgress; using SharpCompress.Archives; using SharpCompress.Common; using SharpCompress.Readers; namespace auto_creamapi.Services { public static class DownloadCreamApiService { private const string ArchivePassword = "cs.rin.ru"; private static string _filename; private static DownloadWindow _wnd; public static async Task DownloadAndExtract(string username, string password) { _wnd = new DownloadWindow(); _wnd.Show(); var download = Download(username, password); await download; download.Wait(); var extract = Extract(); await extract; extract.Wait(); _wnd.Close(); } private static async Task Download(string username, string password) { var container = new CookieContainer(); var handler = new HttpClientHandler {CookieContainer = container}; var client = new HttpClient(handler); var formContent = new FormUrlEncodedContent(new[] { new KeyValuePair("username", username), new KeyValuePair("password", password), new KeyValuePair("redirect", "./ucp.php?mode=login"), new KeyValuePair("login", "login") }); var response1 = await client.PostAsync("https://cs.rin.ru/forum/ucp.php?mode=login", formContent); MyLogger.Log.Debug($"Login Status Code: {response1.EnsureSuccessStatusCode().StatusCode.ToString()}"); var cookie = container.GetCookies(new Uri("https://cs.rin.ru/forum/ucp.php?mode=login")) .FirstOrDefault(c => c.Name.Contains("_sid")); MyLogger.Log.Debug($"Login Cookie: {cookie}"); var response2 = await client.GetAsync("https://cs.rin.ru/forum/viewtopic.php?t=70576"); MyLogger.Log.Debug( $"Download Page Status Code: {response2.EnsureSuccessStatusCode().StatusCode.ToString()}"); var content = response2.Content.ReadAsStringAsync(); var contentResult = await content; var expression = new Regex(".*\\/download\\/file\\.php\\?id=.*)\">(?.*)<\\/a>.*"); using var reader = new StringReader(contentResult); string line; var archiveFileList = new Dictionary(); while ((line = await reader.ReadLineAsync()) != null) { var match = expression.Match(line); // ReSharper disable once InvertIf if (match.Success) { archiveFileList.Add(match.Groups["filename"].Value, $"https://cs.rin.ru/forum{match.Groups["url"].Value}"); MyLogger.Log.Debug(archiveFileList.LastOrDefault().Key); } } /*foreach (var (filename, url) in archiveFileList) { MyLogger.Log.Information($"Downloading file: {filename}"); var fileResponse = await client.GetAsync(url); var download = fileResponse.Content.ReadAsByteArrayAsync(); await File.WriteAllBytesAsync(filename, await download); }*/ MyLogger.Log.Debug("Choosing first element from list..."); var (filename, url) = archiveFileList.FirstOrDefault(); _filename = filename; if (File.Exists(_filename)) { MyLogger.Log.Information($"{_filename} already exists, skipping download..."); return; } MyLogger.Log.Information("Start download..."); await _wnd.FilenameLabel.Dispatcher.InvokeAsync( () => _wnd.FilenameLabel.Content = _filename, DispatcherPriority.Background); await _wnd.InfoLabel.Dispatcher.InvokeAsync( () => _wnd.InfoLabel.Content = "Downloading...", DispatcherPriority.Background); /*var fileResponse = await client.GetAsync(url); var download = fileResponse.Content.ReadAsByteArrayAsync(); await File.WriteAllBytesAsync(filename, await download); MyLogger.Log.Information($"Download success? {download.IsCompletedSuccessfully}");*/ var progress = new Progress( x => { _wnd.PercentLabel.Dispatcher.Invoke( () => _wnd.PercentLabel.Content = x.PercentComplete.ToString("P"), DispatcherPriority.Background); _wnd.ProgressBar.Dispatcher.Invoke( () => _wnd.ProgressBar.Value = x.PercentComplete, DispatcherPriority.Background); }); await using var fileStream = File.OpenWrite(_filename); var task = client.GetAsync(url, fileStream, progress); var response = await task; if (task.IsCompletedSuccessfully) { _wnd.PercentLabel.Dispatcher.Invoke( () => _wnd.PercentLabel.Content = "100,00%", DispatcherPriority.Background); _wnd.ProgressBar.Dispatcher.Invoke( () => _wnd.ProgressBar.Value = 1, DispatcherPriority.Background); } } private static async Task Extract() { MyLogger.Log.Information("Start extraction..."); var options = new ReaderOptions {Password = ArchivePassword}; var archive = ArchiveFactory.Open(_filename, options); var expression1 = new Regex(@"nonlog_build\\steam_api(?:64)?\.dll"); await _wnd.ProgressBar.Dispatcher.InvokeAsync( () => _wnd.ProgressBar.IsIndeterminate = true, DispatcherPriority.ContextIdle); await _wnd.FilenameLabel.Dispatcher.InvokeAsync( () => _wnd.FilenameLabel.Content = _filename, DispatcherPriority.ContextIdle); await _wnd.InfoLabel.Dispatcher.InvokeAsync( () => _wnd.InfoLabel.Content = "Extracting...", DispatcherPriority.ContextIdle); await _wnd.PercentLabel.Dispatcher.InvokeAsync( () => _wnd.PercentLabel.Content = "100%", DispatcherPriority.ContextIdle); foreach (var entry in archive.Entries) { // ReSharper disable once InvertIf if (!entry.IsDirectory && expression1.IsMatch(entry.Key)) { MyLogger.Log.Debug(entry.Key); entry.WriteToDirectory(Directory.GetCurrentDirectory(), new ExtractionOptions { ExtractFullPath = false, Overwrite = true }); } } MyLogger.Log.Information("Extraction done!"); } } }