From 20adf93d392dd559ef56e5778c1cf317460acb63 Mon Sep 17 00:00:00 2001 From: Florian Stinglmayr Date: Tue, 17 Sep 2024 19:53:17 +0200 Subject: [PATCH] implement log splitting for discord posting --- EliteBGS/DiscordLogGenerator.cs | 49 +++++++++++++++++++++++++++++++++ EliteBGS/GenericDiscordLog.cs | 9 +++++- EliteBGS/MainWindow.xaml.cs | 28 ++++--------------- EliteBGS/NonaDiscordLog.cs | 4 +++ EliteBGS/OneLineDiscordLog.cs | 22 +++++++++++++++ 5 files changed, 89 insertions(+), 23 deletions(-) diff --git a/EliteBGS/DiscordLogGenerator.cs b/EliteBGS/DiscordLogGenerator.cs index 925c88d..d9e649d 100644 --- a/EliteBGS/DiscordLogGenerator.cs +++ b/EliteBGS/DiscordLogGenerator.cs @@ -198,4 +198,53 @@ public class DiscordLogGenerator { return log.ToString().Trim(); } + + public virtual string[] SplitLog(string log, int maxcount = 2000) { + throw new NotImplementedException(); + } + + protected string[] SplitLogWithHeader(string log, string header, int maxcount = 2000) { + string[] lines = log.Split("\n"); + List chunks = new(); + string chunk = string.Empty; + bool done = false; + + // First split the log into its headers + // skip first bot header line + for (int i = 1; i < lines.Length; i++) { + string line = lines[i]; + + if (line.StartsWith(header) && !string.IsNullOrEmpty(chunk)) { + chunks.Add(chunk.Trim()); + chunk = string.Empty; + } + + chunk = chunk + "\n" + line; + } + + int curchunk = 0; + string botheader = BotHeader().Trim() + "\n"; + // Leave room for botheder and some leeway + int maxlength = (2000 - botheader.Length - 10); + + // Then try to collate chunks + for (curchunk = 0; curchunk < chunks.Count; ++curchunk) { + int count = chunks[curchunk].Length; + while (count < maxlength && (curchunk+1) < chunks.Count) { + count += chunks[curchunk + 1].Length + 2; + if (count < maxlength) { + chunks[curchunk] += "\n"; + chunks[curchunk] += chunks[curchunk + 1]; + chunks.RemoveAt(curchunk + 1); + } + } + } + + // Readd bott headers + for (int i = 0; i < chunks.Count; i++) { + chunks[i] = chunks[i].Insert(0, botheader); + } + + return chunks.ToArray(); + } } diff --git a/EliteBGS/GenericDiscordLog.cs b/EliteBGS/GenericDiscordLog.cs index eeb73c8..2a6efae 100644 --- a/EliteBGS/GenericDiscordLog.cs +++ b/EliteBGS/GenericDiscordLog.cs @@ -1,4 +1,7 @@ -namespace EliteBGS; +using System.Collections.Generic; +using System.Windows.Documents; + +namespace EliteBGS; public class GenericDiscordLog : DiscordLogGenerator { public override string ToString() { @@ -8,4 +11,8 @@ public class GenericDiscordLog : DiscordLogGenerator { public override string Name { get { return "Generic"; } } + + public override string[] SplitLog(string log, int maxcount = 2000) { + return SplitLogWithHeader(log, "**Date:**", maxcount); + } } diff --git a/EliteBGS/MainWindow.xaml.cs b/EliteBGS/MainWindow.xaml.cs index 8bd5a27..e00c02f 100644 --- a/EliteBGS/MainWindow.xaml.cs +++ b/EliteBGS/MainWindow.xaml.cs @@ -653,27 +653,17 @@ public partial class MainWindow : MetroWindow { } } - private bool CheckDiscordPostMessageLength() { - var content = DiscordLog.Text; - if (string.IsNullOrEmpty(content)) { - return true; - } - - if (content.Length >= DiscordPoster.DiscordLimit) { - MessageBox.Show("The log is too long for discord posting (limit of 2000 characters).", - "Error", MessageBoxButton.OK, MessageBoxImage.Error); - return false; - } - - return true; - } - private void PostToDiscordWebhook(DiscordWebhook hook) { if (string.IsNullOrEmpty(DiscordLog.Text)) { return; } try { - DiscordPoster.PostToDiscord(hook, DiscordLog.Text); + DiscordLogGenerator discord = LogType.SelectedItem as DiscordLogGenerator; + var chunks = discord.SplitLog(DiscordLog.Text); + + foreach (var chunk in chunks) { + DiscordPoster.PostToDiscord(hook, chunk); + } Log(string.Format("successfully posted to discord webhook {0}", hook.Name)); } catch (Exception ex) { @@ -693,16 +683,10 @@ public partial class MainWindow : MetroWindow { if (hook == null) { return; } - if (!CheckDiscordPostMessageLength()) { - return; - } PostToDiscordWebhook(hook); } private void PostToAll_Click(object sender, RoutedEventArgs e) { - if (!CheckDiscordPostMessageLength()) { - return; - } foreach (DiscordWebhook hook in Config.Global.Webhooks) { PostToDiscordWebhook(hook); } diff --git a/EliteBGS/NonaDiscordLog.cs b/EliteBGS/NonaDiscordLog.cs index 0569d5f..a5bd60d 100644 --- a/EliteBGS/NonaDiscordLog.cs +++ b/EliteBGS/NonaDiscordLog.cs @@ -91,4 +91,8 @@ public class NonaDiscordLog : DiscordLogGenerator { public override string Name { get { return "NovaNavy"; } } + + public override string[] SplitLog(string log, int maxcount = 2000) { + return SplitLogWithHeader(log, ":clock2: `Date:`", maxcount); + } } diff --git a/EliteBGS/OneLineDiscordLog.cs b/EliteBGS/OneLineDiscordLog.cs index 6209829..d3bebb3 100644 --- a/EliteBGS/OneLineDiscordLog.cs +++ b/EliteBGS/OneLineDiscordLog.cs @@ -1,6 +1,9 @@ using EliteBGS.LogGenerator; +using System; +using System.Collections.Generic; using System.Linq; using System.Text; +using System.Windows.Documents; namespace EliteBGS; @@ -25,6 +28,25 @@ public class OneLineDiscordLog : DiscordLogGenerator { return ""; } + public override string[] SplitLog(string log, int maxcount = 2000) { + string[] lines = log.Split('\n'); + List chunks = new(); + string chunk = string.Empty; + + for (int i = 0; i < lines.Length; i++) { + string line = lines[i]; + if ((chunk.Length + line.Length) > maxcount || i == lines.Length - 1) { + chunks.Add(chunk.Trim()); + chunk = string.Empty; + chunk = chunk.Insert(0, BotHeader()).Trim(); + } else { + chunk = chunk + "\n" + line; + } + } + + return chunks.ToArray(); + } + public override string GenerateDiscordLog(Report report) { StringBuilder log = new StringBuilder();