diff --git a/HyperbolicDownloader/FileProcessing/FileCompressor.cs b/HyperbolicDownloader/FileProcessing/FileCompressor.cs index 9b05462..487f0e8 100644 --- a/HyperbolicDownloader/FileProcessing/FileCompressor.cs +++ b/HyperbolicDownloader/FileProcessing/FileCompressor.cs @@ -24,13 +24,11 @@ internal static class FileCompressor { byte[] buffer = new byte[chunkSize]; int bytesRead; - using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read)) - using (BufferedStream bs = new BufferedStream(fs)) + using FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); + using BufferedStream bs = new BufferedStream(fs); + while ((bytesRead = bs.Read(buffer, 0, chunkSize)) != 0) { - while ((bytesRead = bs.Read(buffer, 0, chunkSize)) != 0) - { - yield return buffer; - } + yield return buffer; } } } \ No newline at end of file diff --git a/HyperbolicDownloader/Networking/HostsManager.cs b/HyperbolicDownloader/Networking/HostsManager.cs index b485bc8..e7f4b18 100644 --- a/HyperbolicDownloader/Networking/HostsManager.cs +++ b/HyperbolicDownloader/Networking/HostsManager.cs @@ -9,7 +9,7 @@ namespace HyperbolicDownloader; internal class HostsManager { - private readonly List hosts = new List(); + private List hosts = new List(); public int Count => hosts.Count; public void AddRange(IEnumerable hosts) @@ -98,6 +98,7 @@ internal class HostsManager public void SaveHosts() { + hosts = hosts.OrderByDescending(h => h.LastActive).ToList(); File.WriteAllText(Program.HostsFilePath, JsonSerializer.Serialize(hosts)); } } \ No newline at end of file diff --git a/HyperbolicDownloader/Networking/NetworkClient.cs b/HyperbolicDownloader/Networking/NetworkClient.cs index adc1993..a0309c7 100644 --- a/HyperbolicDownloader/Networking/NetworkClient.cs +++ b/HyperbolicDownloader/Networking/NetworkClient.cs @@ -1,5 +1,6 @@ using HyperbolicDownloader.FileProcessing; +using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Text; @@ -155,44 +156,51 @@ namespace HyperbolicDownloader.Networking private async Task Upload(TcpClient client, string hash) { - byte[] bytesToSend; - hash = hash.Trim(); - NetworkStream nwStream = client.GetStream(); - client.SendBufferSize = 64000; - if (filesManager.TryGet(hash, out HyperFileInfo? hyperFileInfo) && File.Exists(hyperFileInfo?.FilePath)) + try { - if (hash != await FileValidator.CalculateHashAsync(hyperFileInfo.FilePath)) + byte[] bytesToSend; + hash = hash.Trim(); + NetworkStream nwStream = client.GetStream(); + client.SendBufferSize = 64000; + if (filesManager.TryGet(hash, out HyperFileInfo? hyperFileInfo) && File.Exists(hyperFileInfo?.FilePath)) { - bytesToSend = Encoding.ASCII.GetBytes("Hash does not match!"); - await nwStream.WriteAsync(bytesToSend); - return; - } - - //string compressedFilePath = $"{hash + DateTime.Now.Millisecond}.temp"; - - //FileCompressor.CompressFile(hyperFileInfo.FilePath, compressedFilePath); - - FileInfo compressedFileInfo = new FileInfo(hyperFileInfo.FilePath); - - bytesToSend = Encoding.ASCII.GetBytes($"{compressedFileInfo.Length}/{Path.GetFileName(hyperFileInfo.FilePath)}"); - await nwStream.WriteAsync(bytesToSend); - - foreach (byte[]? chunk in FileCompressor.ReadChunks(hyperFileInfo.FilePath, 64000)) - { - if (chunk is not null) + if (hash != await FileValidator.CalculateHashAsync(hyperFileInfo.FilePath)) { - await nwStream.WriteAsync(chunk); + bytesToSend = Encoding.ASCII.GetBytes("Hash does not match!"); + await nwStream.WriteAsync(bytesToSend); + return; } - } - // File.Delete(compressedFilePath); + //string compressedFilePath = $"{hash + DateTime.Now.Millisecond}.temp"; + + //FileCompressor.CompressFile(hyperFileInfo.FilePath, compressedFilePath); + + FileInfo compressedFileInfo = new FileInfo(hyperFileInfo.FilePath); + + bytesToSend = Encoding.ASCII.GetBytes($"{compressedFileInfo.Length}/{Path.GetFileName(hyperFileInfo.FilePath)}"); + await nwStream.WriteAsync(bytesToSend); + + foreach (byte[]? chunk in FileCompressor.ReadChunks(hyperFileInfo.FilePath, 64000)) + { + if (chunk is not null) + { + await nwStream.WriteAsync(chunk); + } + } + + // File.Delete(compressedFilePath); + } + else + { + bytesToSend = Encoding.ASCII.GetBytes("File not found!"); + await nwStream.WriteAsync(bytesToSend); + } + client.Close(); } - else + catch (Exception ex) { - bytesToSend = Encoding.ASCII.GetBytes("File not found!"); - await nwStream.WriteAsync(bytesToSend); + Debug.WriteLine(ex); } - client.Close(); } public void StopListening() diff --git a/HyperbolicDownloader/Program.cs b/HyperbolicDownloader/Program.cs index 77c9573..bb9cb37 100644 --- a/HyperbolicDownloader/Program.cs +++ b/HyperbolicDownloader/Program.cs @@ -16,7 +16,7 @@ namespace HyperbolicDownloader; internal class Program { - private const int BroadcastPort = 2155; + public const int BroadcastPort = 2155; public const string HostsFilePath = "Hosts.json"; public const string FilesInfoPath = "Files.json"; @@ -85,7 +85,7 @@ internal class Program Console.WriteLine("Running local discovery routine..."); BroadcastClient.Send(BroadcastPort, PrivatePort.ToString()); - await Task.Delay(5000); + await Task.Delay(3000); int activeHostsCount = 0; if (hostsManager.Count > 0) @@ -96,9 +96,8 @@ internal class Program if (activeHostsCount == 0) { - hostsManager.AddRange(await Setup.ConfigureHost()); - Console.WriteLine("Checking if hosts are active..."); - activeHostsCount = hostsManager.CheckHostsActivity(); + ConsoleExt.WriteLine("No active hosts found!", ConsoleColor.Red); + ConsoleExt.WriteLine("Use 'add host xxx.xxx.xxx.xxx:yyyy' to add a new host.", ConsoleColor.Red); } Console.WriteLine($"{hostsManager.Count} known host(s)."); diff --git a/HyperbolicDownloader/UserInterface/InputHandler.cs b/HyperbolicDownloader/UserInterface/InputHandler.cs index f2d50ce..922f349 100644 --- a/HyperbolicDownloader/UserInterface/InputHandler.cs +++ b/HyperbolicDownloader/UserInterface/InputHandler.cs @@ -26,6 +26,7 @@ internal class InputHandler commander.Register((_) => Console.Clear(), "clear", "cls"); commander.Register(Exit, "exit", "quit"); commander.Register(ShowInfo, "info", "inf"); + commander.Register(Discover, "discover", "disc"); commander.Register(GetFile, "get"); Command addCommand = commander.Register(AddFile, "add"); @@ -38,7 +39,7 @@ internal class InputHandler listCommand.Register(ListFiles, "files"); listCommand.Register(ListHosts, "hosts"); - commander.Register((_) => hostsManager.CheckHostsActivity(), "status", "check"); + commander.Register(CheckActiveHosts, "status", "check"); this.filesManager = filesManager; } @@ -101,6 +102,10 @@ internal class InputHandler { ConsoleExt.WriteLine($"Invalid host! Error message: {ex.Message}", ConsoleColor.Red); } + catch (IOException ex) + { + ConsoleExt.WriteLine($"Invalid host! Error message: {ex.Message}", ConsoleColor.Red); + } } else { @@ -172,6 +177,26 @@ internal class InputHandler ConsoleExt.WriteLine($"The private port is: {Program.PrivatePort}", ConsoleColor.Green); } + private void Discover(string _) + { + Console.WriteLine("Running local discovery routine..."); + BroadcastClient.Send(Program.BroadcastPort, Program.PrivatePort.ToString()); + Thread.Sleep(3000); + } + + private void CheckActiveHosts(string _) + { + int activeHostsCount = hostsManager.CheckHostsActivity(); + if (activeHostsCount == 0) + { + ConsoleExt.WriteLine("No active hosts found!", ConsoleColor.Red); + ConsoleExt.WriteLine("Use 'add host xxx.xxx.xxx.xxx:yyyy' to add a new host.", ConsoleColor.Red); + } + + Console.WriteLine($"{hostsManager.Count} known host(s)."); + Console.WriteLine($"{activeHostsCount} active host(s)."); + } + private void Exit(string _) { hostsManager.SaveHosts(); @@ -236,8 +261,19 @@ internal class InputHandler byte[] bytesToSend = Encoding.ASCII.GetBytes($"Download {hash}"); nwStream.Write(bytesToSend); - nwStream.ReadTimeout = 5000; - int bytesRead = nwStream.Read(buffer, 0, tcpClient.ReceiveBufferSize); + nwStream.ReadTimeout = 30000; + + int bytesRead; + try + { + bytesRead = nwStream.Read(buffer, 0, tcpClient.ReceiveBufferSize); + } + catch (IOException) + { + Console.WriteLine(); + ConsoleExt.WriteLine("Lost connection to other host!", ConsoleColor.Red); + continue; + } string dataReceived = Encoding.ASCII.GetString(buffer, 0, bytesRead); diff --git a/HyperbolicDownloader/UserInterface/Setup.cs b/HyperbolicDownloader/UserInterface/Setup.cs deleted file mode 100644 index 8764d25..0000000 --- a/HyperbolicDownloader/UserInterface/Setup.cs +++ /dev/null @@ -1,60 +0,0 @@ -using HyperbolicDownloader.Networking; - -using Stone_Red_Utilities.ConsoleExtentions; - -using System.Net; -using System.Net.Sockets; - -namespace HyperbolicDownloader.UserInterface; - -internal static class Setup -{ - public static async Task> ConfigureHost() - { - ConsoleExt.WriteLine("No active hosts found!", ConsoleColor.Red); - do - { - Console.WriteLine(); - Console.CursorVisible = true; - Console.Write("Please enter an IP address manually: "); - string? ipAddressInput = Console.ReadLine(); - - Console.Write("Please enter an port number manually: "); - string? portInput = Console.ReadLine(); - Console.CursorVisible = false; - - _ = int.TryParse(portInput, out int port); - if (port < 1000 || port >= 6000) - { - ConsoleExt.WriteLine("Invalid port number!", ConsoleColor.Red); - } - else if (IPAddress.TryParse(ipAddressInput, out IPAddress? ipAddress)) - { - try - { - Console.WriteLine("Waiting for response..."); - NetworkSocket? localSocket = Program.GetLocalSocket() ?? new NetworkSocket("0.0.0.0", 0, DateTime.MinValue); - List? recivedHosts = await NetworkClient.SendAsync>(ipAddress, port, "GetHostsList", localSocket); - - if (recivedHosts is not null) - { - ConsoleExt.WriteLine($"Success! Added {recivedHosts.Count} new host(s).", ConsoleColor.Green); - return recivedHosts; - } - else - { - ConsoleExt.WriteLine($"Invalid response!", ConsoleColor.Red); - } - } - catch (SocketException ex) - { - ConsoleExt.WriteLine($"Invalid host! Error message: {ex.Message}", ConsoleColor.Red); - } - } - else - { - ConsoleExt.WriteLine("Invalid IP address!", ConsoleColor.Red); - } - } while (true); - } -} \ No newline at end of file