Author SHA1 Message Date
owner 5fe35192c6 Misc changes such as performance tuning, added support for more than 64 threads for the scanner. 2024-12-04 13:20:45 +01:00
owner a1f5b08ac3 Merge pull request 'Make it so the filter does not iterate over already filtered IPs.' (#22) from OptimizeContentFilter into main
Reviewed-on: #22
2024-11-29 18:18:00 +00:00
owner 2cff817044 Make it so the filter does not iterate over already filtered IPs. 2024-11-29 19:13:27 +01:00
owner 407bbc1556 Merge pull request 'Reworked the queue items.' (#21) from SplitUpQueueItem into main
Reviewed-on: #21
2024-11-29 13:21:44 +00:00
owner f2ace6f571 Reworked the queue items. 2024-11-29 12:59:07 +01:00
owner 3034e66126 Changed GET to HEAD for checking robots txt. 2024-11-29 11:02:51 +01:00
owner 701ffff27e Merge pull request 'Duscarded object is now a struct.' (#17) from ConvertDiscardedToStruct into main
Reviewed-on: #17
2024-11-28 13:37:01 +00:00
owner ec9cca59da Duscarded object is now a struct. 2024-11-28 14:36:36 +01:00
owner 90d1d6b429 Merge pull request 'Unfiltered object is now a struct.' (#15) from ReworkUnfilteredObject into main
Reviewed-on: #15
2024-11-28 13:25:35 +00:00
owner 3d8f903d30 Unfiltered object is now a struct. 2024-11-28 14:24:33 +01:00
owner eedca27a11 Merge pull request 'Fixed.' (#14) from FixGetProgress into main
Reviewed-on: #14
2024-11-28 10:32:39 +00:00
owner 69a22fb3eb Fixed. 2024-11-28 10:26:44 +01:00
owner d3270d3117 Merge pull request 'Fixed duplicate insertions into the filtered database.' (#11) from IgnoreAlreadySavedIpInTheFilteredDatabaseAfterResuming into main
Reviewed-on: #11
2024-11-27 15:09:13 +00:00
owner f02203c14c Fixed duplicate insertions into the filtered database. 2024-11-27 15:53:00 +01:00
owner 7ad691c439 Merge pull request 'CreateRuntimeVariable' (#8) from CreateRuntimeVariable into main
Reviewed-on: #8
2024-11-27 10:40:12 +00:00
owner 4eaaf0f244 Fix communication between applications. 2024-11-27 11:33:53 +01:00
owner a160992c08 Remove random sqlite file. 2024-11-26 19:44:55 +01:00
33 changed files with 628 additions and 277 deletions
+2 -2
View File
@@ -6,8 +6,8 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platform>x64</Platform>
<Optimize>true</Optimize>
<!--<Platform>x64</Platform>-->
<Optimize>false</Optimize>
</PropertyGroup>
<ItemGroup>
-37
View File
@@ -1,37 +0,0 @@
VACUUM;
DROP TABLE Filtered;
CREATE TABLE "Filtered" (
"Id" INTEGER NOT NULL,
"Ip" TEXT NOT NULL,
"Port1" INTEGER NOT NULL,
"Port2" INTEGER NOT NULL,
"Title1" TEXT NOT NULL,
"Title2" TEXT NOT NULL,
"Description1" TEXT NOT NULL,
"Description2" TEXT NOT NULL,
"Url1" TEXT NOT NULL,
"Url2" TEXT NOT NULL,
"ServerType1" TEXT NOT NULL,
"ServerType2" TEXT NOT NULL,
"RobotsTXT1" TEXT NOT NULL,
"RobotsTXT2" TEXT NOT NULL,
"HttpVersion1" TEXT NOT NULL,
"HttpVersion2" TEXT NOT NULL,
"CertificateIssuerCountry" TEXT NOT NULL,
"CertificateOrganizationName" TEXT NOT NULL,
"IpV6" TEXT NOT NULL,
"TlsVersion" TEXT NOT NULL,
"CipherSuite" TEXT NOT NULL,
"KeyExchangeAlgorithm" TEXT NOT NULL,
"PublicKeyType1" TEXT NOT NULL,
"PublicKeyType2" TEXT NOT NULL,
"PublicKeyType3" TEXT NOT NULL,
"AcceptEncoding1" TEXT NOT NULL,
"AcceptEncoding2" TEXT NOT NULL,
"ALPN" TEXT NOT NULL,
"Connection1" TEXT NOT NULL,
"Connection2" TEXT NOT NULL,
PRIMARY KEY("Id" AUTOINCREMENT)
)
-19
View File
@@ -1,19 +0,0 @@
DROP TABLE Unfiltered;
DROP TABLE Runtimes;
CREATE TABLE "Unfiltered" (
"Id" INTEGER NOT NULL,
"Ip" TEXT NOT NULL,
"ResponseCode" INTEGER NOT NULL,
"Port1" INTEGER NOT NULL,
"Port2" INTEGER NOT NULL,
"Filtered" INTEGER NOT NULL,
CONSTRAINT "PK_Unfiltered" PRIMARY KEY("Id" AUTOINCREMENT)
);
CREATE TABLE "Runtimes" (
"Id" INTEGER NOT NULL CONSTRAINT "PK_Runtimes" PRIMARY KEY AUTOINCREMENT,
"StartTime" TEXT NOT NULL,
"EndTime" TEXT NOT NULL,
"ThreadNumber" INTEGER NOT NULL
);
+7 -6
View File
@@ -43,6 +43,8 @@ public class Communication
{
using ResponseSocket rep = new();
//rep.Options.IPv4Only = true;
rep.Bind("tcp://127.0.0.1:5556");
while (_isRunning)
@@ -51,6 +53,8 @@ public class Communication
CommunicationObject? communicationObject = JsonSerializer.Deserialize<CommunicationObject>(message);
//rep.SendFrame(JsonSerializer.SerializeToUtf8Bytes("Success"));
if (communicationObject is null)
{
continue;
@@ -134,12 +138,7 @@ public class Communication
case CommunicationCommand.ChangeRuntimeVariable:
{
Console.WriteLine("lmao");
if (string.IsNullOrWhiteSpace(communicationObject.VariableValue))
{
break;
}
if (string.IsNullOrWhiteSpace(communicationObject.VariableValue)) break;
if (communicationObject.Variable == RuntimeVariable.DbContent.ToString())
{
@@ -165,6 +164,8 @@ public class Communication
_contentFilter.SetTimeout(value);
}
rep.SendFrame(JsonSerializer.SerializeToUtf8Bytes("Success"));
break;
}
}
+43 -30
View File
@@ -1,6 +1,5 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Text;
using Backend.Helper;
using Models.Handler;
using Models.Model.Backend;
@@ -9,22 +8,26 @@ namespace Backend.Handler;
public class ContentFilter
{
private readonly ConcurrentQueue<QueueItem> _queue;
private readonly ConcurrentQueue<Filtered> _queue;
private readonly ConcurrentQueue<UnfilteredQueueItem> _unfilteredQueue;
private readonly DbHandler _dbHandler;
private readonly string _getDomainPort80;
private readonly string _getDomainPort443;
private bool _stop;
private int _timeOut;
private string _basePath;
private readonly string _basePath;
public ContentFilter(ConcurrentQueue<QueueItem> queue, DbHandler dbHandler, string basePath)
public ContentFilter(ConcurrentQueue<Filtered> queue, ConcurrentQueue<UnfilteredQueueItem> unfilteredQueue, DbHandler dbHandler, string basePath)
{
_queue = queue;
_dbHandler = dbHandler;
_basePath = basePath;
_unfilteredQueue = unfilteredQueue;
_getDomainPort80 = $"{basePath}/Backend/Scripts/GetDomainNamePort80.sh";
_getDomainPort443 = $"{basePath}/Backend/Scripts/GetDomainNamePort443.sh";
SetTimeout(3000);
}
public void SetTimeout(int timeOut)
@@ -37,6 +40,7 @@ public class ContentFilter
WaitHandle[] waitHandles = new WaitHandle[1];
EventWaitHandle handle = new(false, EventResetMode.ManualReset);
waitHandles[0] = handle;
Thread f = new (Filter!);
f.Start(handle);
@@ -47,43 +51,39 @@ public class ContentFilter
{
while (!_stop)
{
long indexes = _dbHandler.GetUnfilteredIndexes();
List<long> indexes = _dbHandler.GetUnfilteredIndexes();
for (long i = 0; i < indexes; i++)
for (int i = 0; i < indexes.Count; i++)
{
if (_stop) break;
Unfiltered? unfiltered = _dbHandler.ReadUnfilteredWithId(i);
Unfiltered unfiltered = _dbHandler.ReadUnfilteredWithId(indexes[i]);
if (unfiltered is null || unfiltered.Filtered == 1) continue;
if (unfiltered.Filtered) continue;
unfiltered.Filtered = 1;
Ip ip = unfiltered.Ip;
QueueItem superUnfilteredObject = new()
unfiltered.Filtered = true;
UnfilteredQueueItem superUnfilteredObject = new()
{
Unfiltered = unfiltered,
Operations = Operations.Update
};
_queue.Enqueue(superUnfilteredObject);
_unfilteredQueue.Enqueue(superUnfilteredObject);
if (_dbHandler.GetFilteredIp(unfiltered.Ip))
if (_dbHandler.FilteredIpExists(unfiltered.Ip))
{
continue;
}
Filtered filtered = GetSiteData(unfiltered.Ip);
Filtered filtered = GetSiteData(ip);
filtered.Port1 = unfiltered.Port1;
filtered.Port2 = unfiltered.Port2;
QueueItem superFilteredObject = new()
{
Filtered = filtered,
Operations = Operations.Insert
};
_queue.Enqueue(superFilteredObject);
_queue.Enqueue(filtered);
}
Thread.Sleep(_timeOut);
@@ -92,7 +92,7 @@ public class ContentFilter
((EventWaitHandle) obj).Set();
}
private Filtered GetSiteData(string ip)
private Filtered GetSiteData(Ip ip)
{
StartProcess(ip, 80);
StartProcess(ip, 443);
@@ -161,19 +161,33 @@ public class ContentFilter
for (int i = 0; i < ports.Length; i++)
{
string? html;
string? html = "";
if (ports[i] == 80)
{
if (string.IsNullOrWhiteSpace(url1)) continue;
html = Task.Run(() => HttpClientHelper.GetHtml(url1, 80).Result).Result;
try
{
html = HttpClientHelper.GetHtml(url1, 80).GetAwaiter().GetResult();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
else
{
if (string.IsNullOrWhiteSpace(url2)) continue;
html = Task.Run(() => HttpClientHelper.GetHtml(url2, 443).Result).Result;
try
{
html = HttpClientHelper.GetHtml(url2, 443).GetAwaiter().GetResult();
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
if (string.IsNullOrWhiteSpace(html)) continue;
@@ -182,8 +196,8 @@ public class ContentFilter
if (ports[i] == 443 && string.IsNullOrWhiteSpace(title2)) { FilterHelper.GetTitle(html ,out title2); }
if (ports[i] == 80 && string.IsNullOrWhiteSpace(description1)) { FilterHelper.GetDescription(html, out description1); }
if (ports[i] == 443 && string.IsNullOrWhiteSpace(description2)) { FilterHelper.GetDescription(html, out description2); }
if (ports[i] == 80 && !robotsTxt1) { robotsTxt1 = Task.Run(() => HttpClientHelper.HasRobotsTxt(url1, 80).Result).Result; }
if (ports[i] == 443 && !robotsTxt2) { robotsTxt2 = Task.Run(() => HttpClientHelper.HasRobotsTxt(url2, 443).Result).Result; }
if (ports[i] == 80 && !robotsTxt1) { robotsTxt1 = HttpClientHelper.HasRobotsTxt(url1, 80).GetAwaiter().GetResult(); }
if (ports[i] == 443 && !robotsTxt2) { robotsTxt2 = HttpClientHelper.HasRobotsTxt(url2, 443).GetAwaiter().GetResult(); }
}
Filtered siteData = new()
@@ -220,19 +234,18 @@ public class ContentFilter
return siteData;
}
private void StartProcess(string ip, int port)
private void StartProcess(Ip ip, int port)
{
string fileName = port == 80 ? _getDomainPort80 : _getDomainPort443;
Process proc = new();
proc.StartInfo = new()
{
FileName = fileName,
Arguments = $"{ip}",
FileName = "/bin/bash",
Arguments = $"{fileName} {ip.Ip1}.{ip.Ip2}.{ip.Ip3}.{ip.Ip4} {_basePath}/Backend/Scripts/{port}Header.txt",
UseShellExecute = false,
RedirectStandardOutput = false,
RedirectStandardError = false,
RedirectStandardInput = false,
CreateNoWindow = true
};
+64 -35
View File
@@ -1,5 +1,4 @@
using System.Collections.Concurrent;
using System.Globalization;
using System.Net;
using System.Net.NetworkInformation;
using Backend.Helper;
@@ -18,28 +17,31 @@ public class ScanSettings
public class IpScanner
{
private readonly ConcurrentQueue<QueueItem> _queue;
private readonly ConcurrentQueue<Discarded> _discardedQueue;
private readonly ConcurrentQueue<UnfilteredQueueItem> _unfilteredQueue;
private readonly ConcurrentQueue<ScannerResumeObject> _resumeQueue;
private readonly DbHandler _dbHandler;
private bool _stop;
private int _timeout;
public IpScanner(ConcurrentQueue<QueueItem> queue, DbHandler dbHandler, ConcurrentQueue<Discarded> discardedQueue)
public IpScanner(ConcurrentQueue<UnfilteredQueueItem> unfilteredQueue, ConcurrentQueue<Discarded> discardedQueue,
ConcurrentQueue<ScannerResumeObject> resumeQueue, DbHandler dbHandler
)
{
_queue = queue;
_dbHandler = dbHandler;
_discardedQueue = discardedQueue;
_unfilteredQueue = unfilteredQueue;
_resumeQueue = resumeQueue;
SetTimeout(128);
SetTimeout(64);
}
public void SetTimeout(int milliseconds)
{
Console.WriteLine($"Setting timeout to {milliseconds}ms");
_timeout = milliseconds;
}
public WaitHandle[] Start(int threads)
public List<WaitHandle[]> Start(int threads)
{
int threadsAmount = 0;
if (threads % 2 == 0)
@@ -47,7 +49,22 @@ public class IpScanner
threadsAmount = 256 / threads;
}
WaitHandle[] waitHandles = new WaitHandle[threads];
WaitHandle[] waitHandle1;
WaitHandle[] waitHandle2;
if (threads <= 64)
{
waitHandle1 = new WaitHandle[threads];
waitHandle2 = new WaitHandle[threads];
}
else
{
waitHandle1 = new WaitHandle[64];
waitHandle2 = new WaitHandle[64];
}
int counter = 0;
int counter2 = 0;
for (int i = 0; i < threads; i++)
{
@@ -61,15 +78,32 @@ public class IpScanner
Handle = handle
};
waitHandles[i] = handle;
if (i < 64)
{
waitHandle1[counter] = handle;
counter++;
}
else
{
waitHandle2[counter2] = handle;
counter2++;
}
Thread f = new (Scan!);
f.Start(scanSettings);
Console.WriteLine($"Scanner thread ({i}) started");
Thread.Sleep(1000);
Thread.Sleep(100);
}
List<WaitHandle[]> waitHandles = new();
Console.WriteLine("Waithandle 1 count = " + waitHandle1.Length);
Console.WriteLine("Waithandle 2 count = " + waitHandle2.Length);
waitHandles.Add(waitHandle1);
waitHandles.Add(waitHandle2);
return waitHandles;
}
@@ -119,7 +153,6 @@ public class IpScanner
if (_discardedQueue.Count >= 2000)
{
Console.WriteLine("loooooooooooooooooooooooooooool");
Thread.Sleep(500);
}
@@ -131,7 +164,13 @@ public class IpScanner
break;
}
string ip = $"{i}.{j}.{k}.{l}";
Ip ip = new()
{
Ip1 = i,
Ip2 = j,
Ip3 = k,
Ip4 = l
};
IPStatus responseCode = IPStatus.Unknown;
@@ -139,15 +178,15 @@ public class IpScanner
{
// Sometimes, if the pinger gets a Destination Unreachable Communication administratively prohibited response, the pinger will throw an exception.
// https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol?useskin=vector#Control_messages
_ = IPAddress.TryParse(ip, out IPAddress? address);
_ = IPAddress.TryParse(ip.ToString(), out IPAddress? address);
if (address is not null)
{
responseCode = ping.Send(address, _timeout, buf, null).Status;
}
}
catch (Exception e)
catch
{
Console.WriteLine(e);
//
}
if (responseCode != IPStatus.Success)
@@ -156,7 +195,7 @@ public class IpScanner
continue;
}
(int, int) ports = TcpClientHelper.CheckPort(ip, 80, 443);
(int, int) ports = TcpClientHelper.CheckPort(ip.ToString(), 80, 443);
if (ports is { Item1: 0, Item2: 0 })
{
@@ -164,7 +203,7 @@ public class IpScanner
continue;
}
_queue.Enqueue(CreateUnfilteredQueueItem(ip, (int)responseCode, ports));
_unfilteredQueue.Enqueue(CreateUnfilteredQueueItem(ip, ports));
}
if (_stop)
@@ -186,49 +225,39 @@ public class IpScanner
resumeObject.FirstByte = i;
break;
}
//Console.WriteLine($"Thread ({scanSettings.ThreadNumber}) is at index ({i}) out of ({scanSettings.End}). Remaining ({scanSettings.End - i})");
Console.WriteLine($"Thread ({scanSettings.ThreadNumber}) is at index ({i}) out of ({scanSettings.End}). Remaining ({scanSettings.End - i})");
}
QueueItem resume = new()
{
ResumeObject = resumeObject,
Operations = Operations.Insert
};
_queue.Enqueue(resume);
_resumeQueue.Enqueue(resumeObject);
scanSettings.Handle!.Set();
}
private static Discarded CreateDiscardedQueueItem(string ip, int responseCode)
private static Discarded CreateDiscardedQueueItem(Ip ip, int responseCode)
{
Discarded discarded = new()
return new()
{
Ip = ip,
ResponseCode = responseCode
};
return discarded;
}
private static QueueItem CreateUnfilteredQueueItem(string ip, int responseCode, (int, int) ports)
private static UnfilteredQueueItem CreateUnfilteredQueueItem(Ip ip, (int, int) ports)
{
Unfiltered unfiltered = new()
{
Ip = ip,
ResponseCode = responseCode,
Port1 = ports.Item1,
Port2 = ports.Item2,
Filtered = 0
Filtered = false
};
QueueItem superUnfilteredObject = new()
return new()
{
Unfiltered = unfiltered,
Operations = Operations.Insert
};
return superUnfilteredObject;
}
public void Stop()
+32 -9
View File
@@ -17,12 +17,14 @@ public class ThreadHandler
public ThreadHandler(string path)
{
ConcurrentQueue<QueueItem> contentQueue = new();
ConcurrentQueue<Filtered> filteredQueue = new();
ConcurrentQueue<Discarded> discardedQueue = new();
ConcurrentQueue<UnfilteredQueueItem> unfilteredQueue = new();
ConcurrentQueue<ScannerResumeObject> scannerResumeQueue = new();
_dbHandler = new(contentQueue, discardedQueue, path);
_ipScanner = new(contentQueue, _dbHandler, discardedQueue);
_contentFilter = new(contentQueue, _dbHandler, path);
_dbHandler = new(filteredQueue, discardedQueue, unfilteredQueue, scannerResumeQueue, path);
_ipScanner = new(unfilteredQueue, discardedQueue, scannerResumeQueue, _dbHandler);
_contentFilter = new(filteredQueue, unfilteredQueue, _dbHandler, path);
_communication = new(_dbHandler, this, _ipScanner, _contentFilter, path);
}
@@ -32,28 +34,37 @@ public class ThreadHandler
Thread indexer = new(StartContentFilter);
Thread database = new(StartDbHandler);
Thread discarded = new(StartDiscardedDbHandler);
Thread filtered = new(StartFilteredDbHandler);
Thread resume = new(StartResumeDbHandler);
Thread communication = new(StartCommunicationHandler);
scanner.Start();
indexer.Start();
database.Start();
discarded.Start();
filtered.Start();
resume.Start();
communication.Start();
scanner.Join();
indexer.Join();
database.Join();
discarded.Join();
filtered.Join();
resume.Join();
communication.Join();
}
private void StartScanner()
{
Thread.Sleep(10000); // Let the database handler instantiate and warm up first.
Thread.Sleep(5000); // Let the database handler instantiate and warm up first.
WaitHandle[] wait = _ipScanner.Start(2);
List<WaitHandle[]> wait = _ipScanner.Start(128);
WaitHandle.WaitAll(wait);
for (int i = 0; i < wait.Count; i++)
{
WaitHandle.WaitAll(wait[i]);
}
Console.WriteLine("Scanner finished");
@@ -62,6 +73,8 @@ public class ThreadHandler
private void StartContentFilter()
{
Thread.Sleep(5000);
WaitHandle[] wait = _contentFilter.Start();
WaitHandle.WaitAll(wait);
@@ -73,12 +86,22 @@ public class ThreadHandler
private void StartDbHandler()
{
_dbHandler.StartContent();
_dbHandler.UnfilteredDbHandler();
}
private void StartFilteredDbHandler()
{
_dbHandler.FilteredDbHandler();
}
private void StartResumeDbHandler()
{
_dbHandler.ResumeDbHandler();
}
private void StartDiscardedDbHandler()
{
WaitHandle[] wait = _dbHandler.Start(2);
WaitHandle[] wait = _dbHandler.Start(4);
WaitHandle.WaitAll(wait);
+12 -8
View File
@@ -1,3 +1,5 @@
using System.Diagnostics;
namespace Backend.Helper;
public static class HttpClientHelper
@@ -16,19 +18,20 @@ public static class HttpClientHelper
}
client.DefaultRequestHeaders.Accept.Clear();
client.Timeout = TimeSpan.FromSeconds(1);
HttpResponseMessage? response = null;
HttpResponseMessage? response;
try
{
response = await client.GetAsync("/");
}
catch (Exception e)
catch
{
Console.WriteLine(e);
return "";
}
if (response is null || !response.IsSuccessStatusCode)
if (!response.IsSuccessStatusCode)
{
return "";
}
@@ -50,16 +53,17 @@ public static class HttpClientHelper
}
client.DefaultRequestHeaders.Accept.Clear();
client.Timeout = TimeSpan.FromSeconds(1);
HttpResponseMessage? response = null;
try
{
response = await client.GetAsync("/robots.txt");
{//
response = await client.SendAsync(new(HttpMethod.Head, "/robots.txt"));
}
catch (Exception e)
catch
{
Console.WriteLine(e);
//
}
return response is not null && response.IsSuccessStatusCode;
+1 -1
View File
@@ -1,3 +1,3 @@
#!/bin/bash
curl -k -vvI -m 10 https://"$1" &> 443Header.txt
curl -k -vvI -m 10 https://"$1" &> "$2"
+2 -1
View File
@@ -1,3 +1,4 @@
#!/bin/bash
curl -k -vvI -m 10 http://"$1" &> 80Header.txt
curl -k -vvI -m 10 http://"$1" &> "$2"
#80Header.txt
+1 -4
View File
@@ -60,7 +60,7 @@ public static class Commands
VariableValue = value
};
SendAndRecieveStringMessage(communicationObject);
Console.WriteLine(SendAndRecieveStringMessage(communicationObject));
}
public static void GetHelp()
@@ -109,11 +109,8 @@ public static class Commands
[RequiresDynamicCode("Calls System.Text.Json.JsonSerializer.SerializeToUtf8Bytes<TValue>(TValue, JsonSerializerOptions)")]
private static ScanningStatus GetProgress(CommunicationObject communicationObject)
{
//byte[] bytes = MessagePackSerializer.Serialize(communicationObject, ContractlessStandardResolver.Options);
byte[] lol = JsonSerializer.SerializeToUtf8Bytes(communicationObject);
using RequestSocket client = new();
client.Connect("tcp://127.0.0.1:5556");
client.SendFrame(lol);
+3
View File
@@ -39,7 +39,10 @@ do
else if (string.Equals(input, "R"))
{
Console.WriteLine("Variable name.");
string? variable = Console.ReadLine();
Console.WriteLine("Variable value.");
string? value = Console.ReadLine();
if (string.IsNullOrWhiteSpace(variable) || string.IsNullOrWhiteSpace(value))
Binary file not shown.
Binary file not shown.
Binary file not shown.
+278 -55
View File
@@ -1,4 +1,5 @@
using System.Collections.Concurrent;
using System.Diagnostics;
using Microsoft.Data.Sqlite;
using Models.Model.Backend;
using Models.Model.External;
@@ -7,8 +8,10 @@ namespace Models.Handler;
public class DbHandler
{
private readonly ConcurrentQueue<QueueItem> _contentQueue;
private readonly ConcurrentQueue<Filtered> _filteredQueue;
private readonly ConcurrentQueue<UnfilteredQueueItem> _unfilteredQueue;
private readonly ConcurrentQueue<Discarded> _discardedQueue;
private readonly ConcurrentQueue<ScannerResumeObject> _resumeQueue;
private readonly string _unfilteredConnectionString;
private readonly string _discardedConnectionString;
@@ -16,15 +19,67 @@ public class DbHandler
private readonly string _resumeConnectionString;
private readonly List<string> _discardedConnectionStrings = [];
private const string InsertStatement = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off; INSERT INTO Unfiltered (Ip, ResponseCode, Port1, Port2, Filtered) VALUES (@ip, @responseCode, @port1, @port2, @filtered)";
private const string InsertIntoFiltered = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off; INSERT INTO Filtered (Ip, Port1, Port2, Title1, Title2, Description1, Description2, Url1, Url2, ServerType1, ServerType2, RobotsTXT1, RobotsTXT2, HttpVersion1, HttpVersion2, CertificateIssuerCountry, CertificateOrganizationName, IpV6, TlsVersion, CipherSuite, KeyExchangeAlgorithm, PublicKeyType1, PublicKeyType2, PublicKeyType3, AcceptEncoding1, AcceptEncoding2, ALPN, Connection1, Connection2) VALUES (@ip, @port1, @port2, @title1, @title2, @description1, @description2, @url1, @url2, @serverType1, @serverType2, @robotsTXT1, @robotsTXT2, @httpVersion1, @httpVersion2, @certificateIssuerCountry, @certificateOrganizationName, @ipV6, @tlsVersion, @cipherSuite, @keyExchangeAlgorithm, @publicKeyType1, @publicKeyType2, @publicKeyType3, @acceptEncoding1, @acceptEncoding2, @aLPN, @connection1, @connection2)";
private const string InsertIntoDiscarded = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off; INSERT INTO Discarded (Ip, ResponseCode) VALUES (@ip, @responseCode)";
private const string InsertIntoResume = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off; INSERT INTO Resume (ThreadNumber, StartRange, EndRange, FirstByte, SecondByte, ThirdByte, FourthByte) VALUES (@threadNumber, @startRange, @endRange, @firstByte, @secondByte, @thirdByte, @fourthByte);";
private const string InsertStatement = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;" +
" PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off;" +
" INSERT INTO Unfiltered (Ip1, Ip2, Ip3, Ip4, Port1, Port2, Filtered)" +
" VALUES (@ip1, @ip2, @ip3, @ip4, @port1, @port2, @filtered)";
private const string InsertIntoFiltered = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;" +
" PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = on;" +
" INSERT INTO Filtered (Ip1, Ip2, Ip3, Ip4, Port1, Port2, Title1, Title2," +
" Description1, Description2, Url1, Url2, ServerType1, ServerType2," +
" RobotsTXT1, RobotsTXT2, HttpVersion1, HttpVersion2, CertificateIssuerCountry," +
" CertificateOrganizationName, IpV6, TlsVersion, CipherSuite, KeyExchangeAlgorithm," +
" PublicKeyType1, PublicKeyType2, PublicKeyType3, AcceptEncoding1, AcceptEncoding2," +
" ALPN, Connection1, Connection2) VALUES (@ip1, @ip2, @ip3, @ip4, @port1, @port2, " +
" @title1, @title2, @description1, @description2, @url1, @url2, " +
" (SELECT ServerId FROM ServerType WHERE Type = @serverType1), " +
" (SELECT ServerId FROM ServerType WHERE Type = @serverType2), " +
" @robotsTXT1, @robotsTXT2," +
" (SELECT HttpId FROM HttpVersion WHERE Version = @httpVersion1)," +
" (SELECT HttpId FROM HttpVersion WHERE Version = @httpVersion2)," +
" (SELECT CertificateIssuerId FROM CertificateIssuerCountry WHERE Country = @certificateIssuerCountry)," +
" (SELECT CertificateOrganizationId FROM CertificateOrganizationName WHERE Name = @certificateOrganizationName), " +
" @ipV6, " +
" (SELECT TlsId FROM TlsVersion WHERE Version = @tlsVersion)," +
" (SELECT CipherId FROM CipherSuite WHERE Suite = @cipherSuite)," +
" (SELECT KeyExchangeId FROM KeyExchangeAlgorithm WHERE Algorithm = @keyExchangeAlgorithm)," +
" (SELECT PublicKeyId FROM PublicKeyType WHERE Type = @publicKeyType1)," +
" (SELECT PublicKeyId FROM PublicKeyType WHERE Type = @publicKeyType2)," +
" (SELECT PublicKeyId FROM PublicKeyType WHERE Type = @publicKeyType3)," +
" (SELECT AcceptId FROM AcceptEncoding WHERE Encoding = @acceptEncoding1)," +
" (SELECT AcceptId FROM AcceptEncoding WHERE Encoding = @acceptEncoding2)," +
" (SELECT ALPNId FROM ALPN WHERE ALPNValue = @aLPN)," +
" (SELECT ConnectionId FROM Connection WHERE ConnectionValue = @connection1)," +
" (SELECT ConnectionId FROM Connection WHERE ConnectionValue = @connection2))";
private const string InsertIntoFilteredServerType = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO ServerType (Type) VALUES (@type)";
private const string InsertIntoFilteredHttpVersion = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO HttpVersion (Version) VALUES (@version)";
private const string InsertIntoFilteredCertificateIssuerCountry = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO CertificateIssuerCountry (Country) VALUES (@country)";
private const string InsertIntoFilteredCertificateOrganizationName = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO CertificateOrganizationName (Name) VALUES (@name)";
private const string InsertIntoFilteredTlsVersion = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO TlsVersion (Version) VALUES (@version)";
private const string InsertIntoFilteredCipherSuite = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO CipherSuite (Suite) VALUES (@suite)";
private const string InsertIntoFilteredKeyExchangeAlgorithm = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO KeyExchangeAlgorithm (Algorithm) VALUES (@algorithm)";
private const string InsertIntoFilteredPublicKeyType = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO PublicKeyType (Type) VALUES (@type)";
private const string InsertIntoFilteredAcceptEncoding = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO AcceptEncoding (Encoding) VALUES (@encoding)";
private const string InsertIntoFilteredALPN = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO ALPN (ALPNValue) VALUES (@alpnValue)";
private const string InsertIntoFilteredConnection = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY; PRAGMA journal_mode = MEMORY; INSERT OR IGNORE INTO Connection (ConnectionValue) VALUES (@connectionValue)";
private const string InsertIntoDiscarded = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;" +
" PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off;" +
" INSERT INTO Discarded (Ip1, Ip2, Ip3, Ip4, ResponseCode)" +
" VALUES (@ip1, @ip2, @ip3, @ip4, @responseCode)";
private const string InsertIntoResume = "PRAGMA synchronous = OFF; PRAGMA temp_store = MEMORY;" +
" PRAGMA journal_mode = MEMORY; PRAGMA foreign_keys = off;" +
" INSERT INTO Resume (ThreadNumber, StartRange, EndRange, FirstByte, SecondByte, ThirdByte, FourthByte)" +
" VALUES (@threadNumber, @startRange, @endRange, @firstByte, @secondByte, @thirdByte, @fourthByte);";
private const string ReadUnfilteredStatement = "SELECT * FROM Unfiltered WHERE Id = @id;";
private const string ReadUnfilteredIdsStatement = "SELECT Id FROM Unfiltered WHERE Id != 0 ORDER BY Id DESC LIMIT 1;";
private const string ReadUnfilteredIdsStatement = "SELECT Id FROM Unfiltered WHERE Filtered == 0;";
private const string ReadFilteredStatement = "SELECT Title2, Url2 FROM Filtered WHERE (Url2 NOT NULL AND Url2 != '') AND (Title2 NOT NULL AND Title2 != '') ORDER BY Url2 DESC;";
private const string ReadFilteredIdsStatement = "SELECT Id FROM Filtered WHERE Id != 0 ORDER BY Id DESC LIMIT 1;";
private const string ReadFilteredIpStatement = "SELECT Ip1, Ip2, Ip3, Ip4 FROM Filtered WHERE Ip1 == @ip1 AND Ip2 == @ip1 AND Ip3 == @ip1 AND Ip4 == @ip1 ORDER BY Ip1 DESC LIMIT 1;";
private const string ReadDiscardedSeqIdsStatement = "SELECT seq FROM sqlite_sequence;";
private const string ReadAndDeleteResumeStatement = "SELECT * FROM Resume WHERE ThreadNumber == @threadNumber; DELETE FROM RESUME WHERE ThreadNumber == @threadNumber;";
@@ -46,12 +101,17 @@ public class DbHandler
private readonly string _basePath;
public DbHandler(ConcurrentQueue<QueueItem> contentQueue, ConcurrentQueue<Discarded> discardedQueue, string basePath)
public DbHandler(ConcurrentQueue<Filtered> filteredQueue,
ConcurrentQueue<Discarded> discardedQueue,
ConcurrentQueue<UnfilteredQueueItem> unfilteredQueue,
ConcurrentQueue<ScannerResumeObject> resumeQueue, string basePath)
{
_contentQueue = contentQueue;
_filteredQueue = filteredQueue;
_discardedQueue = discardedQueue;
_unfilteredQueue = unfilteredQueue;
_resumeQueue = resumeQueue;
SetContentWaitTime(10);
SetContentWaitTime(100);
SetDiscardedWaitTime(10);
_basePath = basePath;
@@ -72,41 +132,78 @@ public class DbHandler
_discardedWaitTime = waitTime;
}
public void StartContent()
public void UnfilteredDbHandler()
{
Console.WriteLine("Content DbHandler started");
Console.WriteLine("Unfiltered DbHandler started");
while (!_stop)
{
if (_contentQueue.IsEmpty || _pause)
if (_unfilteredQueue.IsEmpty || _pause)
{
Thread.Sleep(_contentWaitTime);
_paused = true;
continue;
}
_contentQueue.TryDequeue(out QueueItem? queueItem);
_unfilteredQueue.TryDequeue(out UnfilteredQueueItem queueItem);
if (queueItem is null) { continue; }
switch (queueItem.Operations)
if (queueItem.Operations == Operations.Insert)
{
case Operations.Insert when queueItem.Unfiltered is not null:
InsertUnfiltered(queueItem.Unfiltered);
break;
case Operations.Insert when queueItem.Filtered is not null:
InsertFiltered(queueItem.Filtered);
break;
case Operations.Insert when queueItem.ResumeObject is not null:
InsertResumeObject(queueItem.ResumeObject);
break;
case Operations.Update when queueItem.Unfiltered is not null:
UpdateUnfiltered(queueItem.Unfiltered);
break;
InsertUnfiltered(queueItem.Unfiltered);
}
else if (queueItem.Operations == Operations.Update)
{
UpdateUnfiltered(queueItem.Unfiltered);
}
}
Console.WriteLine("Content DbHandler stopped.");
Console.WriteLine("Unfiltered DbHandler stopped.");
}
public void FilteredDbHandler()
{
Console.WriteLine("Filtered DB handler started");
while (!_stop)
{
if (_filteredQueue.IsEmpty || _pause)
{
Thread.Sleep(_contentWaitTime);
_paused = true;
continue;
}
_filteredQueue.TryDequeue(out Filtered? queueItem);
InsertFiltered(queueItem!);
}
Console.WriteLine("Filtered DbHandler stopped.");
}
public void ResumeDbHandler()
{
Console.WriteLine("Resume DB handler started");
while (!_stop)
{
if (_resumeQueue.IsEmpty || _pause)
{
Thread.Sleep(_contentWaitTime);
_paused = true;
continue;
}
_resumeQueue.TryDequeue(out ScannerResumeObject? queueItem);
if (queueItem is not null)
{
InsertResumeObject(queueItem);
}
}
Console.WriteLine("Resume DbHandler stopped.");
}
public WaitHandle[] Start(int threads)
@@ -125,7 +222,7 @@ public class DbHandler
waitHandles[i] = handle;
Thread f = new (RunDiscarded!);
Thread f = new (DiscardedDbHandler!);
f.Start(discardedDbHandlerSetting);
Thread.Sleep(1000);
@@ -134,7 +231,7 @@ public class DbHandler
return waitHandles;
}
private void RunDiscarded(object obj)
private void DiscardedDbHandler(object obj)
{
DiscardedDbHandlerSetting discardedDbHandlerSetting = (DiscardedDbHandlerSetting)obj;
Console.WriteLine($"Discarded DbHandler started with thread: ({discardedDbHandlerSetting.ThreadId})");
@@ -150,16 +247,14 @@ public class DbHandler
continue;
}
_discardedQueue.TryDequeue(out Discarded? queueItem);
if (queueItem is null) { continue; }
_discardedQueue.TryDequeue(out Discarded queueItem);
InsertDiscarded(queueItem, connectionString);
}
discardedDbHandlerSetting.Handle!.Set();
Console.WriteLine("Content DbHandler stopped.");
Console.WriteLine("Discarded DbHandler stopped.");
}
private void InsertUnfiltered(Unfiltered unfiltered)
@@ -169,8 +264,10 @@ public class DbHandler
using SqliteCommand command = new(InsertStatement, connection);
command.Parameters.AddWithValue("@ip", unfiltered.Ip);
command.Parameters.AddWithValue("@responseCode", unfiltered.ResponseCode);
command.Parameters.AddWithValue("@ip1", unfiltered.Ip.Ip1);
command.Parameters.AddWithValue("@ip2", unfiltered.Ip.Ip2);
command.Parameters.AddWithValue("@ip3", unfiltered.Ip.Ip3);
command.Parameters.AddWithValue("@ip4", unfiltered.Ip.Ip4);
command.Parameters.AddWithValue("@port1", unfiltered.Port1);
command.Parameters.AddWithValue("@port2", unfiltered.Port2);
command.Parameters.AddWithValue("@filtered", unfiltered.Filtered);
@@ -186,7 +283,10 @@ public class DbHandler
using SqliteCommand command = new(InsertIntoDiscarded, connection);
command.Parameters.AddWithValue("@ip", discarded.Ip);
command.Parameters.AddWithValue("@ip1", discarded.Ip.Ip1);
command.Parameters.AddWithValue("@ip2", discarded.Ip.Ip2);
command.Parameters.AddWithValue("@ip3", discarded.Ip.Ip3);
command.Parameters.AddWithValue("@ip4", discarded.Ip.Ip4);
command.Parameters.AddWithValue("@responseCode", discarded.ResponseCode);
_ = command.ExecuteNonQuery();
@@ -198,9 +298,79 @@ public class DbHandler
using SqliteConnection connection = new(_filteredConnectionString);
connection.Open();
using SqliteCommand command = new(InsertIntoFiltered, connection);
SqliteCommand command = new(InsertIntoFilteredServerType, connection);
command.Parameters.AddWithValue("@type", filtered.ServerType1);
_ = command.ExecuteNonQuery();
command.Parameters.AddWithValue("@ip", filtered.Ip);
command = new(InsertIntoFilteredServerType, connection);
command.Parameters.AddWithValue("@type", filtered.ServerType2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredHttpVersion, connection);
command.Parameters.AddWithValue("@version", filtered.HttpVersion1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredHttpVersion, connection);
command.Parameters.AddWithValue("@version", filtered.HttpVersion2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredCertificateIssuerCountry, connection);
command.Parameters.AddWithValue("@country", filtered.CertificateIssuerCountry);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredCertificateOrganizationName, connection);
command.Parameters.AddWithValue("@name", filtered.CertificateOrganizationName);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredTlsVersion, connection);
command.Parameters.AddWithValue("@version", filtered.TlsVersion);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredCipherSuite, connection);
command.Parameters.AddWithValue("@suite", filtered.CipherSuite);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredKeyExchangeAlgorithm, connection);
command.Parameters.AddWithValue("@algorithm", filtered.KeyExchangeAlgorithm);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredPublicKeyType, connection);
command.Parameters.AddWithValue("@type", filtered.PublicKeyType1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredPublicKeyType, connection);
command.Parameters.AddWithValue("@type", filtered.PublicKeyType2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredPublicKeyType, connection);
command.Parameters.AddWithValue("@type", filtered.PublicKeyType3);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredAcceptEncoding, connection);
command.Parameters.AddWithValue("@encoding", filtered.AcceptEncoding1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredAcceptEncoding, connection);
command.Parameters.AddWithValue("@encoding", filtered.AcceptEncoding2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredALPN, connection);
command.Parameters.AddWithValue("@alpnValue", filtered.ALPN);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredConnection, connection);
command.Parameters.AddWithValue("@connectionValue", filtered.Connection1);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFilteredConnection, connection);
command.Parameters.AddWithValue("@connectionValue", filtered.Connection2);
_ = command.ExecuteNonQuery();
command = new(InsertIntoFiltered, connection);
command.Parameters.AddWithValue("@ip1", filtered.Ip.Ip1);
command.Parameters.AddWithValue("@ip2", filtered.Ip.Ip2);
command.Parameters.AddWithValue("@ip3", filtered.Ip.Ip3);
command.Parameters.AddWithValue("@ip4", filtered.Ip.Ip4);
command.Parameters.AddWithValue("@port1", filtered.Port1);
command.Parameters.AddWithValue("@port2", filtered.Port2);
command.Parameters.AddWithValue("@url1", filtered.Url1);
@@ -229,8 +399,9 @@ public class DbHandler
command.Parameters.AddWithValue("@aLPN", filtered.ALPN);
command.Parameters.AddWithValue("@connection1", filtered.Connection1);
command.Parameters.AddWithValue("@connection2", filtered.Connection2);
_ = command.ExecuteNonQuery();
command.Dispose();
connection.Close();
}
@@ -266,7 +437,7 @@ public class DbHandler
connection.Close();
}
public Unfiltered? ReadUnfilteredWithId(long id)
public Unfiltered ReadUnfilteredWithId(long id)
{
using SqliteConnection connection = new(_unfilteredConnectionString);
connection.Open();
@@ -275,26 +446,30 @@ public class DbHandler
command.Parameters.AddWithValue("@id", id);
using SqliteDataReader reader = command.ExecuteReader();
if (!reader.HasRows) return null;
if (!reader.HasRows) return new();
Unfiltered unfiltered = new();
Ip ip = new();
while (reader.Read())
{
unfiltered.Id = reader.GetInt32(0);
unfiltered.Ip = reader.GetString(1);
unfiltered.Port1 = reader.GetInt32(3);
unfiltered.Port2 = reader.GetInt32(4);
unfiltered.Filtered = reader.GetInt32(5);
ip.Ip1 = reader.GetInt32(1);
ip.Ip2 = reader.GetInt32(2);
ip.Ip3 = reader.GetInt32(3);
ip.Ip4 = reader.GetInt32(4);
unfiltered.Port1 = reader.GetInt32(5);
unfiltered.Port2 = reader.GetInt32(6);
unfiltered.Filtered = reader.GetBoolean(7);
}
unfiltered.Ip = ip;
return unfiltered;
}
public long GetUnfilteredIndexes()
public List<long> GetUnfilteredIndexes()
{
long rowId = 0;
using SqliteConnection connection = new(_unfilteredConnectionString);
connection.Open();
@@ -303,15 +478,17 @@ public class DbHandler
if (!reader.HasRows)
{
return 0;
return [];
}
List<long> ids = [];
while (reader.Read())
{
rowId = reader.GetInt64(0);
ids.Add(reader.GetInt64(0));
}
return rowId;
return ids;
}
public long GetFilteredIndexes()
@@ -363,8 +540,54 @@ public class DbHandler
return rowId;
}
public bool GetFilteredIp(string ip)
public bool FilteredIpExists(Ip ip)
{
using SqliteConnection connection = new(_filteredConnectionString);
connection.Open();
using SqliteCommand command = new(ReadFilteredIpStatement, connection);
command.Parameters.AddWithValue("@ip1", ip.Ip1);
command.Parameters.AddWithValue("@ip2", ip.Ip2);
command.Parameters.AddWithValue("@ip3", ip.Ip3);
command.Parameters.AddWithValue("@ip4", ip.Ip4);
using SqliteDataReader reader = command.ExecuteReader();
if (!reader.HasRows)
{
return false;
}
Ip tempIp = new();
while (reader.Read())
{
tempIp.Ip1 = reader.GetInt32(0);
tempIp.Ip2 = reader.GetInt32(1);
tempIp.Ip3 = reader.GetInt32(2);
tempIp.Ip4 = reader.GetInt32(3);
}
if (tempIp.Ip1 != ip.Ip1)
{
return false;
}
if (tempIp.Ip2 != ip.Ip2)
{
return false;
}
if (tempIp.Ip3 != ip.Ip3)
{
return false;
}
if (tempIp.Ip4 != ip.Ip4)
{
return false;
}
return true;
}
@@ -513,7 +736,7 @@ public class DbHandler
{
string databaseName = $"Data Source={_basePath}/Models/Discarded{threadNumber}.db";
const string createStatement = "CREATE TABLE IF NOT EXISTS Discarded (Id INTEGER NOT NULL, Ip TEXT NOT NULL, ResponseCode INTEGER NOT NULL, PRIMARY KEY(Id AUTOINCREMENT))";
const string createStatement = "CREATE TABLE IF NOT EXISTS Discarded (Id INTEGER NOT NULL, Ip1 INTEGER NOT NULL, Ip2 INTEGER NOT NULL, Ip3 INTEGER NOT NULL, Ip4 INTEGER NOT NULL, ResponseCode INTEGER NOT NULL, PRIMARY KEY(Id AUTOINCREMENT))";
_discardedConnectionStrings.Add(databaseName);
+3 -2
View File
@@ -1,7 +1,8 @@
namespace Models.Model.Backend;
public class Discarded
public struct Discarded
{
public string Ip { get; set; } = "";
public Ip Ip { get; set; }
public int ResponseCode { get; set; }
}
+1 -1
View File
@@ -2,7 +2,7 @@ namespace Models.Model.Backend;
public class Filtered
{
public string Ip { get; set; } = "";
public Ip Ip { get; set; }
public string Title1 { get; set; } = "";
public string Title2 { get; set; } = "";
public string Description1 { get; set; } = "";
+17
View File
@@ -0,0 +1,17 @@
namespace Models.Model.Backend;
public struct Ip
{
public int Ip1 { get; set; }
public int Ip2 { get; set; }
public int Ip3 { get; set; }
public int Ip4 { get; set; }
public override string ToString()
{
return $"{Ip1}.{Ip2}.{Ip3}.{Ip4}";
}
}
-1
View File
@@ -4,5 +4,4 @@ public enum Operations
{
Insert,
Update,
Optimize,
}
-9
View File
@@ -1,9 +0,0 @@
namespace Models.Model.Backend;
public class QueueItem
{
public Unfiltered? Unfiltered { get; init; }
public Filtered? Filtered { get; init; }
public ScannerResumeObject? ResumeObject { get; init; }
public Operations Operations { get; init; }
}
+3 -5
View File
@@ -1,16 +1,14 @@
namespace Models.Model.Backend;
public class Unfiltered
public struct Unfiltered
{
public int Id { get; set; }
public string Ip { get; set; } = "";
public int ResponseCode { get; init; }
public Ip Ip { get; set; }
public int Port1 { get; set; }
public int Port2 { get; set; }
public int Filtered { get; set; }
public bool Filtered { get; set; }
}
@@ -0,0 +1,7 @@
namespace Models.Model.Backend;
public struct UnfilteredQueueItem
{
public Unfiltered Unfiltered { get; init; }
public Operations Operations { get; init; }
}
-1
View File
@@ -8,6 +8,5 @@
<ItemGroup>
<PackageReference Include="Microsoft.Data.Sqlite" Version="8.0.10" />
<PackageReference Include="SQLite" Version="3.13.0" />
</ItemGroup>
</Project>
-3
View File
@@ -1,3 +0,0 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cbackend/@EntryIndexedValue">False</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=models_005Cinternal/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
+112
View File
@@ -0,0 +1,112 @@
VACUUM;
CREATE TABLE IF NOT EXISTS "ServerType" (
"ServerId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Type" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "HttpVersion" (
"HttpId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Version" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "CertificateIssuerCountry" (
"CertificateIssuerId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Country" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "CertificateOrganizationName" (
"CertificateOrganizationId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Name" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "TlsVersion" (
"TlsId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Version" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "CipherSuite" (
"CipherId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Suite" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "KeyExchangeAlgorithm" (
"KeyExchangeId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Algorithm" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "PublicKeyType" (
"PublicKeyId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Type" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "AcceptEncoding" (
"AcceptId" INTEGER PRIMARY KEY AUTOINCREMENT,
"Encoding" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "ALPN" (
"ALPNId" INTEGER PRIMARY KEY AUTOINCREMENT,
"ALPNValue" TEXT NOT NULL UNIQUE
);
CREATE TABLE IF NOT EXISTS "Connection" (
"ConnectionId" INTEGER PRIMARY KEY AUTOINCREMENT,
"ConnectionValue" TEXT NOT NULL UNIQUE
);
DROP TABLE Filtered;
CREATE TABLE "Filtered" (
"Id" INTEGER NOT NULL,
"Ip1" INTEGER NOT NULL,
"Ip2" INTEGER NOT NULL,
"Ip3" INTEGER NOT NULL,
"Ip4" INTEGER NOT NULL,
"Port1" INTEGER NOT NULL,
"Port2" INTEGER NOT NULL,
"Title1" TEXT NOT NULL,
"Title2" TEXT NOT NULL,
"Description1" TEXT NOT NULL,
"Description2" TEXT NOT NULL,
"Url1" TEXT NOT NULL,
"Url2" TEXT NOT NULL,
"ServerType1" INTEGER NOT NULL,
"ServerType2" INTEGER NOT NULL,
"RobotsTXT1" TEXT NOT NULL,
"RobotsTXT2" TEXT NOT NULL,
"HttpVersion1" INTEGER NOT NULL,
"HttpVersion2" INTEGER NOT NULL,
"CertificateIssuerCountry" INTEGER NOT NULL,
"CertificateOrganizationName" INTEGER NOT NULL,
"IpV6" TEXT NOT NULL,
"TlsVersion" INTEGER NOT NULL,
"CipherSuite" INTEGER NOT NULL,
"KeyExchangeAlgorithm" INTEGER NOT NULL,
"PublicKeyType1" INTEGER NOT NULL,
"PublicKeyType2" INTEGER NOT NULL,
"PublicKeyType3" INTEGER NOT NULL,
"AcceptEncoding1" INTEGER NOT NULL,
"AcceptEncoding2" INTEGER NOT NULL,
"ALPN" INTEGER NOT NULL,
"Connection1" INTEGER NOT NULL,
"Connection2" INTEGER NOT NULL,
PRIMARY KEY("Id" AUTOINCREMENT),
FOREIGN KEY("ALPN") REFERENCES "ALPN"("ALPNId"),
FOREIGN KEY("AcceptEncoding1") REFERENCES "AcceptEncoding"("AcceptId"),
FOREIGN KEY("AcceptEncoding2") REFERENCES "AcceptEncoding"("AcceptId"),
FOREIGN KEY("CertificateIssuerCountry") REFERENCES "CertificateIssuerCountry"("CertificateIssuerId"),
FOREIGN KEY("CertificateOrganizationName") REFERENCES "CertificateOrganizationName"("CertificateOrganizationId"),
FOREIGN KEY("CipherSuite") REFERENCES "CipherSuite"("CipherId"),
FOREIGN KEY("Connection1") REFERENCES "Connection"("ConnectionId"),
FOREIGN KEY("Connection2") REFERENCES "Connection"("ConnectionId"),
FOREIGN KEY("HttpVersion1") REFERENCES "HttpVersion"("HttpId"),
FOREIGN KEY("HttpVersion2") REFERENCES "HttpVersion"("HttpId"),
FOREIGN KEY("KeyExchangeAlgorithm") REFERENCES "KeyExchangeAlgorithm"("KeyExchangeId"),
FOREIGN KEY("PublicKeyType1") REFERENCES "PublicKeyType"("PublicKeyId"),
FOREIGN KEY("PublicKeyType2") REFERENCES "PublicKeyType"("PublicKeyId"),
FOREIGN KEY("PublicKeyType3") REFERENCES "PublicKeyType"("PublicKeyId"),
FOREIGN KEY("ServerType1") REFERENCES "ServerType"("ServerId"),
FOREIGN KEY("ServerType2") REFERENCES "ServerType"("ServerId"),
FOREIGN KEY("TlsVersion") REFERENCES "TlsVersion"("TlsId")
)
+13
View File
@@ -0,0 +1,13 @@
DROP TABLE Unfiltered;
CREATE TABLE "Unfiltered" (
"Id" INTEGER NOT NULL,
"Ip1" INTEGER NOT NULL,
"Ip2" INTEGER NOT NULL,
"Ip3" INTEGER NOT NULL,
"Ip4" INTEGER NOT NULL,
"Port1" INTEGER NOT NULL,
"Port2" INTEGER NOT NULL,
"Filtered" INTEGER NOT NULL,
CONSTRAINT "PK_Unfiltered" PRIMARY KEY("Id" AUTOINCREMENT)
)
+5 -26
View File
@@ -1,27 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000006pdb6Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003Fd17d4b69379a42eb90f15b17ef6c846a5400_003F39_003F1eeed291_003F02000006pdb6Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000007pdb1Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F096da63313a8436fb75089601a728c765200_003Fbb_003Ff6383783_003F02000007pdb1Low_002Ecs_002Fz_003A2_002D1/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000007pdb1Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F357247e747614c8297021dd08d79da3d5200_003Ff2_003Fc4ae8c87_003F02000007pdb1Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000010pdb3Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F80cf8253b0c2409096d0c0e368300af28200_003Fdd_003F8098fc19_003F02000010pdb3Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000011pdb4Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F1f6cfdd1e3a14f6390237f6ab98b06af8000_003F0d_003Febdca535_003F02000011pdb4Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAttributes_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F9a4cb3a98df697f884fa5f45bc79e4291fa3e948c7f42560e14678e12055e_003FAttributes_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAttribute_002ECoreCLR_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fbb9be2cb8efb72a7d2286fbdd10a293b55b3e2a912f49fac6a7719673268e4b_003FAttribute_002ECoreCLR_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConcurrentQueue_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fb049a159646b52d2dd6ced21de315f79dff86421243e94ffd4f29c6f7e4df25_003FConcurrentQueue_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AConsole_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F2ccd2056ec55b7b67558d52e32a887ed5ac7e346fc429b218c188d0a99cb5be_003FConsole_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFormatters_002EMessagePack_002EGeneratedMessagePackResolver_002EModels_002EModel_002EExternal_002ECommunicationObjectFormatter_002Eg_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F5029ca69753a60cb407b1053f5834320dadee066_003FFormatters_002EMessagePack_002EGeneratedMessagePackResolver_002EModels_002EModel_002EExternal_002ECommunicationObjectFormatter_002Eg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFormatters_002EMessagePack_002EGeneratedMessagePackResolver_002EModels_002EModel_002EExternal_002ESearchResultsFormatter_002Eg_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F99b5d033f8bfb58a6a753ca88a3d956f2228bd48_003FFormatters_002EMessagePack_002EGeneratedMessagePackResolver_002EModels_002EModel_002EExternal_002ESearchResultsFormatter_002Eg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFuture_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F13cbfe6856867dd1ed4e39575e46d816dae2a146a8ceec8f76b5897f5e0fe_003FFuture_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpContent_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F5a55e5df9328b51021ba85b8f12ff49eca8772dba9772c0d61d5e28edf255c_003FHttpContent_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpMethodAttribute_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F2e4732e712a98f9ac0d080ac68669b3db6d98781e0d5ad89886cb6bcc890b18_003FHttpMethodAttribute_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIFormatterResolver_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fc7d856f45ddf907f9face6c2bdba7836cc70fed4bb2b8ebd83ee6917584af3_003FIFormatterResolver_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIOThread_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F125fae6d49819da7be4fb21fbb4a936a7ec325971cf9264a24af55bf7111ad8_003FIOThread_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIPStatus_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8fe420eaf60c4dfca87ce1d5f1cdfa4816200_003Fbd_003F71bcce16_003FIPStatus_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMessagePackReader_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F5cffb8c94881849b6aa8abe7ba5e7cafe05d991f859903020362d6aac371_003FMessagePackReader_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMessagePackSerializer_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fe5f8b0187e62d74a4b9fefd657c192dab367bb342ef5ffbd90a4ed2ea428ec7a_003FMessagePackSerializer_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APingOptions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F77bf2fbffc5491eadd62f1dbebc233798cd7fcb9b39ab7ee3bb35519f4d94ecc_003FPingOptions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APing_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F3080b18e3637ea741b5b65abd6aee06e41494a82a58b3e2ed87d4ddb5cc62_003FPing_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APing_002EUnix_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F8d57f5f5fd3290d6a89a5b767ad89988dd893c988eba430cd461b8b88d7ad9d_003FPing_002EUnix_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARep_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Feea8e921c916164ccc376e162da148b8215450dfae96e08bdd29119165c67f_003FRep_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AReq_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F33fafcc2bb6e91ae8abb5a52936d39cd93951ad9208861e758ca93efa619eaf3_003FReq_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATask_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F35f3a54f5acb408a3e219b2de039f1a39557b7e4515f11238cba07b60c0ce_003FTask_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextWriter_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fdda89b2ed0975050b6847325357a756a5866a5435e3ddb4feff535ba36facb7_003FTextWriter_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A0200000Cpdb6Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003Fb53c196a821648e4ae3b142a6ae58d7b9400_003Fa8_003F21a43479_003F0200000Cpdb6Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003A02000011pdb3Low_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FDecompilerCache_003FILViewer_003F7c3ed02c2ce44598b7f304f8ac45e58f8600_003F6d_003F99b875d1_003F02000011pdb3Low_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADirectoryInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fe4ec446cfe0489bc3ef68a45c6766d183e999ebdc657e94fb1ad059de2bb9_003FDirectoryInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AHttpResponseMessage_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F85e97f467d698c9e98eae9e3a1b39d58541173e57992d8f7111eabdd3db3526_003FHttpResponseMessage_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AThread_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E2_003Fresharper_002Dhost_003FSourcesCache_003F693e634d7742afaf486acd69d84fe2a9e1ee1b11ba84f29cd1d67668d20dd59_003FThread_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
View File