Port more things!

This commit is contained in:
Ske
2020-12-24 14:52:44 +01:00
parent f6fb8204bb
commit 47b16dc51b
26 changed files with 332 additions and 186 deletions

View File

@@ -1,6 +1,8 @@
using System.Threading.Tasks;
using Myriad.Gateway;
using Myriad.Rest;
using Myriad.Types;
namespace Myriad.Cache
{
@@ -29,7 +31,7 @@ namespace Myriad.Cache
case GuildRoleDeleteEvent grd:
return cache.RemoveRole(grd.GuildId, grd.RoleId);
case MessageCreateEvent mc:
return cache.SaveUser(mc.Author);
return cache.SaveMessageCreate(mc);
}
return default;
@@ -46,5 +48,23 @@ namespace Myriad.Cache
foreach (var member in guildCreate.Members)
await cache.SaveUser(member.User);
}
private static async ValueTask SaveMessageCreate(this IDiscordCache cache, MessageCreateEvent evt)
{
await cache.SaveUser(evt.Author);
foreach (var mention in evt.Mentions)
await cache.SaveUser(mention);
}
public static async ValueTask<User?> GetOrFetchUser(this IDiscordCache cache, DiscordApiClient rest, ulong userId)
{
if (cache.TryGetUser(userId, out var cacheUser))
return cacheUser;
var restUser = await rest.GetUser(userId);
if (restUser != null)
await cache.SaveUser(restUser);
return restUser;
}
}
}

View File

@@ -6,7 +6,7 @@ namespace Myriad.Extensions
{
public static string Mention(this User user) => $"<@{user.Id}>";
public static string AvatarUrl(this User user) =>
$"https://cdn.discordapp.com/avatars/{user.Id}/{user.Avatar}.png";
public static string AvatarUrl(this User user, string? format = "png", int? size = 128) =>
$"https://cdn.discordapp.com/avatars/{user.Id}/{user.Avatar}.{format}?size={size}";
}
}

View File

@@ -27,6 +27,7 @@ namespace Myriad.Gateway
public IReadOnlyDictionary<int, Shard> Shards => _shards;
public ClusterSessionState SessionState => GetClusterState();
public User? User => _shards.Values.Select(s => s.User).FirstOrDefault(s => s != null);
public ApplicationPartial? Application => _shards.Values.Select(s => s.Application).FirstOrDefault(s => s != null);
private ClusterSessionState GetClusterState()
{

View File

@@ -32,6 +32,7 @@ namespace Myriad.Gateway
public ShardState State { get; private set; }
public TimeSpan? Latency { get; private set; }
public User? User { get; private set; }
public ApplicationPartial? Application { get; private set; }
public Func<IGatewayEvent, Task>? OnEventReceived { get; set; }
@@ -258,6 +259,7 @@ namespace Myriad.Gateway
ShardInfo = ready.Shard;
SessionInfo = SessionInfo with { Session = ready.SessionId };
User = ready.User;
Application = ready.Application;
State = ShardState.Open;
return Task.CompletedTask;

View File

@@ -33,8 +33,11 @@ namespace Myriad.Rest
public Task<Message?> GetMessage(ulong channelId, ulong messageId) =>
_client.Get<Message>($"/channels/{channelId}/messages/{messageId}", ("GetMessage", channelId));
public Task<Channel?> GetGuild(ulong id) =>
_client.Get<Channel>($"/guilds/{id}", ("GetGuild", id));
public Task<Guild?> GetGuild(ulong id) =>
_client.Get<Guild>($"/guilds/{id}", ("GetGuild", id));
public Task<Channel[]> GetGuildChannels(ulong id) =>
_client.Get<Channel[]>($"/guilds/{id}/channels", ("GetGuildChannels", id))!;
public Task<User?> GetUser(ulong id) =>
_client.Get<User>($"/users/{id}", ("GetUser", default));

View File

@@ -77,8 +77,8 @@ namespace Myriad.Rest.Ratelimit
var headerNextReset = DateTimeOffset.UtcNow + headers.ResetAfter.Value; // todo: server time
if (headerNextReset > _nextReset)
{
_logger.Debug("{BucketKey}/{BucketMajor}: Received reset time {NextReset} from server",
Key, Major, _nextReset);
_logger.Debug("{BucketKey}/{BucketMajor}: Received reset time {NextReset} from server (after: {NextResetAfter})",
Key, Major, headerNextReset, headers.ResetAfter.Value);
_nextReset = headerNextReset;
_resetTimeValid = true;
@@ -101,7 +101,7 @@ namespace Myriad.Rest.Ratelimit
_semaphore.Wait();
// If we're past the reset time *and* we haven't reset already, do that
var timeSinceReset = _nextReset - now;
var timeSinceReset = now - _nextReset;
var shouldReset = _resetTimeValid && timeSinceReset > TimeSpan.Zero;
if (shouldReset)
{

View File

@@ -1,10 +1,22 @@
using Myriad.Types;
using System.Text.Json.Serialization;
using Myriad.Types;
using Myriad.Utils;
namespace Myriad.Rest.Types.Requests
{
public record MessageEditRequest
{
public string? Content { get; set; }
public Embed? Embed { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<string?> Content { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<Embed?> Embed { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<Message.MessageFlags> Flags { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<AllowedMentions> AllowedMentions { get; init; }
}
}

View File

@@ -7,7 +7,7 @@ namespace Myriad.Rest.Types.Requests
public string? Content { get; set; }
public object? Nonce { get; set; }
public bool Tts { get; set; }
public AllowedMentions AllowedMentions { get; set; }
public AllowedMentions? AllowedMentions { get; set; }
public Embed? Embed { get; set; }
}
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using Myriad.Utils;
namespace Myriad.Serialization
{
public class OptionalConverter: JsonConverter<IOptional>
{
public override IOptional? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var innerType = typeToConvert.GetGenericArguments()[0];
var inner = JsonSerializer.Deserialize(ref reader, innerType, options);
// TODO: rewrite to JsonConverterFactory to cut down on reflection
return (IOptional?) Activator.CreateInstance(
typeof(Optional<>).MakeGenericType(innerType),
BindingFlags.Instance | BindingFlags.Public,
null,
new[] {inner},
null);
}
public override void Write(Utf8JsonWriter writer, IOptional value, JsonSerializerOptions options)
{
var innerType = value.GetType().GetGenericArguments()[0];
JsonSerializer.Serialize(writer, value.GetValue(), innerType, options);
}
public override bool CanConvert(Type typeToConvert)
{
if (!typeToConvert.IsGenericType)
return false;
if (typeToConvert.GetGenericTypeDefinition() != typeof(Optional<>))
return false;
return true;
}
}
}

32
Myriad/Utils/Optional.cs Normal file
View File

@@ -0,0 +1,32 @@
using System.Text.Json.Serialization;
using Myriad.Serialization;
namespace Myriad.Utils
{
public interface IOptional
{
bool HasValue { get; }
object? GetValue();
}
[JsonConverter(typeof(OptionalConverter))]
public readonly struct Optional<T>: IOptional
{
public Optional(T value)
{
HasValue = true;
Value = value;
}
public bool HasValue { get; }
public object? GetValue() => Value;
public T Value { get; }
public static implicit operator Optional<T>(T value) => new(value);
public static Optional<T> Some(T value) => new(value);
public static Optional<T> None() => default;
}
}