run dotnet format

This commit is contained in:
spiral 2021-08-27 11:03:47 -04:00
parent 05989242f9
commit ac2671452d
No known key found for this signature in database
GPG Key ID: A6059F0CA0E1BD31
278 changed files with 1913 additions and 1808 deletions

View File

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Myriad.Types;
@ -11,66 +11,71 @@ namespace Myriad.Builders
public EmbedBuilder Title(string? title)
{
_embed = _embed with {Title = title};
_embed = _embed with { Title = title };
return this;
}
public EmbedBuilder Description(string? description)
{
_embed = _embed with { Description = description};
_embed = _embed with { Description = description };
return this;
}
public EmbedBuilder Url(string? url)
{
_embed = _embed with {Url = url};
_embed = _embed with { Url = url };
return this;
}
public EmbedBuilder Color(uint? color)
{
_embed = _embed with {Color = color};
_embed = _embed with { Color = color };
return this;
}
public EmbedBuilder Footer(Embed.EmbedFooter? footer)
{
_embed = _embed with {
_embed = _embed with
{
Footer = footer
};
};
return this;
}
public EmbedBuilder Image(Embed.EmbedImage? image)
{
_embed = _embed with {
_embed = _embed with
{
Image = image
};
};
return this;
}
public EmbedBuilder Thumbnail(Embed.EmbedThumbnail? thumbnail)
{
_embed = _embed with {
_embed = _embed with
{
Thumbnail = thumbnail
};
};
return this;
}
public EmbedBuilder Author(Embed.EmbedAuthor? author)
{
_embed = _embed with {
_embed = _embed with
{
Author = author
};
};
return this;
}
public EmbedBuilder Timestamp(string? timestamp)
{
_embed = _embed with {
_embed = _embed with
{
Timestamp = timestamp
};
};
return this;
}

View File

@ -1,4 +1,4 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using Myriad.Gateway;
@ -69,9 +69,9 @@ namespace Myriad.Cache
private static async ValueTask SaveMessageCreate(this IDiscordCache cache, MessageCreateEvent evt)
{
await cache.TrySaveDmChannelStub(evt.GuildId, evt.ChannelId);
await cache.SaveUser(evt.Author);
foreach (var mention in evt.Mentions)
foreach (var mention in evt.Mentions)
await cache.SaveUser(mention);
}
@ -84,7 +84,7 @@ namespace Myriad.Cache
private static async ValueTask SaveThreadListSync(this IDiscordCache cache, ThreadListSyncEvent evt)
{
foreach (var thread in evt.Threads)
foreach (var thread in evt.Threads)
await cache.SaveChannel(thread);
}
}

View File

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;
using Myriad.Types;

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
@ -15,7 +15,7 @@ namespace Myriad.Cache
private readonly ConcurrentDictionary<ulong, CachedGuild> _guilds = new();
private readonly ConcurrentDictionary<ulong, Role> _roles = new();
private readonly ConcurrentDictionary<ulong, User> _users = new();
public ValueTask SaveGuild(Guild guild)
{
SaveGuildRaw(guild);
@ -61,18 +61,20 @@ namespace Myriad.Cache
var found = false;
for (var i = 0; i < guild.Guild.Roles.Length; i++)
{
if (guild.Guild.Roles[i].Id != role.Id)
if (guild.Guild.Roles[i].Id != role.Id)
continue;
guild.Guild.Roles[i] = role;
found = true;
}
if (!found)
{
_guilds[guildId] = guild with {
Guild = guild.Guild with {
Roles = guild.Guild.Roles.Concat(new[] { role}).ToArray()
_guilds[guildId] = guild with
{
Guild = guild.Guild with
{
Roles = guild.Guild.Roles.Concat(new[] { role }).ToArray()
}
};
}
@ -87,7 +89,7 @@ namespace Myriad.Cache
// We may get a message create before channel create and we want to have it saved
_channels.GetOrAdd(channelId, id => new Channel
{
Id = id,
Id = id,
Type = Channel.ChannelType.Dm
});
return default;
@ -134,7 +136,7 @@ namespace Myriad.Cache
return false;
}
public bool TryGetChannel(ulong channelId, out Channel channel) =>
public bool TryGetChannel(ulong channelId, out Channel channel) =>
_channels.TryGetValue(channelId, out channel!);
public bool TryGetDmChannel(ulong userId, out Channel channel)
@ -143,7 +145,7 @@ namespace Myriad.Cache
if (!_dmChannels.TryGetValue(userId, out var channelId))
return false;
return TryGetChannel(channelId, out channel);
}
}
public bool TryGetUser(ulong userId, out User user) =>
_users.TryGetValue(userId, out user!);

