using System.Diagnostics.CodeAnalysis; using System.Text.Json; using Backend.Helper; using Models.Handler; using Models.Model.Backend; using Models.Model.External; using NetMQ; using NetMQ.Sockets; namespace Backend.Handler; public class Communication { private readonly DbHandler _dbHandler; private readonly ThreadHandler _threadHandler; private readonly IpScanner _ipScanner; private readonly ContentFilter _contentFilter; private bool _isRunning = true; private string _basePath; public Communication(DbHandler dbHandler, ThreadHandler threadHandler, IpScanner ipScanner, ContentFilter contentFilter, string basePath) { _dbHandler = dbHandler; _threadHandler = threadHandler; _ipScanner = ipScanner; _contentFilter = contentFilter; _basePath = basePath; } public WaitHandle[] Start() { WaitHandle[] waitHandles = new WaitHandle[1]; EventWaitHandle handle = new(false, EventResetMode.ManualReset); waitHandles[0] = handle; Thread thread = new(Server!); thread.Start(handle); return waitHandles; } private void Server(object obj) { using ResponseSocket rep = new(); //rep.Options.IPv4Only = true; rep.Bind("tcp://127.0.0.1:5556"); while (_isRunning) { byte[] message = rep.ReceiveFrameBytes(); CommunicationObject? communicationObject = JsonSerializer.Deserialize(message); //rep.SendFrame(JsonSerializer.SerializeToUtf8Bytes("Success")); if (communicationObject is null) { continue; } OnServerOnReceiveReady(communicationObject, rep); } ((EventWaitHandle) obj).Set(); } [RequiresDynamicCode("Calls System.Text.Json.JsonSerializer.Serialize(TValue, JsonSerializerOptions)")] [RequiresUnreferencedCode("Calls System.Text.Json.JsonSerializer.Serialize(TValue, JsonSerializerOptions)")] private void OnServerOnReceiveReady(CommunicationObject communicationObject, ResponseSocket rep) { switch (communicationObject.Command) { case CommunicationCommand.GetScanningProgress: { DatabaseSizes databaseSizes = FilesystemHelper.GetDatabaseSizes(_basePath); long discardedIndexes = _dbHandler.GetDiscardedIndexes(); ScanningStatus status = new(); // 4294967296 is all Ipv4 addresses. if (discardedIndexes != 0) { status.PercentageOfIpv4Scanned = (float)discardedIndexes / 4294967296 * 100; } else { // This is a workaround for the frontend not understanding a 0f as an actual float, so we use a very small float. status.PercentageOfIpv4Scanned = 0.0000000001f; } status.AmountOfIpv4Left = 4294967296 - discardedIndexes; status.TotalFiltered = _dbHandler.GetFilteredIndexes(); status.TotalDiscarded = discardedIndexes; status.MyDbSize = databaseSizes.MyDbSize; status.FilteredDbSize = databaseSizes.FilteredDbSize; status.DiscardedDbSize = databaseSizes.DiscardedDbSize; byte[] serializedResult = JsonSerializer.SerializeToUtf8Bytes(status); rep.SendFrame(serializedResult); break; } case CommunicationCommand.DbReindex: { _dbHandler.ReIndex(); SendStringResponse(rep, "All Dbs have been reindexed."); break; } case CommunicationCommand.DbVacuum: { _dbHandler.Vacuum(); SendStringResponse(rep, "All Dbs have been vacuumed."); break; } case CommunicationCommand.GetSearches: { if (!string.IsNullOrWhiteSpace(communicationObject.SearchTerm)) { SendSearchResponse(rep, communicationObject.SearchTerm); } break; } case CommunicationCommand.StopScanning: { _isRunning = false; break; } case CommunicationCommand.ChangeRuntimeVariable: { if (string.IsNullOrWhiteSpace(communicationObject.VariableValue)) break; if (communicationObject.Variable == RuntimeVariable.DbContent.ToString()) { int value = int.Parse(communicationObject.VariableValue); _dbHandler.SetContentWaitTime(value); } if (communicationObject.Variable == RuntimeVariable.DbDiscarded.ToString()) { int value = int.Parse(communicationObject.VariableValue); _dbHandler.SetDiscardedWaitTime(value); } if (communicationObject.Variable == RuntimeVariable.ScannerTimeout.ToString()) { int value = int.Parse(communicationObject.VariableValue); _ipScanner.SetTimeout(value); } if (communicationObject.Variable == RuntimeVariable.ContentFilter.ToString()) { int value = int.Parse(communicationObject.VariableValue); _contentFilter.SetTimeout(value); } rep.SendFrame(JsonSerializer.SerializeToUtf8Bytes("Success")); break; } } } private static void SendStringResponse(ResponseSocket rep, string response) { byte[] serializedResult = JsonSerializer.SerializeToUtf8Bytes(response); rep.SendFrame(serializedResult); } private static void SendSearchResponse(ResponseSocket rep, string searchTerm) { //SearchResults result = SearchHelper.Search(communicationObject.SearchTerm!, _dbHandler); SearchResults result = new() { Results = [] }; SearchResult lol = new() { Url = "Remember to use an actual search tearm. Like 'dotnet 9.0'", Title = "Remember to use an actual search tearm. Like 'dotnet 9.0'", }; result.Results.Add(lol); string serializedResult = JsonSerializer.Serialize(result); rep.SendFrame(serializedResult); } }