From 67a5f9777ab8e80a8aa8c8c7dd97644f7a041bb9 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Sun, 27 Aug 2023 21:24:28 +0100 Subject: [PATCH] fix: add support for unicode emojis --- VPLink/Services/DiscordMessageService.cs | 26 ++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/VPLink/Services/DiscordMessageService.cs b/VPLink/Services/DiscordMessageService.cs index 8611e36..2230eaf 100644 --- a/VPLink/Services/DiscordMessageService.cs +++ b/VPLink/Services/DiscordMessageService.cs @@ -96,6 +96,9 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage SanitizeContent(guild, message.Content, ref builder); var content = builder.ToString(); + Span testSpan = stackalloc byte[Utf8Encoding.GetByteCount(content)]; + Utf8Encoding.GetBytes(content, testSpan); + _logger.LogInformation("Message by {Author}: {Content}", author, content); var messages = new List(); @@ -141,14 +144,16 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage private static void AddMessage(ICollection messages, string displayName, string content) { - Span buffer = stackalloc byte[255]; // VP message length limit int byteCount = Utf8Encoding.GetByteCount(content); + Span buffer = stackalloc byte[byteCount]; + Utf8Encoding.GetBytes(content, buffer); + var offset = 0; while (offset < byteCount) { - int length = Math.Min(byteCount - offset, 255); - Utf8Encoding.GetBytes(content.AsSpan(offset, length), buffer); - messages.Add(new RelayedMessage(displayName, Utf8Encoding.GetString(buffer), false)); + int length = Math.Min(byteCount - offset, 255); // VP message length limit + Span slice = buffer.Slice(offset, length); + messages.Add(new RelayedMessage(displayName, Utf8Encoding.GetString(slice), false)); offset += length; } } @@ -199,6 +204,8 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage { Utf8ValueStringBuilder wordBuffer = ZString.CreateUtf8StringBuilder(); + Span chars = stackalloc char[2]; + Span bytes = stackalloc byte[4]; for (var index = 0; index < content.Length; index++) { char current = content[index]; @@ -207,6 +214,13 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage AddWord(guild, ref builder, ref wordBuffer, current); wordBuffer.Clear(); } + else if (char.IsSurrogate(current)) + { + content.Slice(index++, 2).CopyTo(chars); + int byteCount = Utf8Encoding.GetByteCount(chars); + Utf8Encoding.GetBytes(chars, bytes); + wordBuffer.AppendLiteral(bytes[..byteCount]); + } else { wordBuffer.Append(current); @@ -256,6 +270,10 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage MentionUtility.ParseTag(guild, temp[..tagLength], ref builder, whitespace); break; + case var _ when char.IsSurrogate(current): + buffer.Append(chars.Slice(index++, 2)); + break; + default: buffer.Append(current); break;