diff --git a/Protest/Database/Database.cs b/Protest/Database/Database.cs index b5300129..c0a49d1e 100644 --- a/Protest/Database/Database.cs +++ b/Protest/Database/Database.cs @@ -42,16 +42,21 @@ public record Entry { private long lastCachedVersion = -1; private Cache.Entry lastCached; - private readonly JsonSerializerOptions databaseSerializerOptions = new(); - private readonly JsonSerializerOptions attrubutesSerializerOptions = new(); - private readonly JsonSerializerOptions attrubutesSerializerOptionsWithPassword = new(); - private readonly JsonSerializerOptions contactsSerializerOptions = new(); + private readonly JsonSerializerOptions databaseSerializerOptions; + private readonly JsonSerializerOptions attrubutesSerializerOptions; + private readonly JsonSerializerOptions attrubutesSerializerOptionsWithPassword; + private readonly JsonSerializerOptions contactsSerializerOptions; public Database(string name, string location) { this.name = name; this.location = location; dictionary = new ConcurrentDictionary(); + databaseSerializerOptions = new JsonSerializerOptions(); + attrubutesSerializerOptions = new JsonSerializerOptions(); + attrubutesSerializerOptionsWithPassword = new JsonSerializerOptions(); + contactsSerializerOptions = new JsonSerializerOptions(); + databaseSerializerOptions.Converters.Add(new DatabaseJsonConverter(name, location, true)); attrubutesSerializerOptions.Converters.Add(new AttributesJsonConverter(true)); attrubutesSerializerOptionsWithPassword.Converters.Add(new AttributesJsonConverter(false)); diff --git a/Protest/Front/oversight.js b/Protest/Front/oversight.js index 07c8850a..3bdb422e 100644 --- a/Protest/Front/oversight.js +++ b/Protest/Front/oversight.js @@ -143,9 +143,9 @@ class Oversight extends Window { this.socket.send(this.params.file); this.ConsoleLog("Web-socket connection established", "info"); - this.socket.send("ping=true"); - this.socket.send("cpu=true"); - this.socket.send("cores=true"); + //this.socket.send("ping=true"); + //this.socket.send("cpu=true"); + //this.socket.send("cores=true"); if (this.hideConsoleOnce) { this.hideConsoleOnce = false; @@ -477,21 +477,28 @@ class Oversight extends Window { btnOK.addEventListener("click", ()=> { //TODO: this.count++; - this.socket.send(`addwmi=${queryInput.value}&id=${this.count}`); - chartsList.push(""); + //this.socket.send(`wmi=${queryInput.value}&id=${this.count}`); + + this.socket.send(JSON.stringify({ + action: "addwmi", + value: queryInput.value, + id: this.count + })); + + this.chartsList.push(""); }); } Start() { if (!this.socket) return; - this.socket.send("start"); + this.socket.send("{\"action\":\"start\"}"); this.startButton.disabled = true; this.pauseButton.disabled = false; } Pause() { if (!this.socket) return; - this.socket.send("pause"); + this.socket.send("{\"action\":\"pause\"}"); this.startButton.disabled = false; this.pauseButton.disabled = true; } diff --git a/Protest/Front/ui.css b/Protest/Front/ui.css index af55d88d..0bb18f3c 100644 --- a/Protest/Front/ui.css +++ b/Protest/Front/ui.css @@ -169,10 +169,11 @@ } .menufilter-option:hover { background-color: var(--clr-transparent); - + border: var(--clr-transparent) 1px solid; } .menufilter-option:active { background-color: color-mix(in hsl shorter hue, var(--clr-transparent) 85%, rgba(0,0,0,.6)); + border: var(--clr-transparent) 1px solid; } #menufilterdot { @@ -226,6 +227,7 @@ background-position: center 8px; background-repeat: no-repeat; background-color: #80808030; + box-shadow: #484848 0 0 0 1px inset; transition: .15s; } @@ -247,6 +249,7 @@ background-position: 4px 4px; background-repeat: no-repeat; background-color: #80808030; + box-shadow: #484848 0 0 0 1px inset; transition: .15s; } @@ -254,11 +257,13 @@ .menu-grid-item:hover, .menu-list-item:hover { background-color: var(--clr-transparent) !important; + box-shadow: var(--clr-transparent) 0 0 0 1px inset; } .menu-grid-item:active, .menu-list-item:active { background-color: color-mix(in hsl shorter hue, var(--clr-transparent) 85%, rgba(0,0,0,.6)) !important; + box-shadow: var(--clr-transparent) 0 0 0 1px inset; } #btnPersonalize, #btnLogout { @@ -322,7 +327,6 @@ opacity: 0; } - #username:focus-within > #btnLogout { visibility: visible; opacity: 1; @@ -330,16 +334,20 @@ #username:focus-within > #lblUsername { right: 48px; background-color: var(--clr-transparent) !important; + border: var(--clr-transparent) 1px solid; } #lblUsername:focus { background-color: var(--clr-transparent) !important; + border: var(--clr-transparent) 1px solid; } #lblUsername:hover, #btnPersonalize:hover, #btnLogout:hover { background-color: var(--clr-transparent); + border: var(--clr-transparent) 1px solid; } #lblUsername:active, #btnPersonalize:active, #btnLogout:active { background-color: color-mix(in hsl shorter hue, var(--clr-transparent) 85%, rgba(0,0,0,.6)) !important; + border: var(--clr-transparent) 1px solid; } #contextmenu { diff --git a/Protest/Front/ui.js b/Protest/Front/ui.js index 5f72423f..c9fd1895 100644 --- a/Protest/Front/ui.js +++ b/Protest/Front/ui.js @@ -17,8 +17,9 @@ const UI = { } //automatically disable animations if prefers-reduced-motion - if (window.matchMedia('(prefers-reduced-motion)').matches && localStorage.getItem("animations") === null) + if (window.matchMedia('(prefers-reduced-motion)').matches && localStorage.getItem("animations") === null) { localStorage.setItem("animations", "false"); + } WIN.always_maxed = localStorage.getItem("w_always_maxed") === "true"; taskbar.className = localStorage.getItem("w_tasktooltip") === "false" ? "no-tooltip" : ""; diff --git a/Protest/Http/Auth.cs b/Protest/Http/Auth.cs index 41fb8ac8..ce1ce9b5 100644 --- a/Protest/Http/Auth.cs +++ b/Protest/Http/Auth.cs @@ -12,7 +12,7 @@ internal static class Auth { private const long HOUR = 36_000_000_000L; private const long SESSION_TIMEOUT = 120L * HOUR; //5 days - private static readonly JsonSerializerOptions serializerOptions = new(); + private static readonly JsonSerializerOptions serializerOptions; internal static readonly ConcurrentDictionary acl = new(); internal static readonly ConcurrentDictionary sessions = new(); @@ -37,6 +37,7 @@ public record Session { } static Auth() { + serializerOptions = new JsonSerializerOptions(); serializerOptions.Converters.Add(new AccessControlJsonConverter()); } diff --git a/Protest/Http/Cache.cs b/Protest/Http/Cache.cs index 16390c66..656d37fd 100644 --- a/Protest/Http/Cache.cs +++ b/Protest/Http/Cache.cs @@ -6,11 +6,11 @@ //#define SVG_TO_SVGZ #define SVG_TO_LIGHT +using System.Collections.Concurrent; +using System.Collections.Generic; using System.IO; using System.IO.Compression; -using System.Collections.Generic; using System.Text; -using System.Collections.Concurrent; using System.Threading; namespace Protest.Http; @@ -87,7 +87,7 @@ public Cache(string path) { LoadFiles(); #if DEBUG - Console.WriteLine("Front end cache:"); + Console.WriteLine("Front-end cache:"); if (_gzip > 0) { Console.WriteLine($" GZip : {100 * _gzip / (_raw + 1),5}% {_raw,10} -> {_gzip,8}"); } if (_deflate > 0) { Console.WriteLine($" Deflate : {100 * _deflate / (_raw + 1),5}% {_raw,10} -> {_deflate,8}"); } if (_brotli > 0) { Console.WriteLine($" Brotli : {100 * _brotli / (_raw + 1),5}% {_raw,10} -> {_brotli,8}"); } diff --git a/Protest/Http/KeepAlive.cs b/Protest/Http/KeepAlive.cs index 836b9a4d..a1a465b0 100644 --- a/Protest/Http/KeepAlive.cs +++ b/Protest/Http/KeepAlive.cs @@ -23,9 +23,10 @@ private struct Entry { private static readonly ConcurrentDictionary connections = new(); - private static readonly JsonSerializerOptions messageSerializerOptions = new(); + private static readonly JsonSerializerOptions messageSerializerOptions; static KeepAlive() { + messageSerializerOptions = new JsonSerializerOptions(); messageSerializerOptions.Converters.Add(new MessageJsonConverter()); } diff --git a/Protest/Tasks/Fetch.cs b/Protest/Tasks/Fetch.cs index eace5ef2..cb74d11b 100644 --- a/Protest/Tasks/Fetch.cs +++ b/Protest/Tasks/Fetch.cs @@ -33,12 +33,13 @@ struct Result { public int unsuccessful; } - private static readonly JsonSerializerOptions fetchSerializerOptions = new(); + private static readonly JsonSerializerOptions fetchSerializerOptions; public static TaskWrapper task; private static Result? result; static Fetch() { + fetchSerializerOptions = new JsonSerializerOptions(); fetchSerializerOptions.Converters.Add(new FetchedDataJsonConverter()); } diff --git a/Protest/Tools/DebitNotes.cs b/Protest/Tools/DebitNotes.cs index c6a75ae7..eeef367c 100644 --- a/Protest/Tools/DebitNotes.cs +++ b/Protest/Tools/DebitNotes.cs @@ -10,7 +10,7 @@ namespace Protest.Tools; internal static class DebitNotes { static private readonly object syncLock = new object(); - static private readonly JsonSerializerOptions debitSerializerOptions = new(); + static private readonly JsonSerializerOptions debitSerializerOptions; public record Device { public string description; @@ -34,6 +34,7 @@ public record Record { } static DebitNotes() { + debitSerializerOptions = new JsonSerializerOptions(); debitSerializerOptions.Converters.Add(new DebitJsonConverter()); } diff --git a/Protest/Tools/LocateIp.cs b/Protest/Tools/LocateIp.cs index 7d8ffafa..37e957d7 100644 --- a/Protest/Tools/LocateIp.cs +++ b/Protest/Tools/LocateIp.cs @@ -9,10 +9,13 @@ namespace Protest.Tools; internal static class LocateIp { - static private readonly JsonSerializerOptions locationDerializerOptions = new(); - static private readonly JsonSerializerOptions locationDerializerOptionsOnlyLocation = new(); + static private readonly JsonSerializerOptions locationDerializerOptions; + static private readonly JsonSerializerOptions locationDerializerOptionsOnlyLocation; static LocateIp() { + locationDerializerOptions = new JsonSerializerOptions(); + locationDerializerOptionsOnlyLocation = new JsonSerializerOptions(); + locationDerializerOptions.Converters.Add(new IP2LApiJsonConverter(false)); locationDerializerOptionsOnlyLocation.Converters.Add(new IP2LApiJsonConverter(true)); } diff --git a/Protest/Tools/Oversight.cs b/Protest/Tools/Oversight.cs index 0b07a69e..6bd0f12f 100644 --- a/Protest/Tools/Oversight.cs +++ b/Protest/Tools/Oversight.cs @@ -1,6 +1,5 @@ -using System.Net.WebSockets; -using System.Net; -using System.Text; +using System.Net; +using System.Net.WebSockets; using System.Threading; using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; @@ -9,11 +8,38 @@ using System.Management; using System.Collections.Generic; using System.Data; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; using Protest.Http; namespace Protest.Tools; -internal class Oversight { +internal static class Oversight { + public enum Action { + none, + start, + pause, + interval, + addicmp, + addwmi, + addsnmp, + remove + } + + public struct Query { + public Action action; + public string value; + public int id; + } + + private static JsonSerializerOptions actionSerializerOptions; + + static Oversight() { + actionSerializerOptions = new JsonSerializerOptions(); + actionSerializerOptions.Converters.Add(new ActionJsonConverter()); + } + private static async void WsWriteText(WebSocket ws, [StringSyntax(StringSyntaxAttribute.Json)] string text) { if (ws.State != WebSocketState.Open) { return; } await ws.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(text), 0, text.Length), WebSocketMessageType.Text, true, CancellationToken.None); @@ -69,9 +95,9 @@ public static async void WebSocketHandler(HttpListenerContext ctx) { object sendSync = new object(); bool paused = false; - bool ping = false; - bool cpu = false; - bool cores = false; + bool ping = true; + bool cpu = true; + bool cores = true; int interval = 500; ConcurrentDictionary wmiQueries = new ConcurrentDictionary(); @@ -180,20 +206,37 @@ public static async void WebSocketHandler(HttpListenerContext ctx) { } string msg = Encoding.Default.GetString(buff, 0, receiveResult.Count); - string[] split = msg.Split("="); - string value = (split.Length > 1) ? split[1] : null; - - switch (split[0]) { - case "start": paused = false; break; - case "pause": paused = true; break; - - case "interval" : _ = int.TryParse(value, out interval); break; - case "ping" : ping = value == "true"; break; - case "cpu" : cpu = value == "true"; break; - case "cores" : cores = value == "true"; break; - case "processes" : break; - case "addwmi" : break; - case "removewmi" : break; + Console.WriteLine(msg); + + Query query = JsonSerializer.Deserialize(msg, actionSerializerOptions); + Console.WriteLine("ac:" + query.action); + Console.WriteLine("va:" + query.value); + Console.WriteLine("id:" + query.id); + + switch (query.action) { + case Action.start: + paused = false; + break; + + case Action.pause: + paused = true; + break; + + case Action.interval: + _ = int.TryParse(query.value, out interval); + break; + + case Action.addicmp: + break; + + case Action.addwmi: + break; + + case Action.addsnmp: + break; + + case Action.remove: + break; } } } @@ -222,11 +265,14 @@ private static long DoPing(string host, int timeout) { PingReply reply = p.Send(host, timeout); return (int)reply.Status switch { + (int)IPStatus.Success => reply.RoundtripTime, + (int)IPStatus.DestinationUnreachable or (int)IPStatus.DestinationHostUnreachable or (int)IPStatus.DestinationNetworkUnreachable => -1, - (int)IPStatus.Success => reply.RoundtripTime, + 11050 => -1, + _ => -1, }; } @@ -272,7 +318,6 @@ private static byte[] DoCpuCores(ManagementScope scope, bool getCores) { } return cores.ToArray(); - } catch { return null; @@ -288,3 +333,40 @@ private static byte[] DoWmi(ManagementScope scope, ConcurrentDictionary { + public override Oversight.Query Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + Oversight.Query action = new Oversight.Query(); + + while (reader.Read()) { + if (reader.TokenType == JsonTokenType.EndObject) { + break; + } + + if (reader.TokenType == JsonTokenType.PropertyName) { + string propertyName = reader.GetString(); + reader.Read(); + + switch (propertyName) { + case "action": action .action = Enum.Parse(reader.GetString()); break; + case "value" : action .value = reader.GetString(); break; + case "id" : action .id = reader.GetInt32(); break; + } + } + } + + return action ; + } + + public override void Write(Utf8JsonWriter writer, Oversight.Query value, JsonSerializerOptions options) { + ReadOnlySpan _action = "action".AsSpan(); + ReadOnlySpan _value = "value".AsSpan(); + ReadOnlySpan _id = stackalloc[] {'i', 'd'}; + + writer.WriteStartObject(); + writer.WriteString(_action, value.action.ToString()); + writer.WriteString(_value, value.value); + writer.WriteNumber(_id, value.id); + writer.WriteEndObject(); + } +} diff --git a/Protest/Tools/PasswordStrength.cs b/Protest/Tools/PasswordStrength.cs index a82a6df3..630b85c0 100644 --- a/Protest/Tools/PasswordStrength.cs +++ b/Protest/Tools/PasswordStrength.cs @@ -53,9 +53,10 @@ public static class PasswordStrength { "dragon" }; - static private readonly JsonSerializerOptions emailProfilesSerializerOptions = new(); + static private readonly JsonSerializerOptions emailProfilesSerializerOptions; static PasswordStrength() { + emailProfilesSerializerOptions = new JsonSerializerOptions(); emailProfilesSerializerOptions.Converters.Add(new SmtpProfilesJsonConverter(false)); } diff --git a/Protest/Tools/SmtpProfiles.cs b/Protest/Tools/SmtpProfiles.cs index 30c0176f..27224d2e 100644 --- a/Protest/Tools/SmtpProfiles.cs +++ b/Protest/Tools/SmtpProfiles.cs @@ -8,8 +8,8 @@ namespace Protest.Tools; internal static class SmtpProfiles { - static readonly JsonSerializerOptions smtpProfileSerializerOptions = new(); - static readonly JsonSerializerOptions smtpProfileSerializerOptionsWithPasswords = new(); + static readonly JsonSerializerOptions smtpProfileSerializerOptions; + static readonly JsonSerializerOptions smtpProfileSerializerOptionsWithPasswords; public record Profile { public string server; @@ -23,6 +23,9 @@ public record Profile { } static SmtpProfiles() { + smtpProfileSerializerOptions = new JsonSerializerOptions(); + smtpProfileSerializerOptionsWithPasswords = new JsonSerializerOptions(); + smtpProfileSerializerOptions.Converters.Add(new SmtpProfilesJsonConverter(true)); smtpProfileSerializerOptionsWithPasswords.Converters.Add(new SmtpProfilesJsonConverter(false)); }