mirror of https://github.com/oliverbooth/VPLink
Merge branch 'release/1.3.1' into main
This commit is contained in:
commit
1f57ecca06
|
@ -1,5 +1,4 @@
|
||||||
using Cysharp.Text;
|
using Cysharp.Text;
|
||||||
using Humanizer;
|
|
||||||
|
|
||||||
namespace VPLink.Common.Data;
|
namespace VPLink.Common.Data;
|
||||||
|
|
||||||
|
@ -35,13 +34,12 @@ public struct PlainTextMessageBuilder : IDisposable
|
||||||
/// <param name="timestamp">The timestamp.</param>
|
/// <param name="timestamp">The timestamp.</param>
|
||||||
/// <param name="format">The format.</param>
|
/// <param name="format">The format.</param>
|
||||||
/// <param name="whitespace">The trailing whitespace trivia.</param>
|
/// <param name="whitespace">The trailing whitespace trivia.</param>
|
||||||
public void AddTimestamp(DateTimeOffset timestamp, TimestampFormat format = TimestampFormat.None,
|
public void AddTimestamp(DateTimeOffset timestamp, TimestampFormat format, char whitespace = ' ')
|
||||||
char whitespace = ' ')
|
|
||||||
{
|
{
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case TimestampFormat.Relative:
|
case TimestampFormat.Relative:
|
||||||
AddWord(timestamp.Humanize(), whitespace);
|
AddWord(FormatRelativeTime(timestamp), whitespace);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TimestampFormat.None:
|
case TimestampFormat.None:
|
||||||
|
@ -104,4 +102,53 @@ public struct PlainTextMessageBuilder : IDisposable
|
||||||
{
|
{
|
||||||
return _builder.ToString().Trim();
|
return _builder.ToString().Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string FormatRelativeTime(DateTimeOffset targetTime)
|
||||||
|
{
|
||||||
|
TimeSpan timeDifference = DateTimeOffset.Now - targetTime;
|
||||||
|
bool isFuture = timeDifference.TotalMilliseconds < 0;
|
||||||
|
int value;
|
||||||
|
string unit;
|
||||||
|
|
||||||
|
timeDifference = TimeSpan.FromMilliseconds(Math.Abs(timeDifference.TotalMilliseconds));
|
||||||
|
switch (timeDifference.TotalDays)
|
||||||
|
{
|
||||||
|
case >= 365:
|
||||||
|
unit = "year";
|
||||||
|
value = (int)(timeDifference.TotalDays / 365);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case >= 30:
|
||||||
|
unit = "month";
|
||||||
|
value = (int)(timeDifference.TotalDays / 30);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case >= 1:
|
||||||
|
unit = "day";
|
||||||
|
value = (int)timeDifference.TotalDays;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (timeDifference.TotalHours >= 1)
|
||||||
|
{
|
||||||
|
unit = "hour";
|
||||||
|
value = (int)timeDifference.TotalHours;
|
||||||
|
}
|
||||||
|
else if (timeDifference.TotalMinutes >= 1)
|
||||||
|
{
|
||||||
|
unit = "minute";
|
||||||
|
value = (int)timeDifference.TotalMinutes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unit = "second";
|
||||||
|
value = (int)timeDifference.TotalSeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
string suffix = value > 1 ? "s" : "";
|
||||||
|
return isFuture ? $"in {value} {unit}{suffix}" : $"{value} {unit}{suffix} ago";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,11 @@ public static class MentionUtility
|
||||||
else
|
else
|
||||||
switch (contents[0])
|
switch (contents[0])
|
||||||
{
|
{
|
||||||
|
// custom emote
|
||||||
|
case ':':
|
||||||
|
ParseCustomEmote(contents, ref builder, whitespaceTrivia);
|
||||||
|
break;
|
||||||
|
|
||||||
// user mention
|
// user mention
|
||||||
case '@':
|
case '@':
|
||||||
ParseUserMention(guild, contents, ref builder, whitespaceTrivia);
|
ParseUserMention(guild, contents, ref builder, whitespaceTrivia);
|
||||||
|
@ -71,6 +76,15 @@ public static class MentionUtility
|
||||||
whitespaceTrivia);
|
whitespaceTrivia);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ParseCustomEmote(ReadOnlySpan<char> contents,
|
||||||
|
ref PlainTextMessageBuilder builder,
|
||||||
|
char whitespaceTrivia)
|
||||||
|
{
|
||||||
|
contents = contents[1..];
|
||||||
|
ReadOnlySpan<char> name = contents[..contents.IndexOf(':')];
|
||||||
|
builder.AddWord($":{name.ToString()}:", whitespaceTrivia);
|
||||||
|
}
|
||||||
|
|
||||||
private static void ParseTimestamp(ReadOnlySpan<char> contents,
|
private static void ParseTimestamp(ReadOnlySpan<char> contents,
|
||||||
ref PlainTextMessageBuilder builder,
|
ref PlainTextMessageBuilder builder,
|
||||||
char whitespaceTrivia)
|
char whitespaceTrivia)
|
||||||
|
|
|
@ -96,6 +96,9 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage
|
||||||
SanitizeContent(guild, message.Content, ref builder);
|
SanitizeContent(guild, message.Content, ref builder);
|
||||||
var content = builder.ToString();
|
var content = builder.ToString();
|
||||||
|
|
||||||
|
Span<byte> testSpan = stackalloc byte[Utf8Encoding.GetByteCount(content)];
|
||||||
|
Utf8Encoding.GetBytes(content, testSpan);
|
||||||
|
|
||||||
_logger.LogInformation("Message by {Author}: {Content}", author, content);
|
_logger.LogInformation("Message by {Author}: {Content}", author, content);
|
||||||
|
|
||||||
var messages = new List<RelayedMessage>();
|
var messages = new List<RelayedMessage>();
|
||||||
|
@ -141,14 +144,16 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage
|
||||||
|
|
||||||
private static void AddMessage(ICollection<RelayedMessage> messages, string displayName, string content)
|
private static void AddMessage(ICollection<RelayedMessage> messages, string displayName, string content)
|
||||||
{
|
{
|
||||||
Span<byte> buffer = stackalloc byte[255]; // VP message length limit
|
|
||||||
int byteCount = Utf8Encoding.GetByteCount(content);
|
int byteCount = Utf8Encoding.GetByteCount(content);
|
||||||
|
Span<byte> buffer = stackalloc byte[byteCount];
|
||||||
|
Utf8Encoding.GetBytes(content, buffer);
|
||||||
|
|
||||||
var offset = 0;
|
var offset = 0;
|
||||||
while (offset < byteCount)
|
while (offset < byteCount)
|
||||||
{
|
{
|
||||||
int length = Math.Min(byteCount - offset, 255);
|
int length = Math.Min(byteCount - offset, 255); // VP message length limit
|
||||||
Utf8Encoding.GetBytes(content.AsSpan(offset, length), buffer);
|
Span<byte> slice = buffer.Slice(offset, length);
|
||||||
messages.Add(new RelayedMessage(displayName, Utf8Encoding.GetString(buffer), false));
|
messages.Add(new RelayedMessage(displayName, Utf8Encoding.GetString(slice), false));
|
||||||
offset += length;
|
offset += length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,6 +204,8 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage
|
||||||
{
|
{
|
||||||
Utf8ValueStringBuilder wordBuffer = ZString.CreateUtf8StringBuilder();
|
Utf8ValueStringBuilder wordBuffer = ZString.CreateUtf8StringBuilder();
|
||||||
|
|
||||||
|
Span<char> chars = stackalloc char[2];
|
||||||
|
Span<byte> bytes = stackalloc byte[4];
|
||||||
for (var index = 0; index < content.Length; index++)
|
for (var index = 0; index < content.Length; index++)
|
||||||
{
|
{
|
||||||
char current = content[index];
|
char current = content[index];
|
||||||
|
@ -207,6 +214,13 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage
|
||||||
AddWord(guild, ref builder, ref wordBuffer, current);
|
AddWord(guild, ref builder, ref wordBuffer, current);
|
||||||
wordBuffer.Clear();
|
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
|
else
|
||||||
{
|
{
|
||||||
wordBuffer.Append(current);
|
wordBuffer.Append(current);
|
||||||
|
@ -256,6 +270,10 @@ internal sealed class DiscordMessageService : BackgroundService, IDiscordMessage
|
||||||
MentionUtility.ParseTag(guild, temp[..tagLength], ref builder, whitespace);
|
MentionUtility.ParseTag(guild, temp[..tagLength], ref builder, whitespace);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case var _ when char.IsSurrogate(current):
|
||||||
|
buffer.Append(chars.Slice(index++, 2));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
buffer.Append(current);
|
buffer.Append(current);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<Authors>Oliver Booth</Authors>
|
<Authors>Oliver Booth</Authors>
|
||||||
<RepositoryUrl>https://github.com/oliverbooth/VpBridge</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oliverbooth/VpBridge</RepositoryUrl>
|
||||||
<RepositoryType>git</RepositoryType>
|
<RepositoryType>git</RepositoryType>
|
||||||
<VersionPrefix>1.3.0</VersionPrefix>
|
<VersionPrefix>1.3.1</VersionPrefix>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
|
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
|
||||||
|
|
Loading…
Reference in New Issue