feat: upgrade to .NET 6, refactor everything
This commit is contained in:
@@ -1,125 +1,118 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Myriad.Extensions;
|
||||
using Myriad.Gateway;
|
||||
using Myriad.Types;
|
||||
|
||||
namespace Myriad.Cache
|
||||
namespace Myriad.Cache;
|
||||
|
||||
public static class DiscordCacheExtensions
|
||||
{
|
||||
public static class DiscordCacheExtensions
|
||||
public static ValueTask HandleGatewayEvent(this IDiscordCache cache, IGatewayEvent evt)
|
||||
{
|
||||
public static ValueTask HandleGatewayEvent(this IDiscordCache cache, IGatewayEvent evt)
|
||||
switch (evt)
|
||||
{
|
||||
switch (evt)
|
||||
{
|
||||
case ReadyEvent ready:
|
||||
return cache.SaveOwnUser(ready.User.Id);
|
||||
case GuildCreateEvent gc:
|
||||
return cache.SaveGuildCreate(gc);
|
||||
case GuildUpdateEvent gu:
|
||||
return cache.SaveGuild(gu);
|
||||
case GuildDeleteEvent gd:
|
||||
return cache.RemoveGuild(gd.Id);
|
||||
case ChannelCreateEvent cc:
|
||||
return cache.SaveChannel(cc);
|
||||
case ChannelUpdateEvent cu:
|
||||
return cache.SaveChannel(cu);
|
||||
case ChannelDeleteEvent cd:
|
||||
return cache.RemoveChannel(cd.Id);
|
||||
case GuildRoleCreateEvent grc:
|
||||
return cache.SaveRole(grc.GuildId, grc.Role);
|
||||
case GuildRoleUpdateEvent gru:
|
||||
return cache.SaveRole(gru.GuildId, gru.Role);
|
||||
case GuildRoleDeleteEvent grd:
|
||||
return cache.RemoveRole(grd.GuildId, grd.RoleId);
|
||||
case MessageReactionAddEvent mra:
|
||||
return cache.TrySaveDmChannelStub(mra.GuildId, mra.ChannelId);
|
||||
case MessageCreateEvent mc:
|
||||
return cache.SaveMessageCreate(mc);
|
||||
case MessageUpdateEvent mu:
|
||||
return cache.TrySaveDmChannelStub(mu.GuildId.Value, mu.ChannelId);
|
||||
case MessageDeleteEvent md:
|
||||
return cache.TrySaveDmChannelStub(md.GuildId, md.ChannelId);
|
||||
case MessageDeleteBulkEvent md:
|
||||
return cache.TrySaveDmChannelStub(md.GuildId, md.ChannelId);
|
||||
case ThreadCreateEvent tc:
|
||||
return cache.SaveChannel(tc);
|
||||
case ThreadUpdateEvent tu:
|
||||
return cache.SaveChannel(tu);
|
||||
case ThreadDeleteEvent td:
|
||||
return cache.RemoveChannel(td.Id);
|
||||
case ThreadListSyncEvent tls:
|
||||
return cache.SaveThreadListSync(tls);
|
||||
}
|
||||
|
||||
return default;
|
||||
case ReadyEvent ready:
|
||||
return cache.SaveOwnUser(ready.User.Id);
|
||||
case GuildCreateEvent gc:
|
||||
return cache.SaveGuildCreate(gc);
|
||||
case GuildUpdateEvent gu:
|
||||
return cache.SaveGuild(gu);
|
||||
case GuildDeleteEvent gd:
|
||||
return cache.RemoveGuild(gd.Id);
|
||||
case ChannelCreateEvent cc:
|
||||
return cache.SaveChannel(cc);
|
||||
case ChannelUpdateEvent cu:
|
||||
return cache.SaveChannel(cu);
|
||||
case ChannelDeleteEvent cd:
|
||||
return cache.RemoveChannel(cd.Id);
|
||||
case GuildRoleCreateEvent grc:
|
||||
return cache.SaveRole(grc.GuildId, grc.Role);
|
||||
case GuildRoleUpdateEvent gru:
|
||||
return cache.SaveRole(gru.GuildId, gru.Role);
|
||||
case GuildRoleDeleteEvent grd:
|
||||
return cache.RemoveRole(grd.GuildId, grd.RoleId);
|
||||
case MessageReactionAddEvent mra:
|
||||
return cache.TrySaveDmChannelStub(mra.GuildId, mra.ChannelId);
|
||||
case MessageCreateEvent mc:
|
||||
return cache.SaveMessageCreate(mc);
|
||||
case MessageUpdateEvent mu:
|
||||
return cache.TrySaveDmChannelStub(mu.GuildId.Value, mu.ChannelId);
|
||||
case MessageDeleteEvent md:
|
||||
return cache.TrySaveDmChannelStub(md.GuildId, md.ChannelId);
|
||||
case MessageDeleteBulkEvent md:
|
||||
return cache.TrySaveDmChannelStub(md.GuildId, md.ChannelId);
|
||||
case ThreadCreateEvent tc:
|
||||
return cache.SaveChannel(tc);
|
||||
case ThreadUpdateEvent tu:
|
||||
return cache.SaveChannel(tu);
|
||||
case ThreadDeleteEvent td:
|
||||
return cache.RemoveChannel(td.Id);
|
||||
case ThreadListSyncEvent tls:
|
||||
return cache.SaveThreadListSync(tls);
|
||||
}
|
||||
|
||||
public static ValueTask TryUpdateSelfMember(this IDiscordCache cache, Shard shard, IGatewayEvent evt)
|
||||
{
|
||||
if (evt is GuildCreateEvent gc)
|
||||
return cache.SaveSelfMember(gc.Id, gc.Members.FirstOrDefault(m => m.User.Id == shard.User?.Id)!);
|
||||
if (evt is MessageCreateEvent mc && mc.Member != null && mc.Author.Id == shard.User?.Id)
|
||||
return cache.SaveSelfMember(mc.GuildId!.Value, mc.Member);
|
||||
if (evt is GuildMemberAddEvent gma && gma.User.Id == shard.User?.Id)
|
||||
return cache.SaveSelfMember(gma.GuildId, gma);
|
||||
if (evt is GuildMemberUpdateEvent gmu && gmu.User.Id == shard.User?.Id)
|
||||
return cache.SaveSelfMember(gmu.GuildId, gmu);
|
||||
return default;
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
private static async ValueTask SaveGuildCreate(this IDiscordCache cache, GuildCreateEvent guildCreate)
|
||||
{
|
||||
await cache.SaveGuild(guildCreate);
|
||||
|
||||
foreach (var channel in guildCreate.Channels)
|
||||
// The channel object does not include GuildId for some reason...
|
||||
await cache.SaveChannel(channel with { GuildId = guildCreate.Id });
|
||||
|
||||
foreach (var member in guildCreate.Members)
|
||||
await cache.SaveUser(member.User);
|
||||
|
||||
foreach (var thread in guildCreate.Threads)
|
||||
await cache.SaveChannel(thread);
|
||||
}
|
||||
|
||||
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)
|
||||
await cache.SaveUser(mention);
|
||||
}
|
||||
|
||||
private static ValueTask TrySaveDmChannelStub(this IDiscordCache cache, ulong? guildId, ulong channelId)
|
||||
{
|
||||
// DM messages don't get Channel Create events first, so we need to save
|
||||
// some kind of stub channel object until we get the real one
|
||||
return guildId != null ? default : cache.SaveDmChannelStub(channelId);
|
||||
}
|
||||
|
||||
private static async ValueTask SaveThreadListSync(this IDiscordCache cache, ThreadListSyncEvent evt)
|
||||
{
|
||||
foreach (var thread in evt.Threads)
|
||||
await cache.SaveChannel(thread);
|
||||
}
|
||||
|
||||
public static async Task<PermissionSet> PermissionsIn(this IDiscordCache cache, ulong channelId)
|
||||
{
|
||||
var channel = await cache.GetRootChannel(channelId);
|
||||
|
||||
if (channel.GuildId != null)
|
||||
{
|
||||
var userId = await cache.GetOwnUser();
|
||||
var member = await cache.TryGetSelfMember(channel.GuildId.Value);
|
||||
return await cache.PermissionsFor(channelId, userId, member);
|
||||
}
|
||||
|
||||
return PermissionSet.Dm;
|
||||
public static ValueTask TryUpdateSelfMember(this IDiscordCache cache, Shard shard, IGatewayEvent evt)
|
||||
{
|
||||
if (evt is GuildCreateEvent gc)
|
||||
return cache.SaveSelfMember(gc.Id, gc.Members.FirstOrDefault(m => m.User.Id == shard.User?.Id)!);
|
||||
if (evt is MessageCreateEvent mc && mc.Member != null && mc.Author.Id == shard.User?.Id)
|
||||
return cache.SaveSelfMember(mc.GuildId!.Value, mc.Member);
|
||||
if (evt is GuildMemberAddEvent gma && gma.User.Id == shard.User?.Id)
|
||||
return cache.SaveSelfMember(gma.GuildId, gma);
|
||||
if (evt is GuildMemberUpdateEvent gmu && gmu.User.Id == shard.User?.Id)
|
||||
return cache.SaveSelfMember(gmu.GuildId, gmu);
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
private static async ValueTask SaveGuildCreate(this IDiscordCache cache, GuildCreateEvent guildCreate)
|
||||
{
|
||||
await cache.SaveGuild(guildCreate);
|
||||
|
||||
foreach (var channel in guildCreate.Channels)
|
||||
// The channel object does not include GuildId for some reason...
|
||||
await cache.SaveChannel(channel with { GuildId = guildCreate.Id });
|
||||
|
||||
foreach (var member in guildCreate.Members)
|
||||
await cache.SaveUser(member.User);
|
||||
|
||||
foreach (var thread in guildCreate.Threads)
|
||||
await cache.SaveChannel(thread);
|
||||
}
|
||||
|
||||
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)
|
||||
await cache.SaveUser(mention);
|
||||
}
|
||||
|
||||
private static ValueTask TrySaveDmChannelStub(this IDiscordCache cache, ulong? guildId, ulong channelId) =>
|
||||
// DM messages don't get Channel Create events first, so we need to save
|
||||
// some kind of stub channel object until we get the real one
|
||||
guildId != null ? default : cache.SaveDmChannelStub(channelId);
|
||||
|
||||
private static async ValueTask SaveThreadListSync(this IDiscordCache cache, ThreadListSyncEvent evt)
|
||||
{
|
||||
foreach (var thread in evt.Threads)
|
||||
await cache.SaveChannel(thread);
|
||||
}
|
||||
|
||||
public static async Task<PermissionSet> PermissionsIn(this IDiscordCache cache, ulong channelId)
|
||||
{
|
||||
var channel = await cache.GetRootChannel(channelId);
|
||||
|
||||
if (channel.GuildId != null)
|
||||
{
|
||||
var userId = await cache.GetOwnUser();
|
||||
var member = await cache.TryGetSelfMember(channel.GuildId.Value);
|
||||
return await cache.PermissionsFor(channelId, userId, member);
|
||||
}
|
||||
|
||||
return PermissionSet.Dm;
|
||||
}
|
||||
}
|
@@ -1,34 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Myriad.Types;
|
||||
|
||||
namespace Myriad.Cache
|
||||
namespace Myriad.Cache;
|
||||
|
||||
public interface IDiscordCache
|
||||
{
|
||||
public interface IDiscordCache
|
||||
{
|
||||
public ValueTask SaveOwnUser(ulong userId);
|
||||
public ValueTask SaveGuild(Guild guild);
|
||||
public ValueTask SaveChannel(Channel channel);
|
||||
public ValueTask SaveUser(User user);
|
||||
public ValueTask SaveSelfMember(ulong guildId, GuildMemberPartial member);
|
||||
public ValueTask SaveRole(ulong guildId, Role role);
|
||||
public ValueTask SaveDmChannelStub(ulong channelId);
|
||||
public ValueTask SaveOwnUser(ulong userId);
|
||||
public ValueTask SaveGuild(Guild guild);
|
||||
public ValueTask SaveChannel(Channel channel);
|
||||
public ValueTask SaveUser(User user);
|
||||
public ValueTask SaveSelfMember(ulong guildId, GuildMemberPartial member);
|
||||
public ValueTask SaveRole(ulong guildId, Role role);
|
||||
public ValueTask SaveDmChannelStub(ulong channelId);
|
||||
|
||||
public ValueTask RemoveGuild(ulong guildId);
|
||||
public ValueTask RemoveChannel(ulong channelId);
|
||||
public ValueTask RemoveUser(ulong userId);
|
||||
public ValueTask RemoveRole(ulong guildId, ulong roleId);
|
||||
public ValueTask RemoveGuild(ulong guildId);
|
||||
public ValueTask RemoveChannel(ulong channelId);
|
||||
public ValueTask RemoveUser(ulong userId);
|
||||
public ValueTask RemoveRole(ulong guildId, ulong roleId);
|
||||
|
||||
public Task<ulong> GetOwnUser();
|
||||
public Task<Guild?> TryGetGuild(ulong guildId);
|
||||
public Task<Channel?> TryGetChannel(ulong channelId);
|
||||
public Task<Channel?> TryGetDmChannel(ulong userId);
|
||||
public Task<User?> TryGetUser(ulong userId);
|
||||
public Task<GuildMemberPartial?> TryGetSelfMember(ulong guildId);
|
||||
public Task<Role?> TryGetRole(ulong roleId);
|
||||
public Task<ulong> GetOwnUser();
|
||||
public Task<Guild?> TryGetGuild(ulong guildId);
|
||||
public Task<Channel?> TryGetChannel(ulong channelId);
|
||||
public Task<Channel?> TryGetDmChannel(ulong userId);
|
||||
public Task<User?> TryGetUser(ulong userId);
|
||||
public Task<GuildMemberPartial?> TryGetSelfMember(ulong guildId);
|
||||
public Task<Role?> TryGetRole(ulong roleId);
|
||||
|
||||
public IAsyncEnumerable<Guild> GetAllGuilds();
|
||||
public Task<IEnumerable<Channel>> GetGuildChannels(ulong guildId);
|
||||
}
|
||||
public IAsyncEnumerable<Guild> GetAllGuilds();
|
||||
public Task<IEnumerable<Channel>> GetGuildChannels(ulong guildId);
|
||||
}
|
@@ -1,206 +1,190 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Myriad.Types;
|
||||
|
||||
namespace Myriad.Cache
|
||||
namespace Myriad.Cache;
|
||||
|
||||
public class MemoryDiscordCache: IDiscordCache
|
||||
{
|
||||
public class MemoryDiscordCache: IDiscordCache
|
||||
private readonly ConcurrentDictionary<ulong, Channel> _channels = new();
|
||||
private readonly ConcurrentDictionary<ulong, ulong> _dmChannels = new();
|
||||
private readonly ConcurrentDictionary<ulong, GuildMemberPartial> _guildMembers = new();
|
||||
private readonly ConcurrentDictionary<ulong, CachedGuild> _guilds = new();
|
||||
private readonly ConcurrentDictionary<ulong, Role> _roles = new();
|
||||
private readonly ConcurrentDictionary<ulong, User> _users = new();
|
||||
private ulong? _ownUserId { get; set; }
|
||||
|
||||
public ValueTask SaveGuild(Guild guild)
|
||||
{
|
||||
private readonly ConcurrentDictionary<ulong, Channel> _channels = new();
|
||||
private readonly ConcurrentDictionary<ulong, ulong> _dmChannels = new();
|
||||
private readonly ConcurrentDictionary<ulong, CachedGuild> _guilds = new();
|
||||
private readonly ConcurrentDictionary<ulong, Role> _roles = new();
|
||||
private readonly ConcurrentDictionary<ulong, User> _users = new();
|
||||
private readonly ConcurrentDictionary<ulong, GuildMemberPartial> _guildMembers = new();
|
||||
private ulong? _ownUserId { get; set; }
|
||||
SaveGuildRaw(guild);
|
||||
|
||||
public ValueTask SaveGuild(Guild guild)
|
||||
{
|
||||
SaveGuildRaw(guild);
|
||||
|
||||
foreach (var role in guild.Roles)
|
||||
// Don't call SaveRole because that updates guild state
|
||||
// and we just got a brand new one :)
|
||||
_roles[role.Id] = role;
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public async ValueTask SaveChannel(Channel channel)
|
||||
{
|
||||
_channels[channel.Id] = channel;
|
||||
|
||||
if (channel.GuildId != null && _guilds.TryGetValue(channel.GuildId.Value, out var guild))
|
||||
guild.Channels.TryAdd(channel.Id, true);
|
||||
|
||||
if (channel.Recipients != null)
|
||||
{
|
||||
foreach (var recipient in channel.Recipients)
|
||||
{
|
||||
_dmChannels[recipient.Id] = channel.Id;
|
||||
await SaveUser(recipient);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ValueTask SaveOwnUser(ulong userId)
|
||||
{
|
||||
// this (hopefully) never changes at runtime, so we skip out on re-assigning it
|
||||
if (_ownUserId == null)
|
||||
_ownUserId = userId;
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask SaveUser(User user)
|
||||
{
|
||||
_users[user.Id] = user;
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask SaveSelfMember(ulong guildId, GuildMemberPartial member)
|
||||
{
|
||||
_guildMembers[guildId] = member;
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask SaveRole(ulong guildId, Role role)
|
||||
{
|
||||
foreach (var role in guild.Roles)
|
||||
// Don't call SaveRole because that updates guild state
|
||||
// and we just got a brand new one :)
|
||||
_roles[role.Id] = role;
|
||||
|
||||
if (_guilds.TryGetValue(guildId, out var guild))
|
||||
return default;
|
||||
}
|
||||
|
||||
public async ValueTask SaveChannel(Channel channel)
|
||||
{
|
||||
_channels[channel.Id] = channel;
|
||||
|
||||
if (channel.GuildId != null && _guilds.TryGetValue(channel.GuildId.Value, out var guild))
|
||||
guild.Channels.TryAdd(channel.Id, true);
|
||||
|
||||
if (channel.Recipients != null)
|
||||
foreach (var recipient in channel.Recipients)
|
||||
{
|
||||
// TODO: this code is stinky
|
||||
var found = false;
|
||||
for (var i = 0; i < guild.Guild.Roles.Length; i++)
|
||||
{
|
||||
if (guild.Guild.Roles[i].Id != role.Id)
|
||||
continue;
|
||||
_dmChannels[recipient.Id] = channel.Id;
|
||||
await SaveUser(recipient);
|
||||
}
|
||||
}
|
||||
|
||||
guild.Guild.Roles[i] = role;
|
||||
found = true;
|
||||
}
|
||||
public ValueTask SaveOwnUser(ulong userId)
|
||||
{
|
||||
// this (hopefully) never changes at runtime, so we skip out on re-assigning it
|
||||
if (_ownUserId == null)
|
||||
_ownUserId = userId;
|
||||
|
||||
if (!found)
|
||||
{
|
||||
_guilds[guildId] = guild with
|
||||
{
|
||||
Guild = guild.Guild with
|
||||
{
|
||||
Roles = guild.Guild.Roles.Concat(new[] { role }).ToArray()
|
||||
}
|
||||
};
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask SaveUser(User user)
|
||||
{
|
||||
_users[user.Id] = user;
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask SaveSelfMember(ulong guildId, GuildMemberPartial member)
|
||||
{
|
||||
_guildMembers[guildId] = member;
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask SaveRole(ulong guildId, Role role)
|
||||
{
|
||||
_roles[role.Id] = role;
|
||||
|
||||
if (_guilds.TryGetValue(guildId, out var guild))
|
||||
{
|
||||
// TODO: this code is stinky
|
||||
var found = false;
|
||||
for (var i = 0; i < guild.Guild.Roles.Length; i++)
|
||||
{
|
||||
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() }
|
||||
};
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask SaveDmChannelStub(ulong channelId)
|
||||
{
|
||||
// Use existing channel object if present, otherwise add a stub
|
||||
// We may get a message create before channel create and we want to have it saved
|
||||
_channels.GetOrAdd(channelId, id => new Channel { Id = id, Type = Channel.ChannelType.Dm });
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask RemoveGuild(ulong guildId)
|
||||
{
|
||||
_guilds.TryRemove(guildId, out _);
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask RemoveChannel(ulong channelId)
|
||||
{
|
||||
if (!_channels.TryRemove(channelId, out var channel))
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask SaveDmChannelStub(ulong channelId)
|
||||
{
|
||||
// Use existing channel object if present, otherwise add a stub
|
||||
// We may get a message create before channel create and we want to have it saved
|
||||
_channels.GetOrAdd(channelId, id => new Channel
|
||||
{
|
||||
Id = id,
|
||||
Type = Channel.ChannelType.Dm
|
||||
});
|
||||
return default;
|
||||
}
|
||||
if (channel.GuildId != null && _guilds.TryGetValue(channel.GuildId.Value, out var guild))
|
||||
guild.Channels.TryRemove(channel.Id, out _);
|
||||
|
||||
public ValueTask RemoveGuild(ulong guildId)
|
||||
{
|
||||
_guilds.TryRemove(guildId, out _);
|
||||
return default;
|
||||
}
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask RemoveChannel(ulong channelId)
|
||||
{
|
||||
if (!_channels.TryRemove(channelId, out var channel))
|
||||
return default;
|
||||
public ValueTask RemoveUser(ulong userId)
|
||||
{
|
||||
_users.TryRemove(userId, out _);
|
||||
return default;
|
||||
}
|
||||
|
||||
if (channel.GuildId != null && _guilds.TryGetValue(channel.GuildId.Value, out var guild))
|
||||
guild.Channels.TryRemove(channel.Id, out _);
|
||||
public Task<ulong> GetOwnUser() => Task.FromResult(_ownUserId!.Value);
|
||||
|
||||
return default;
|
||||
}
|
||||
public ValueTask RemoveRole(ulong guildId, ulong roleId)
|
||||
{
|
||||
_roles.TryRemove(roleId, out _);
|
||||
return default;
|
||||
}
|
||||
|
||||
public ValueTask RemoveUser(ulong userId)
|
||||
{
|
||||
_users.TryRemove(userId, out _);
|
||||
return default;
|
||||
}
|
||||
public Task<Guild?> TryGetGuild(ulong guildId)
|
||||
{
|
||||
_guilds.TryGetValue(guildId, out var cg);
|
||||
return Task.FromResult(cg?.Guild);
|
||||
}
|
||||
|
||||
public Task<ulong> GetOwnUser() => Task.FromResult(_ownUserId!.Value);
|
||||
public Task<Channel?> TryGetChannel(ulong channelId)
|
||||
{
|
||||
_channels.TryGetValue(channelId, out var channel);
|
||||
return Task.FromResult(channel);
|
||||
}
|
||||
|
||||
public ValueTask RemoveRole(ulong guildId, ulong roleId)
|
||||
{
|
||||
_roles.TryRemove(roleId, out _);
|
||||
return default;
|
||||
}
|
||||
public Task<Channel?> TryGetDmChannel(ulong userId)
|
||||
{
|
||||
if (!_dmChannels.TryGetValue(userId, out var channelId))
|
||||
return Task.FromResult((Channel?)null);
|
||||
return TryGetChannel(channelId);
|
||||
}
|
||||
|
||||
public Task<Guild?> TryGetGuild(ulong guildId)
|
||||
{
|
||||
_guilds.TryGetValue(guildId, out var cg);
|
||||
return Task.FromResult(cg?.Guild);
|
||||
}
|
||||
public Task<User?> TryGetUser(ulong userId)
|
||||
{
|
||||
_users.TryGetValue(userId, out var user);
|
||||
return Task.FromResult(user);
|
||||
}
|
||||
|
||||
public Task<Channel?> TryGetChannel(ulong channelId)
|
||||
{
|
||||
_channels.TryGetValue(channelId, out var channel);
|
||||
return Task.FromResult(channel);
|
||||
}
|
||||
public Task<GuildMemberPartial?> TryGetSelfMember(ulong guildId)
|
||||
{
|
||||
_guildMembers.TryGetValue(guildId, out var guildMember);
|
||||
return Task.FromResult(guildMember);
|
||||
}
|
||||
|
||||
public Task<Channel?> TryGetDmChannel(ulong userId)
|
||||
{
|
||||
if (!_dmChannels.TryGetValue(userId, out var channelId))
|
||||
return Task.FromResult((Channel?)null);
|
||||
return TryGetChannel(channelId);
|
||||
}
|
||||
public Task<Role?> TryGetRole(ulong roleId)
|
||||
{
|
||||
_roles.TryGetValue(roleId, out var role);
|
||||
return Task.FromResult(role);
|
||||
}
|
||||
|
||||
public Task<User?> TryGetUser(ulong userId)
|
||||
{
|
||||
_users.TryGetValue(userId, out var user);
|
||||
return Task.FromResult(user);
|
||||
}
|
||||
public IAsyncEnumerable<Guild> GetAllGuilds()
|
||||
{
|
||||
return _guilds.Values
|
||||
.Select(g => g.Guild)
|
||||
.ToAsyncEnumerable();
|
||||
}
|
||||
|
||||
public Task<GuildMemberPartial?> TryGetSelfMember(ulong guildId)
|
||||
{
|
||||
_guildMembers.TryGetValue(guildId, out var guildMember);
|
||||
return Task.FromResult(guildMember);
|
||||
}
|
||||
public Task<IEnumerable<Channel>> GetGuildChannels(ulong guildId)
|
||||
{
|
||||
if (!_guilds.TryGetValue(guildId, out var guild))
|
||||
throw new ArgumentException("Guild not found", nameof(guildId));
|
||||
|
||||
public Task<Role?> TryGetRole(ulong roleId)
|
||||
{
|
||||
_roles.TryGetValue(roleId, out var role);
|
||||
return Task.FromResult(role);
|
||||
}
|
||||
return Task.FromResult(guild.Channels.Keys.Select(c => _channels[c]));
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<Guild> GetAllGuilds()
|
||||
{
|
||||
return _guilds.Values
|
||||
.Select(g => g.Guild)
|
||||
.ToAsyncEnumerable();
|
||||
}
|
||||
private CachedGuild SaveGuildRaw(Guild guild) =>
|
||||
_guilds.GetOrAdd(guild.Id, (_, g) => new CachedGuild(g), guild);
|
||||
|
||||
public Task<IEnumerable<Channel>> GetGuildChannels(ulong guildId)
|
||||
{
|
||||
if (!_guilds.TryGetValue(guildId, out var guild))
|
||||
throw new ArgumentException("Guild not found", nameof(guildId));
|
||||
|
||||
return Task.FromResult(guild.Channels.Keys.Select(c => _channels[c]));
|
||||
}
|
||||
|
||||
private CachedGuild SaveGuildRaw(Guild guild) =>
|
||||
_guilds.GetOrAdd(guild.Id, (_, g) => new CachedGuild(g), guild);
|
||||
|
||||
private record CachedGuild(Guild Guild)
|
||||
{
|
||||
public readonly ConcurrentDictionary<ulong, bool> Channels = new();
|
||||
}
|
||||
private record CachedGuild(Guild Guild)
|
||||
{
|
||||
public readonly ConcurrentDictionary<ulong, bool> Channels = new();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user