diff --git a/SharpENDEC/App.config b/SharpENDEC/App.config
index 560f8b5..883ef30 100644
--- a/SharpENDEC/App.config
+++ b/SharpENDEC/App.config
@@ -1,13 +1,13 @@
-
+
-
-
+
+
-
+
@@ -141,12 +141,12 @@
-
+
-
+
@@ -154,4 +154,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SharpENDEC/ENDEC/AlertProcessor.cs b/SharpENDEC/ENDEC/AlertProcessor.cs
index 255838c..e1ccb3b 100644
--- a/SharpENDEC/ENDEC/AlertProcessor.cs
+++ b/SharpENDEC/ENDEC/AlertProcessor.cs
@@ -1,11 +1,15 @@
-using SharpENDEC.Properties;
+using NAudio.Wave.SampleProviders;
+using NAudio.Wave;
+using SharpENDEC.Properties;
using System;
using System.Collections.Generic;
-using System.Drawing;
+using System.Globalization;
using System.IO;
+using System.Linq;
+using System.Net.Http;
+using System.Speech.Synthesis;
using System.Text.RegularExpressions;
using System.Threading;
-using System.Threading.Tasks;
namespace SharpENDEC
{
@@ -33,37 +37,52 @@ public static void AlertProcessor()
public static void ProcessAlertItem(SharpDataItem relayItem)
{
- bool IsUI = Settings.Default.WirelessAlertMode;
- foreach (Match match in Regex.Matches(relayItem.Data, @"([^<]+)\s*([^<]+)", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline))
+ // check if file is even valid
+ if (!relayItem.Data.StartsWith("\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- Match statusMatch = Regex.Match(relayItem.Data, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- Match messageTypeMatch = Regex.Match(relayItem.Data, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- MatchCollection broadcastImmediatelyMatches = Regex.Matches(relayItem.Data, @"layer:SOREM:1.0:Broadcast_Immediately\s*\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- MatchCollection urgencyMatches = Regex.Matches(relayItem.Data, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- MatchCollection severityMatches = Regex.Matches(relayItem.Data, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ //bool IsUI = Settings.Default.WirelessAlertMode;
+ //foreach (Match match in ValueNameRegex.Matches(relayItem.Data))
+ //{
+ // if (match.Groups[1].Value == "layer:SOREM:2.0:WirelessText")
+ // {
+ // if (!string.IsNullOrWhiteSpace(match.Groups[2].Value))
+ // {
+ // IsUI = true;
+ // break;
+ // }
+ // }
+
+ // //ConsoleExt.WriteLine($"valueName: {match.Groups[1].Value}");
+ // //ConsoleExt.WriteLine($"value: {match.Groups[2].Value}");
+ //}
+
+ Match sentMatch = SentRegex.Match(relayItem.Data);
+ Match statusMatch = StatusRegex.Match(relayItem.Data);
+ Match messageTypeMatch = MessageTypeRegex.Match(relayItem.Data);
+ MatchCollection broadcastImmediatelyMatches = BroadcastImmediatelyRegex.Matches(relayItem.Data);
+ MatchCollection urgencyMatches = UrgencyRegex.Matches(relayItem.Data);
+ MatchCollection severityMatches = InfoRegex.Matches(relayItem.Data);
bool final = false;
for (int i = 0; i < severityMatches.Count; i++)
{
- if (Check.Config(relayItem.Data, statusMatch.Groups[1].Value, messageTypeMatch.Groups[1].Value, severityMatches[i].Groups[1].Value, urgencyMatches[i].Groups[1].Value, broadcastImmediatelyMatches[i].Groups[1].Value))
+ try
{
- final = true;
- break;
+ if (Check.Config(relayItem.Data, statusMatch.Groups[1].Value, messageTypeMatch.Groups[1].Value, severityMatches[i].Groups[1].Value, urgencyMatches[i].Groups[1].Value, broadcastImmediatelyMatches[i].Groups[1].Value))
+ {
+ final = true;
+ break;
+ }
+ }
+ catch (Exception e)
+ {
+ ConsoleExt.WriteLineErr($"[Alert Processor] An incompatible or damaged XML was detected, and won't be processed further. {e.Message}");
+ return;
}
}
@@ -73,7 +92,7 @@ public static void ProcessAlertItem(SharpDataItem relayItem)
return;
}
- MatchCollection infoMatches = Regex.Matches(relayItem.Data, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ MatchCollection infoMatches = InfoRegex.Matches(relayItem.Data);
int infoProc = 0;
foreach (Match infoMatch in infoMatches)
@@ -82,7 +101,7 @@ public static void ProcessAlertItem(SharpDataItem relayItem)
ConsoleExt.WriteLine($"[Alert Processor] {LanguageStrings.GenericProcessingValueOfValue(Settings.Default.CurrentLanguage, infoProc, infoMatches.Count)}");
string infoEN = $"{infoMatch.Groups[1].Value}";
string lang = "en";
- if (Regex.Match(infoEN, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value == "fr-CA")
+ if (LanguageRegex.Match(infoEN).Groups[1].Value == "fr-CA")
{
lang = "fr";
}
@@ -93,12 +112,13 @@ public static void ProcessAlertItem(SharpDataItem relayItem)
string Status = statusMatch.Groups[1].Value;
string MsgType = messageTypeMatch.Groups[1].Value;
- string EventType = Regex.Match(infoEN, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value;
- string urgency = Regex.Match(infoEN, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value;
- string severity = Regex.Match(infoEN, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value;
- //string when = Regex.Match(@"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value;
+ Match effectiveMatch = EffectiveRegex.Match(relayItem.Data);
+ Match expiryMatch = ExpiresRegex.Match(relayItem.Data);
+ string EventType = EventRegex.Match(infoEN).Groups[1].Value;
+ string urgency = UrgencyRegex.Match(infoEN).Groups[1].Value;
+ string severity = SeverityRegex.Match(infoEN).Groups[1].Value;
string broadcastImmediately;
- Match broadcastImmediatelyMatch = Regex.Match(infoEN, @"layer:SOREM:1.0:Broadcast_Immediately\s*\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ Match broadcastImmediatelyMatch = BroadcastImmediatelyRegex.Match(infoEN);
if (broadcastImmediatelyMatch.Success)
{
broadcastImmediately = broadcastImmediatelyMatch.Groups[1].Value;
@@ -110,107 +130,140 @@ public static void ProcessAlertItem(SharpDataItem relayItem)
EventDetails EventInfo = GetEventDetails(EventType);
- ConsoleExt.WriteLine(Status, ConsoleColor.DarkGray);
- ConsoleExt.WriteLine(MsgType, ConsoleColor.DarkGray);
- ConsoleExt.WriteLine($"{EventType} | {EventInfo.FriendlyName}", ConsoleColor.DarkGray);
- ConsoleExt.WriteLine(urgency, ConsoleColor.DarkGray);
- ConsoleExt.WriteLine(severity, ConsoleColor.DarkGray);
- ConsoleExt.WriteLine(broadcastImmediately, ConsoleColor.DarkGray);
- ConsoleExt.WriteLine(sentMatch.Groups[1].Value, ConsoleColor.DarkGray);
+ ConsoleExt.WriteLine($"Status: {Status}", ConsoleColor.Green);
+ ConsoleExt.WriteLine($"Message Type: {MsgType}", ConsoleColor.Green);
+ ConsoleExt.WriteLine($"Event Type: {EventType}", ConsoleColor.Green);
+ ConsoleExt.WriteLine($"Urgency: {urgency}", ConsoleColor.Green);
+ ConsoleExt.WriteLine($"Severity: {severity}", ConsoleColor.Green);
+ ConsoleExt.WriteLine($"Broadcast Immediately: {broadcastImmediately}", ConsoleColor.Green);
+ ConsoleExt.WriteLine($"Sent: {sentMatch.Groups[1].Value}", ConsoleColor.Green);
+ ConsoleExt.WriteLine($"Effective: {effectiveMatch.Groups[1].Value}", ConsoleColor.Green);
+ ConsoleExt.WriteLine($"Expires: {expiryMatch.Groups[1].Value}", ConsoleColor.Green);
+
+ if (DateTime.Parse(expiryMatch.Groups[1].Value, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal) <= DateTime.Now)
+ {
+ ConsoleExt.WriteLine($"[Alert Processor] {LanguageStrings.AlertIgnoredDueToExpiry(Settings.Default.CurrentLanguage)}", ConsoleColor.DarkGray);
+ continue;
+ }
bool Stop = false;
if (Check.Config(infoEN, statusMatch.Groups[1].Value, MsgType, severity, urgency, broadcastImmediately))
{
+ //foreach (var handler in handlers)
+ //{
+ // var handlerInstance = (ISharpPlugin)Activator.CreateInstance(handler);
+ // if (!handlerInstance.RelayAlert(infoEN, statusMatch.Groups[1].Value, MsgType, severity, urgency, broadcastImmediately))
+ // Stop = true;
+ //}
+
foreach (string EventName in Settings.Default.EnforceEventBlacklist)
{
if (EventType.ToLower() == EventName.ToLower())
{
Stop = true;
+ break;
}
}
if (Stop)
{
ConsoleExt.WriteLine($"[Alert Processor] {LanguageStrings.AlertIgnoredDueToBlacklist(Settings.Default.CurrentLanguage)}", ConsoleColor.DarkGray);
+ //foreach (var handler in handlers)
+ //{
+ // var handlerInstance = (ISharpPlugin)Activator.CreateInstance(handler);
+ // handlerInstance.AlertBlacklisted();
+ //}
continue;
}
ConsoleExt.WriteLine($"[Alert Processor] {LanguageStrings.GeneratingProductText(Settings.Default.CurrentLanguage)}");
Generate gen = new Generate(infoEN, MsgType, sentMatch.Groups[1].Value);
-
var info = gen.BroadcastInfo(lang);
//if (true) //(!string.IsNullOrWhiteSpace(info.BroadcastText))
{
//ConsoleExt.WriteLine($"[Alert Processor] {LanguageStrings.GeneratingProductAudio}");
File.WriteAllText($"{AssemblyDirectory}\\inactive-text.txt", string.Empty);
- File.WriteAllText($"{AssemblyDirectory}\\active-text.txt", $"{info.BroadcastText}\x20");
- File.WriteAllText($"{AssemblyDirectory}\\static-text.txt", $"{info.BroadcastText}\x20");
+ File.WriteAllText($"{AssemblyDirectory}\\active-text.txt", $"{info}\x20");
+ File.WriteAllText($"{AssemblyDirectory}\\static-text.txt", $"{info}\x20");
- ConsoleExt.WriteLine($"[Alert Processor] -> {info.BroadcastText}", ConsoleColor.Magenta);
+ ConsoleExt.WriteLine($"[Alert Processor] -> {info}", ConsoleColor.Magenta);
- gen.GenerateAudio(info.BroadcastText, lang);
+ //foreach (var handler in handlers)
+ //{
+ // var handlerInstance = (ISharpPlugin)Activator.CreateInstance(handler);
+ // handlerInstance.ProvideBroadcastText(info.BroadcastText);
+ //}
- if (IsUI)
- {
- Color BackColor;
- Color ForeColor;
+ gen.GenerateAudio(info, lang);
- switch (severity.ToLower())
- {
- case "extreme":
- BackColor = Color.Red;
- ForeColor = Color.Yellow;
- break;
- case "severe":
- BackColor = Color.OrangeRed;
- ForeColor = Color.Black;
- break;
- case "moderate":
- BackColor = Color.Gold;
- ForeColor = Color.Black;
- break;
- case "minor":
- BackColor = Color.LightGreen;
- ForeColor = Color.Black;
- break;
- case "unknown":
- default:
- BackColor = Color.White;
- ForeColor = Color.Black;
- break;
- }
+ //foreach (var handler in handlers)
+ //{
+ // var handlerInstance = (ISharpPlugin)Activator.CreateInstance(handler);
+ // handlerInstance.AlertRelayingNow(info.BroadcastText);
+ //}
- //Task.Run(() =>
- //{
- // AlertForm af = new AlertForm
- // {
- // PlayAudio = () => Play($"{AudioDirectory}\\audio.wav"),
- // EventBackColor = BackColor,
- // EventForeColor = ForeColor,
- // EventTextContent = EventInfo.FriendlyName
- // };
- // af.Show();
- //}).Wait(30000);
-
- Task.Run(() =>
- {
- NotifyOverlay no = new NotifyOverlay
- {
- EventShortInfoText = $"{EventInfo.FriendlyName}",
- EventLongInfoText = $"{info.BroadcastText}",
- EventTypeText = $"{EventInfo.FriendlyName}"
- };
- no.ShowDialog();
- }).Wait(30000);
- }
- else
+ //if (IsUI)
+ //{
+ // Color BackColor;
+ // Color ForeColor;
+
+ // switch (severity.ToLower())
+ // {
+ // case "extreme":
+ // BackColor = Color.Red;
+ // ForeColor = Color.Yellow;
+ // break;
+ // case "severe":
+ // BackColor = Color.OrangeRed;
+ // ForeColor = Color.Black;
+ // break;
+ // case "moderate":
+ // BackColor = Color.Gold;
+ // ForeColor = Color.Black;
+ // break;
+ // case "minor":
+ // BackColor = Color.LightGreen;
+ // ForeColor = Color.Black;
+ // break;
+ // case "unknown":
+ // default:
+ // BackColor = Color.White;
+ // ForeColor = Color.Black;
+ // break;
+ // }
+
+ // //Task.Run(() =>
+ // //{
+ // // AlertForm af = new AlertForm
+ // // {
+ // // PlayAudio = () => Play($"{AudioDirectory}\\audio.wav"),
+ // // EventBackColor = BackColor,
+ // // EventForeColor = ForeColor,
+ // // EventTextContent = EventInfo.FriendlyName
+ // // };
+ // // af.Show();
+ // //}).Wait(30000);
+
+ // Task.Run(() =>
+ // {
+ // NotifyOverlay no = new NotifyOverlay
+ // {
+ // EventShortInfoText = $"{EventInfo.FriendlyName}",
+ // EventLongInfoText = $"{info}",
+ // EventTypeText = $"{EventInfo.FriendlyName}"
+ // };
+ // no.ShowDialog();
+ // }).Wait(30000);
+ //}
+ //else
{
+
ConsoleExt.WriteLine($"[Alert Processor] {LanguageStrings.PlayingAudio(Settings.Default.CurrentLanguage)}");
ConsoleExt.WriteLine($"[Alert Processor] {Play($"{AudioDirectory}\\in.wav").AudioLength.TotalMilliseconds} millisecond(s) played");
- if (EventInfo.Severity.Contains("Severe") || EventInfo.Severity.Contains("Extreme"))
+ if (EventInfo.Severity.ToLower().Contains("severe") || EventInfo.Severity.ToLower().Contains("extreme"))
ConsoleExt.WriteLine($"[Alert Processor] {Play($"{AudioDirectory}\\attn.wav").AudioLength.TotalMilliseconds} millisecond(s) played.");
else
{
@@ -226,7 +279,7 @@ public static void ProcessAlertItem(SharpDataItem relayItem)
}
File.WriteAllText($"{AssemblyDirectory}\\active-text.txt", string.Empty);
- File.WriteAllText($"{AssemblyDirectory}\\inactive-text.txt", $"{info.BroadcastText}\x20");
+ File.WriteAllText($"{AssemblyDirectory}\\inactive-text.txt", $"{info}\x20");
}
//else
//{
@@ -240,5 +293,691 @@ public static void ProcessAlertItem(SharpDataItem relayItem)
}
//ConsoleExt.WriteLine("[Alert Processor] Processed all available entries.", ConsoleColor.DarkGray);
}
+
+ public class Generate
+ {
+ private readonly string InfoData;
+ private readonly string MsgType;
+ private readonly string Sent;
+ //private readonly string Effective;
+ //private readonly string Expires;
+
+ public Generate(string InfoDataZ, string MsgTypeZ, string SentDate)
+ {
+ InfoData = InfoDataZ;
+ MsgType = MsgTypeZ;
+ Sent = SentDate;
+ //Effective = EffectiveDate;
+ //Expires = ExpiryDate;
+ }
+
+ public string BroadcastInfo(string lang)
+ {
+ string BroadcastText = "";
+
+ string SentenceAppendEnd(string value)
+ {
+ value = value.Trim();
+ if (value.EndsWith(".") || value.EndsWith("!") || value.EndsWith(",")) return value;
+ else return value += ".";
+ }
+
+ string SentenceAppendSpace(string value)
+ {
+ value = value.Trim();
+ if (string.IsNullOrWhiteSpace(value)) return string.Empty;
+ else return value += "\x20";
+ }
+
+ string SentencePuncuationCorrection(string value)
+ {
+ value = value.Trim();
+ while (value.EndsWith("\x20.") || value.EndsWith("\x20,"))
+ {
+ value = value.Substring(0, value.Length - 1);
+ }
+ return value = SentenceAppendEnd(value.Substring(0, value.Length - 2));
+ }
+
+ string issue, update, cancel;
+ if (lang == "fr")
+ {
+ issue = "émis";
+ update = "mis à jour";
+ cancel = "annulé";
+ }
+ else
+ {
+ issue = "issued";
+ update = "updated";
+ cancel = "cancelled";
+ }
+
+ string MsgPrefix;
+ switch (MsgType.ToLower())
+ {
+ case "alert":
+ MsgPrefix = issue;
+ break;
+ case "update":
+ MsgPrefix = update;
+ break;
+ case "cancel":
+ MsgPrefix = cancel;
+ break;
+ default:
+ MsgPrefix = "issued";
+ break;
+ }
+
+ DateTime sentDate;
+ try
+ {
+ sentDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
+ }
+ catch (Exception e)
+ {
+ ConsoleExt.WriteLine(e.Message);
+ sentDate = DateTime.Now;
+ }
+
+ DateTime effectiveDate;
+ try
+ {
+ effectiveDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
+ }
+ catch (Exception e)
+ {
+ ConsoleExt.WriteLine(e.Message);
+ effectiveDate = DateTime.Now;
+ }
+
+ DateTime expiryDate;
+ try
+ {
+ expiryDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
+ }
+ catch (Exception e)
+ {
+ ConsoleExt.WriteLine(e.Message);
+ expiryDate = DateTime.Now.AddHours(1);
+ }
+
+ //DateTime sentDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal).ToUniversalTime();
+
+ string TimeZoneName = "Unknown Time Zone";
+
+ switch (lang)
+ {
+ case "fr":
+ //TimeZoneName = OffsetToTimeZoneName(int.Parse(sentISO));
+ TimeZoneName = "Temps Universel Coordonné";
+ break;
+ case "en":
+ default:
+ //TimeZoneName = OffsetToTimeZoneName(int.Parse(sentISO));
+ TimeZoneName = "Coordinated Universal Time";
+ break;
+ }
+
+ string SentFormatted = lang == "fr" ? $"{sentDate:HH}'{sentDate:h}'{sentDate:mm} {TimeZoneName}" : $"{sentDate:HH:mm} {TimeZoneName}, {sentDate:MMMM dd}, {sentDate:yyyy}";
+ string BeginFormatted = lang == "fr" ? $"{effectiveDate:HH}'{effectiveDate:h}'{effectiveDate:mm} {TimeZoneName}" : $"{effectiveDate:HH:mm} {TimeZoneName}, {effectiveDate:MMMM dd}, {effectiveDate:yyyy}";
+ string EndFormatted = lang == "fr" ? $"{expiryDate:HH}'{expiryDate:h}'{expiryDate:mm} {TimeZoneName}" : $"{expiryDate:HH:mm} {TimeZoneName}, {expiryDate:MMMM dd}, {expiryDate:yyyy}";
+
+ string EventType;
+ try
+ {
+ EventType = EventTypeRegex.Match(InfoData).Groups[1].Value;
+ EventType = Regex.Replace(EventType.ToLower(), @"(^\w)|(\s\w)", m => m.Value.ToUpper());
+ EventType = lang == "fr" ? $"Le type d'événement est {EventType}." : $"Event type is {EventType}.";
+ }
+ catch (Exception)
+ {
+ EventType = lang == "fr" ? $"Le type d'événement n'a pas été spécifié." : $"Event type is not known.";
+ }
+
+ string Coverage;
+ try
+ {
+ Coverage = CoverageRegex.Match(InfoData).Groups[1].Value;
+ Coverage = lang == "fr" ? $"Pour {Coverage} :" : $"For {Coverage}:";
+ }
+ catch (Exception)
+ {
+ Coverage = lang == "fr" ? "Pour :" : "For:";
+ }
+
+ string[] areaDescMatches = AreaDescriptionRegex.Matches(InfoData)
+ .Cast()
+ .Select(m => m.Groups[1].Value)
+ .ToArray();
+
+ string AreaDesc = string.Join(", ", areaDescMatches) + ".";
+
+ string SenderName;
+
+ try
+ {
+ SenderName = SenderNameRegex.Match(InfoData).Groups[1].Value;
+ }
+ catch (Exception)
+ {
+ SenderName = "an unknown issuer";
+ }
+
+ string Description;
+
+ try
+ {
+ Description = SentenceAppendEnd(DescriptionRegex.Match(InfoData).Groups[1].Value.Replace("\r\n", " ").Replace("\n", " "));
+ }
+ catch (Exception)
+ {
+ Description = "";
+ }
+
+ string Instruction;
+
+ try
+ {
+ Instruction = SentenceAppendEnd(InstructionRegex.Match(InfoData).Groups[1].Value.Replace("\r\n", " ").Replace("\n", " "));
+ }
+ catch (Exception)
+ {
+ Instruction = "";
+ }
+
+ string Effective;
+
+ try
+ {
+ Effective = effectiveDate.ToString();
+ }
+ catch (Exception)
+ {
+ Effective = "currently";
+ }
+
+ string Expiry;
+
+ try
+ {
+ Expiry = expiryDate.ToString();
+ }
+ catch (Exception)
+ {
+ Expiry = "soon";
+ }
+
+ // Effective {Effective}, and expiring {Expires}.
+
+ BroadcastText += SentenceAppendSpace(EventType);
+ BroadcastText += SentenceAppendSpace(Coverage);
+ BroadcastText += SentenceAppendSpace(SentenceAppendEnd(AreaDesc));
+
+ if (BeginFormatted != EndFormatted)
+ {
+ switch (lang)
+ {
+ case "fr":
+ BroadcastText += SentenceAppendSpace($"Alerte émise le {SentFormatted}, {MsgPrefix} par {SenderName}.");
+ BroadcastText += SentenceAppendSpace($"Cette alerte prend effet le {BeginFormatted}, et expire le {EndFormatted}.");
+ break;
+ case "en":
+ default:
+ BroadcastText += SentenceAppendSpace($"Alertez {MsgPrefix} sur {SentFormatted}, par {SenderName}.");
+ BroadcastText += SentenceAppendSpace($"This alert takes effect on {BeginFormatted}, and expires on {EndFormatted}.");
+ break;
+ }
+ }
+
+ BroadcastText += SentenceAppendSpace(SentenceAppendEnd(Description));
+ BroadcastText += SentenceAppendSpace(SentenceAppendEnd(Instruction));
+
+ Match match = BroadcastTextRegex.Match(InfoData);
+
+ if (match.Success)
+ {
+ BroadcastText = match.Groups[1].Value.Replace("\r\n", "\x20").Replace("\n", "\x20").Replace("\x20\x20\x20", "\x20").Replace("\x20\x20", "\x20").Trim();
+ }
+
+ BroadcastText = SentencePuncuationCorrection(BroadcastText.Replace("###", string.Empty).Replace("\x20\x20\x20", "\x20").Replace("\x20\x20", "\x20").Trim());
+ BroadcastText = SentenceAppendEnd(BroadcastText);
+
+ return BroadcastText;
+ }
+
+ //public string LegacyBroadcastInfo(string lang)
+ //{
+ // string BroadcastText = "";
+
+ // string SentenceAppendEnd(string value)
+ // {
+ // value = value.Trim();
+ // if (value.EndsWith(".") || value.EndsWith("!") || value.EndsWith(",")) return value;
+ // else return value += ".";
+ // }
+
+ // string SentenceAppendSpace(string value)
+ // {
+ // value = value.Trim();
+ // if (string.IsNullOrWhiteSpace(value)) return string.Empty;
+ // else return value += "\x20";
+ // }
+
+ // string SentencePuncuationCorrection(string value)
+ // {
+ // value = value.Trim();
+ // while (value.EndsWith("\x20.") ||
+ // value.EndsWith("\x20,") ||
+ // value.EndsWith("\x20!") ||
+ // value.EndsWith("\x20?") ||
+ // value.EndsWith("\x20?") ||
+ // value.EndsWith("\x20"))
+ // {
+ // value = value.Substring(0, value.Length - 1);
+ // }
+ // return value = SentenceAppendEnd(value.Substring(0, value.Length - 2));
+ // }
+
+ // Match match = BroadcastTextRegex.Match(InfoData);
+
+ // if (match.Success)
+ // {
+ // BroadcastText = match.Groups[1].Value.Replace("\r\n", "\x20").Replace("\n", "\x20").Replace("\x20\x20\x20", "\x20").Replace("\x20\x20", "\x20").Trim();
+ // }
+ // else
+ // {
+ // string issue, update, cancel;
+ // if (lang == "fr")
+ // {
+ // issue = "émis";
+ // update = "mis à jour";
+ // cancel = "annulé";
+ // }
+ // else
+ // {
+ // issue = "issued";
+ // update = "updated";
+ // cancel = "cancelled";
+ // }
+
+ // string MsgPrefix;
+ // switch (MsgType.ToLower())
+ // {
+ // case "alert":
+ // MsgPrefix = issue;
+ // break;
+ // case "update":
+ // MsgPrefix = update;
+ // break;
+ // case "cancel":
+ // MsgPrefix = cancel;
+ // break;
+ // default:
+ // MsgPrefix = "issued";
+ // break;
+ // }
+
+ // DateTime sentDate;
+ // try
+ // {
+ // sentDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
+ // }
+ // catch (Exception e)
+ // {
+ // ConsoleExt.WriteLine(e.Message);
+ // sentDate = DateTime.Now;
+ // }
+
+ // DateTime effectiveDate;
+ // try
+ // {
+ // effectiveDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
+ // }
+ // catch (Exception e)
+ // {
+ // ConsoleExt.WriteLine(e.Message);
+ // effectiveDate = DateTime.Now;
+ // }
+
+ // DateTime expiryDate;
+ // try
+ // {
+ // expiryDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
+ // }
+ // catch (Exception e)
+ // {
+ // ConsoleExt.WriteLine(e.Message);
+ // expiryDate = DateTime.Now.AddHours(1);
+ // }
+
+ // //DateTime sentDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToUniversalTime();
+
+ // string TimeZoneName = "Unknown Time Zone";
+
+ // string OffsetToTimeZoneName(int utcOffset)
+ // {
+ // utcOffset = +1;
+ // DateTime now = DateTime.UtcNow;
+ // List matchingTimeZones = new List();
+ // foreach (TimeZoneInfo tz in TimeZoneInfo.GetSystemTimeZones())
+ // {
+ // TimeSpan offset = tz.BaseUtcOffset;
+
+ // if (offset.Hours == utcOffset)
+ // {
+ // ConsoleExt.WriteLine($"{tz.DaylightName} {tz.DaylightName}", ConsoleColor.DarkGray);
+ // if (tz.IsDaylightSavingTime(now))
+ // {
+ // matchingTimeZones.Add(tz.DaylightName);
+ // }
+ // else
+ // {
+ // matchingTimeZones.Add(tz.StandardName);
+ // }
+ // }
+ // }
+
+ // return matchingTimeZones.Count > 0 ? matchingTimeZones[0] : $"UTC -{utcOffset}";
+ // }
+
+ // string sentISO = sentDate.ToString("zz");
+
+ // switch (lang)
+ // {
+ // case "fr":
+ // TimeZoneName = OffsetToTimeZoneName(int.Parse(sentISO));
+ // break;
+ // case "en":
+ // default:
+ // TimeZoneName = OffsetToTimeZoneName(int.Parse(sentISO));
+ // break;
+ // }
+
+ // string SentFormatted = lang == "fr" ? $"{sentDate:HH}'{sentDate:h}'{sentDate:mm} {TimeZoneName}." : $"{sentDate:HH:mm} {TimeZoneName}, {sentDate:MMMM dd}, {sentDate:yyyy}.";
+ // string BeginFormatted = lang == "fr" ? $"{effectiveDate:HH}'{effectiveDate:h}'{effectiveDate:mm} {TimeZoneName}." : $"{effectiveDate:HH:mm} {TimeZoneName}, {effectiveDate:MMMM dd}, {effectiveDate:yyyy}.";
+ // string EndFormatted = lang == "fr" ? $"{expiryDate:HH}'{expiryDate:h}'{expiryDate:mm} {TimeZoneName}." : $"{expiryDate:HH:mm} {TimeZoneName}, {expiryDate:MMMM dd}, {expiryDate:yyyy}.";
+
+ // string EventType;
+ // try
+ // {
+ // EventType = EventRegex.Match(InfoData).Groups[1].Value;
+ // }
+ // catch (Exception)
+ // {
+ // // why
+ // EventType = EventRegex.Match(InfoData).Groups[1].Value;
+ // EventType = lang == "fr" ? $"alerte {EventType}" : $"{EventType} alert";
+ // }
+
+ // string Coverage;
+ // try
+ // {
+ // Coverage = CoverageRegex.Match(InfoData).Groups[1].Value;
+ // Coverage = lang == "fr" ? $"en {Coverage} pour:" : $"in {Coverage} for:";
+ // }
+ // catch (Exception)
+ // {
+ // Coverage = lang == "fr" ? "pour:" : "for:";
+ // }
+
+ // string[] areaDescMatches = AreaDescriptionRegex.Matches(InfoData)
+ // .Cast()
+ // .Select(m => m.Groups[1].Value)
+ // .ToArray();
+
+ // string AreaDesc = string.Join(", ", areaDescMatches) + ".";
+
+ // string SenderName;
+
+ // try
+ // {
+ // SenderName = SenderNameRegex.Match(InfoData).Groups[1].Value;
+ // }
+ // catch (Exception)
+ // {
+ // SenderName = "an alert issuer";
+ // }
+
+ // string Description;
+
+ // try
+ // {
+ // Description = SentenceAppendEnd(DescriptionRegex.Match(InfoData).Groups[1].Value.Replace("\n", " "));
+ // }
+ // catch (Exception)
+ // {
+ // Description = "";
+ // }
+
+ // string Instruction;
+
+ // try
+ // {
+ // Instruction = SentenceAppendEnd(InstructionRegex.Match(InfoData).Groups[1].Value.Replace("\n", " "));
+ // }
+ // catch (Exception)
+ // {
+ // Instruction = "";
+ // }
+
+ // string Effective;
+
+ // try
+ // {
+ // Effective = effectiveDate.ToString();
+ // }
+ // catch (Exception)
+ // {
+ // Effective = "currently";
+ // }
+
+ // string Expiry;
+
+ // try
+ // {
+ // Expiry = expiryDate.ToString();
+ // }
+ // catch (Exception)
+ // {
+ // Expiry = "soon";
+ // }
+
+ // // Effective {Effective}, and expiring {Expires}.
+
+ // switch (lang)
+ // {
+ // case "fr":
+ // BroadcastText = SentenceAppendSpace("À");
+ // BroadcastText += SentenceAppendSpace(SentFormatted);
+ // BroadcastText += SentenceAppendSpace(SenderName);
+ // BroadcastText += SentenceAppendSpace("a");
+ // BroadcastText += SentenceAppendSpace(MsgPrefix);
+ // BroadcastText += SentenceAppendSpace("une");
+ // break;
+ // case "en":
+ // default:
+ // BroadcastText = SentenceAppendSpace("At");
+ // BroadcastText += SentenceAppendSpace(SentFormatted);
+ // BroadcastText += SentenceAppendSpace(SenderName);
+ // BroadcastText += SentenceAppendSpace("has");
+ // BroadcastText += SentenceAppendSpace(MsgPrefix);
+ // BroadcastText += SentenceAppendSpace("a");
+ // break;
+ // }
+ // BroadcastText += SentenceAppendSpace(EventType);
+ // BroadcastText += SentenceAppendSpace(Coverage);
+ // BroadcastText += SentenceAppendSpace(SentenceAppendEnd(AreaDesc));
+ // BroadcastText += SentenceAppendSpace(SentenceAppendEnd(Description));
+ // BroadcastText += SentenceAppendSpace(SentenceAppendEnd(Instruction));
+ // BroadcastText = SentencePuncuationCorrection(BroadcastText.Replace("###", string.Empty).Replace("\x20\x20\x20", "\x20").Replace("\x20\x20", "\x20").Trim());
+ // //BroadcastText = lang == "fr" ?
+ // // $"À {SentFormatted} {SenderName} a {MsgPrefix} une {EventType} {Coverage} {AreaDesc}. {Description} {Instruction}".Replace("###", "").Replace(" ", " ").Trim() :
+ // // $"At {SentFormatted} {SenderName} has {MsgPrefix} a {EventType} {Coverage} {AreaDesc}. {Description} {Instruction}".Replace("###", "").Replace(" ", " ").Trim();
+ // }
+
+ // BroadcastText = SentenceAppendEnd(BroadcastText);
+ // //if (BroadcastText.EndsWith("\x20.")) BroadcastText = BroadcastText.TrimEnd('\x20', '.');
+ // //if (BroadcastText.EndsWith(".")) BroadcastText = BroadcastText.TrimEnd('.');
+ // //if (!BroadcastText.EndsWith(".") || !BroadcastText.EndsWith("!")) BroadcastText += ".";
+
+ // return BroadcastText;
+ //}
+
+ public bool GetAudio(string audioLink, string output, int decodeType)
+ {
+ if (decodeType == 1)
+ {
+ ConsoleExt.WriteLine("Decoding audio from Base64.");
+ try
+ {
+ byte[] audioData = Convert.FromBase64String(audioLink);
+ File.WriteAllBytes(output, audioData);
+ return true;
+ }
+ catch (Exception ex)
+ {
+ ConsoleExt.WriteLine($"Decoder failed: {ex.Message}");
+ return false;
+ }
+ }
+ else if (decodeType == 0)
+ {
+ ConsoleExt.WriteLine("Downloading audio.");
+ try
+ {
+ using (HttpClient webClient = new HttpClient())
+ {
+ File.WriteAllBytes(output, webClient.GetByteArrayAsync(audioLink).Result);
+ }
+ return true;
+ }
+ catch (Exception ex)
+ {
+ ConsoleExt.WriteLine($"Downloader failed: {ex.Message}");
+ }
+ return false;
+ }
+ else
+ {
+ ConsoleExt.WriteLine("Invalid DecodeType specified.");
+ return false;
+ }
+ }
+
+ private readonly SpeechSynthesizer engine = new SpeechSynthesizer();
+
+ public void GenerateAudio(string text, string lang)
+ {
+ try
+ {
+ Match Resource = ResourceDescriptionRegex.Match(InfoData);
+ if (!Resource.Success) throw new Exception("[Alert Processor] Audio field not found. TTS will be generated instead.");
+ string broadcastAudioResource = Resource.Groups[1].Value;
+ string audioLink = string.Empty;
+ string audioType = string.Empty;
+ int decode = -1;
+
+ if (broadcastAudioResource.Contains(""))
+ {
+ Match Link = DerefURIRegex.Match(broadcastAudioResource);
+ Match Type = MimeRegex.Match(broadcastAudioResource);
+ decode = 1;
+ if (Link.Success && Type.Success)
+ {
+ audioLink = Link.Groups[1].Value;
+ audioType = Type.Groups[1].Value;
+ }
+ }
+ else
+ {
+ Match Link = TypeURIRegex.Match(broadcastAudioResource);
+ Match Type = MimeRegex.Match(broadcastAudioResource);
+ decode = 0;
+ if (Link.Success && Type.Success)
+ {
+ audioLink = Link.Groups[1].Value;
+ audioType = Type.Groups[1].Value;
+ }
+ }
+
+ ConsoleExt.WriteLine(audioLink);
+ //Thread.Sleep(5000);
+
+ string audioFile;
+ switch (audioType)
+ {
+ case "audio/mpeg":
+ audioFile = "PreAudio.mp3";
+ break;
+ case "audio/x-ms-wma":
+ audioFile = "PreAudio.wma";
+ break;
+ default:
+ audioFile = "PreAudio.wav";
+ break;
+ }
+
+ if (File.Exists($"{AudioDirectory}\\{audioFile}")) File.Delete($"{AudioDirectory}\\{audioFile}");
+ if (File.Exists($"{AudioDirectory}\\audio.wav")) File.Delete($"{AudioDirectory}\\audio.wav");
+
+ if (GetAudio(audioLink, audioFile, decode))
+ {
+ using (var audioFileReader = new AudioFileReader(audioFile))
+ {
+ var volumeSampleProvider = new VolumeSampleProvider(audioFileReader.ToSampleProvider())
+ {
+ Volume = 2.5f,
+ };
+ WaveFileWriter.CreateWaveFile16($"{AudioDirectory}\\audio.wav", volumeSampleProvider);
+ }
+
+ if (!File.Exists($"{AudioDirectory}\\audio.wav"))
+ {
+ ConsoleExt.WriteLine("Post processing failed.");
+ File.Move(audioFile, $"{AudioDirectory}\\audio.wav");
+ }
+
+ //string ffmpegCmd = $"{AssemblyDirectory}\\ffmpeg.exe -y -i {audioFile} -filter:a volume=2.5 {AssemblyDirectory.Replace("\\", "/")}/Audio/audio.wav";
+ //Process p = Process.Start("cmd.exe", $"/c {ffmpegCmd}");
+ //p.WaitForExit(12000);
+ //if (p.ExitCode != 0 || !File.Exists($"{AssemblyDirectory}\\Audio\\audio.wav"))
+ //{
+ // ConsoleExt.WriteLine("Post processing failed. Please make sure ffmpeg is in the program folder.");
+ // File.Move(audioFile, $"{AssemblyDirectory}\\Audio\\audio.wav");
+ //}
+ //new SoundPlayer($"{AssemblyDirectory}\\Audio\\audio.wav").PlaySync();
+ }
+ else
+ {
+ throw new Exception();
+ }
+ }
+ catch (Exception ex)
+ {
+ ConsoleExt.WriteLine(ex.Message);
+
+ //ConsoleExt.WriteLine(lang);
+ foreach (var voice in engine.GetInstalledVoices())
+ {
+ //ConsoleExt.WriteLine(voice.VoiceInfo.Culture.TwoLetterISOLanguageName.ToLower());
+ if (voice.VoiceInfo.Name.Contains(Settings.Default.SpeechVoice) && voice.VoiceInfo.Culture.TwoLetterISOLanguageName.ToLower() == lang)
+ {
+ //ConsoleExt.WriteLine(voice.VoiceInfo.Name, ConsoleColor.Magenta);
+ engine.SelectVoice(voice.VoiceInfo.Name);
+ break;
+ }
+ }
+
+ text = text.Replace("#", "hashtag\x20");
+ text = text.Replace("*", "star\x20");
+
+ engine.SetOutputToWaveFile($"{AudioDirectory}\\audio.wav");
+ engine.Speak(text);
+ engine.Dispose();
+ }
+ }
+ }
}
}
diff --git a/SharpENDEC/ENDEC/DataProcessor.cs b/SharpENDEC/ENDEC/DataProcessor.cs
index 88fbb28..b2d6606 100644
--- a/SharpENDEC/ENDEC/DataProcessor.cs
+++ b/SharpENDEC/ENDEC/DataProcessor.cs
@@ -1,18 +1,13 @@
-using NAudio.Wave.SampleProviders;
-using NAudio.Wave;
+using NAudio.Wave;
using SharpENDEC.Properties;
using System;
-using System.Drawing;
-using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
-using System.Speech.Synthesis;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using NAudio.Utils;
-using System.Collections.Generic;
namespace SharpENDEC
{
@@ -25,15 +20,24 @@ public static void DataProcessor()
while (true)
{
SharpDataItem relayItem = Check.WatchForItemsInList();
- ConsoleExt.WriteLine($"[Data Processor] {LanguageStrings.CapturedFromFileWatcher(Settings.Default.CurrentLanguage)}", ConsoleColor.Cyan);
+
+ if (relayItem.IsNull()) continue;
+
+ ConsoleExt.WriteLine($"[Data Processor] {LanguageStrings.CapturedFromFileWatcher(Settings.Default.CurrentLanguage, DateTime.Now)}", ConsoleColor.Cyan);
lock (SharpDataHistory) SharpDataHistory.Add(relayItem);
lock (SharpDataQueue) SharpDataQueue.Remove(relayItem);
+ // trim history for memory saving
+ if (SharpDataHistory.Count > 50)
+ {
+ SharpDataHistory.RemoveRange(50, SharpDataHistory.Count - 50);
+ }
+
if (relayItem.Data.Contains("NAADS-Heartbeat"))
{
ConsoleExt.WriteLine($"[Data Processor] {LanguageStrings.HeartbeatDetected(Settings.Default.CurrentLanguage)}", ConsoleColor.Green);
- Match referencesMatch = Regex.Match(relayItem.Data, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ Match referencesMatch = ReferencesRegex.Match(relayItem.Data);
if (referencesMatch.Success)
{
string references = referencesMatch.Groups[1].Value;
@@ -45,10 +49,10 @@ public static void DataProcessor()
else
{
lock (SharpAlertQueue) SharpAlertQueue.Add(relayItem);
- ConsoleExt.WriteLine(LanguageStrings.AlertQueued(Settings.Default.CurrentLanguage));
+ ConsoleExt.WriteLine($"[Data Processor] {LanguageStrings.AlertQueued(Settings.Default.CurrentLanguage)}");
}
- ConsoleExt.WriteLine($"[Data Processor] {LanguageStrings.LastDataReceived(Settings.Default.CurrentLanguage)} {DateTime.Now:yyyy-MM-dd HH:mm:ss}.");
+ //ConsoleExt.WriteLine($"[Data Processor] {LanguageStrings.LastDataReceived(Settings.Default.CurrentLanguage)} {DateTime.Now:yyyy-MM-dd HH:mm:ss}.");
}
}
//catch (ThreadAbortException)
@@ -70,7 +74,7 @@ private static (bool FilePlayed, TimeSpan AudioLength) Play(string filePath, flo
if (!DefaultDevice) outputDevice.DeviceNumber = Settings.Default.SoundDevice;
outputDevice.Init(audioFile);
outputDevice.Play();
- ConsoleExt.WriteLine($"[Data Processor] -> {filePath}.");
+ ConsoleExt.WriteLine($"[Audio Player] -> {filePath}.");
while (outputDevice.PlaybackState == PlaybackState.Playing)
{
if (SkipPlayback)
@@ -195,7 +199,7 @@ public static bool Config(string InfoX, string Status, string MsgType,
Final = true;
}
}
- catch
+ catch (Exception)
{
Final = false;
}
@@ -211,9 +215,7 @@ public static bool Config(string InfoX, string Status, string MsgType,
{
try
{
- MatchCollection matches = Regex.Matches(InfoX,
- @"\s*profile:CAP-CP:Location:0.3\s*\s*(.*?)\s*",
- RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ MatchCollection matches = LocationRegex.Matches(InfoX);
bool GeoMatch = false;
foreach (Match match in matches)
{
@@ -231,7 +233,7 @@ public static bool Config(string InfoX, string Status, string MsgType,
}
catch (Exception ex)
{
- ConsoleExt.WriteLine($"[Data Processor] {ex.Message}", ConsoleColor.Red);
+ ConsoleExt.WriteLineErr($"[Data Processor] {ex.Message}");
return false;
}
}
@@ -248,14 +250,14 @@ public static bool Config(string InfoX, string Status, string MsgType,
public static void Heartbeat(string References)
{
- ConsoleExt.WriteLine($"[Heartbeat] {LanguageStrings.DownloadingFiles(Settings.Default.CurrentLanguage)}", ConsoleColor.DarkYellow);
+ ConsoleExt.WriteLine($"[Heartbeat] {LanguageStrings.DownloadingFiles(Settings.Default.CurrentLanguage)}", ConsoleColor.Yellow);
string[] RefList = References.Split(' ');
int DataMatched = 0;
int Total = 0;
+ client.DefaultRequestHeaders.UserAgent.ParseAdd($"Mozilla/5.0 (compatible; SharpENDEC/{VersionInfo.ReleaseVersion}.{VersionInfo.MinorVersion})");
foreach (string i in RefList)
{
Total++;
- ConsoleExt.WriteLine($"[Heartbeat] {LanguageStrings.GenericProcessingValueOfValue(Settings.Default.CurrentLanguage, Total, RefList.Length)}", ConsoleColor.DarkYellow);
string filename = string.Empty;
string[] k = i.Split(',');
string sentDTFull = k[2].Replace("-", "_").Replace(":", "_").Replace("+", "p");
@@ -270,18 +272,18 @@ public static void Heartbeat(string References)
if (SharpDataQueue.Any(x => x.Name == filename) || SharpDataHistory.Any(x => x.Name == filename))
{
- ConsoleExt.WriteLine($"[Heartbeat] {LanguageStrings.DataPreviouslyProcessed(Settings.Default.CurrentLanguage)}", ConsoleColor.Yellow);
+ ConsoleExt.WriteLine($"[Heartbeat] -x {filename}", ConsoleColor.DarkGray);
DataMatched++;
}
else
{
- ConsoleExt.WriteLine($"[Heartbeat] {filename}...", ConsoleColor.Yellow);
+ //ConsoleExt.WriteLine($"[Heartbeat] {LanguageStrings.GenericProcessingValueOfValue(Settings.Default.CurrentLanguage, Total, RefList.Length)}", ConsoleColor.Yellow);
string url1 = $"http://{Dom1}/{sentDT}/{filename}";
string url2 = $"http://{Dom2}/{sentDT}/{filename}";
try
{
- ConsoleExt.WriteLine($"-> {url1}", ConsoleColor.Yellow);
+ ConsoleExt.WriteLine($"-> {filename}", ConsoleColor.DarkYellow);
Task xml = client.GetStringAsync(url1);
xml.Wait();
lock (SharpDataQueue) SharpDataQueue.Add(new SharpDataItem(filename, xml.Result));
@@ -291,9 +293,8 @@ public static void Heartbeat(string References)
{
try
{
- ConsoleExt.WriteLine($"[Heartbeat] {e1.Message}", ConsoleColor.Red);
- ConsoleExt.WriteLine($"[Heartbeat] {filename}...", ConsoleColor.Yellow);
- ConsoleExt.WriteLine($"-> {url2}", ConsoleColor.Yellow);
+ ConsoleExt.WriteLineErr($"[Heartbeat] {e1.Message}");
+ ConsoleExt.WriteLine($"-> {url2}", ConsoleColor.DarkYellow);
Task xml = client.GetStringAsync(url2);
xml.Wait();
lock (SharpDataQueue) SharpDataQueue.Add(new SharpDataItem(filename, xml.Result));
@@ -301,8 +302,8 @@ public static void Heartbeat(string References)
}
catch (Exception e2)
{
- ConsoleExt.WriteLine($"[Heartbeat] {e2.Message}", ConsoleColor.Red);
- ConsoleExt.WriteLine($"[Heartbeat] {LanguageStrings.DownloadFailure(Settings.Default.CurrentLanguage)}", ConsoleColor.Red);
+ ConsoleExt.WriteLineErr($"[Heartbeat] {e2.Message}");
+ ConsoleExt.WriteLine($"[Heartbeat] {LanguageStrings.DownloadFailure(Settings.Default.CurrentLanguage)}", ConsoleColor.DarkBlue);
}
}
}
@@ -313,7 +314,6 @@ public static void Heartbeat(string References)
public static SharpDataItem WatchForItemsInList()
{
- //ConsoleExt.WriteLine($"[Data Processor] Watching for new strings in FileStringListTempName.");
while (true)
{
if (SharpDataQueue.Count != 0)
@@ -324,338 +324,7 @@ public static SharpDataItem WatchForItemsInList()
return data;
}
}
- Thread.Sleep(50);
- }
- return null;
- }
- }
-
- public class Generate
- {
- private readonly string InfoData;
- private readonly string MsgType;
- private readonly string Sent;
-
- public Generate(string InfoDataZ, string MsgTypeZ, string SentDate)
- {
- InfoData = InfoDataZ;
- MsgType = MsgTypeZ;
- Sent = SentDate;
- }
-
- public (string BroadcastText, bool) BroadcastInfo(string lang)
- {
- string BroadcastText = "";
-
- Match match = Regex.Match(InfoData, @"layer:SOREM:1.0:Broadcast_Text\s*\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- if (match.Success)
- {
- BroadcastText = match.Groups[1].Value.Replace("\r\n", " ").Replace("\n", " ").Replace(" ", " ").Trim();
- }
- else
- {
- string issue, update, cancel;
- if (lang == "fr")
- {
- issue = "émis";
- update = "mis à jour";
- cancel = "annulé";
- }
- else
- {
- issue = "issued";
- update = "updated";
- cancel = "cancelled";
- }
-
- string MsgPrefix;
- switch (MsgType.ToLower())
- {
- case "alert":
- MsgPrefix = issue;
- break;
- case "update":
- MsgPrefix = update;
- break;
- case "cancel":
- MsgPrefix = cancel;
- break;
- default:
- MsgPrefix = "issued";
- break;
- }
-
- DateTime sentDate;
- try
- {
- // .ToUniversalTime()
- sentDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
- }
- catch (Exception e)
- {
- ConsoleExt.WriteLine(e.Message);
- sentDate = DateTime.Now;
- }
-
- //DateTime sentDate = DateTime.Parse(Sent, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToUniversalTime();
-
- string SentFormatted = lang == "fr" ? $"{sentDate:HH}'{sentDate:h}'{sentDate:mm zzz}." : $"{sentDate:HH:mm z}, {sentDate:MMMM dd}, {sentDate:yyyy}.";
-
- string EventType;
- try
- {
- EventType = Regex.Match(InfoData, @"layer:EC-MSC-SMC:1.0:Alert_Name\s*\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value;
- }
- catch (Exception)
- {
- EventType = Regex.Match(InfoData, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value;
- EventType = lang == "fr" ? $"alerte {EventType}" : $"{EventType} alert";
- }
-
- string Coverage;
- try
- {
- Coverage = Regex.Match(InfoData, @"layer:EC-MSC-SMC:1.0:Alert_Coverage\s*\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value;
- Coverage = lang == "fr" ? $"en {Coverage} pour:" : $"in {Coverage} for:";
- }
- catch (Exception)
- {
- Coverage = lang == "fr" ? "pour:" : "for:";
- }
-
- string[] areaDescMatches = Regex.Matches(InfoData, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline)
- .Cast()
- .Select(m => m.Groups[1].Value)
- .ToArray();
-
- string AreaDesc = string.Join(", ", areaDescMatches) + ".";
-
- string SenderName;
-
- try
- {
- SenderName = Regex.Match(InfoData, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value;
- }
- catch (Exception)
- {
- SenderName = "an alert issuer";
- }
-
- string Description;
-
- try
- {
- Description = Regex.Match(InfoData, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value.Replace("\n", " ");
- if (!Description.EndsWith(".")) Description += ".";
- }
- catch (Exception)
- {
- Description = "";
- }
-
- string Instruction;
-
- try
- {
- Instruction = Regex.Match(InfoData, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value.Replace("\n", " ");
- if (!Instruction.EndsWith(".")) Instruction += ".";
- }
- catch (Exception)
- {
- Instruction = "";
- }
-
- string Effective;
-
- try
- {
- Effective = Regex.Match(InfoData, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value.Replace("\n", " ");
- DateTime.Parse(Effective, CultureInfo.InvariantCulture);
- }
- catch (Exception)
- {
- Effective = "currently";
- }
-
- string Expires;
-
- try
- {
- Expires = Regex.Match(InfoData, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline).Groups[1].Value.Replace("\n", " ");
- DateTime.Parse(Expires, CultureInfo.InvariantCulture);
- }
- catch (Exception)
- {
- Expires = "soon";
- }
-
- // Effective {Effective}, and expiring {Expires}.
-
- BroadcastText = lang == "fr" ?
- $"À {SentFormatted} {SenderName} a {MsgPrefix} une {EventType} {Coverage} {AreaDesc}. {Description} {Instruction}".Replace("###", "").Replace(" ", " ").Trim() :
- $"At {SentFormatted} {SenderName} has {MsgPrefix} a {EventType} {Coverage} {AreaDesc}. {Description} {Instruction}".Replace("###", "").Replace(" ", " ").Trim();
- }
-
- if (BroadcastText.EndsWith("\x20.")) BroadcastText = BroadcastText.TrimEnd('\x20', '.');
- if (BroadcastText.EndsWith(".")) BroadcastText = BroadcastText.TrimEnd('.');
- if (!BroadcastText.EndsWith(".") || !BroadcastText.EndsWith("!")) BroadcastText += ".";
-
- //if (Debugger.IsAttached) BroadcastText += "\x20| Debugging in progress";
-
- return (BroadcastText, true);
- }
-
- public bool GetAudio(string audioLink, string output, int decodeType)
- {
- if (decodeType == 1)
- {
- ConsoleExt.WriteLine("Decoding audio from Base64.");
- try
- {
- byte[] audioData = Convert.FromBase64String(audioLink);
- File.WriteAllBytes(output, audioData);
- return true;
- }
- catch (Exception ex)
- {
- ConsoleExt.WriteLine($"Decoder failed: {ex.Message}");
- return false;
- }
- }
- else if (decodeType == 0)
- {
- ConsoleExt.WriteLine("Downloading audio.");
- try
- {
- using (HttpClient webClient = new HttpClient())
- {
- File.WriteAllBytes(output, webClient.GetByteArrayAsync(audioLink).Result);
- }
- return true;
- }
- catch (Exception ex)
- {
- ConsoleExt.WriteLine($"Downloader failed: {ex.Message}");
- }
- return false;
- }
- else
- {
- ConsoleExt.WriteLine("Invalid DecodeType specified.");
- return false;
- }
- }
-
- private readonly SpeechSynthesizer engine = new SpeechSynthesizer();
-
- public void GenerateAudio(string text, string lang)
- {
- try
- {
- Match Resource = Regex.Match(InfoData, @"\s*(.*?)\s*\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- if (!Resource.Success) throw new Exception("Audio field not found. TTS will be generated instead.");
- string broadcastAudioResource = Resource.Groups[1].Value;
- string audioLink = string.Empty;
- string audioType = string.Empty;
- int decode = -1;
-
- if (broadcastAudioResource.Contains(""))
- {
- Match Link = Regex.Match(broadcastAudioResource, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- Match Type = Regex.Match(broadcastAudioResource, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- decode = 1;
- if (Link.Success && Type.Success)
- {
- audioLink = Link.Groups[1].Value;
- audioType = Type.Groups[1].Value;
- }
- }
- else
- {
- Match Link = Regex.Match(broadcastAudioResource, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- Match Type = Regex.Match(broadcastAudioResource, @"\s*(.*?)\s*", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
- decode = 0;
- if (Link.Success && Type.Success)
- {
- audioLink = Link.Groups[1].Value;
- audioType = Type.Groups[1].Value;
- }
- }
-
- ConsoleExt.WriteLine(audioLink);
- //Thread.Sleep(5000);
-
- string audioFile;
- switch (audioType)
- {
- case "audio/mpeg":
- audioFile = "PreAudio.mp3";
- break;
- case "audio/x-ms-wma":
- audioFile = "PreAudio.wma";
- break;
- default:
- audioFile = "PreAudio.wav";
- break;
- }
-
- if (File.Exists($"{AudioDirectory}\\{audioFile}")) File.Delete($"{AudioDirectory}\\{audioFile}");
- if (File.Exists($"{AudioDirectory}\\audio.wav")) File.Delete($"{AudioDirectory}\\audio.wav");
-
- if (GetAudio(audioLink, audioFile, decode))
- {
- using (var audioFileReader = new AudioFileReader(audioFile))
- {
- var volumeSampleProvider = new VolumeSampleProvider(audioFileReader.ToSampleProvider())
- {
- Volume = 2.5f,
- };
- WaveFileWriter.CreateWaveFile16($"{AudioDirectory}\\audio.wav", volumeSampleProvider);
- }
-
- if (!File.Exists($"{AudioDirectory}\\audio.wav"))
- {
- ConsoleExt.WriteLine("Post processing failed.");
- File.Move(audioFile, $"{AudioDirectory}\\audio.wav");
- }
-
- //string ffmpegCmd = $"{AssemblyDirectory}\\ffmpeg.exe -y -i {audioFile} -filter:a volume=2.5 {AssemblyDirectory.Replace("\\", "/")}/Audio/audio.wav";
- //Process p = Process.Start("cmd.exe", $"/c {ffmpegCmd}");
- //p.WaitForExit(12000);
- //if (p.ExitCode != 0 || !File.Exists($"{AssemblyDirectory}\\Audio\\audio.wav"))
- //{
- // ConsoleExt.WriteLine("Post processing failed. Please make sure ffmpeg is in the program folder.");
- // File.Move(audioFile, $"{AssemblyDirectory}\\Audio\\audio.wav");
- //}
- //new SoundPlayer($"{AssemblyDirectory}\\Audio\\audio.wav").PlaySync();
- }
- else
- {
- throw new Exception();
- }
- }
- catch (Exception ex)
- {
- ConsoleExt.WriteLine(ex.Message);
-
- //ConsoleExt.WriteLine(lang);
- foreach (var voice in engine.GetInstalledVoices())
- {
- //ConsoleExt.WriteLine(voice.VoiceInfo.Culture.TwoLetterISOLanguageName.ToLower());
- if (voice.VoiceInfo.Name.Contains(Settings.Default.SpeechVoice) && voice.VoiceInfo.Culture.TwoLetterISOLanguageName.ToLower() == lang)
- {
- //ConsoleExt.WriteLine(voice.VoiceInfo.Name, ConsoleColor.Magenta);
- engine.SelectVoice(voice.VoiceInfo.Name);
- break;
- }
- }
-
- text = text.Replace("#", "hashtag\x20");
- text = text.Replace("*", "star\x20");
-
- engine.SetOutputToWaveFile($"{AudioDirectory}\\audio.wav");
- engine.Speak(text);
- engine.Dispose();
+ Thread.Sleep(100);
}
}
}
diff --git a/SharpENDEC/ENDEC/FeedCapture.cs b/SharpENDEC/ENDEC/FeedCapture.cs
index b7c04ee..35bbd17 100644
--- a/SharpENDEC/ENDEC/FeedCapture.cs
+++ b/SharpENDEC/ENDEC/FeedCapture.cs
@@ -5,7 +5,6 @@
using System.Linq;
using System.Net.Sockets;
using System.Text;
-using System.Text.RegularExpressions;
using System.Threading;
namespace SharpENDEC
@@ -64,7 +63,7 @@ private void Receive(string host, int port, string delimiter)
}
catch (IOException e)
{
- ConsoleExt.WriteLine($"[{host}:{port}] {e.Message}", ConsoleColor.Red);
+ ConsoleExt.WriteLineErr($"[{host}:{port}] {e.Message}");
return;
}
Thread.Sleep(1000);
@@ -93,8 +92,8 @@ private void Receive(string host, int port, string delimiter)
if (chunk.Contains(delimiter))
{
ConsoleExt.WriteLine($"[{host}:{port}] {LanguageStrings.ProcessedStream(Settings.Default.CurrentLanguage, data.Count, now)}");
- string capturedSent = Regex.Match(dataReceived, @"\s*(.*?)\s*", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline).Groups[1].Value.Replace("-", "_").Replace("+", "p").Replace(":", "_");
- string capturedIdent = Regex.Match(dataReceived, @"\s*(.*?)\s*", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline).Groups[1].Value.Replace("-", "_").Replace("+", "p").Replace(":", "_");
+ string capturedSent = SentRegex.Match(dataReceived).Groups[1].Value.Replace("-", "_").Replace("+", "p").Replace(":", "_");
+ string capturedIdent = IdentifierRegex.Match(dataReceived).Groups[1].Value.Replace("-", "_").Replace("+", "p").Replace(":", "_");
string filename = $"{capturedSent}I{capturedIdent}.xml";
if (SharpDataQueue.Any(x => x.Name == filename) || SharpDataHistory.Any(x => x.Name == filename))
@@ -104,7 +103,7 @@ private void Receive(string host, int port, string delimiter)
else
{
SharpDataQueue.Add(new SharpDataItem(filename, dataReceived));
- ConsoleExt.WriteLine($"[{host}:{port}] {LanguageStrings.FileDownloaded(Settings.Default.CurrentLanguage, host)}");
+ ConsoleExt.WriteLine($"[{host}:{port}] {LanguageStrings.FileDownloaded(Settings.Default.CurrentLanguage)}");
}
dataReceived = string.Empty;
}
@@ -112,7 +111,9 @@ private void Receive(string host, int port, string delimiter)
{
if (data.Count > 10000000)
{
- throw new Exception($"[{host}:{port}] The data exceeds the 10 MB limit. The server may be malfunctioning.");
+ //throw new OverflowException($"[{host}:{port}] The data exceeds the 10 MB limit. The server may be malfunctioning.");
+ ConsoleExt.WriteLineErr($"[{host}:{port}] The data exceeds the 10 MB limit. The server may be malfunctioning.");
+ return;
}
else ConsoleExt.WriteLine($"[{host}:{port}] {data.Count} bytes total including the current chunk.");
}
@@ -121,13 +122,13 @@ private void Receive(string host, int port, string delimiter)
}
catch (SocketException e)
{
- ConsoleExt.WriteLine($"[{host}:{port}] {e.Message}");
+ ConsoleExt.WriteLineErr($"[{host}:{port}] {e.Message}");
Thread.Sleep(1000);
return;
}
catch (TimeoutException)
{
- ConsoleExt.WriteLine($"[{host}:{port}] {LanguageStrings.HostTimedOut(Settings.Default.CurrentLanguage, host)}");
+ ConsoleExt.WriteLineErr($"[{host}:{port}] {LanguageStrings.HostTimedOut(Settings.Default.CurrentLanguage, host)}");
return;
}
catch (ThreadAbortException)
@@ -140,6 +141,8 @@ private void Receive(string host, int port, string delimiter)
public bool Main()
{
+ if (!SharpDataQueue.IsNull()) SharpDataQueue.Clear();
+ if (!SharpDataHistory.IsNull()) SharpDataHistory.Clear();
SharpDataQueue = new List();
SharpDataHistory = new List();
@@ -149,7 +152,7 @@ void StartServerConnection()
{
Thread thread = new Thread(() => Receive(server, 8080, ""));
thread.Start();
- ClientThreads.Add(thread);
+ CaptureThreads.Add(thread);
ConsoleExt.WriteLine($"{LanguageStrings.StartingConnection(Settings.Default.CurrentLanguage, server, 8080)}", ConsoleColor.DarkGray);
Thread.Sleep(250);
}
@@ -161,9 +164,9 @@ void StartServerConnection()
{
while (true)
{
- for (int i = 0; i < ClientThreads.Count; i++)
+ for (int i = 0; i < CaptureThreads.Count; i++)
{
- if (!ClientThreads[i].IsAlive)
+ if (!CaptureThreads[i].IsAlive)
{
if (!ShutdownCapture)
{
@@ -171,15 +174,15 @@ void StartServerConnection()
string server = Settings.Default.CanadianServers[i];
Thread newThread = new Thread(() => Receive(server, 8080, ""));
newThread.Start();
- ClientThreads[i] = newThread;
+ CaptureThreads[i] = newThread;
}
}
}
if (ShutdownCapture)
{
- lock (ClientThreads)
- foreach (var thread in ClientThreads)
+ lock (CaptureThreads)
+ foreach (var thread in CaptureThreads)
{
try
{
diff --git a/SharpENDEC/ENDEC/RegexList.cs b/SharpENDEC/ENDEC/RegexList.cs
new file mode 100644
index 0000000..c58a5a3
--- /dev/null
+++ b/SharpENDEC/ENDEC/RegexList.cs
@@ -0,0 +1,110 @@
+using System.Text.RegularExpressions;
+
+namespace SharpENDEC
+{
+ public static partial class ENDEC
+ {
+ //public static readonly Regex ValueNameRegex = new Regex(
+ // @"([^<]+)\s*([^<]+)",
+ // RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex SentRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex StatusRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex MessageTypeRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex BroadcastImmediatelyRegex = new Regex(
+ @"layer:SOREM:1.0:Broadcast_Immediately\s*\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex UrgencyRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex SeverityRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex InfoRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex EffectiveRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex ExpiresRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex EventRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ public static readonly Regex EventTypeRegex = new Regex(
+ @"layer:EC-MSC-SMC:1.0:Alert_Name\s*\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex LanguageRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex SenderNameRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex CoverageRegex = new Regex(
+ @"layer:EC-MSC-SMC:1.0:Alert_Coverage\s*\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex DescriptionRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex InstructionRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex BroadcastTextRegex = new Regex(
+ @"layer:SOREM:1.0:Broadcast_Text\s*\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex AreaDescriptionRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex ResourceDescriptionRegex = new Regex(
+ @"\s*(.*?)\s*\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex DerefURIRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex TypeURIRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex MimeRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex IdentifierRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex ReferencesRegex = new Regex(
+ @"\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ public static readonly Regex LocationRegex = new Regex(
+ @"\s*profile:CAP-CP:Location:0.3\s*\s*(.*?)\s*",
+ RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ }
+}
diff --git a/SharpENDEC/ENDEC/ServerRunner.cs b/SharpENDEC/ENDEC/ServerRunner.cs
new file mode 100644
index 0000000..d8cae9a
--- /dev/null
+++ b/SharpENDEC/ENDEC/ServerRunner.cs
@@ -0,0 +1,304 @@
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace SharpENDEC
+{
+ public static partial class ENDEC
+ {
+ internal static MainExt.RandomGenerator rnd = new MainExt.RandomGenerator();
+ internal static List AuthenticatedCookies = new List();
+
+ public static void HTTPServerProcessor()
+ {
+ lock (AuthenticatedCookies) AuthenticatedCookies.Clear();
+
+ try
+ {
+ HttpListener listener = new HttpListener();
+ listener.Prefixes.Add("http://localhost:8050/");
+ listener.Start();
+
+ while (true)
+ {
+ HttpListenerContext context = listener.GetContext();
+ Task.Run(() =>
+ {
+ string path = context.Request.Url.AbsolutePath.ToLower();
+ HttpListenerResponse response = context.Response;
+
+ List QueryString = new List();
+
+ foreach (string query in context.Request.QueryString)
+ {
+ QueryString.Add(query);
+ }
+
+ switch (path)
+ {
+ case "/":
+ Endpoints.HandleHomeEndpoint(response, context.Request.HttpMethod, QueryString);
+ break;
+ case "/version":
+ Endpoints.HandleVersionEndpoint(response, context.Request.HttpMethod, QueryString);
+ break;
+ case "/login":
+ Endpoints.HandleLoginEndpoint(response, context.Request.HttpMethod, QueryString);
+ break;
+ default:
+ HandleNotFound(response);
+ break;
+ }
+ });
+ }
+ }
+ catch (Exception)
+ {
+ lock (AuthenticatedCookies) AuthenticatedCookies.Clear();
+ }
+ }
+
+ internal static void WriteAndClose(HttpListenerResponse response, byte[] buffer, int code)
+ {
+ response.StatusCode = code;
+ response.ContentLength64 = buffer.Length;
+ response.OutputStream.Write(buffer, 0, buffer.Length);
+ response.OutputStream.Close();
+ }
+
+ private static class Endpoints
+ {
+ public static void HandleHomeEndpoint(HttpListenerResponse response, string method, List query)
+ {
+ switch (method.ToUpper())
+ {
+ case "GET":
+ byte[] buffer = Encoding.UTF8.GetBytes($"The version is here. Query: {query.ListToString()}");
+ WriteAndClose(response, buffer, 200);
+ break;
+ default:
+ HandleWrongMethod(response);
+ break;
+ }
+ }
+
+ public static void HandleHealthDataEndpoint(HttpListenerResponse response, string method, List query)
+ {
+ switch (method.ToUpper())
+ {
+ case "GET":
+ lock (CaptureThreads)
+ {
+ foreach (Thread thread in CaptureThreads)
+ {
+ if (thread.IsAlive) ConsoleExt.WriteLine(thread.Name + " is alive");
+ }
+ }
+ byte[] buffer = Encoding.UTF8.GetBytes("");
+ WriteAndClose(response, buffer, 200);
+ break;
+ default:
+ HandleWrongMethod(response);
+ break;
+ }
+ }
+
+ internal static RandomGenerator rnd = new RandomGenerator();
+
+ public static void HandleLoginEndpoint(HttpListenerResponse response, string method, List query)
+ {
+ switch (method.ToUpper())
+ {
+ case "GET":
+ byte[] buffer_GET = Encoding.UTF8.GetBytes($"{rnd.Next(0, 10000)} {query}");
+ WriteAndClose(response, buffer_GET, 200);
+ break;
+ case "POST":
+ byte[] buffer_POST = Encoding.UTF8.GetBytes($"{rnd.Next(0, 10000)} {query}");
+ int cookieContent = rnd.NextLarge(0, 1000);
+ AuthenticatedCookies.Add($"{cookieContent}");
+ response.SetCookie(new Cookie("Authentify", ""));
+ WriteAndClose(response, buffer_POST, 200);
+ break;
+ default:
+ HandleWrongMethod(response);
+ break;
+ }
+ }
+
+ public static void HandleVersionEndpoint(HttpListenerResponse response, string method, List query)
+ {
+ switch (method.ToUpper())
+ {
+ case "GET":
+ byte[] buffer = Encoding.UTF8.GetBytes($"You queried \"{query.ListToString()}\"! Here's what you asked for though: {VersionInfo.FriendlyVersion}");
+ WriteAndClose(response, buffer, 200);
+ break;
+ default:
+ HandleWrongMethod(response);
+ break;
+ }
+ }
+ }
+
+ private static void HandleNotFound(HttpListenerResponse response)
+ {
+ string responseString = $"{VersionInfo.FriendlyVersion}Endpoint Not Found";
+ byte[] buffer = Encoding.UTF8.GetBytes(responseString);
+ response.StatusCode = 404;
+ response.ContentLength64 = buffer.Length;
+ response.OutputStream.Write(buffer, 0, buffer.Length);
+ response.OutputStream.Close();
+ }
+
+ private static void HandleBadRequest(HttpListenerResponse response)
+ {
+ string responseString = $"{VersionInfo.FriendlyVersion}Bad Request";
+ byte[] buffer = Encoding.UTF8.GetBytes(responseString);
+ response.StatusCode = 400;
+ response.ContentLength64 = buffer.Length;
+ response.OutputStream.Write(buffer, 0, buffer.Length);
+ response.OutputStream.Close();
+ }
+
+ private static void HandleUnauthorized(HttpListenerResponse response)
+ {
+ string responseString = $"{VersionInfo.FriendlyVersion}Request Unauthorized";
+ byte[] buffer = Encoding.UTF8.GetBytes(responseString);
+ response.StatusCode = 401;
+ response.ContentLength64 = buffer.Length;
+ response.OutputStream.Write(buffer, 0, buffer.Length);
+ response.OutputStream.Close();
+ }
+
+ private static void HandleWrongMethod(HttpListenerResponse response)
+ {
+ string responseString = $"{VersionInfo.FriendlyVersion}Wrong Method";
+ byte[] buffer = Encoding.UTF8.GetBytes(responseString);
+ response.StatusCode = 405;
+ response.ContentLength64 = buffer.Length;
+ response.OutputStream.Write(buffer, 0, buffer.Length);
+ response.OutputStream.Close();
+ }
+ }
+
+ ///
+ /// Secure random generator
+ ///
+ ///
+ ///
+ ///
+ public class RandomGenerator : IDisposable
+ {
+ private readonly RNGCryptoServiceProvider csp;
+
+ ///
+ /// Constructor
+ ///
+ public RandomGenerator()
+ {
+ csp = new RNGCryptoServiceProvider();
+ }
+
+ ///
+ /// Get the next random value between minValue and maxExclusiveValue.
+ ///
+ public int Next(int minValue, int maxExclusiveValue)
+ {
+ if (minValue == maxExclusiveValue)
+ return minValue;
+
+ if (minValue > maxExclusiveValue)
+ {
+ throw new ArgumentOutOfRangeException($"{nameof(minValue)} must be lower than {nameof(maxExclusiveValue)}");
+ }
+
+ var diff = (long)maxExclusiveValue - minValue;
+ var upperBound = uint.MaxValue / diff * diff;
+
+ uint ui;
+ do
+ {
+ ui = GetRandomUInt();
+ } while (ui >= upperBound);
+
+ return (int)(minValue + (ui % diff));
+ }
+
+ ///
+ /// Get the next random value between (minValue * random) and (maxExclusiveValue * random) with random attempts.
+ ///
+ public int NextLarge(int minValue, int maxExclusiveValue)
+ {
+ if (minValue == maxExclusiveValue)
+ return minValue;
+
+ if (minValue > maxExclusiveValue)
+ {
+ throw new ArgumentOutOfRangeException($"{nameof(minValue)} must be lower than {nameof(maxExclusiveValue)}");
+ }
+
+ minValue *= 1000 * Next(minValue, maxExclusiveValue);
+ maxExclusiveValue *= 1000 * Next(minValue, maxExclusiveValue);
+
+ var diff = (long)maxExclusiveValue - minValue;
+ var upperBound = uint.MaxValue / diff * diff;
+
+ uint ui;
+ do
+ {
+ ui = GetRandomUInt();
+ } while (ui >= upperBound);
+
+ return (int)(minValue + (ui % diff));
+ }
+
+ private uint GetRandomUInt()
+ {
+ var randomBytes = GenerateRandomBytes(sizeof(uint));
+ return BitConverter.ToUInt32(randomBytes, 0);
+ }
+
+ private byte[] GenerateRandomBytes(int bytesNumber)
+ {
+ var buffer = new byte[bytesNumber];
+ csp.GetBytes(buffer);
+ return buffer;
+ }
+
+ private bool _disposed;
+
+ ///
+ /// Public implementation of Dispose pattern callable by consumers.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Protected implementation of Dispose pattern.
+ ///
+ ///
+ protected virtual void Dispose(bool disposing)
+ {
+ if (_disposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ // Dispose managed state (managed objects).
+ csp?.Dispose();
+ }
+
+ _disposed = true;
+ }
+ }
+}
diff --git a/SharpENDEC/ILLink/ILLink.Descriptors.LibraryBuild.xml b/SharpENDEC/ILLink/ILLink.Descriptors.LibraryBuild.xml
new file mode 100644
index 0000000..a42d7f0
--- /dev/null
+++ b/SharpENDEC/ILLink/ILLink.Descriptors.LibraryBuild.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/SharpENDEC/InternalExtensions/ConsoleExt.cs b/SharpENDEC/InternalExtensions/ConsoleExt.cs
index 8708c42..0fd3e56 100644
--- a/SharpENDEC/InternalExtensions/ConsoleExt.cs
+++ b/SharpENDEC/InternalExtensions/ConsoleExt.cs
@@ -1,4 +1,5 @@
using System;
+using System.IO;
namespace SharpENDEC
{
@@ -21,5 +22,14 @@ public static void Write(string value = "", ConsoleColor foreground = ConsoleCol
Console.Write(value);
Console.ForegroundColor = og;
}
+
+ public static void WriteLineErr(string value = "")
+ {
+ File.AppendAllText("error.log", $"{DateTime.Now:F} | {value}");
+ og = Console.ForegroundColor;
+ Console.ForegroundColor = ConsoleColor.DarkRed;
+ Console.WriteLine(value);
+ Console.ForegroundColor = og;
+ }
}
}
diff --git a/SharpENDEC/InternalExtensions/MainExt.cs b/SharpENDEC/InternalExtensions/MainExt.cs
index 4c54de1..3900042 100644
--- a/SharpENDEC/InternalExtensions/MainExt.cs
+++ b/SharpENDEC/InternalExtensions/MainExt.cs
@@ -1,14 +1,15 @@
using System;
-using System.Diagnostics;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Security.Cryptography;
using System.Threading;
-using System.Threading.Tasks;
-using ThreadState = System.Threading.ThreadState;
namespace SharpENDEC
{
public static class MainExt
{
- private static Exception ex = new Exception();
+ public static Exception LastException { get; private set; }
///
/// This method is for dummy purposes, and does not perform any tasks.
@@ -22,7 +23,7 @@ public static void UnknownCaller()
///
public static Exception UnknownException()
{
- return new Exception("DummyException");
+ return new Exception("UnknownException");
}
///
@@ -31,51 +32,75 @@ public static Exception UnknownException()
/// The method that called the exception.
/// The exception that caused the unsafe state.
/// The reason why the unsafe state was invoked.
- /// Whether or not to restart and ignore the infinite rule.
+ /// Whether or not to restart and ignore the infinite wait rule.
public static void UnsafeStateShutdown(Action caller, Exception exception, string reason, bool restart = true)
{
- lock (ex)
+ LastException = exception;
+ lock (LastException)
{
if (caller.IsNull()) caller = UnknownCaller;
if (exception.IsNull()) exception = UnknownException();
if (string.IsNullOrEmpty(reason)) reason = "No reason provided.";
- ex = exception;
+ try { if (!Program.WatchdogService.IsNull()) Program.WatchdogService.Abort(LastException); } catch (Exception) { }
- lock (ENDEC.ClientThreads)
+ DateTime ExceptionTime = DateTime.Now;
+
+ lock (ENDEC.CaptureThreads)
{
- foreach (Thread thread in ENDEC.ClientThreads)
- try { if (!thread.IsNull()) thread.Abort(ex); } catch (Exception) { }
- ENDEC.ClientThreads.Clear();
+ foreach (Thread thread in ENDEC.CaptureThreads)
+ try { if (!thread.IsNull()) thread.Abort(LastException); } catch (Exception) { }
+ ENDEC.CaptureThreads.Clear();
}
lock (Program.MainThreads)
{
- foreach (var (thread, method) in Program.MainThreads)
- try { if (!thread.IsNull()) thread.Abort(ex); } catch (Exception) { }
+ foreach (var (thread, method, isMTA) in Program.MainThreads)
+ try { if (!thread.IsNull()) thread.Abort(LastException); } catch (Exception) { }
Program.MainThreads.Clear();
}
ENDEC.Capture = null;
+ ENDEC.SharpDataQueue = null;
+ ENDEC.SharpDataHistory = null;
+
+ Thread.Sleep(100);
Console.Clear();
Console.ForegroundColor = ConsoleColor.DarkRed;
- string full = ($"{DateTime.Now:G} | Called by {caller.Method.Name}\r\n" +
- $"Stack Trace: {ex.StackTrace}\r\n" +
- $"Source: {ex.Source}\r\n" +
- $"Message: {ex.Message}\r\n" +
- $"{reason}");
+ string full = $"{ExceptionTime:G} | Called by {caller.Method.Name}\r\n" +
+ $"Exception Stack Trace: {LastException.StackTrace}\r\n" +
+ $"Exception Source: {LastException.Source}\r\n" +
+ $"Exception Message: {LastException.Message}\r\n" +
+ $"Caller Reason: {reason}";
Console.WriteLine(full);
- Thread.Sleep(1000);
+ try
+ {
+ string ExceptionDateTime = ExceptionTime.ToString("s").Replace(":", "-");
+ File.WriteAllText(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + $"\\exception_{ExceptionDateTime}.txt", full + "\r\n");
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"Another exception occurred while trying to write an exception.\r\n{e.Message}");
+ }
+#if DEBUG
Debug.Assert(false, "The program went into an unsafe state.", full);
- Console.Clear();
+#else
+ Thread.Sleep(5000);
+#endif
if (restart)
{
Console.Clear();
- new Thread(() => Program.Main()).Start();
+#if !DEBUG
+ Environment.Exit(1984);
+#else
+ new Thread(() => Program.Main(null)).Start();
+#endif
+ }
+ else
+ {
+ Environment.Exit(1985);
}
- else Thread.Sleep(Timeout.Infinite);
-
}
}
@@ -84,5 +109,56 @@ public static bool IsNull(this object obj)
if (obj == null) return true;
return false;
}
+
+ public static string ListToString(this List obj)
+ {
+ if (obj == null) return string.Empty;
+ if (obj.Count == 0) return string.Empty;
+ string all = string.Empty;
+ foreach (string str in obj)
+ {
+ all += $"{str},\x20";
+ }
+ return all.Substring(all.Length, all.Length - 2);
+ }
+
+ public class RandomGenerator
+ {
+ readonly RNGCryptoServiceProvider csp;
+
+ public RandomGenerator()
+ {
+ csp = new RNGCryptoServiceProvider();
+ }
+
+ public int Next(int minValue, int maxExclusiveValue)
+ {
+ if (minValue >= maxExclusiveValue)
+ throw new ArgumentOutOfRangeException("minValue must be lower than maxExclusiveValue");
+
+ long diff = (long)maxExclusiveValue - minValue;
+ long upperBound = uint.MaxValue / diff * diff;
+
+ uint ui;
+ do
+ {
+ ui = GetRandomUInt();
+ } while (ui >= upperBound);
+ return (int)(minValue + (ui % diff));
+ }
+
+ private uint GetRandomUInt()
+ {
+ var randomBytes = GenerateRandomBytes(sizeof(uint));
+ return BitConverter.ToUInt32(randomBytes, 0);
+ }
+
+ private byte[] GenerateRandomBytes(int bytesNumber)
+ {
+ byte[] buffer = new byte[bytesNumber];
+ csp.GetBytes(buffer);
+ return buffer;
+ }
+ }
}
}
diff --git a/SharpENDEC/LanguageStrings.cs b/SharpENDEC/LanguageStrings.cs
index 9454b45..6e2cb58 100644
--- a/SharpENDEC/LanguageStrings.cs
+++ b/SharpENDEC/LanguageStrings.cs
@@ -125,17 +125,17 @@ public static string RestartingAfterException(string lang)
}
}
- public static string FileDownloaded(string lang, string host)
+ public static string FileDownloaded(string lang)
{
switch (lang)
{
case "french":
- return $"Données enregistrées. | De : {host}";
+ return $"Données enregistrées.";
case "inuktitut":
- return $"ᑎᑎᕋᖅᓯᒪᔪᑦ ᖃᐅᔨᓴᖅᑕᐅᓂᑯᐃᑦ ᑐᖅᑯᖅᑕᐅᓯᒪᔪᑦ. | ᐅᕙᙵᑦ: {host}";
+ return $"ᑎᑎᕋᖅᓯᒪᔪᑦ ᖃᐅᔨᓴᖅᑕᐅᓂᑯᐃᑦ ᑐᖅᑯᖅᑕᐅᓯᒪᔪᑦ.";
case "english":
default:
- return $"Data saved. | From: {host}";
+ return $"File saved.";
}
}
@@ -172,12 +172,22 @@ public static string DataIgnoredDueToMatchingPairs(string lang, int count)
switch (lang)
{
case "french":
- return $"{count} chaîne(s) avaient des paires correspondantes et n'ont pas été traités.";
- case "inuktitut":
- return $"{count} ᐊᒃᖢᓇᐅᔭᑦ ᐊᔾᔨᒌᓂᒃ ᐱᖃᑎᒌᓚᐅᖅᐳᑦ, ᐱᓕᕆᐊᖑᓚᐅᙱᖦᖢᑎᒡᓗ.";
+ return $"{count} alerte(s) avaient des noms correspondants et n'ont pas été téléchargées.";
case "english":
default:
- return $"{count} string(s) had matching pairs, and were not processed.";
+ return $"{count} alert(s) had matching names, and were not downloaded.";
+ }
+ }
+
+ public static string AlertInvalid(string lang)
+ {
+ switch (lang)
+ {
+ case "french":
+ return "Cette alerte n'est pas valide et ne peut pas être traitée.";
+ case "english":
+ default:
+ return "This alert is invalid and cannot be processed.";
}
}
@@ -187,8 +197,6 @@ public static string AlertIgnoredDueToPreferences(string lang)
{
case "french":
return "Cette alerte ne sera pas traitée en raison des préférences de l'utilisateur.";
- case "inuktitut":
- return "ᑖᓐᓇ ᖃᐅᔨᓴᕈᑎ ᐱᓕᕆᐊᖑᔾᔮᙱᑦᑐᖅ ᐊᑐᖅᑎᑦ ᓂᕈᐊᕆᔭᖏᑦ ᐱᔾᔪᑎᒋᓪᓗᒋᑦ.";
case "english":
default:
return "This alert won't be processed due to the user preferences.";
@@ -251,7 +259,7 @@ public static string PlayingAudio(string lang)
}
}
- public static string CapturedFromFileWatcher(string lang)
+ public static string CapturedFromFileWatcher(string lang, DateTime dt)
{
switch (lang)
{
@@ -261,7 +269,7 @@ public static string CapturedFromFileWatcher(string lang)
return "ᓄᑖᑦ ᓈᓴᐅᑏᑦ/ᑎᑎᖅᑲᐃᑦ ᐱᔭᐅᓚᐅᖅᑐᑦ.";
case "english":
default:
- return "New data was captured.";
+ return $"Data captured at {dt:T}.";
}
}
@@ -354,14 +362,12 @@ public static string ConfigurationLossProblem(string lang)
switch (lang)
{
case "french":
- return $"Vous perdrez probablement votre configuration parce que vous utilisez un compte invité." +
+ return $"Vous perdrez probablement votre configuration parce que vous utilisez un compte invité.\r\n" +
$"S’il vous plaît exécuter SharpENDEC sous un utilisateur normal pour garder votre configuration !";
- case "inuktitut":
- return "";
case "english":
default:
- return $"ᐋᖅᑭᒃᓯᒪᓂᕆᔭᐃᑦ ᐊᓯᐅᔨᑐᐃᓐᓇᕆᐊᖃᖅᑕᑦ ᓲᖃᐃᒻᒪ ᐊᑐᕋᕕᑦ ᖃᐃᖁᔭᐅᓯᒪᔪᒥᒃ ᓇᓕᖅᑲᒥᒃ.\r\n" +
- $"SharpENDEC-ᑯᑦ ᐃᖏᕐᕋᑎᖃᑦᑕᕐᓂᐊᖅᐸᑎᑦ ᐊᑐᒐᔪᒃᑕᒃᑯᑦ ᐋᖅᑭᒃᓯᒪᓂᕆᔭᐃᑦᑏᓐᓇᕋᓱᒡᓗᒍ!";
+ return $"You will lose your configuration because you are using a guest account.\r\n" +
+ $"Please run SharpENDEC under a normal user to keep your configuration!";
}
}
@@ -370,12 +376,10 @@ public static string DataPreviouslyProcessed(string lang)
switch (lang)
{
case "french":
- return "Les données ont été ignorées car elles se trouvaient déjà dans la file d’attente ou dans l’historique.";
- case "inuktitut":
- return "ᑖᒃᑯᐊ ᑎᑎᕋᖅᓯᒪᔪᑦ ᐲᖅᑕᐅᑐᐃᓐᓇᓚᐅᖅᑐᑦ ᐱᔾᔪᑎᒋᓪᓗᒍ ᐱᑕᖃᕇᕐᒪᑦ ᐅᕝᕙᓘᓐᓃᑦ ᐅᐊᑦᑎᐊᕈᓐᓂᓴᕐᓂᒃ.";
+ return "Les données ont été ignorées en raison d'une correspondance file d'attente/historique.";
case "english":
default:
- return "The data was skipped because it's already in either the queue or history.";
+ return "The data was skipped due to a queue/history match.";
}
}
@@ -385,8 +389,6 @@ public static string GenericProcessingValueOfValue(string lang, int x, int y)
{
case "french":
return $"Traitement {x} de {y}.";
- case "inuktitut":
- return $"ᐱᓕᕆᐊᖃᕐᓂᖅ {x} ᑲᑎᖦᖢᒋᑦ {y}.";
case "english":
default:
return $"Processing {x} of {y}.";
@@ -400,8 +402,6 @@ public static string DownloadFailure(string lang)
{
case "french":
return $"Impossible de télécharger le fichier.";
- case "inuktitut":
- return $"ᒥᓇᕆᙱᑕᖓ ᑎᑎᖅᑲᖓ.";
case "english":
default:
return $"Failed to download the file.";
@@ -414,11 +414,21 @@ public static string AlertIgnoredDueToBlacklist(string lang)
{
case "french":
return "Cette alerte ne sera pas traitée en raison de la liste noire.";
- case "inuktitut":
- return "ᑖᓐᓇ ᖃᐅᔨᓴᕈᑎ ᐱᓕᕆᐊᖑᔾᔮᙱᑦᑐᖅ ᕿᕐᓂᖅᑕᒧᑦ.";
case "english":
default:
- return "This alert won't be processed due to the blacklist.";
+ return "This alert won't be processed further due to the blacklist.";
+ }
+ }
+
+ public static string AlertIgnoredDueToExpiry(string lang)
+ {
+ switch (lang)
+ {
+ case "french":
+ return "Cette alerte ne sera plus traitée parce qu'elle a expiré.";
+ case "english":
+ default:
+ return "This alert won't be processed further because it has expired.";
}
}
}
diff --git a/SharpENDEC/Plugins/DiscordWebhook.cs b/SharpENDEC/Plugins/DiscordWebhook.cs
new file mode 100644
index 0000000..47b4f08
--- /dev/null
+++ b/SharpENDEC/Plugins/DiscordWebhook.cs
@@ -0,0 +1,25 @@
+using System.Diagnostics;
+
+namespace SharpENDEC
+{
+ public class DiscordWebhook : ISharpPlugin
+ {
+ public void AlertBlacklisted()
+ {
+ }
+
+ public void AlertRelayingNow(string BroadcastText)
+ {
+ //Process.Start("cmd.exe", $"/c start cmd.exe /k echo {BroadcastText}");
+ }
+
+ public void ProvideBroadcastText(string text)
+ {
+ }
+
+ public bool RelayAlert(string info, string status, string MsgType, string severity, string urgency, string broadcastImmediately)
+ {
+ return true;
+ }
+ }
+}
diff --git a/SharpENDEC/Plugins/ISharpPlugin.cs b/SharpENDEC/Plugins/ISharpPlugin.cs
new file mode 100644
index 0000000..a07ee0e
--- /dev/null
+++ b/SharpENDEC/Plugins/ISharpPlugin.cs
@@ -0,0 +1,10 @@
+namespace SharpENDEC
+{
+ internal interface ISharpPlugin
+ {
+ void AlertBlacklisted();
+ void AlertRelayingNow(string BroadcastText);
+ void ProvideBroadcastText(string text);
+ bool RelayAlert(string info, string status, string MsgType, string severity, string urgency, string broadcastImmediately);
+ }
+}
diff --git a/SharpENDEC/Program.cs b/SharpENDEC/Program.cs
index 34a427f..43f2983 100644
--- a/SharpENDEC/Program.cs
+++ b/SharpENDEC/Program.cs
@@ -2,12 +2,19 @@
using SharpENDEC.Properties;
using System;
using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
using System.IO;
+using System.Linq;
+using System.Management;
using System.Reflection;
+using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Speech.Synthesis;
using System.Threading;
+using System.Windows.Forms;
using static SharpENDEC.VersionInfo;
+using ThreadState = System.Threading.ThreadState;
namespace SharpENDEC
{
@@ -55,12 +62,16 @@ public static void ClearFolder(string directory)
///
public static void Init(string VersionID, bool RecoveredFromProblem)
{
- Console.Title = VersionID;
+ EnablePerformanceProcessor = false;
+ Console.Title = VersionID + " | *";
+ EnablePerformanceProcessor = true;
+
ConsoleExt.WriteLine($"{VersionID}\r\n" +
- $"Source code forked from QuantumENDEC 4.\r\n\r\n" +
+ $"This project wouldn't have been possible without ApatheticDELL's QuantumENDEC!\r\n\r\n" +
$"Project created by BunnyTub.\r\n" +
$"Logo created by ApatheticDELL.\r\n" +
- $"Translations may not be 100% accurate due to language deviations.\r\n");
+ $"Translations may not be 100% accurate due to language deviations.\r\n" +
+ $"Translations are not fully complete, and may be undone.\r\n");
if (RecoveredFromProblem) ConsoleExt.WriteLine(LanguageStrings.RecoveredFromFailure(Settings.Default.CurrentLanguage), ConsoleColor.DarkRed);
if (IsAdministrator) ConsoleExt.WriteLine(LanguageStrings.ElevationSecurityProblem(Settings.Default.CurrentLanguage), ConsoleColor.Yellow);
@@ -70,15 +81,15 @@ public static void Init(string VersionID, bool RecoveredFromProblem)
if (!File.Exists($"{AudioDirectory}\\attn.wav"))
{
+ ConsoleExt.WriteLine("The attention tone audio \"attn.wav\" doesn't exist. The default one will be extracted and used instead.");
MemoryStream mem = new MemoryStream();
Resources.attn.CopyTo(mem);
File.WriteAllBytes("Audio\\attn.wav", mem.ToArray());
mem.Dispose();
- ConsoleExt.WriteLine("The attention tone audio \"attn.wav\" doesn't exist. The default one will be used instead.");
}
//ConsoleExt.WriteLine();
- ConsoleExt.WriteLine($"Press SPACE to pause for 30 seconds.");
+ ConsoleExt.WriteLine($"Press SPACE to pause for 15 seconds.");
bool alreadyPaused = false;
@@ -92,8 +103,8 @@ public static void Init(string VersionID, bool RecoveredFromProblem)
switch (Console.ReadKey(true).Key)
{
case ConsoleKey.Spacebar:
- ConsoleExt.WriteLine("Paused for 30 seconds.");
- Thread.Sleep(30000);
+ ConsoleExt.WriteLine("Paused for 15 seconds.");
+ Thread.Sleep(15000);
alreadyPaused = true;
continue;
}
@@ -471,36 +482,7 @@ public static void StreamProcessor()
}
public static FeedCapture Capture;
- public static List ClientThreads = new List();
-
- //public static Thread MethodToThread(Action method)
- //{
- // return new Thread(() =>
- // {
- // try
- // {
- // method();
- // }
- // catch (ThreadAbortException ex)
- // {
- // ConsoleExt.WriteLine($"Shutdown caught in thread: {ex.Message}");
- // File.AppendAllText($"{AssemblyDirectory}\\exception.log",
- // $"{DateTime.Now:G} | Shutdown in {method.Method.Name}\r\n" +
- // $"{ex.StackTrace}\r\n" +
- // $"{ex.Source}\r\n" +
- // $"{ex.Message}\r\n");
- // }
- // catch (Exception ex)
- // {
- // ConsoleExt.WriteLine($"Exception caught in thread: {ex.Message}");
- // File.AppendAllText($"{AssemblyDirectory}\\exception.log",
- // $"{DateTime.Now:G} | Exception in {method.Method.Name}\r\n" +
- // $"{ex.StackTrace}\r\n" +
- // $"{ex.Source}\r\n" +
- // $"{ex.Message}\r\n");
- // }
- // });
- //}
+ public static List CaptureThreads = new List();
public static void KeyboardProcessor()
{
@@ -541,6 +523,43 @@ public static void KeyboardProcessor()
SkipPlayback = true;
ConsoleExt.WriteLine("Audio playback has been disabled for this time only.");
break;
+ case ConsoleKey.O:
+ OpenFileDialog AlertFileDialog = new OpenFileDialog
+ {
+ //InitialDirectory = "C:\\",
+ Filter = "CAP files (*.xml, *.cap)|*.xml;*.cap",
+ FilterIndex = 0,
+ CheckFileExists = true,
+ Multiselect = false
+ };
+ //AlertFileDialog.RestoreDirectory = true;
+
+ ConsoleExt.WriteLine("Opening file picker.");
+
+ if (AlertFileDialog.ShowDialog() != DialogResult.OK)
+ {
+ ConsoleExt.WriteLine("No file chosen.");
+ break;
+ }
+
+ try
+ {
+ string data = File.ReadAllText(AlertFileDialog.FileName);
+ lock (SharpDataQueue)
+ SharpDataQueue.Add(new SharpDataItem(AlertFileDialog.SafeFileName, data));
+ ConsoleExt.WriteLine("Added file to queue.");
+ }
+ catch (Exception e)
+ {
+ ConsoleExt.WriteLineErr(e.Message);
+ }
+ finally
+ {
+ AlertFileDialog.Dispose();
+ }
+
+ break;
+
//case ConsoleKey.G:
// ConsoleExt.WriteLine("GUI shown.");
// break;
@@ -551,7 +570,70 @@ public static void KeyboardProcessor()
}
}
- public static void AddThread(ThreadStart method)
+ public static bool EnablePerformanceProcessor = false;
+
+ public static void TitleProcessor()
+ {
+ string originalTitle = Console.Title;
+ Process thisProcess = Process.GetCurrentProcess();
+ PerformanceCounter cpuCounter;
+ cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
+
+ while (true)
+ {
+ if (EnablePerformanceProcessor)
+ {
+ Console.Title = originalTitle.Replace("*", $"{cpuCounter.NextValue() / Environment.ProcessorCount:0.00}% CPU - {thisProcess.WorkingSet64 / (1024 * 1024)} MB");
+ thisProcess.Refresh();
+ }
+ Thread.Sleep(1000);
+ }
+ }
+
+ public static void BatteryProcessor()
+ {
+ // if (Battery.UsageEnabled) then DoBatteryStuff
+ //try
+ {
+ while (true)
+ {
+ try
+ {
+ foreach (ManagementObject battery in new ManagementObjectSearcher("Select * from Win32_Battery")
+ .Get()
+ .Cast())
+ {
+ string name = battery["Name"]?.ToString();
+ string status = battery["Status"]?.ToString();
+ int estimatedChargeRemaining = Convert.ToInt32(battery["EstimatedChargeRemaining"]);
+ int estimatedRunTime = Convert.ToInt32(battery["EstimatedRunTime"]);
+
+ Console.WriteLine($"Battery Name: {name}");
+ Console.WriteLine($"Status: {status}");
+ Console.WriteLine($"Charge Remaining: {estimatedChargeRemaining}%");
+
+ // Estimated run time in minutes, -1 means unknown
+ if (estimatedRunTime != -1)
+ {
+ Console.WriteLine($"Estimated Run Time: {TimeSpan.FromMinutes(estimatedRunTime)}");
+ }
+ else
+ {
+ Console.WriteLine("Estimated Run Time: Unknown");
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"An error occurred: {ex.Message}");
+ }
+ //Thread.Sleep(10000);
+ Thread.Sleep(1000);
+ }
+ }
+ }
+
+ public static Thread AddThread(ThreadStart method, bool isMTA)
{
Thread thread = new Thread(() =>
{
@@ -559,19 +641,43 @@ public static void AddThread(ThreadStart method)
catch (ThreadAbortException) { }
catch (Exception e) { MainExt.UnsafeStateShutdown(null, e, e.Message); }
});
- Program.MainThreads.Add((thread, method));
+ if (isMTA) thread.SetApartmentState(ApartmentState.MTA);
+ else thread.SetApartmentState(ApartmentState.STA);
+ Program.MainThreads.Add((thread, method, isMTA));
thread.Start();
+ return thread;
}
+ public static void KillAllThreads()
+ {
+ var threadList = new List();
+ foreach (var (thread, _, _) in Program.MainThreads)
+ {
+ threadList.Add(thread);
+ }
+ Program.MainThreads.Clear();
+ foreach (var thread in threadList)
+ {
+ thread.Abort();
+ }
+ }
+
public static void RestartAllThreads()
{
- foreach (var (thread, method) in Program.MainThreads)
+ var threadList = new List<(Thread thread, ThreadStart method, bool isMTA)>();
+ foreach (var (thread, method, isMTA) in Program.MainThreads)
+ {
+ threadList.Add((thread, method, isMTA));
+ RestartThread(thread, method, isMTA);
+ }
+ Program.MainThreads.Clear();
+ foreach (var (thread, method, isMTA) in threadList)
{
- RestartThread(thread, method);
+ Program.MainThreads.Add((thread, method, isMTA));
}
}
- public static void RestartThread(Thread serviceThread, ThreadStart method)
+ public static void RestartThread(Thread serviceThread, ThreadStart method, bool IsMTAThread)
{
if (serviceThread != null)
{
@@ -579,55 +685,102 @@ public static void RestartThread(Thread serviceThread, ThreadStart method)
serviceThread.Abort();
}
- Thread newThread = new Thread(method);
- newThread.Start();
-
- int index = Program.MainThreads.IndexOf((serviceThread, method));
- if (index >= 0)
- {
- Program.MainThreads[index] = (newThread, method);
- }
- else
+ Thread thread = new Thread(() =>
{
- Program.MainThreads.Add((newThread, method));
- }
+ try { method(); }
+ catch (ThreadAbortException) { }
+ catch (Exception e) { MainExt.UnsafeStateShutdown(null, e, e.Message); }
+ });
+ if (IsMTAThread) thread.SetApartmentState(ApartmentState.MTA);
+ else thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+
+ //int index = Program.MainThreads.IndexOf((serviceThread, method));
+ //if (index >= 0)
+ //{
+ // Program.MainThreads[index] = (newThread, method);
+ //}
+ //else
+ //{
+ // Program.MainThreads.Add((newThread, method));
+ //}
}
+ //public static IEnumerable handlers = AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes())
+ // .Where(p => typeof(ISharpPlugin).IsAssignableFrom(p) && p.IsClass);
+
public static Thread Watchdog()
{
return new Thread(() =>
{
- string ProgramVersion = FriendlyVersion;
- Init(ProgramVersion, false);
-
- void ShutdownCapture()
+ try
{
- if (Capture != null)
+ string ProgramVersion = FriendlyVersion;
+ Init(ProgramVersion, false);
+
+ void ShutdownCapture()
{
- Capture.ShutdownCapture = true;
- while (Capture.ShutdownCapture)
+ if (Capture != null)
{
- Thread.Sleep(500);
+ Capture.ShutdownCapture = true;
+ while (Capture.ShutdownCapture)
+ {
+ Thread.Sleep(500);
+ }
}
+ ConsoleExt.WriteLine($"{LanguageStrings.ThreadShutdown(Settings.Default.CurrentLanguage, $"Data Processor")}");
}
- ConsoleExt.WriteLine($"{LanguageStrings.ThreadShutdown(Settings.Default.CurrentLanguage, $"Data Processor")}");
- }
- Config();
+ Config();
- while (true)
- {
- Check.LastHeartbeat = DateTime.Now;
+ //foreach (var handler in handlers)
+ //{
+ // var handlerInstance = (ISharpPlugin)Activator.CreateInstance(handler);
+ // //handlerInstance.AlertBlacklisted();
+ //}
+
+#if !DEBUG
+ Process parent;
+
+ try
+ {
+ var myId = Process.GetCurrentProcess().Id;
+ var search = new ManagementObjectSearcher("root\\CIMV2",
+ $"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {Process.GetCurrentProcess().Id}");
+ var results = search.Get().GetEnumerator();
+ results.MoveNext();
+ parent = Process.GetProcessById((int)(uint)results.Current["ParentProcessId"]);
+ }
+ catch (Exception)
+ {
+ ConsoleExt.WriteLine("Process is malfunctioning.");
+ return;
+ }
+#endif
//if (!Program.MainThreads.Contains(Thread.CurrentThread)) Program.MainThreads.Add(Thread.CurrentThread);
- AddThread(StreamProcessor);
- AddThread(DataProcessor);
- AddThread(AlertProcessor);
- AddThread(KeyboardProcessor);
+ AddThread(StreamProcessor, true);
+ AddThread(DataProcessor, true);
+ AddThread(AlertProcessor, true);
+ AddThread(KeyboardProcessor, false);
+ AddThread(TitleProcessor, true);
+ //AddThread(BatteryProcessor);
+ AddThread(HTTPServerProcessor, true);
+
+ Check.LastHeartbeat = DateTime.Now;
while (true)
{
+#if !DEBUG
+ if (parent.HasExited)
+ {
+ ShutdownCapture();
+ KillAllThreads();
+ Environment.Exit(1985);
+ }
+#endif
+
if ((DateTime.Now - Check.LastHeartbeat).TotalMinutes >= 5)
{
if ((DateTime.Now - Check.LastHeartbeat).TotalMinutes >= 10)
@@ -643,9 +796,9 @@ void ShutdownCapture()
}
catch (Exception)
{
-
+
}
-
+
break;
}
//else ConsoleExt.WriteLine($"[Watchdog] {LanguageStrings.WatchdogForcedRestartWarning(Settings.Default.CurrentLanguage)}", ConsoleColor.Red);
@@ -653,6 +806,8 @@ void ShutdownCapture()
Thread.Sleep(5000);
}
}
+ catch (ThreadAbortException) { }
+ catch (Exception e) { MainExt.UnsafeStateShutdown(null, e, e.Message); }
});
}
}
@@ -660,30 +815,103 @@ void ShutdownCapture()
internal static class Program
{
internal static Thread WatchdogService;
- //internal static Thread StreamService;
- //internal static Thread RelayService;
- //internal static Thread KeyboardProc;
- //internal static Thread BatteryProc;
- internal static List<(Thread, ThreadStart)> MainThreads = new List<(Thread, ThreadStart)>();
+ internal static List<(Thread, ThreadStart, bool)> MainThreads = new List<(Thread, ThreadStart, bool)>();
+ internal const uint ENABLE_QUICK_EDIT = 0x0040;
+ internal const uint ENABLE_EXTENDED_FLAGS = 0x0080;
+ public const int STD_INPUT_HANDLE = -10;
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ internal static extern IntPtr GetStdHandle(int nStdHandle);
+
+ [DllImport("kernel32.dll")]
+ internal static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
+
+ [DllImport("kernel32.dll")]
+ internal static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
[STAThread]
- internal static void Main()
+ internal static void Main(string[] args)
{
Console.Title = "SharpENDEC";
Console.ForegroundColor = ConsoleColor.White;
- // PLUGIN IMPLEMENTATION!!!
- // BATTERY IMPLEMENTATION!!!
- // GUI IMPLEMENTATION!!!
- //Thread thread = new Thread(() => new ConsoleForm().ShowDialog());
- //thread.Start();
- WatchdogService = ENDEC.Watchdog();
- WatchdogService.Start();
- Console.CancelKeyPress += CancelAllOperations;
+
+#if !DEBUG
+ string WatchdogArgument = "--redundant-watchdog";
+
+ if (args.Length == 1)
+ {
+ if (args[0] == WatchdogArgument)
+ {
+#endif
+ DisableConsoleHighlighting();
+ // BATTERY IMPLEMENTATION!!! - BUSY
+ // GUI IMPLEMENTATION!!! - UNKNOWN / BUSY
+ WatchdogService = ENDEC.Watchdog();
+ WatchdogService.Start();
+#if !DEBUG
+ }
+ }
+ else
+ {
+ bool restart = false;
+
+ do
+ {
+ using (var p = new Process
+ {
+ StartInfo = new ProcessStartInfo(Assembly.GetExecutingAssembly().Location)
+ {
+ Arguments = WatchdogArgument,
+ UseShellExecute = false
+ }
+ })
+ {
+ p.Start();
+ p.WaitForExit();
+
+ if (p.ExitCode == 1984)
+ {
+ restart = true;
+ }
+ else
+ {
+ restart = false;
+ }
+ }
+ } while (restart);
+ }
+#endif
}
- private static void CancelAllOperations(object sender, ConsoleCancelEventArgs e)
+ internal static bool DisableConsoleHighlighting()
{
+ IntPtr consoleHandle = GetStdHandle(STD_INPUT_HANDLE);
+
+ if (!GetConsoleMode(consoleHandle, out uint mode))
+ {
+ var MarshalException = new Win32Exception(unchecked(Marshal.GetLastWin32Error()));
+ ConsoleExt.WriteLineErr($"Could not get the console mode. This may cause problems if you select text often.\r\n" +
+ $"You can ignore this message if you're not running Windows 10 or above.\r\n" +
+ $"Reason: {MarshalException.Message}");
+ Thread.Sleep(5000);
+ return false;
+ }
+
+ mode &= ~ENABLE_QUICK_EDIT;
+ mode |= ENABLE_EXTENDED_FLAGS;
+
+ if (!SetConsoleMode(consoleHandle, mode))
+ {
+ var MarshalException = new Win32Exception(unchecked(Marshal.GetLastWin32Error()));
+ ConsoleExt.WriteLineErr($"Could not set the console mode. This may cause problems if you select text often.\r\n" +
+ $"You can ignore this message if you're not running Windows 10 or above.\r\n" +
+ $"Reason: {MarshalException.Message}");
+ Thread.Sleep(5000);
+ return false;
+ }
+ // if we don't use unchecked(), the error might cause an error
+ return true;
}
}
}
\ No newline at end of file
diff --git a/SharpENDEC/SharpENDEC.csproj b/SharpENDEC/SharpENDEC.csproj
index 3fe8c0c..5abbdb2 100644
--- a/SharpENDEC/SharpENDEC.csproj
+++ b/SharpENDEC/SharpENDEC.csproj
@@ -66,13 +66,37 @@
..\packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll
+
+ ..\packages\Microsoft.Bcl.AsyncInterfaces.9.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll
+
..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll
True
True
-
- ..\packages\NAudio.1.10.0\lib\net35\NAudio.dll
+
+ ..\packages\Microsoft.Win32.Registry.5.0.0\lib\net461\Microsoft.Win32.Registry.dll
+
+
+ ..\packages\NAudio.2.2.1\lib\net472\NAudio.dll
+
+
+ ..\packages\NAudio.Asio.2.2.1\lib\netstandard2.0\NAudio.Asio.dll
+
+
+ ..\packages\NAudio.Core.2.2.1\lib\netstandard2.0\NAudio.Core.dll
+
+
+ ..\packages\NAudio.Midi.2.2.1\lib\netstandard2.0\NAudio.Midi.dll
+
+
+ ..\packages\NAudio.Wasapi.2.2.1\lib\netstandard2.0\NAudio.Wasapi.dll
+
+
+ ..\packages\NAudio.WinForms.2.2.1\lib\net472\NAudio.WinForms.dll
+
+
+ ..\packages\NAudio.WinMM.2.2.1\lib\netstandard2.0\NAudio.WinMM.dll
..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll
@@ -83,15 +107,18 @@
True
True
+
+ ..\packages\System.Buffers.4.6.0\lib\net462\System.Buffers.dll
+
-
- ..\packages\System.Console.4.3.0\lib\net46\System.Console.dll
+
+ ..\packages\System.Console.4.3.1\lib\net46\System.Console.dll
True
True
-
- ..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\net46\System.Diagnostics.DiagnosticSource.dll
+
+ ..\packages\System.Diagnostics.DiagnosticSource.9.0.0\lib\net462\System.Diagnostics.DiagnosticSource.dll
..\packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll
@@ -129,6 +156,9 @@
True
True
+
+ ..\packages\System.IO.Pipelines.9.0.0\lib\net462\System.IO.Pipelines.dll
+
..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll
True
@@ -140,8 +170,11 @@
True
-
- ..\packages\System.Net.Http.4.3.0\lib\net46\System.Net.Http.dll
+
+ ..\packages\System.Memory.4.6.0\lib\net462\System.Memory.dll
+
+
+ ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll
True
True
@@ -151,18 +184,24 @@
True
+
+ ..\packages\System.Numerics.Vectors.4.6.0\lib\net462\System.Numerics.Vectors.dll
+
..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll
True
True
-
- ..\packages\System.Runtime.4.3.0\lib\net462\System.Runtime.dll
+
+ ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll
True
True
-
- ..\packages\System.Runtime.Extensions.4.3.0\lib\net462\System.Runtime.Extensions.dll
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.1.0\lib\net462\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ ..\packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll
True
True
@@ -176,8 +215,12 @@
True
True
+
+ ..\packages\System.Security.AccessControl.6.0.1\lib\net461\System.Security.AccessControl.dll
+
- ..\packages\System.Security.Cryptography.Algorithms.4.3.0\lib\net463\System.Security.Cryptography.Algorithms.dll
+ ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll
+ True
True
@@ -190,17 +233,32 @@
True
True
-
- ..\packages\System.Security.Cryptography.X509Certificates.4.3.0\lib\net461\System.Security.Cryptography.X509Certificates.dll
+
+ ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll
True
True
+
+ ..\packages\System.Security.Principal.Windows.5.0.0\lib\net461\System.Security.Principal.Windows.dll
+
+
+ ..\packages\System.Text.Encodings.Web.9.0.0\lib\net462\System.Text.Encodings.Web.dll
+
+
+ ..\packages\System.Text.Json.9.0.0\lib\net462\System.Text.Json.dll
+
- ..\packages\System.Text.RegularExpressions.4.3.0\lib\net463\System.Text.RegularExpressions.dll
+ ..\packages\System.Text.RegularExpressions.4.3.1\lib\net463\System.Text.RegularExpressions.dll
True
True
+
+ ..\packages\System.Threading.Tasks.Extensions.4.6.0\lib\net462\System.Threading.Tasks.Extensions.dll
+
+
+ ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll
+
@@ -210,13 +268,14 @@
- ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll
+ ..\packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll
True
True
+
Form
@@ -229,7 +288,10 @@
+
+
+
Form
@@ -307,6 +369,7 @@
+
@@ -321,30 +384,29 @@
false
+
-
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
+
+
REM del "$(TargetDir)SharpENDEC.pdb"
-del "$(TargetDir)SharpENDEC.exe.config"
-
-del "$(TargetDir)NAudio.xml"
-
-del "$(TargetDir)Newtonsoft.Json.xml"
+del "$(TargetDir)*.config"
-del "$(TargetDir)System.Diagnostics.DiagnosticSource.xml"
+del "$(TargetDir)*.xml"
cd $(ProjectDir)
powershell -ExecutionPolicy Bypass -File "$(ProjectDir)UpdateVersionInfo.ps1"
+
+
\ No newline at end of file
diff --git a/SharpENDEC/VersionInfo.cs b/SharpENDEC/VersionInfo.cs
index f0a2847..ca54395 100644
--- a/SharpENDEC/VersionInfo.cs
+++ b/SharpENDEC/VersionInfo.cs
@@ -1,5 +1,3 @@
-using System.Diagnostics;
-
namespace SharpENDEC
{
public static class VersionInfo
@@ -8,11 +6,11 @@ public static class VersionInfo
// You can change the release, minor, and cutting edge variables.
// ---
// Use VersionInfoTemplate.cs!
- public const int BuildNumber = 596;
- public const string BuiltOnDate = "2024-10-20";
- public const string BuiltOnTime = "09:14";
+ public const int BuildNumber = 704;
+ public const string BuiltOnDate = "2024-11-28";
+ public const string BuiltOnTime = "18:30";
public const string BuiltTimeZone = "Eastern Standard Time";
- public static readonly int ReleaseVersion = 2;
+ public static readonly int ReleaseVersion = 3;
public static readonly int MinorVersion = 0;
public static readonly bool IsCuttingEdge = false;
public static string FriendlyVersion
@@ -25,9 +23,7 @@ public static string FriendlyVersion
}
else
{
- if (Debugger.IsAttached) return $"SharpENDEC | Cutting Edge {ReleaseVersion}.{MinorVersion}-c (Build {BuildNumber}) | Built on {BuiltOnDate} {BuiltOnTime} ({BuiltTimeZone})";
- else return $"SharpENDEC | Cutting Edge {ReleaseVersion}.{MinorVersion}-c (Build {BuildNumber}) | Built on {BuiltOnDate} {BuiltOnTime} ({BuiltTimeZone})\r\n" +
- $"Debugger Attached | Is Logging: {Debugger.IsLogging()}";
+ return $"SharpENDEC | Cutting Edge {ReleaseVersion}.{MinorVersion}-c (Build {BuildNumber}) | Built on {BuiltOnDate} {BuiltOnTime} ({BuiltTimeZone})";
}
}
}
diff --git a/SharpENDEC/VersionInfoTemplate.cs b/SharpENDEC/VersionInfoTemplate.cs
index def75a8..a519a92 100644
--- a/SharpENDEC/VersionInfoTemplate.cs
+++ b/SharpENDEC/VersionInfoTemplate.cs
@@ -1,6 +1,4 @@
-using System.Diagnostics;
-
-namespace SharpENDEC
+namespace SharpENDEC
{
public static class VersionInfoTemplate
{
@@ -12,7 +10,7 @@ public static class VersionInfoTemplate
public const string BuiltOnDate = "";
public const string BuiltOnTime = "";
public const string BuiltTimeZone = "";
- public static readonly int ReleaseVersion = 2;
+ public static readonly int ReleaseVersion = 3;
public static readonly int MinorVersion = 0;
public static readonly bool IsCuttingEdge = false;
public static string FriendlyVersion
@@ -25,9 +23,7 @@ public static string FriendlyVersion
}
else
{
- if (Debugger.IsAttached) return $"SharpENDEC | Cutting Edge {ReleaseVersion}.{MinorVersion}-c (Build {BuildNumber}) | Built on {BuiltOnDate} {BuiltOnTime} ({BuiltTimeZone})";
- else return $"SharpENDEC | Cutting Edge {ReleaseVersion}.{MinorVersion}-c (Build {BuildNumber}) | Built on {BuiltOnDate} {BuiltOnTime} ({BuiltTimeZone})\r\n" +
- $"Debugger Attached | Is Logging: {Debugger.IsLogging()}";
+ return $"SharpENDEC | Cutting Edge {ReleaseVersion}.{MinorVersion}-c (Build {BuildNumber}) | Built on {BuiltOnDate} {BuiltOnTime} ({BuiltTimeZone})";
}
}
}
diff --git a/SharpENDEC/packages.config b/SharpENDEC/packages.config
index 7daa006..bc02615 100644
--- a/SharpENDEC/packages.config
+++ b/SharpENDEC/packages.config
@@ -1,18 +1,27 @@
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
+
@@ -22,32 +31,42 @@
+
-
-
+
+
+
+
-
-
+
+
+
-
+
+
-
+
+
-
+
+
+
+
-
+
+
\ No newline at end of file