mirror of
https://github.com/Stone-Red-Code/HyperbolicDownloader.git
synced 2026-09-04 00:56:09 +02:00
- Order hosts by last active
- Remove `Setup.cs` file - Add discover command - Increase request timeout when downloading a file to avoid errors - Better exception handling for file up/down-loading
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace HyperbolicDownloader;
|
||||
|
||||
internal class HostsManager
|
||||
{
|
||||
private readonly List<NetworkSocket> hosts = new List<NetworkSocket>();
|
||||
private List<NetworkSocket> hosts = new List<NetworkSocket>();
|
||||
public int Count => hosts.Count;
|
||||
|
||||
public void AddRange(IEnumerable<NetworkSocket> 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));
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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).");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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<List<NetworkSocket>> 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<NetworkSocket>? recivedHosts = await NetworkClient.SendAsync<List<NetworkSocket>>(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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user