View File

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;
using Myriad.Cache;
@ -15,7 +15,7 @@ namespace Myriad.Extensions
throw new KeyNotFoundException($"Guild {guildId} not found in cache");
return guild;
}
public static Channel GetChannel(this IDiscordCache cache, ulong channelId)
{
if (!cache.TryGetChannel(channelId, out var channel))
@ -36,14 +36,14 @@ namespace Myriad.Extensions
throw new KeyNotFoundException($"User {userId} not found in cache");
return user;
}
public static Role GetRole(this IDiscordCache cache, ulong roleId)
{
if (!cache.TryGetRole(roleId, out var role))
throw new KeyNotFoundException($"User {roleId} not found in cache");
return role;
}
public static async ValueTask<User?> GetOrFetchUser(this IDiscordCache cache, DiscordApiClient rest, ulong userId)
{
if (cache.TryGetUser(userId, out var cacheUser))
@ -54,7 +54,7 @@ namespace Myriad.Extensions
await cache.SaveUser(restUser);
return restUser;
}
public static async ValueTask<Channel?> GetOrFetchChannel(this IDiscordCache cache, DiscordApiClient rest, ulong channelId)
{
if (cache.TryGetChannel(channelId, out var cacheChannel))
@ -79,9 +79,9 @@ namespace Myriad.Extensions
public static Channel GetRootChannel(this IDiscordCache cache, ulong channelOrThread)
{
var channel = cache.GetChannel(channelOrThread);
if (!channel.IsThread())
if (!channel.IsThread())
return channel;
var parent = cache.GetChannel(channel.ParentId!.Value);
return parent;
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Extensions
{

View File

@ -1,7 +1,7 @@
namespace Myriad.Extensions
namespace Myriad.Extensions
{
public static class GuildExtensions
{
}
}

View File

@ -1,4 +1,4 @@
using Myriad.Gateway;
using Myriad.Gateway;
using Myriad.Types;
namespace Myriad.Extensions
@ -7,7 +7,7 @@ namespace Myriad.Extensions
{
public static string JumpLink(this Message msg) =>
$"https://discord.com/channels/{msg.GuildId}/{msg.ChannelId}/{msg.Id}";
public static string JumpLink(this MessageReactionAddEvent msg) =>
$"https://discord.com/channels/{msg.GuildId}/{msg.ChannelId}/{msg.MessageId}";
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
@ -21,12 +21,12 @@ namespace Myriad.Extensions
if (!cache.TryGetChannel(channelId, out var channel))
// todo: handle channel not found better
return PermissionSet.Dm;
if (channel.GuildId == null)
return PermissionSet.Dm;
var rootChannel = cache.GetRootChannel(channelId);
var guild = cache.GetGuild(channel.GuildId.Value);
if (isWebhook)
@ -34,10 +34,10 @@ namespace Myriad.Extensions
return PermissionsFor(guild, rootChannel, userId, member);
}
public static PermissionSet EveryonePermissions(this Guild guild) =>
guild.Roles.FirstOrDefault(r => r.Id == guild.Id)?.Permissions ?? PermissionSet.Dm;
public static PermissionSet EveryonePermissions(this IDiscordCache cache, Channel channel)
{
if (channel.Type == Channel.ChannelType.Dm)
@ -62,7 +62,7 @@ namespace Myriad.Extensions
{
if (channel.Type == Channel.ChannelType.Dm)
return PermissionSet.Dm;
if (member == null)
// this happens with system (Discord platform-owned) users - they're not actually in the guild, so there is no member object.
return EveryonePermissions(guild);

View File

@ -1,4 +1,4 @@
using System;
using System;
using Myriad.Types;
@ -7,7 +7,7 @@ namespace Myriad.Extensions
public static class SnowflakeExtensions
{
public static readonly DateTimeOffset DiscordEpoch = new(2015, 1, 1, 0, 0, 0, TimeSpan.Zero);
public static DateTimeOffset SnowflakeToTimestamp(ulong snowflake) =>
DiscordEpoch + TimeSpan.FromMilliseconds(snowflake >> 22);

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Extensions
{
@ -6,7 +6,7 @@ namespace Myriad.Extensions
{
public static string Mention(this User user) => $"<@{user.Id}>";
public static string AvatarUrl(this User user, string? format = "png", int? size = 128) =>
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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
@ -30,7 +30,7 @@ namespace Myriad.Gateway
public IReadOnlyDictionary<int, Shard> Shards => _shards;
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);
public async Task Start(GatewayInfo.Bot info)
{
await Start(info.Url, 0, info.Shards - 1, info.Shards, info.SessionStartLimit.MaxConcurrency);
@ -39,7 +39,7 @@ namespace Myriad.Gateway
public async Task Start(string url, int shardMin, int shardMax, int shardTotal, int recommendedConcurrency)
{
_ratelimiter = GetRateLimiter(recommendedConcurrency);
var shardCount = shardMax - shardMin + 1;
_logger.Information("Starting {ShardCount} of {ShardTotal} shards (#{ShardMin}-#{ShardMax}) at {Url}",
shardCount, shardTotal, shardMin, shardMax, url);
@ -51,7 +51,7 @@ namespace Myriad.Gateway
private async Task StartShards()
{
_logger.Information("Connecting shards...");
foreach (var shard in _shards.Values)
foreach (var shard in _shards.Values)
await shard.Start();
}
@ -60,7 +60,7 @@ namespace Myriad.Gateway
var shard = new Shard(_gatewaySettings, shardInfo, _ratelimiter!, url, _logger);
shard.OnEventReceived += evt => OnShardEventReceived(shard, evt);
_shards[shardInfo.ShardId] = shard;
ShardCreated?.Invoke(shard);
}
@ -69,12 +69,12 @@ namespace Myriad.Gateway
if (EventReceived != null)
await EventReceived(shard, evt);
}
private int GetActualShardConcurrency(int recommendedConcurrency)
{
if (_gatewaySettings.MaxShardConcurrency == null)
return recommendedConcurrency;
return Math.Min(_gatewaySettings.MaxShardConcurrency.Value, recommendedConcurrency);
}
@ -84,7 +84,7 @@ namespace Myriad.Gateway
{
return new TwilightGatewayRatelimiter(_logger, _gatewaySettings.GatewayQueueUrl);
}
var concurrency = GetActualShardConcurrency(recommendedConcurrency);
return new LocalGatewayRatelimiter(_logger, concurrency);
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record GuildDeleteEvent(ulong Id, bool Unavailable): IGatewayEvent;
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record GuildRoleDeleteEvent(ulong GuildId, ulong RoleId): IGatewayEvent;
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
namespace Myriad.Gateway
@ -7,33 +7,33 @@ namespace Myriad.Gateway
{
public static readonly Dictionary<string, Type> EventTypes = new()
{
{"READY", typeof(ReadyEvent)},
{"RESUMED", typeof(ResumedEvent)},
{"GUILD_CREATE", typeof(GuildCreateEvent)},
{"GUILD_UPDATE", typeof(GuildUpdateEvent)},
{"GUILD_DELETE", typeof(GuildDeleteEvent)},
{"GUILD_MEMBER_ADD", typeof(GuildMemberAddEvent)},
{"GUILD_MEMBER_REMOVE", typeof(GuildMemberRemoveEvent)},
{"GUILD_MEMBER_UPDATE", typeof(GuildMemberUpdateEvent)},
{"GUILD_ROLE_CREATE", typeof(GuildRoleCreateEvent)},
{"GUILD_ROLE_UPDATE", typeof(GuildRoleUpdateEvent)},
{"GUILD_ROLE_DELETE", typeof(GuildRoleDeleteEvent)},
{"CHANNEL_CREATE", typeof(ChannelCreateEvent)},
{"CHANNEL_UPDATE", typeof(ChannelUpdateEvent)},
{"CHANNEL_DELETE", typeof(ChannelDeleteEvent)},
{"THREAD_CREATE", typeof(ThreadCreateEvent)},
{"THREAD_UPDATE", typeof(ThreadUpdateEvent)},
{"THREAD_DELETE", typeof(ThreadDeleteEvent)},
{"THREAD_LIST_SYNC", typeof(ThreadListSyncEvent)},
{"MESSAGE_CREATE", typeof(MessageCreateEvent)},
{"MESSAGE_UPDATE", typeof(MessageUpdateEvent)},
{"MESSAGE_DELETE", typeof(MessageDeleteEvent)},
{"MESSAGE_DELETE_BULK", typeof(MessageDeleteBulkEvent)},
{"MESSAGE_REACTION_ADD", typeof(MessageReactionAddEvent)},
{"MESSAGE_REACTION_REMOVE", typeof(MessageReactionRemoveEvent)},
{"MESSAGE_REACTION_REMOVE_ALL", typeof(MessageReactionRemoveAllEvent)},
{"MESSAGE_REACTION_REMOVE_EMOJI", typeof(MessageReactionRemoveEmojiEvent)},
{"INTERACTION_CREATE", typeof(InteractionCreateEvent)}
{ "READY", typeof(ReadyEvent) },
{ "RESUMED", typeof(ResumedEvent) },
{ "GUILD_CREATE", typeof(GuildCreateEvent) },
{ "GUILD_UPDATE", typeof(GuildUpdateEvent) },
{ "GUILD_DELETE", typeof(GuildDeleteEvent) },
{ "GUILD_MEMBER_ADD", typeof(GuildMemberAddEvent) },
{ "GUILD_MEMBER_REMOVE", typeof(GuildMemberRemoveEvent) },
{ "GUILD_MEMBER_UPDATE", typeof(GuildMemberUpdateEvent) },
{ "GUILD_ROLE_CREATE", typeof(GuildRoleCreateEvent) },
{ "GUILD_ROLE_UPDATE", typeof(GuildRoleUpdateEvent) },
{ "GUILD_ROLE_DELETE", typeof(GuildRoleDeleteEvent) },
{ "CHANNEL_CREATE", typeof(ChannelCreateEvent) },
{ "CHANNEL_UPDATE", typeof(ChannelUpdateEvent) },
{ "CHANNEL_DELETE", typeof(ChannelDeleteEvent) },
{ "THREAD_CREATE", typeof(ThreadCreateEvent) },
{ "THREAD_UPDATE", typeof(ThreadUpdateEvent) },
{ "THREAD_DELETE", typeof(ThreadDeleteEvent) },
{ "THREAD_LIST_SYNC", typeof(ThreadListSyncEvent) },
{ "MESSAGE_CREATE", typeof(MessageCreateEvent) },
{ "MESSAGE_UPDATE", typeof(MessageUpdateEvent) },
{ "MESSAGE_DELETE", typeof(MessageDeleteEvent) },
{ "MESSAGE_DELETE_BULK", typeof(MessageDeleteBulkEvent) },
{ "MESSAGE_REACTION_ADD", typeof(MessageReactionAddEvent) },
{ "MESSAGE_REACTION_REMOVE", typeof(MessageReactionRemoveEvent) },
{ "MESSAGE_REACTION_REMOVE_ALL", typeof(MessageReactionRemoveAllEvent) },
{ "MESSAGE_REACTION_REMOVE_EMOJI", typeof(MessageReactionRemoveEmojiEvent) },
{ "INTERACTION_CREATE", typeof(InteractionCreateEvent) }
};
}
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record MessageDeleteBulkEvent(ulong[] Ids, ulong ChannelId, ulong? GuildId): IGatewayEvent;
}

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record MessageDeleteEvent(ulong Id, ulong ChannelId, ulong? GuildId): IGatewayEvent;
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record MessageReactionRemoveAllEvent(ulong ChannelId, ulong MessageId, ulong? GuildId): IGatewayEvent;
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
using Myriad.Utils;
namespace Myriad.Gateway

View File

@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using Myriad.Types;

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record ResumedEvent: IGatewayEvent;
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Gateway
{

View File

@ -1,11 +1,11 @@
using System;
using System;
namespace Myriad.Gateway
{
// TODO: unused?
public class GatewayCloseException: Exception
{
public GatewayCloseException(int closeCode, string closeReason): base($"{closeCode}: {closeReason}")
public GatewayCloseException(int closeCode, string closeReason) : base($"{closeCode}: {closeReason}")
{
CloseCode = closeCode;
CloseReason = closeReason;

View File

@ -1,4 +1,4 @@
using System;
using System;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace Myriad.Gateway
{
@ -7,10 +7,12 @@ namespace Myriad.Gateway
[JsonPropertyName("op")] public GatewayOpcode Opcode { get; init; }
[JsonPropertyName("d")] public object? Payload { get; init; }
[JsonPropertyName("s")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("s")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? Sequence { get; init; }
[JsonPropertyName("t")] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("t")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? EventType { get; init; }
}

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record GatewaySettings
{

View File

@ -1,4 +1,4 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
namespace Myriad.Gateway.Limit
{

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Net.Http;
using System.Threading.Tasks;
@ -14,7 +14,7 @@ namespace Myriad.Gateway.Limit
{
Timeout = TimeSpan.FromSeconds(60)
};
public TwilightGatewayRatelimiter(ILogger logger, string url)
{
_url = url;

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record GatewayHello(int HeartbeatInterval);
}

View File

@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace Myriad.Gateway
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record GatewayResume(string Token, string SessionId, int Seq);
}

View File

@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using Myriad.Serialization;
using Myriad.Types;

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Net.WebSockets;
using System.Text.Json;
using System.Threading.Tasks;
@ -68,18 +68,18 @@ namespace Myriad.Gateway
_conn = new ShardConnection(_jsonSerializerOptions, _logger);
}
private async Task ShardLoop()
{
// may be superfluous but this adds shard id to ambient context which is nice
using var _ = LogContext.PushProperty("ShardId", _info.ShardId);
while (true)
{
try
{
await ConnectInner();
await HandleConnectionOpened();
while (_conn.State == WebSocketState.Open)
@ -90,7 +90,7 @@ namespace Myriad.Gateway
await _stateManager.HandlePacketReceived(packet);
}
await HandleConnectionClosed(_conn.CloseStatus, _conn.CloseStatusDescription);
_logger.Information("Shard {ShardId}: Reconnecting after delay {ReconnectDelay}",
@ -103,20 +103,20 @@ namespace Myriad.Gateway
catch (Exception e)
{
_logger.Error(e, "Shard {ShardId}: Error in main shard loop, reconnecting in 5 seconds...", _info.ShardId);
// todo: exponential backoff here? this should never happen, ideally...
await Task.Delay(TimeSpan.FromSeconds(5));
}
}
}
public async Task Start()
{
if (_worker == null)
_worker = ShardLoop();
// we can probably TCS this instead of spin loop but w/e
while (State != ShardState.Identifying)
while (State != ShardState.Identifying)
await Task.Delay(100);
}
@ -128,7 +128,7 @@ namespace Myriad.Gateway
Payload = payload
});
}
private async Task ConnectInner()
{
while (true)
@ -148,12 +148,12 @@ namespace Myriad.Gateway
}
}
}
private async Task DisconnectInner(WebSocketCloseStatus closeStatus)
{
await _conn.Disconnect(closeStatus, null);
}
private async Task SendIdentify()
{
await _conn.Send(new GatewayPacket
@ -165,8 +165,8 @@ namespace Myriad.Gateway
Intents = _settings.Intents,
Properties = new GatewayIdentify.ConnectionProperties
{
Browser = LibraryName,
Device = LibraryName,
Browser = LibraryName,
Device = LibraryName,
Os = Environment.OSVersion.ToString()
},
Shard = _info,
@ -175,7 +175,7 @@ namespace Myriad.Gateway
}
});
}
private async Task SendResume((string SessionId, int? LastSeq) arg)
{
await _conn.Send(new GatewayPacket
@ -184,12 +184,12 @@ namespace Myriad.Gateway
Payload = new GatewayResume(_settings.Token, arg.SessionId, arg.LastSeq ?? 0)
});
}
private async Task SendHeartbeat(int? lastSeq)
{
await _conn.Send(new GatewayPacket {Opcode = GatewayOpcode.Heartbeat, Payload = lastSeq});
await _conn.Send(new GatewayPacket { Opcode = GatewayOpcode.Heartbeat, Payload = lastSeq });
}
private async Task Reconnect(WebSocketCloseStatus closeStatus, TimeSpan delay)
{
_reconnectDelay = delay;
@ -202,7 +202,7 @@ namespace Myriad.Gateway
Ready?.Invoke();
if (arg is ResumedEvent)
Resumed?.Invoke();
await (OnEventReceived?.Invoke(arg) ?? Task.CompletedTask);
}
@ -215,7 +215,7 @@ namespace Myriad.Gateway
private async Task HandleConnectionClosed(WebSocketCloseStatus? closeStatus, string? description)
{
_logger.Information("Shard {ShardId}: Connection closed ({CloseStatus}/{Description})",
_logger.Information("Shard {ShardId}: Connection closed ({CloseStatus}/{Description})",
_info.ShardId, closeStatus, description ?? "<null>");
await _stateManager.HandleConnectionClosed();
SocketClosed?.Invoke(closeStatus, description);

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Net.WebSockets;
using System.Text.Json;
using System.Threading;
@ -13,11 +13,11 @@ namespace Myriad.Gateway
private ClientWebSocket? _client;
private readonly ILogger _logger;
private readonly ShardPacketSerializer _serializer;
public WebSocketState State => _client?.State ?? WebSocketState.Closed;
public WebSocketCloseStatus? CloseStatus => _client?.CloseStatus;
public string? CloseStatusDescription => _client?.CloseStatusDescription;
public ShardConnection(JsonSerializerOptions jsonSerializerOptions, ILogger logger)
{
_logger = logger.ForContext<ShardConnection>();
@ -28,7 +28,7 @@ namespace Myriad.Gateway
{
_client?.Dispose();
_client = new ClientWebSocket();
await _client.ConnectAsync(GetConnectionUri(url), ct);
}
@ -40,7 +40,7 @@ namespace Myriad.Gateway
public async Task Send(GatewayPacket packet)
{
// from `ManagedWebSocket.s_validSendStates`
if (_client is not {State: WebSocketState.Open or WebSocketState.CloseReceived})
if (_client is not { State: WebSocketState.Open or WebSocketState.CloseReceived })
return;
try
@ -62,7 +62,7 @@ namespace Myriad.Gateway
public async Task<GatewayPacket?> Read()
{
// from `ManagedWebSocket.s_validReceiveStates`
if (_client is not {State: WebSocketState.Open or WebSocketState.CloseSent})
if (_client is not { State: WebSocketState.Open or WebSocketState.CloseSent })
return null;
try
@ -79,7 +79,7 @@ namespace Myriad.Gateway
return null;
}
private Uri GetConnectionUri(string baseUri) => new UriBuilder(baseUri)
{
Query = "v=9&encoding=json"
@ -89,10 +89,10 @@ namespace Myriad.Gateway
{
if (_client == null)
return;
var client = _client;
_client = null;
// from `ManagedWebSocket.s_validCloseStates`
if (client.State is WebSocketState.Open or WebSocketState.CloseReceived or WebSocketState.CloseSent)
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway
namespace Myriad.Gateway
{
public record ShardInfo(int ShardId, int NumShards);
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Buffers;
using System.IO;
using System.Net.WebSockets;
@ -10,7 +10,7 @@ namespace Myriad.Gateway
public class ShardPacketSerializer
{
private const int BufferSize = 64 * 1024;
private readonly JsonSerializerOptions _jsonSerializerOptions;
public ShardPacketSerializer(JsonSerializerOptions jsonSerializerOptions)
@ -21,15 +21,15 @@ namespace Myriad.Gateway
public async ValueTask<(WebSocketMessageType type, GatewayPacket? packet)> ReadPacket(ClientWebSocket socket)
{
using var buf = MemoryPool<byte>.Shared.Rent(BufferSize);
var res = await socket.ReceiveAsync(buf.Memory, default);
if (res.MessageType == WebSocketMessageType.Close)
return (res.MessageType, null);
if (res.EndOfMessage)
// Entire packet fits within one buffer, deserialize directly
return DeserializeSingleBuffer(buf, res);
// Otherwise copy to stream buffer and deserialize from there
return await DeserializeMultipleBuffer(socket, buf, res);
}
@ -51,7 +51,7 @@ namespace Myriad.Gateway
stream.Write(buf.Memory.Span.Slice(0, res.Count));
}
return DeserializeObject(res, stream.GetBuffer().AsSpan(0, (int) stream.Length));
return DeserializeObject(res, stream.GetBuffer().AsSpan(0, (int)stream.Length));
}
private (WebSocketMessageType type, GatewayPacket packet) DeserializeSingleBuffer(

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
@ -8,7 +8,7 @@ namespace Myriad.Gateway.State
{
private Task? _worker;
private CancellationTokenSource? _workerCts;
public TimeSpan? CurrentHeartbeatInterval { get; private set; }
public async ValueTask Start(TimeSpan heartbeatInterval, Func<Task> callback)
@ -23,9 +23,9 @@ namespace Myriad.Gateway.State
public async ValueTask Stop()
{
if (_worker == null)
if (_worker == null)
return;
_workerCts?.Cancel();
try
{
@ -38,12 +38,12 @@ namespace Myriad.Gateway.State
_worker = null;
CurrentHeartbeatInterval = null;
}
private async Task Worker(TimeSpan heartbeatInterval, Func<Task> callback, CancellationToken ct)
{
var initialDelay = GetInitialHeartbeatDelay(heartbeatInterval);
await Task.Delay(initialDelay, ct);
while (!ct.IsCancellationRequested)
{
await callback();

View File

@ -1,4 +1,4 @@
namespace Myriad.Gateway.State
namespace Myriad.Gateway.State
{
public enum ShardState
{

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Net.WebSockets;
using System.Text.Json;
using System.Threading.Tasks;
@ -18,7 +18,7 @@ namespace Myriad.Gateway
private readonly ShardInfo _info;
private readonly JsonSerializerOptions _jsonSerializerOptions;
private ShardState _state = ShardState.Disconnected;
private DateTimeOffset? _lastHeartbeatSent;
private TimeSpan? _latency;
private bool _hasReceivedHeartbeatAck;
@ -30,7 +30,7 @@ namespace Myriad.Gateway
public TimeSpan? Latency => _latency;
public User? User { get; private set; }
public ApplicationPartial? Application { get; private set; }
public Func<Task> SendIdentify { get; init; }
public Func<(string SessionId, int? LastSeq), Task> SendResume { get; init; }
public Func<int?, Task> SendHeartbeat { get; init; }
@ -52,7 +52,7 @@ namespace Myriad.Gateway
_state = ShardState.Handshaking;
return Task.CompletedTask;
}
public async Task HandleConnectionClosed()
{
_latency = null;
@ -71,36 +71,36 @@ namespace Myriad.Gateway
case GatewayOpcode.Heartbeat:
await HandleHeartbeatRequest();
break;
case GatewayOpcode.HeartbeatAck:
await HandleHeartbeatAck();
break;
case GatewayOpcode.Reconnect:
{
await HandleReconnect();
break;
}
{
await HandleReconnect();
break;
}
case GatewayOpcode.InvalidSession:
{
var canResume = DeserializePayload<bool>(packet);
await HandleInvalidSession(canResume);
break;
}
{
var canResume = DeserializePayload<bool>(packet);
await HandleInvalidSession(canResume);
break;
}
case GatewayOpcode.Dispatch:
case GatewayOpcode.Dispatch:
_lastSeq = packet.Sequence;
var evt = DeserializeEvent(packet.EventType!, (JsonElement) packet.Payload!);
var evt = DeserializeEvent(packet.EventType!, (JsonElement)packet.Payload!);
if (evt != null)
{
if (evt is ReadyEvent ready)
if (evt is ReadyEvent ready)
await HandleReady(ready);
if (evt is ResumedEvent)
if (evt is ResumedEvent)
await HandleResumed();
await HandleEvent(evt);
}
break;
@ -110,7 +110,7 @@ namespace Myriad.Gateway
private async Task HandleHello(GatewayHello hello)
{
var interval = TimeSpan.FromMilliseconds(hello.HeartbeatInterval);
_hasReceivedHeartbeatAck = true;
await _heartbeatWorker.Start(interval, HandleHeartbeatTimer);
await IdentifyOrResume();
@ -152,14 +152,14 @@ namespace Myriad.Gateway
_sessionId = null;
_lastSeq = null;
}
_logger.Information("Shard {ShardId}: Received Invalid Session (can resume? {CanResume})",
_info.ShardId, canResume);
var delay = TimeSpan.FromMilliseconds(new Random().Next(1000, 5000));
await DoReconnect(WebSocketCloseStatus.NormalClosure, delay);
}
private async Task HandleReconnect()
{
_logger.Information("Shard {ShardId}: Received Reconnect", _info.ShardId);
@ -167,7 +167,7 @@ namespace Myriad.Gateway
// we use 1005 (no error specified) instead
await DoReconnect(WebSocketCloseStatus.Empty, TimeSpan.FromSeconds(1));
}
private Task HandleReady(ReadyEvent ready)
{
_logger.Information("Shard {ShardId}: Received Ready", _info.ShardId);
@ -218,10 +218,10 @@ namespace Myriad.Gateway
private T DeserializePayload<T>(GatewayPacket packet)
{
var packetPayload = (JsonElement) packet.Payload!;
var packetPayload = (JsonElement)packet.Payload!;
return JsonSerializer.Deserialize<T>(packetPayload.GetRawText(), _jsonSerializerOptions)!;
}
private IGatewayEvent? DeserializeEvent(string eventType, JsonElement payload)
{
if (!IGatewayEvent.EventTypes.TryGetValue(eventType, out var clrType))

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
@ -52,7 +52,7 @@ namespace Myriad.Rest
var waitPolicy = Policy
.Handle<RatelimitBucketExhaustedException>()
.WaitAndRetryAsync(3,
(_, e, _) => ((RatelimitBucketExhaustedException) e).RetryAfter,
(_, e, _) => ((RatelimitBucketExhaustedException)e).RetryAfter,
(_, _, _, _) => Task.CompletedTask)
.AsAsyncPolicy<HttpResponseMessage>();
@ -68,7 +68,7 @@ namespace Myriad.Rest
return default;
}
public async Task<T?> Get<T>(string path, (string endpointName, ulong major) ratelimitParams) where T: class
public async Task<T?> Get<T>(string path, (string endpointName, ulong major) ratelimitParams) where T : class
{
using var response = await Send(() => new HttpRequestMessage(HttpMethod.Get, ApiBaseUrl + path),
ratelimitParams, true);
@ -81,7 +81,7 @@ namespace Myriad.Rest
}
public async Task<T?> Post<T>(string path, (string endpointName, ulong major) ratelimitParams, object? body)
where T: class
where T : class
{
using var response = await Send(() =>
{
@ -91,9 +91,9 @@ namespace Myriad.Rest
}, ratelimitParams);
return await ReadResponse<T>(response);
}
public async Task<T?> PostMultipart<T>(string path, (string endpointName, ulong major) ratelimitParams, object? payload, MultipartFile[]? files)
where T: class
where T : class
{
using var response = await Send(() =>
{
@ -105,7 +105,7 @@ namespace Myriad.Rest
}
public async Task<T?> Patch<T>(string path, (string endpointName, ulong major) ratelimitParams, object? body)
where T: class
where T : class
{
using var response = await Send(() =>
{
@ -117,7 +117,7 @@ namespace Myriad.Rest
}
public async Task<T?> Put<T>(string path, (string endpointName, ulong major) ratelimitParams, object? body)
where T: class
where T : class
{
using var response = await Send(() =>
{
@ -160,7 +160,7 @@ namespace Myriad.Rest
request.Content = mfd;
}
private async Task<T?> ReadResponse<T>(HttpResponseMessage response) where T: class
private async Task<T?> ReadResponse<T>(HttpResponseMessage response) where T : class
{
if (response.StatusCode == HttpStatusCode.NoContent)
return null;
@ -174,7 +174,7 @@ namespace Myriad.Rest
return await _retryPolicy.ExecuteAsync(async _ =>
{
using var __ = LogContext.PushProperty("EndpointName", ratelimitParams.endpointName);
var request = createRequest();
_logger.Debug("Request: {RequestMethod} {RequestPath}",
request.Method, request.RequestUri);
@ -189,7 +189,7 @@ namespace Myriad.Rest
_logger.Debug(
"Response: {RequestMethod} {RequestPath} -> {StatusCode} {ReasonPhrase} (in {ResponseDurationMs} ms)",
request.Method, request.RequestUri, (int) response.StatusCode, response.ReasonPhrase, stopwatch.ElapsedMilliseconds);
request.Method, request.RequestUri, (int)response.StatusCode, response.ReasonPhrase, stopwatch.ElapsedMilliseconds);
await HandleApiError(response, ignoreNotFound);
@ -211,7 +211,7 @@ namespace Myriad.Rest
return;
var body = await response.Content.ReadAsStringAsync();
var apiError = TryParseApiError(body);
var apiError = TryParseApiError(body);
if (apiError != null)
_logger.Warning("Discord API error: {DiscordErrorCode} {DiscordErrorMessage}", apiError.Code, apiError.Message);

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Net;
using System.Threading.Tasks;
@ -34,7 +34,7 @@ namespace Myriad.Rest
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))!;
@ -108,7 +108,7 @@ namespace Myriad.Rest
public Task<Webhook> CreateWebhook(ulong channelId, CreateWebhookRequest request) =>
_client.Post<Webhook>($"/channels/{channelId}/webhooks", ("CreateWebhook", channelId), request)!;
public Task<Webhook> GetWebhook(ulong webhookId) =>
_client.Get<Webhook>($"/webhooks/{webhookId}/webhooks", ("GetWebhook", webhookId))!;
@ -121,7 +121,7 @@ namespace Myriad.Rest
var url = $"/webhooks/{webhookId}/{webhookToken}?wait=true";
if (threadId != null)
url += $"&thread_id={threadId}";
return _client.PostMultipart<Message>(url,
("ExecuteWebhook", webhookId), request, files)!;
}

View File

@ -1,4 +1,4 @@
using System.Text.Json;
using System.Text.Json;
namespace Myriad.Rest
{

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Net;
using System.Net.Http;
@ -29,43 +29,49 @@ namespace Myriad.Rest.Exceptions
public class NotFoundException: DiscordRequestException
{
public NotFoundException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError): base(
response, responseBody, apiError) { }
public NotFoundException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError) : base(
response, responseBody, apiError)
{ }
}
public class UnauthorizedException: DiscordRequestException
{
public UnauthorizedException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError): base(
response, responseBody, apiError) { }
public UnauthorizedException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError) : base(
response, responseBody, apiError)
{ }
}
public class ForbiddenException: DiscordRequestException
{
public ForbiddenException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError): base(
response, responseBody, apiError) { }
public ForbiddenException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError) : base(
response, responseBody, apiError)
{ }
}
public class ConflictException: DiscordRequestException
{
public ConflictException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError): base(
response, responseBody, apiError) { }
public ConflictException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError) : base(
response, responseBody, apiError)
{ }
}
public class BadRequestException: DiscordRequestException
{
public BadRequestException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError): base(
response, responseBody, apiError) { }
public BadRequestException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError) : base(
response, responseBody, apiError)
{ }
}
public class TooManyRequestsException: DiscordRequestException
{
public TooManyRequestsException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError):
base(response, responseBody, apiError) { }
public TooManyRequestsException(HttpResponseMessage response, string responseBody, DiscordApiError? apiError) :
base(response, responseBody, apiError)
{ }
}
public class UnknownDiscordRequestException: DiscordRequestException
{
public UnknownDiscordRequestException(HttpResponseMessage response, string responseBody,
DiscordApiError? apiError): base(response, responseBody, apiError) { }
DiscordApiError? apiError) : base(response, responseBody, apiError) { }
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using Myriad.Rest.Ratelimit;
@ -6,12 +6,12 @@ namespace Myriad.Rest.Exceptions
{
public class RatelimitException: Exception
{
public RatelimitException(string? message): base(message) { }
public RatelimitException(string? message) : base(message) { }
}
public class RatelimitBucketExhaustedException: RatelimitException
{
public RatelimitBucketExhaustedException(Bucket bucket, TimeSpan retryAfter): base(
public RatelimitBucketExhaustedException(Bucket bucket, TimeSpan retryAfter) : base(
"Rate limit bucket exhausted, request blocked")
{
Bucket = bucket;
@ -24,6 +24,6 @@ namespace Myriad.Rest.Exceptions
public class GloballyRatelimitedException: RatelimitException
{
public GloballyRatelimitedException(): base("Global rate limit hit") { }
public GloballyRatelimitedException() : base("Global rate limit hit") { }
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading;
using Serilog;
@ -54,7 +54,7 @@ namespace Myriad.Rest.Ratelimit
"{BucketKey}/{BucketMajor}: Bucket has [{BucketRemaining}/{BucketLimit} left], allowing through",
Key, Major, Remaining, Limit);
Remaining--;
return true;
}
@ -73,7 +73,7 @@ namespace Myriad.Rest.Ratelimit
try
{
_semaphore.Wait();
_logger.Verbose("{BucketKey}/{BucketMajor}: Received rate limit headers: {@RateLimitHeaders}",
Key, Major, headers);
@ -90,7 +90,7 @@ namespace Myriad.Rest.Ratelimit
}
}
if (headers.Limit != null)
if (headers.Limit != null)
Limit = headers.Limit.Value;
if (headers.Remaining != null && !_hasReceivedHeaders)
@ -98,7 +98,7 @@ namespace Myriad.Rest.Ratelimit
var oldRemaining = Remaining;
Remaining = Math.Min(headers.Remaining.Value, Remaining);
_logger.Debug("{BucketKey}/{BucketMajor}: Received first remaining of {HeaderRemaining}, previous local remaining is {LocalRemaining}, new local remaining is {Remaining}",
_logger.Debug("{BucketKey}/{BucketMajor}: Received first remaining of {HeaderRemaining}, previous local remaining is {LocalRemaining}, new local remaining is {Remaining}",
Key, Major, headers.Remaining.Value, oldRemaining, Remaining);
_hasReceivedHeaders = true;
}
@ -114,7 +114,7 @@ namespace Myriad.Rest.Ratelimit
try
{
_semaphore.Wait();
// If we don't have any reset data, "snap" it to now
// This happens before first request and at this point the reset is invalid anyway, so it's fine
// but it ensures the stale timeout doesn't trigger early by using `default` value

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
@ -72,7 +72,7 @@ namespace Myriad.Rest.Ratelimit
{
if (now - bucket.LastUsed <= StaleBucketTimeout)
continue;
_logger.Debug("Pruning unused bucket {BucketKey}/{BucketMajor} (last used at {BucketLastUsed})",
bucket.Key, bucket.Major, bucket.LastUsed);
_buckets.TryRemove(key, out _);

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Globalization;
using System.Linq;
using System.Net.Http;
@ -13,7 +13,7 @@ namespace Myriad.Rest.Ratelimit
private const string ResetAfterHeader = "X-RateLimit-Reset-After";
private const string BucketHeader = "X-RateLimit-Bucket";
private const string GlobalHeader = "X-RateLimit-Global";
public bool Global { get; private set; }
public int? Limit { get; private set; }
public int? Remaining { get; private set; }
@ -25,7 +25,7 @@ namespace Myriad.Rest.Ratelimit
public bool HasRatelimitInfo =>
Limit != null && Remaining != null && Reset != null && ResetAfter != null && Bucket != null;
public RatelimitHeaders() { }
public static RatelimitHeaders Parse(HttpResponseMessage response)
@ -41,12 +41,12 @@ namespace Myriad.Rest.Ratelimit
var resetTimestamp = TryGetDouble(response, ResetHeader);
if (resetTimestamp != null)
headers.Reset = DateTimeOffset.FromUnixTimeMilliseconds((long) (resetTimestamp.Value * 1000));
headers.Reset = DateTimeOffset.FromUnixTimeMilliseconds((long)(resetTimestamp.Value * 1000));
var resetAfterSeconds = TryGetDouble(response, ResetAfterHeader);
if (resetAfterSeconds != null)
headers.ResetAfter = TimeSpan.FromSeconds(resetAfterSeconds.Value);
var global = TryGetHeader(response, GlobalHeader);
if (global != null && bool.TryParse(global, out var globalBool))
headers.Global = globalBool;
@ -58,27 +58,27 @@ namespace Myriad.Rest.Ratelimit
{
if (!response.Headers.TryGetValues(headerName, out var values))
return null;
return values.FirstOrDefault();
}
private static int? TryGetInt(HttpResponseMessage response, string headerName)
{
var valueString = TryGetHeader(response, headerName);
if (!int.TryParse(valueString, NumberStyles.Integer, CultureInfo.InvariantCulture, out var value))
return null;
return value;
}
private static double? TryGetDouble(HttpResponseMessage response, string headerName)
{
var valueString = TryGetHeader(response, headerName);
if (!double.TryParse(valueString, NumberStyles.Float, CultureInfo.InvariantCulture, out var value))
return null;
return value;
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using Myriad.Rest.Exceptions;

View File

@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using Myriad.Serialization;

View File

@ -1,4 +1,4 @@
using System.IO;
using System.IO;
namespace Myriad.Rest.Types
{

View File

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using Myriad.Types;

View File

@ -1,4 +1,4 @@
namespace Myriad.Rest.Types.Requests
namespace Myriad.Rest.Types.Requests
{
public record CreateDmRequest(ulong RecipientId);
}

View File

@ -1,4 +1,4 @@
namespace Myriad.Rest.Types.Requests
namespace Myriad.Rest.Types.Requests
{
public record CreateWebhookRequest(string Name);
}

View File

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Rest.Types.Requests
{

View File

@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using Myriad.Types;
using Myriad.Utils;
@ -8,14 +8,14 @@ namespace Myriad.Rest.Types.Requests
public record MessageEditRequest
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<string?> Content { get; init; }
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

@ -1,4 +1,4 @@
using Myriad.Types;
using Myriad.Types;
namespace Myriad.Rest.Types.Requests
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Rest.Types
namespace Myriad.Rest.Types
{
public record ModifyGuildMemberRequest
{

View File

@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using Myriad.Utils;
@ -7,8 +7,8 @@ namespace Myriad.Rest.Types.Requests
public record WebhookMessageEditRequest
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<string?> Content { get; init; }
public Optional<string?> Content { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<AllowedMentions> AllowedMentions { get; init; }
}

View File

@ -1,4 +1,4 @@
using System.Text.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Myriad.Serialization

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Text;
using System.Text.Json;

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -22,11 +22,11 @@ namespace Myriad.Serialization
JsonSerializer.Serialize(writer, value.HasValue ? value.GetValue() : default, typeof(T), options);
}
}
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
var innerType = typeToConvert.GetGenericArguments()[0];
return (JsonConverter?) Activator.CreateInstance(
return (JsonConverter?)Activator.CreateInstance(
typeof(Inner<>).MakeGenericType(innerType),
BindingFlags.Instance | BindingFlags.Public,
null,

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -13,12 +13,12 @@ namespace Myriad.Serialization
var str = reader.GetString();
if (str == null) return default;
return (PermissionSet) ulong.Parse(str);
return (PermissionSet)ulong.Parse(str);
}
public override void Write(Utf8JsonWriter writer, PermissionSet value, JsonSerializerOptions options)
{
writer.WriteStringValue(((ulong) value).ToString());
writer.WriteStringValue(((ulong)value).ToString());
}
}
}

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

View File

@ -1,16 +1,16 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record Activity: ActivityPartial
{
}
public record ActivityPartial
{
public string Name { get; init; }
public ActivityType Type { get; init; }
public string? Url { get; init; }
}
public enum ActivityType
{
Game = 0,

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record Application: ApplicationPartial
{
@ -16,7 +16,7 @@
public string? Slug { get; init; }
public string? CoverImage { get; init; }
}
public record ApplicationPartial
{
public ulong Id { get; init; }

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record ApplicationCommand
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record ApplicationCommandInteractionData
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record ApplicationCommandInteractionDataOption
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record ApplicationCommandOption(ApplicationCommandOption.OptionType Type, string Name, string Description)
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record Interaction
{

View File

@ -1,4 +1,4 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
using Myriad.Rest.Types;
using Myriad.Utils;
@ -9,19 +9,19 @@ namespace Myriad.Types
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<bool?> Tts { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<string?> Content { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<Embed[]?> Embeds { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<AllowedMentions?> AllowedMentions { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<Message.MessageFlags> Flags { get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)]
public Optional<MessageComponent[]?> Components { get; init; }
}

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record InteractionResponse
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record Channel
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record Embed
{
@ -16,44 +16,44 @@
public EmbedAuthor? Author { get; init; }
public Field[]? Fields { get; init; }
public record EmbedFooter (
public record EmbedFooter(
string Text,
string? IconUrl = null,
string? ProxyIconUrl = null
);
public record EmbedImage (
public record EmbedImage(
string? Url,
uint? Width = null,
uint? Height = null
);
public record EmbedThumbnail (
public record EmbedThumbnail(
string? Url,
string? ProxyUrl = null,
uint? Width = null,
uint? Height = null
);
public record EmbedVideo (
public record EmbedVideo(
string? Url,
uint? Width = null,
uint? Height = null
);
public record EmbedProvider (
public record EmbedProvider(
string? Name,
string? Url
);
public record EmbedAuthor (
public record EmbedAuthor(
string? Name = null,
string? Url = null,
string? IconUrl = null,
string? ProxyIconUrl = null
);
public record Field (
public record Field(
string Name,
string Value,
bool Inline = false

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record Emoji
{

View File

@ -1,9 +1,9 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record GatewayInfo
{
public string Url { get; init; }
public record Bot: GatewayInfo
{
public int Shards { get; init; }

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record SessionStartLimit
{

View File

@ -1,4 +1,4 @@
namespace Myriad.Types
namespace Myriad.Types
{
public record Guild
{

Some files were not shown because too many files have changed in this diff Show More