mirror of
https://github.com/barelyprofessional/KfChatDotNet.git
synced 2026-05-02 04:22:04 -04:00
Attempt to improve the way long strings are split up. There's a new extension method called FancySplitMessage to achieve this. Truncation options now work on bytes instead of string length too
This commit is contained in:
@@ -285,7 +285,7 @@ public class ChatBot
|
|||||||
return messageTracker;
|
return messageTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Encoding.UTF8.GetByteCount(messageTracker.Message) > lengthLimit && lengthLimitBehavior != LengthLimitBehavior.DoNothing)
|
if (messageTracker.Message.Utf8LengthBytes() > lengthLimit && lengthLimitBehavior != LengthLimitBehavior.DoNothing)
|
||||||
{
|
{
|
||||||
if (lengthLimitBehavior == LengthLimitBehavior.RefuseToSend)
|
if (lengthLimitBehavior == LengthLimitBehavior.RefuseToSend)
|
||||||
{
|
{
|
||||||
@@ -296,7 +296,8 @@ public class ChatBot
|
|||||||
}
|
}
|
||||||
if (lengthLimitBehavior == LengthLimitBehavior.TruncateNicely)
|
if (lengthLimitBehavior == LengthLimitBehavior.TruncateNicely)
|
||||||
{
|
{
|
||||||
messageTracker.Message = messageTracker.Message.Truncate(lengthLimit);
|
// '…' is 3 bytes so we have to make room for it
|
||||||
|
messageTracker.Message = messageTracker.Message.TruncateBytes(lengthLimit - 3).TrimEnd() + "…";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lengthLimitBehavior == LengthLimitBehavior.TruncateExactly)
|
if (lengthLimitBehavior == LengthLimitBehavior.TruncateExactly)
|
||||||
@@ -304,7 +305,7 @@ public class ChatBot
|
|||||||
// ReSharper disable once ReplaceSubstringWithRangeIndexer
|
// ReSharper disable once ReplaceSubstringWithRangeIndexer
|
||||||
// The range indexer is a fucking piece of shit that does not work.
|
// The range indexer is a fucking piece of shit that does not work.
|
||||||
// TrimEnd in case you end up truncating on a space (happened during testing) as Sneedchat will trim it
|
// TrimEnd in case you end up truncating on a space (happened during testing) as Sneedchat will trim it
|
||||||
messageTracker.Message = messageTracker.Message.Substring(0, lengthLimit).TrimEnd();
|
messageTracker.Message = messageTracker.Message.TruncateBytes(lengthLimit).TrimEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +317,7 @@ public class ChatBot
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SentMessageTrackerModel SendChatMessage(string message, bool bypassSeshDetect = false,
|
public SentMessageTrackerModel SendChatMessage(string message, bool bypassSeshDetect = false,
|
||||||
LengthLimitBehavior lengthLimitBehavior = LengthLimitBehavior.TruncateNicely, int lengthLimit = 500)
|
LengthLimitBehavior lengthLimitBehavior = LengthLimitBehavior.TruncateNicely, int lengthLimit = 1023)
|
||||||
{
|
{
|
||||||
return SendChatMessageAsync(message, bypassSeshDetect, lengthLimitBehavior, lengthLimit).Result;
|
return SendChatMessageAsync(message, bypassSeshDetect, lengthLimitBehavior, lengthLimit).Result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ public class GmKasinoListCommand : ICommand
|
|||||||
result += $"[br]{i}: {image}";
|
result += $"[br]{i}: {image}";
|
||||||
}
|
}
|
||||||
|
|
||||||
await botInstance.SendChatMessagesAsync(result.SplitMessage().ToList(), true);
|
await botInstance.SendChatMessagesAsync(result.FancySplitMessage(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +213,7 @@ public class GnKasinoListCommand : ICommand
|
|||||||
result += $"[br]{i}: {image}";
|
result += $"[br]{i}: {image}";
|
||||||
}
|
}
|
||||||
|
|
||||||
await botInstance.SendChatMessagesAsync(result.SplitMessage().ToList(), true);
|
await botInstance.SendChatMessagesAsync(result.FancySplitMessage(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace KfChatDotNetBot;
|
namespace KfChatDotNetBot;
|
||||||
|
|
||||||
@@ -44,4 +45,80 @@ public static class Extensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Split messages to x number of bytes while avoiding splitting mid-word where possible
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s">String that should get split</param>
|
||||||
|
/// <param name="partLengthBytes">Length limit, no part should be > than the number of bytes specified</param>
|
||||||
|
/// <param name="partLimit">Limit for how many parts to return (returns first n elements). Set to 0 to disable.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static List<string> FancySplitMessage(this string s, int partLengthBytes = 1023, int partLimit = 5)
|
||||||
|
{
|
||||||
|
var output = new List<string>();
|
||||||
|
var part = string.Empty;
|
||||||
|
foreach (var word in s.Split(' '))
|
||||||
|
{
|
||||||
|
if (word.Utf8LengthBytes() > partLengthBytes)
|
||||||
|
{
|
||||||
|
// Add the part already in memory if there is one
|
||||||
|
if (part != string.Empty)
|
||||||
|
{
|
||||||
|
output.Add(part.TrimEnd());
|
||||||
|
part = string.Empty;
|
||||||
|
}
|
||||||
|
// Breaks into chunks of x size which will break really long URLs etc. but no other way really
|
||||||
|
output.AddRange(word.ChunkBytes(partLengthBytes));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (part.Utf8LengthBytes() + word.Utf8LengthBytes() > partLengthBytes)
|
||||||
|
{
|
||||||
|
// TrimEnd() to remove trailing spaces
|
||||||
|
output.Add(part.TrimEnd());
|
||||||
|
part = word + " ";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
part += word + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add on whatever remains
|
||||||
|
if (part != string.Empty)
|
||||||
|
{
|
||||||
|
output.Add(part.TrimEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (partLimit != 0 && output.Count > partLimit)
|
||||||
|
{
|
||||||
|
return output.Take(partLimit).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Utf8LengthBytes(this string s)
|
||||||
|
{
|
||||||
|
return Encoding.UTF8.GetByteCount(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<string> ChunkBytes(this string input, int bytesPerChunk)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(input);
|
||||||
|
|
||||||
|
for (var i = 0; i < bytes.Length; i += bytesPerChunk)
|
||||||
|
{
|
||||||
|
var chunkSize = Math.Min(bytesPerChunk, bytes.Length - i);
|
||||||
|
yield return Encoding.UTF8.GetString(bytes, i, chunkSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static string TruncateBytes(this string s, int limitBytes)
|
||||||
|
{
|
||||||
|
return Encoding.UTF8.GetString(
|
||||||
|
Encoding.UTF8.GetBytes(s)
|
||||||
|
.Take(limitBytes)
|
||||||
|
.ToArray()
|
||||||
|
).TrimEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user