mirror of
https://github.com/Stone-Red-Code/HyperbolicDownloader.git
synced 2026-09-04 09:06:10 +02:00
Add new log command and some general command improvments
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("Critical Code Smell", "S3998:Threads should not lock on objects with weak identity", Justification = "Not a problem in this case", Scope = "member", Target = "~M:HyperbolicDownloader.LogCommands.OnNotificationMessageRecived(System.Object,HyperbolicDownloaderApi.Managment.NotificationMessageEventArgs)")]
|
||||
@@ -19,12 +19,14 @@ internal class InputHandler
|
||||
FileCommands fileCommands = new FileCommands(hostsManager, filesManager);
|
||||
DownloadCommands downloadCommands = new DownloadCommands(hostsManager, filesManager);
|
||||
ClientCommands clientCommands = new ClientCommands();
|
||||
LogCommands logCommands = new LogCommands();
|
||||
|
||||
_ = commander.Register(input => commander.PrintHelp(input), "help");
|
||||
_ = commander.Register(_ => Console.Clear(), (HelpText)"Clears the console.", "clear", "cls");
|
||||
_ = commander.Register(_ => exit = true, (HelpText)"Exits the application.", "exit", "quit");
|
||||
_ = commander.Register(clientCommands.ShowInfo, (HelpText)"Displays the private and public IP address.", "info", "inf");
|
||||
_ = commander.Register(hostCommands.Discover, (HelpText)"Tries to find other active hosts on the local network.", "discover", "disc");
|
||||
_ = commander.Register(logCommands.Log, (HelpText)"Displays live log.", "log");
|
||||
|
||||
Command getCommand = commander.Register(downloadCommands.GetFile, (HelpText)"Attempts to retrieve a file from another host using a hash.", "get");
|
||||
_ = getCommand.Register(downloadCommands.GetFileFrom, (HelpText)"Attempts to retrieve a file from another host using a .hyper file.", "from");
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
using HyperbolicDownloaderApi.Managment;
|
||||
|
||||
using Stone_Red_Utilities.ConsoleExtentions;
|
||||
|
||||
using System.Net;
|
||||
|
||||
namespace HyperbolicDownloader;
|
||||
|
||||
internal class LogCommands
|
||||
{
|
||||
public void Log(string _)
|
||||
{
|
||||
Console.Clear();
|
||||
|
||||
ApiManager.OnNotificationMessageRecived += OnNotificationMessageRecived;
|
||||
|
||||
char c = ' ';
|
||||
|
||||
do
|
||||
{
|
||||
if (c != '\0')
|
||||
{
|
||||
Console.WriteLine("Press 'q' to exit");
|
||||
}
|
||||
c = Console.ReadKey(true).KeyChar;
|
||||
} while (c != 'q');
|
||||
|
||||
ApiManager.OnNotificationMessageRecived -= OnNotificationMessageRecived;
|
||||
|
||||
Console.Clear();
|
||||
|
||||
Console.WriteLine("Log closed");
|
||||
}
|
||||
|
||||
private void OnNotificationMessageRecived(object? sender, NotificationMessageEventArgs e)
|
||||
{
|
||||
if (e.NotificationMessageType == NotificationMessageType.Log)
|
||||
{
|
||||
lock (Console.Out)
|
||||
{
|
||||
if (e.Message?.Contains('>') == true && IPAddress.TryParse(e.Message[..e.Message.IndexOf('>')].Trim(), out IPAddress? ipAddress))
|
||||
{
|
||||
ConsoleExt.Write($"[{DateTime.Now}] ", ConsoleColor.DarkGray);
|
||||
|
||||
byte[] ipAddressBytes = ipAddress.GetAddressBytes();
|
||||
|
||||
Array.Resize(ref ipAddressBytes, 8);
|
||||
|
||||
ConsoleColor consoleColor = (BitConverter.ToInt64(ipAddressBytes) % 12) switch
|
||||
{
|
||||
0 => ConsoleColor.Red,
|
||||
1 => ConsoleColor.Green,
|
||||
2 => ConsoleColor.Yellow,
|
||||
3 => ConsoleColor.Blue,
|
||||
4 => ConsoleColor.Magenta,
|
||||
5 => ConsoleColor.Cyan,
|
||||
6 => ConsoleColor.DarkRed,
|
||||
7 => ConsoleColor.DarkGreen,
|
||||
8 => ConsoleColor.DarkYellow,
|
||||
9 => ConsoleColor.DarkBlue,
|
||||
10 => ConsoleColor.DarkMagenta,
|
||||
11 => ConsoleColor.DarkCyan,
|
||||
_ => ConsoleColor.White
|
||||
};
|
||||
|
||||
ConsoleExt.Write(e.Message[..e.Message.IndexOf('>')], consoleColor);
|
||||
ConsoleExt.Write(e.Message[e.Message.IndexOf('>')..], ConsoleColor.White);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsoleExt.Write($"[{DateTime.Now}] ", ConsoleColor.DarkGray);
|
||||
ConsoleExt.Write(e.Message, ConsoleColor.White);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ internal static class Program
|
||||
if (File.Exists(ApiConfiguration.HostsFilePath))
|
||||
{
|
||||
string hostsJson = await File.ReadAllTextAsync(ApiConfiguration.HostsFilePath);
|
||||
apiManager.HostsManager.AddRange(JsonSerializer.Deserialize<List<NetworkSocket>>(hostsJson) ?? new());
|
||||
_ = apiManager.HostsManager.AddRange(JsonSerializer.Deserialize<List<NetworkSocket>>(hostsJson) ?? new());
|
||||
}
|
||||
|
||||
if (File.Exists(ApiConfiguration.FilesInfoPath))
|
||||
@@ -63,10 +63,15 @@ internal static class Program
|
||||
if (!apiManager.StartTcpListener())
|
||||
{
|
||||
_ = Console.ReadLine();
|
||||
Environment.Exit(-1);
|
||||
}
|
||||
|
||||
Console.WriteLine("Starting broadcast listener...");
|
||||
apiManager.StartBroadcastListener();
|
||||
Console.WriteLine("Starting UDP listener...");
|
||||
if (!apiManager.StartBroadcastListener())
|
||||
{
|
||||
_ = Console.ReadLine();
|
||||
Environment.Exit(-2);
|
||||
}
|
||||
|
||||
int activeHostsCount = 0;
|
||||
if (apiManager.HostsManager.Count > 0)
|
||||
|
||||
@@ -47,7 +47,7 @@ public class DownloadCommands
|
||||
return;
|
||||
}
|
||||
|
||||
hostsManager.AddRange(publicHyperFileInfo.Hosts);
|
||||
_ = hostsManager.AddRange(publicHyperFileInfo.Hosts);
|
||||
GetFile(publicHyperFileInfo.Hash);
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class DownloadCommands
|
||||
|
||||
byte[] bytesToSend = Encoding.ASCII.GetBytes($"Download {hash}");
|
||||
nwStream.Write(bytesToSend);
|
||||
nwStream.ReadTimeout = 30000;
|
||||
nwStream.ReadTimeout = 5000;
|
||||
|
||||
int bytesRead;
|
||||
try
|
||||
@@ -157,9 +157,8 @@ public class DownloadCommands
|
||||
|
||||
using FileStream? fileStream = new FileStream(filePath, FileMode.Create);
|
||||
|
||||
int bytesInOneSecond = 0;
|
||||
int unitsPerSecond = 0;
|
||||
string unit = "Kb";
|
||||
int bytesPerSecond = 0;
|
||||
int transferRate = 0;
|
||||
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
@@ -182,26 +181,16 @@ public class DownloadCommands
|
||||
fileStream.Write(reciveBuffer, 0, bytesRead);
|
||||
totalBytesRead += bytesRead;
|
||||
|
||||
bytesInOneSecond += bytesRead;
|
||||
bytesPerSecond += bytesRead;
|
||||
|
||||
if (stopWatch.Elapsed.TotalSeconds >= 1)
|
||||
{
|
||||
unitsPerSecond = (int)(bytesInOneSecond * stopWatch.Elapsed.TotalSeconds);
|
||||
if (unitsPerSecond > 125000)
|
||||
{
|
||||
unitsPerSecond /= 125000;
|
||||
unit = "Mb";
|
||||
}
|
||||
else
|
||||
{
|
||||
unitsPerSecond /= 125;
|
||||
unit = "Kb";
|
||||
}
|
||||
bytesInOneSecond = 0;
|
||||
transferRate = bytesPerSecond;
|
||||
bytesPerSecond = 0;
|
||||
stopWatch.Restart();
|
||||
}
|
||||
|
||||
ApiManager.SendNotificationMessage($"\rDownloading: {Math.Clamp(Math.Ceiling(100d / fileSize * totalBytesRead), 0, 100)}% {totalBytesRead / 1000}/{fileSize / 1000}KB [{unitsPerSecond}{unit}/s] ");
|
||||
ApiManager.SendNotificationMessage($"\rDownloading: {Math.Clamp(Math.Ceiling(100d / fileSize * totalBytesRead), 0, 100)}% {DisplayFileSize(totalBytesRead)}/{DisplayFileSize(fileSize)} [{DisplayTransferRate(transferRate)}] ");
|
||||
}
|
||||
|
||||
fileStream.Close();
|
||||
@@ -233,4 +222,38 @@ public class DownloadCommands
|
||||
ApiManager.SendNotificationMessageNewLine("None of the available hosts have the requested file!", NotificationMessageType.Error);
|
||||
hostsManager.SaveHosts();
|
||||
}
|
||||
|
||||
private string DisplayTransferRate(long bytesPerSecond)
|
||||
{
|
||||
string[] ordinals = new[] { "", "K", "M", "G", "T", "P", "E" };
|
||||
|
||||
decimal rate = bytesPerSecond * 8;
|
||||
|
||||
int ordinal = 0;
|
||||
|
||||
while (rate > 1000)
|
||||
{
|
||||
rate /= 1000;
|
||||
ordinal++;
|
||||
}
|
||||
|
||||
return $"{Math.Round(rate, 0, MidpointRounding.AwayFromZero)}{ordinals[ordinal]}bps";
|
||||
}
|
||||
|
||||
private string DisplayFileSize(long bytes)
|
||||
{
|
||||
string[] ordinals = new[] { "", "K", "M", "G", "T", "P", "E" };
|
||||
|
||||
decimal rate = bytes;
|
||||
|
||||
int ordinal = 0;
|
||||
|
||||
while (rate > 1000)
|
||||
{
|
||||
rate /= 1000;
|
||||
ordinal++;
|
||||
}
|
||||
|
||||
return $"{Math.Round(rate, 0, MidpointRounding.AwayFromZero)}{ordinals[ordinal]}B";
|
||||
}
|
||||
}
|
||||
@@ -32,11 +32,24 @@ public class FileCommands
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveFile(string hash)
|
||||
public void RemoveFile(string args)
|
||||
{
|
||||
hash = hash.Trim().ToLower();
|
||||
args = args.Trim().ToLower();
|
||||
|
||||
if (filesManager.TryRemove(hash))
|
||||
if (int.TryParse(args, out int index))
|
||||
{
|
||||
List<PrivateHyperFileInfo> fileInfos = filesManager.ToList();
|
||||
|
||||
if (index < 1 || index > fileInfos.Count)
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine("Invalid index!", NotificationMessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
args = fileInfos[index - 1].Hash;
|
||||
}
|
||||
|
||||
if (filesManager.TryRemove(args))
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine($"Successfully removed file!", NotificationMessageType.Success);
|
||||
}
|
||||
@@ -46,7 +59,7 @@ public class FileCommands
|
||||
}
|
||||
}
|
||||
|
||||
public void ListFiles(string _)
|
||||
public void ListFiles(string searchString)
|
||||
{
|
||||
int index = 0;
|
||||
List<PrivateHyperFileInfo> fileInfos = filesManager.ToList();
|
||||
@@ -60,6 +73,12 @@ public class FileCommands
|
||||
foreach (PrivateHyperFileInfo fileInfo in fileInfos)
|
||||
{
|
||||
index++;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(searchString) && !fileInfo.FilePath.Contains(searchString, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ApiManager.SendNotificationMessageNewLine($"{index}) {fileInfo.FilePath}");
|
||||
ApiManager.SendNotificationMessageNewLine($"Hash: {fileInfo.Hash}");
|
||||
ApiManager.SendNotificationMessageNewLine(string.Empty);
|
||||
@@ -67,7 +86,7 @@ public class FileCommands
|
||||
Console.CursorTop--;
|
||||
}
|
||||
|
||||
public void GenerateFileSingle(string hash)
|
||||
public void GenerateFileSingle(string args)
|
||||
{
|
||||
string directoryPath = Path.Combine(ApiConfiguration.BasePath, "GeneratedFiles");
|
||||
if (!Directory.Exists(directoryPath))
|
||||
@@ -75,9 +94,23 @@ public class FileCommands
|
||||
_ = Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
|
||||
hash = hash.Trim().ToLower();
|
||||
args = args.Trim().ToLower();
|
||||
|
||||
if (!filesManager.TryGet(hash, out PrivateHyperFileInfo? localHyperFileInfo))
|
||||
PrivateHyperFileInfo? localHyperFileInfo;
|
||||
|
||||
if (int.TryParse(args, out int index))
|
||||
{
|
||||
List<PrivateHyperFileInfo> fileInfos = filesManager.ToList();
|
||||
|
||||
if (index < 1 || index > fileInfos.Count)
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine("Invalid index!", NotificationMessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
localHyperFileInfo = fileInfos[index - 1];
|
||||
}
|
||||
else if (!filesManager.TryGet(args, out localHyperFileInfo))
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine("The file is not being tracked!", NotificationMessageType.Error);
|
||||
return;
|
||||
@@ -86,7 +119,7 @@ public class FileCommands
|
||||
string fileName = Path.GetFileName(localHyperFileInfo!.FilePath);
|
||||
string filePath = Path.Combine(directoryPath, $"{fileName}.hyper");
|
||||
|
||||
PublicHyperFileInfo publicHyperFileInfo = new PublicHyperFileInfo(hash);
|
||||
PublicHyperFileInfo publicHyperFileInfo = new PublicHyperFileInfo(args);
|
||||
|
||||
NetworkSocket? localHost = ApiManager.GetLocalSocket();
|
||||
if (localHost is null)
|
||||
@@ -106,7 +139,7 @@ public class FileCommands
|
||||
ApiManager.SendNotificationMessageNewLine($"File saved at: {Path.GetFullPath(filePath)}");
|
||||
}
|
||||
|
||||
public void GenerateFileFull(string hash)
|
||||
public void GenerateFileFull(string args)
|
||||
{
|
||||
string directoryPath = Path.Combine(ApiConfiguration.BasePath, "GeneratedFiles");
|
||||
if (!Directory.Exists(directoryPath))
|
||||
@@ -114,9 +147,23 @@ public class FileCommands
|
||||
_ = Directory.CreateDirectory(directoryPath);
|
||||
}
|
||||
|
||||
hash = hash.Trim().ToLower();
|
||||
args = args.Trim().ToLower();
|
||||
|
||||
if (!filesManager.TryGet(hash, out PrivateHyperFileInfo? localHyperFileInfo))
|
||||
PrivateHyperFileInfo? localHyperFileInfo;
|
||||
|
||||
if (int.TryParse(args, out int index))
|
||||
{
|
||||
List<PrivateHyperFileInfo> fileInfos = filesManager.ToList();
|
||||
|
||||
if (index < 1 || index > fileInfos.Count)
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine("Invalid index!", NotificationMessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
localHyperFileInfo = fileInfos[index - 1];
|
||||
}
|
||||
else if (!filesManager.TryGet(args, out localHyperFileInfo))
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine("The file is not being tracked!", NotificationMessageType.Error);
|
||||
return;
|
||||
@@ -125,7 +172,7 @@ public class FileCommands
|
||||
string fileName = Path.GetFileName(localHyperFileInfo!.FilePath);
|
||||
string filePath = Path.Combine(directoryPath, $"{fileName}.hyper");
|
||||
|
||||
PublicHyperFileInfo publicHyperFileInfo = new PublicHyperFileInfo(hash);
|
||||
PublicHyperFileInfo publicHyperFileInfo = new PublicHyperFileInfo(args);
|
||||
|
||||
NetworkSocket? localHost = ApiManager.GetLocalSocket();
|
||||
if (localHost is null)
|
||||
@@ -148,7 +195,7 @@ public class FileCommands
|
||||
|
||||
Console.CursorLeft = 0;
|
||||
|
||||
Task<bool> sendTask = NetworkClient.SendAsync<bool>(ipAddress!, host.Port, "HasFile", hash);
|
||||
Task<bool> sendTask = NetworkClient.SendAsync<bool>(ipAddress!, host.Port, "HasFile", args);
|
||||
|
||||
_ = sendTask.Wait(1000);
|
||||
|
||||
|
||||
@@ -67,6 +67,20 @@ public class HostCommands
|
||||
{
|
||||
string[] parts = args.Split(":");
|
||||
|
||||
if (int.TryParse(args, out int index))
|
||||
{
|
||||
if (hostsManager.Count < index || index < 1)
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine("Invalid index!", NotificationMessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
hostsManager.Remove(hostsManager.ToList()[index - 1], true);
|
||||
ApiManager.SendNotificationMessageNewLine($"Successfully Removed host!", NotificationMessageType.Success);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine("Invalid format! Use this format: (xxx.xxx.xxx.xxx:yyyy)", NotificationMessageType.Error);
|
||||
@@ -144,7 +158,17 @@ public class HostCommands
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine("Waiting for response...", NotificationMessageType.Info);
|
||||
NetworkSocket? localSocket = ApiManager.GetLocalSocket() ?? new NetworkSocket("0.0.0.0", 0, DateTime.MinValue);
|
||||
List<NetworkSocket>? recivedHosts = NetworkClient.Send<List<NetworkSocket>>(ipAddress, port, "GetHostsList", localSocket);
|
||||
Task<List<NetworkSocket>?> sendTask = NetworkClient.SendAsync<List<NetworkSocket>>(ipAddress, port, "GetHostsList", localSocket);
|
||||
|
||||
_ = sendTask.Wait(5000);
|
||||
|
||||
if (!sendTask.IsCompletedSuccessfully)
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine($"No response from {ipAddress}:{port}", NotificationMessageType.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
List<NetworkSocket>? recivedHosts = sendTask.Result;
|
||||
|
||||
if (recivedHosts is not null)
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ public class FilesManager
|
||||
|
||||
public bool Contains(string? hash)
|
||||
{
|
||||
return files.Any(f => f.Hash == hash);
|
||||
return files.Exists(f => f.Hash == hash);
|
||||
}
|
||||
|
||||
public List<PrivateHyperFileInfo> ToList()
|
||||
|
||||
@@ -13,15 +13,14 @@ public class ApiManager
|
||||
{
|
||||
public static event EventHandler<NotificationMessageEventArgs>? OnNotificationMessageRecived;
|
||||
|
||||
public static IPAddress? PublicIpAddress => device?.GetExternalIPAsync().GetAwaiter().GetResult();
|
||||
public FilesManager FilesManager { get; } = new();
|
||||
public HostsManager HostsManager { get; } = new();
|
||||
|
||||
private static readonly Random random = new();
|
||||
private static NatDevice? device;
|
||||
private static Mapping? portMapping;
|
||||
private readonly BroadcastClient broadcastClient = new BroadcastClient();
|
||||
private readonly NetworkClient networkClient;
|
||||
public static IPAddress? PublicIpAddress => device?.GetExternalIPAsync().GetAwaiter().GetResult();
|
||||
public FilesManager FilesManager { get; } = new();
|
||||
public HostsManager HostsManager { get; } = new();
|
||||
|
||||
public ApiManager()
|
||||
{
|
||||
@@ -106,7 +105,7 @@ public class ApiManager
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
SendNotificationMessageNewLine(ex.ToString(), NotificationMessageType.Error);
|
||||
SendNotificationMessageNewLine(ex.Message, NotificationMessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,11 +113,21 @@ public class ApiManager
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
public void StartBroadcastListener()
|
||||
public bool StartBroadcastListener()
|
||||
{
|
||||
try
|
||||
{
|
||||
broadcastClient.StartListening(ApiConfiguration.BroadcastPort);
|
||||
broadcastClient.OnBroadcastRecived += BroadcastClient_OnBroadcastRecived;
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
SendNotificationMessageNewLine($"An error occurred while starting the TCP listener! Error message: {ex.Message}", NotificationMessageType.Error); // net stop hens && net start hns
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool StartTcpListener()
|
||||
{
|
||||
@@ -139,6 +148,16 @@ public class ApiManager
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static void SendNotificationMessage(string message, NotificationMessageType messageType = NotificationMessageType.Info)
|
||||
{
|
||||
OnNotificationMessageRecived?.Invoke(null, new NotificationMessageEventArgs(messageType, message));
|
||||
}
|
||||
|
||||
internal static void SendNotificationMessageNewLine(string message, NotificationMessageType messageType = NotificationMessageType.Info)
|
||||
{
|
||||
OnNotificationMessageRecived?.Invoke(null, new NotificationMessageEventArgs(messageType, message + Environment.NewLine));
|
||||
}
|
||||
|
||||
private async void BroadcastClient_OnBroadcastRecived(object? sender, BroadcastRecivedEventArgs recivedEventArgs)
|
||||
{
|
||||
IPAddress remoteIpAddress = recivedEventArgs.IPEndPoint.Address;
|
||||
@@ -161,7 +180,7 @@ public class ApiManager
|
||||
|
||||
if (success)
|
||||
{
|
||||
HostsManager.Add(new NetworkSocket(remoteIpAddress.ToString(), remotePort, DateTime.Now));
|
||||
_ = HostsManager.Add(new NetworkSocket(remoteIpAddress.ToString(), remotePort, DateTime.Now));
|
||||
try
|
||||
{
|
||||
await NetworkClient.SendAsync(recivedEventArgs.IPEndPoint.Address, remotePort, "DiscoverAnswer", hostsToSend);
|
||||
@@ -176,11 +195,14 @@ public class ApiManager
|
||||
private void DiscoverAnswer(object? sender, MessageRecivedEventArgs<List<NetworkSocket>> recivedEventArgs)
|
||||
{
|
||||
SendNotificationMessageNewLine($"Received answer from {recivedEventArgs.IpAddress}. Returned {recivedEventArgs.Data.Count} host(s).", NotificationMessageType.Info);
|
||||
HostsManager.AddRange(recivedEventArgs.Data);
|
||||
SendNotificationMessageNewLine($"{recivedEventArgs.IpAddress} > Discovery answer {string.Join(", ", recivedEventArgs.Data)}", NotificationMessageType.Log);
|
||||
_ = HostsManager.AddRange(recivedEventArgs.Data);
|
||||
}
|
||||
|
||||
private async void GetHostList(object? sender, MessageRecivedEventArgs<NetworkSocket> recivedEventArgs)
|
||||
{
|
||||
SendNotificationMessageNewLine($"{recivedEventArgs.IpAddress} > Requesting file list", NotificationMessageType.Log);
|
||||
|
||||
List<NetworkSocket> hostsToSend = HostsManager.ToList();
|
||||
|
||||
NetworkSocket? localSocket = GetLocalSocket();
|
||||
@@ -195,7 +217,7 @@ public class ApiManager
|
||||
|
||||
if (recivedEventArgs.Data.Port != 0)
|
||||
{
|
||||
HostsManager.Add(recivedEventArgs.Data);
|
||||
_ = HostsManager.Add(recivedEventArgs.Data);
|
||||
}
|
||||
|
||||
await recivedEventArgs.SendResponseAsync(hostsToSend);
|
||||
@@ -203,6 +225,8 @@ public class ApiManager
|
||||
|
||||
private async void HasFile(object? sender, MessageRecivedEventArgs<string> recivedEventArgs)
|
||||
{
|
||||
SendNotificationMessageNewLine($"{recivedEventArgs.IpAddress} > Check if file exists [{recivedEventArgs.Data}]", NotificationMessageType.Log);
|
||||
|
||||
await recivedEventArgs.SendResponseAsync(FilesManager.Contains(recivedEventArgs.Data));
|
||||
}
|
||||
|
||||
@@ -210,14 +234,4 @@ public class ApiManager
|
||||
{
|
||||
SendNotificationMessageNewLine($"Received \"{recivedEventArgs.Data}\" from {recivedEventArgs.IpAddress}.", NotificationMessageType.Info);
|
||||
}
|
||||
|
||||
internal static void SendNotificationMessage(string message, NotificationMessageType messageType = NotificationMessageType.Info)
|
||||
{
|
||||
OnNotificationMessageRecived?.Invoke(null, new NotificationMessageEventArgs(messageType, message));
|
||||
}
|
||||
|
||||
internal static void SendNotificationMessageNewLine(string message, NotificationMessageType messageType = NotificationMessageType.Info)
|
||||
{
|
||||
OnNotificationMessageRecived?.Invoke(null, new NotificationMessageEventArgs(messageType, message + Environment.NewLine));
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ public class NotificationMessageEventArgs : EventArgs
|
||||
public enum NotificationMessageType
|
||||
{
|
||||
Info,
|
||||
Log,
|
||||
Success,
|
||||
Warning,
|
||||
Error
|
||||
|
||||
@@ -11,9 +11,8 @@ internal class BroadcastClient
|
||||
{
|
||||
public event EventHandler<BroadcastRecivedEventArgs>? OnBroadcastRecived;
|
||||
|
||||
public bool IsListening { get; private set; } = false;
|
||||
|
||||
private UdpClient? udpListener;
|
||||
public bool IsListening { get; private set; } = false;
|
||||
|
||||
public static void Send(int port, string message)
|
||||
{
|
||||
@@ -58,7 +57,7 @@ internal class BroadcastClient
|
||||
udpListener = new UdpClient(port);
|
||||
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, port);
|
||||
|
||||
_ = Task.Run(() =>
|
||||
_ = new TaskFactory().StartNew(() =>
|
||||
{
|
||||
while (IsListening)
|
||||
{
|
||||
@@ -67,7 +66,7 @@ internal class BroadcastClient
|
||||
|
||||
OnBroadcastRecived?.Invoke(this, new BroadcastRecivedEventArgs(groupEP, message));
|
||||
}
|
||||
});
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
}
|
||||
|
||||
public void StopListening()
|
||||
|
||||
@@ -12,16 +12,7 @@ public class HostsManager
|
||||
|
||||
public int AddRange(IEnumerable<NetworkSocket> hosts)
|
||||
{
|
||||
int newHosts = 0;
|
||||
|
||||
foreach (NetworkSocket host in hosts)
|
||||
{
|
||||
if (Add(host))
|
||||
{
|
||||
newHosts++;
|
||||
}
|
||||
}
|
||||
|
||||
int newHosts = hosts.Count(Add);
|
||||
SaveHosts();
|
||||
|
||||
return newHosts;
|
||||
@@ -44,14 +35,14 @@ public class HostsManager
|
||||
{
|
||||
if (DateTime.Now - host.LastActive >= new TimeSpan(24, 0, 0) || forceRemove)
|
||||
{
|
||||
_ = hosts.RemoveAll(x => x.IPAddress == host.IPAddress && x.Port == host.Port);
|
||||
_ = hosts.RemoveAll(x => x.Equals(host));
|
||||
}
|
||||
SaveHosts();
|
||||
}
|
||||
|
||||
public bool Contains(NetworkSocket host)
|
||||
{
|
||||
return hosts.Any(x => x.IPAddress == host.IPAddress && x.Port == host.Port);
|
||||
return hosts.Exists(x => x.Equals(host));
|
||||
}
|
||||
|
||||
public int CheckHostsActivity()
|
||||
@@ -65,7 +56,7 @@ public class HostsManager
|
||||
|
||||
try
|
||||
{
|
||||
_ = tcpClient.ConnectAsync(host.IPAddress, host.Port).Wait(500);
|
||||
_ = tcpClient.ConnectAsync(host.IPAddress, host.Port).Wait(1000);
|
||||
Console.CursorLeft = 0;
|
||||
if (tcpClient.Connected)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using HyperbolicDownloaderApi.FileProcessing;
|
||||
using HyperbolicDownloaderApi.Managment;
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
@@ -10,11 +11,10 @@ namespace HyperbolicDownloaderApi.Networking;
|
||||
|
||||
internal class NetworkClient
|
||||
{
|
||||
public bool IsListening { get; private set; } = false;
|
||||
|
||||
private TcpListener? tcpListener;
|
||||
private readonly FilesManager filesManager;
|
||||
private readonly Dictionary<string, (Type type, Delegate method)> events = new();
|
||||
private TcpListener? tcpListener;
|
||||
public bool IsListening { get; private set; } = false;
|
||||
|
||||
public NetworkClient(FilesManager filesManager)
|
||||
{
|
||||
@@ -98,7 +98,7 @@ internal class NetworkClient
|
||||
tcpListener.Start();
|
||||
IsListening = true;
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
_ = new TaskFactory().StartNew(async () =>
|
||||
{
|
||||
while (IsListening)
|
||||
{
|
||||
@@ -151,45 +151,7 @@ internal class NetworkClient
|
||||
}
|
||||
}
|
||||
tcpListener.Stop();
|
||||
});
|
||||
}
|
||||
|
||||
private async Task Upload(TcpClient client, string hash)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] bytesToSend;
|
||||
hash = hash.Trim();
|
||||
NetworkStream nwStream = client.GetStream();
|
||||
client.SendBufferSize = 64000;
|
||||
if (filesManager.TryGet(hash, out PrivateHyperFileInfo? hyperFileInfo) && File.Exists(hyperFileInfo?.FilePath))
|
||||
{
|
||||
FileInfo fileInfo = new FileInfo(hyperFileInfo.FilePath);
|
||||
|
||||
bytesToSend = Encoding.ASCII.GetBytes($"{fileInfo.Length}/{Path.GetFileName(hyperFileInfo.FilePath)}");
|
||||
|
||||
Array.Resize(ref bytesToSend, 1000);
|
||||
|
||||
await nwStream.WriteAsync(bytesToSend);
|
||||
foreach (byte[]? chunk in FileCompressor.ReadChunks(hyperFileInfo.FilePath, 64000).Where(chunk => chunk is not null))
|
||||
{
|
||||
await nwStream.WriteAsync(chunk);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bytesToSend = Encoding.ASCII.GetBytes("File not found!");
|
||||
await nwStream.WriteAsync(bytesToSend);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.Close();
|
||||
}
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
}
|
||||
|
||||
public void StopListening()
|
||||
@@ -202,4 +164,52 @@ internal class NetworkClient
|
||||
{
|
||||
events.Add(eventName, (typeof(T), eventHandler));
|
||||
}
|
||||
|
||||
private async Task Upload(TcpClient client, string hash)
|
||||
{
|
||||
try
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine($"{(client.Client.RemoteEndPoint as IPEndPoint)?.Address} > Requesting file download [{hash}]", NotificationMessageType.Log);
|
||||
byte[] bytesToSend;
|
||||
hash = hash.Trim();
|
||||
NetworkStream nwStream = client.GetStream();
|
||||
client.SendBufferSize = 64000;
|
||||
if (filesManager.TryGet(hash, out PrivateHyperFileInfo? hyperFileInfo) && File.Exists(hyperFileInfo?.FilePath))
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine($"{(client.Client.RemoteEndPoint as IPEndPoint)?.Address} > Accepting file download [{Path.GetFileName(hyperFileInfo.FilePath)}] [{hash}]", NotificationMessageType.Log);
|
||||
|
||||
FileInfo fileInfo = new FileInfo(hyperFileInfo.FilePath);
|
||||
|
||||
bytesToSend = Encoding.ASCII.GetBytes($"{fileInfo.Length}/{Path.GetFileName(hyperFileInfo.FilePath)}");
|
||||
|
||||
Array.Resize(ref bytesToSend, 1000);
|
||||
|
||||
await nwStream.WriteAsync(bytesToSend);
|
||||
|
||||
ApiManager.SendNotificationMessageNewLine($"{(client.Client.RemoteEndPoint as IPEndPoint)?.Address} > Starting file download of file [{Path.GetFileName(hyperFileInfo.FilePath)}] [{hash}]", NotificationMessageType.Log);
|
||||
|
||||
foreach (byte[]? chunk in FileCompressor.ReadChunks(hyperFileInfo.FilePath, 64000).Where(chunk => chunk is not null))
|
||||
{
|
||||
await nwStream.WriteAsync(chunk);
|
||||
}
|
||||
|
||||
ApiManager.SendNotificationMessageNewLine($"{(client.Client.RemoteEndPoint as IPEndPoint)?.Address} > Completed download of file [{Path.GetFileName(hyperFileInfo.FilePath)}] [{hash}]", NotificationMessageType.Log);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytesToSend = Encoding.ASCII.GetBytes("File not found!");
|
||||
ApiManager.SendNotificationMessageNewLine($"{(client.Client.RemoteEndPoint as IPEndPoint)?.Address} > File not found [{hash}]", NotificationMessageType.Log);
|
||||
await nwStream.WriteAsync(bytesToSend);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ApiManager.SendNotificationMessageNewLine($"{(client.Client.RemoteEndPoint as IPEndPoint)?.Address} > Error downloading file {ex.Message} [{hash}]", NotificationMessageType.Log);
|
||||
Debug.WriteLine(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user