Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
2c09f3a
first cache structuring
Plerx2493 Oct 9, 2023
addd239
use generic cache methods
Plerx2493 Oct 9, 2023
a4b8ec2
impl DiscordMemoryCache
Plerx2493 Oct 9, 2023
0a0be2e
Add better configs
Plerx2493 Oct 10, 2023
5cb135d
Use primary constructors, move files and edit nits
Plerx2493 Oct 10, 2023
6281180
Even better configs and more generic cache impl
Plerx2493 Oct 10, 2023
16c5242
Use reflection to get keyGenMethods
Plerx2493 Oct 11, 2023
4b28c4b
Own CacheEntryOptions, impl static helper methods for CacheKeys
Plerx2493 Oct 11, 2023
7e520fa
Nuke old caches
Plerx2493 Oct 17, 2023
4db91dc
Add TransportGuild
Plerx2493 Oct 19, 2023
15a8214
DiscordGuild cache updates
Plerx2493 Oct 19, 2023
1b218df
much pain
Plerx2493 Oct 20, 2023
12f9ab0
rename Namespace and some pain
Plerx2493 Oct 23, 2023
3ab1f18
Replace old cache methods and start to apply new caching, tldr muuch …
Plerx2493 Oct 27, 2023
643e64b
Update Guild and Channel gateway event dispatch
Plerx2493 Oct 28, 2023
cdd4379
more time in DiscordClient.Dispatch and i will get insane
Plerx2493 Oct 31, 2023
982c851
start the auditlog pain again
Plerx2493 Nov 2, 2023
c4f3f9c
CachedEntity v1.5
Plerx2493 Nov 2, 2023
613e9ec
Start the second rundown on dispatch to add CachedEntity
Plerx2493 Nov 6, 2023
5bde3f6
i fogor
Plerx2493 Nov 7, 2023
e9eea0a
Merge branch 'master' into fix/cacheRework
Plerx2493 Nov 7, 2023
17ebabe
Dispatch readability and auditlog parser v3
Plerx2493 Nov 25, 2023
56db129
auditlog nullability
Plerx2493 Nov 30, 2023
2435d7f
Move presences to new cache and continue to update dispatch
Plerx2493 Dec 6, 2023
28b4abe
Remove hidden api call
Plerx2493 Dec 12, 2023
8d690ca
Merge branch 'master' into fix/cacheRework-merge
Plerx2493 Dec 12, 2023
06cb86b
fix merge issue
Plerx2493 Dec 12, 2023
951e9b0
merge and fix some nullability problems
Plerx2493 Dec 12, 2023
c280da2
start docs
Plerx2493 Dec 14, 2023
efe7021
rename some variables and methods acording to the editor config
Plerx2493 Dec 29, 2023
37a05dd
fix DiscordMessage
Plerx2493 Jan 4, 2024
61836e0
Fix DiscordGuild, DiscordChannel and a bit more
Plerx2493 Jan 5, 2024
d98dbfe
fix Channel#PermissionsForMember and start to fix some cnext attributes
Plerx2493 Jan 23, 2024
891b180
Fix ShardedClient, some renaming and some other fixes
Plerx2493 Jan 27, 2024
4ee9361
Fix voicestates
Plerx2493 Feb 6, 2024
81d7596
Merge branch 'master' into fix/cacheRework
Plerx2493 Feb 6, 2024
05f590f
fix more stuff
Plerx2493 Feb 6, 2024
0b00df4
started fixing message
Plerx2493 Feb 7, 2024
36470c5
More fixing
Plerx2493 Feb 19, 2024
465b777
GetGuild - withCounts und withChannels
Plerx2493 Feb 19, 2024
03b0b2e
Handle DiscordMessageSticker.GuildId is null
Plerx2493 Feb 19, 2024
efc7770
Fix DiscordWidgetSettings and DiscordWidget in DiscordApiClient
Plerx2493 Apr 3, 2024
fdf6f4b
Rename BaseDiscordClient._guilds to _guildIds
Plerx2493 Apr 3, 2024
51e9e47
Fix permission calculation and some minor things in DiscordChannel
Plerx2493 Apr 3, 2024
9e3852c
Don´t have a dublicate/override cache in DiscordClient because the ba…
Plerx2493 Apr 3, 2024
44bded8
Use cache when fetching guild in default
Plerx2493 Apr 3, 2024
b93e1c0
Fix dm channel caching in ApiClient
Plerx2493 Apr 3, 2024
a5edfe1
Forgot a _guilds to _guildIds rename
Plerx2493 Apr 3, 2024
e9fa536
Use new cache in DiscordEmoji static methods
Plerx2493 Apr 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public override async Task<bool> ExecuteCheckAsync(CommandContext ctx, bool help
return true;
}

Permissions pbot = ctx.Channel.PermissionsFor(bot);
Permissions pbot = await ctx.Channel.PermissionsForMemberAsync(bot);

return (pbot & Permissions.Administrator) != 0 ? true : (pbot & this.Permissions) == this.Permissions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ public override async Task<bool> ExecuteCheckAsync(CommandContext ctx, bool help
return false;
}

Permissions pusr = ctx.Channel.PermissionsFor(usr);
Permissions pusr = await ctx.Channel.PermissionsForMemberAsync(usr);

DSharpPlus.Entities.DiscordMember bot = await ctx.Guild.GetMemberAsync(ctx.Client.CurrentUser.Id);
if (bot == null)
{
return false;
}

Permissions pbot = ctx.Channel.PermissionsFor(bot);
Permissions pbot = await ctx.Channel.PermissionsForMemberAsync(bot);

bool usrok = ctx.Guild.OwnerId == usr.Id;
bool botok = ctx.Guild.OwnerId == bot.Id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,28 +30,26 @@ public RequireUserPermissionsAttribute(Permissions permissions, bool ignoreDms =
this.IgnoreDms = ignoreDms;
}

public override Task<bool> ExecuteCheckAsync(CommandContext ctx, bool help)
public async override Task<bool> ExecuteCheckAsync(CommandContext ctx, bool help)
{
if (ctx.Guild == null)
{
return Task.FromResult(this.IgnoreDms);
return this.IgnoreDms;
}

DSharpPlus.Entities.DiscordMember? usr = ctx.Member;
if (usr == null)
{
return Task.FromResult(false);
return false;
}

if (usr.Id == ctx.Guild.OwnerId)
{
return Task.FromResult(true);
return true;
}

Permissions pusr = ctx.Channel.PermissionsFor(usr);
Permissions pusr = await ctx.Channel.PermissionsForMemberAsync(usr);

return (pusr & Permissions.Administrator) != 0
? Task.FromResult(true)
: (pusr & this.Permissions) == this.Permissions ? Task.FromResult(true) : Task.FromResult(false);
return (pusr & Permissions.Administrator) != 0 || (pusr & this.Permissions) == this.Permissions;
}
}
17 changes: 12 additions & 5 deletions DSharpPlus.CommandsNext/CommandsNextExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ internal CommandsNextExtension(CommandsNextConfiguration cfg)

Type t = typeof(CommandsNextExtension);
IEnumerable<MethodInfo> ms = t.GetTypeInfo().DeclaredMethods;
MethodInfo? m = ms.FirstOrDefault(xm => xm.Name == nameof(ConvertArgument) && xm.ContainsGenericParameters && !xm.IsStatic && xm.IsPublic);
MethodInfo? m = ms.FirstOrDefault(xm => xm.Name == nameof(ConvertArgumentAsync) && xm.ContainsGenericParameters && !xm.IsStatic && xm.IsPublic);
this.ConvertGeneric = m;
}

Expand Down Expand Up @@ -949,7 +949,7 @@ public async Task DefaultHelpAsync(CommandContext ctx, [Description("Command to
/// <param name="cmd">Command to execute.</param>
/// <param name="rawArguments">Raw arguments to pass to command.</param>
/// <returns>Created fake context.</returns>
public CommandContext CreateFakeContext(DiscordUser actor, DiscordChannel channel, string messageContents, string prefix, Command cmd, string? rawArguments = null)
public async Task<CommandContext> CreateFakeContextAsync(DiscordUser actor, DiscordChannel channel, string messageContents, string prefix, Command cmd, string? rawArguments = null)
{
DateTimeOffset epoch = new DateTimeOffset(2015, 1, 1, 0, 0, 0, TimeSpan.Zero);
DateTimeOffset now = DateTimeOffset.UtcNow;
Expand Down Expand Up @@ -987,7 +987,14 @@ public CommandContext CreateFakeContext(DiscordUser actor, DiscordChannel channe
}
else
{
mentionedUsers = Utilities.GetUserMentions(msg).Select(this.Client.GetCachedOrEmptyUserInternal).ToList();
foreach (ulong mentionedUserId in Utilities.GetUserMentions(msg))
{
DiscordUser? User = await this.Client.TryGetCachedUserInternalAsync(mentionedUserId);
if (User is not null)
{
mentionedUsers.Add(User);
}
}
}
}

Expand Down Expand Up @@ -1026,7 +1033,7 @@ public CommandContext CreateFakeContext(DiscordUser actor, DiscordChannel channe
/// <param name="value">Value to convert.</param>
/// <param name="ctx">Context in which to convert to.</param>
/// <returns>Converted object.</returns>
public async Task<object> ConvertArgument<T>(string value, CommandContext ctx)
public async Task<object> ConvertArgumentAsync<T>(string value, CommandContext ctx)
{
Type t = typeof(T);
if (!this.ArgumentConverters.ContainsKey(t))
Expand All @@ -1050,7 +1057,7 @@ public async Task<object> ConvertArgument<T>(string value, CommandContext ctx)
/// <param name="ctx">Context in which to convert to.</param>
/// <param name="type">Type to convert to.</param>
/// <returns>Converted object.</returns>
public async Task<object> ConvertArgument(string? value, CommandContext ctx, Type type)
public async Task<object> ConvertArgumentAsync(string? value, CommandContext ctx, Type type)
{
MethodInfo m = this.ConvertGeneric.MakeGenericMethod(type);
try
Expand Down
4 changes: 2 additions & 2 deletions DSharpPlus.CommandsNext/CommandsNextUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ internal static async Task<ArgumentBindingResult> BindArgumentsAsync(CommandCont
{
try
{
array.SetValue(await ctx.CommandsNext.ConvertArgument(rawArgumentList[i], ctx, arg.Type), i - start);
array.SetValue(await ctx.CommandsNext.ConvertArgumentAsync(rawArgumentList[i], ctx, arg.Type), i - start);
}
catch (Exception ex)
{
Expand All @@ -285,7 +285,7 @@ internal static async Task<ArgumentBindingResult> BindArgumentsAsync(CommandCont
{
try
{
args[i + 2] = rawArgumentList[i] != null ? await ctx.CommandsNext.ConvertArgument(rawArgumentList[i], ctx, arg.Type) : arg.DefaultValue;
args[i + 2] = rawArgumentList[i] != null ? await ctx.CommandsNext.ConvertArgumentAsync(rawArgumentList[i], ctx, arg.Type) : arg.DefaultValue;
}
catch (Exception ex)
{
Expand Down
12 changes: 6 additions & 6 deletions DSharpPlus.CommandsNext/Converters/EntityConverters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ async Task<Optional<DiscordUser>> IArgumentConverter<DiscordUser>.ConvertAsync(s
string un = di != -1 ? value.Substring(0, di) : value;
string? dv = di != -1 ? value.Substring(di + 1) : null;

System.Collections.Generic.IEnumerable<DiscordMember> us = ctx.Client.Guilds.Values
System.Collections.Generic.IEnumerable<DiscordMember> us = ctx.Client._guildIds.Values
.SelectMany(xkvp => xkvp.Members.Values).Where(xm =>
xm.Username.Equals(un, cs ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase) &&
((dv != null && xm.Discriminator == dv) || dv == null));
Expand Down Expand Up @@ -137,14 +137,14 @@ Task<Optional<DiscordThreadChannel>> IArgumentConverter<DiscordThreadChannel>.Co
{
if (ulong.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong threadId))
{
DiscordThreadChannel result = ctx.Client.InternalGetCachedThread(threadId);
DiscordThreadChannel result = ctx.Client.InternalGetCachedThreadAsync(threadId);
return Task.FromResult(result != null ? Optional.FromValue(result) : Optional.FromNoValue<DiscordThreadChannel>());
}

Match m = ThreadRegex.Match(value);
if (m.Success && ulong.TryParse(m.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out threadId))
{
DiscordThreadChannel result = ctx.Client.InternalGetCachedThread(threadId);
DiscordThreadChannel result = ctx.Client.InternalGetCachedThreadAsync(threadId);
return Task.FromResult(result != null ? Optional.FromValue(result) : Optional.FromNoValue<DiscordThreadChannel>());
}

Expand Down Expand Up @@ -199,14 +199,14 @@ Task<Optional<DiscordGuild>> IArgumentConverter<DiscordGuild>.ConvertAsync(strin
{
if (ulong.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong gid))
{
return ctx.Client.Guilds.TryGetValue(gid, out DiscordGuild? result)
return ctx.Client._guildIds.TryGetValue(gid, out DiscordGuild? result)
? Task.FromResult(Optional.FromValue(result))
: Task.FromResult(Optional.FromNoValue<DiscordGuild>());
}

bool cs = ctx.Config.CaseSensitive;

DiscordGuild? gld = ctx.Client.Guilds.Values.FirstOrDefault(xg =>
DiscordGuild? gld = ctx.Client._guildIds.Values.FirstOrDefault(xg =>
xg.Name.Equals(value, cs ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase));
return Task.FromResult(gld != null ? Optional.FromValue(gld) : Optional.FromNoValue<DiscordGuild>());
}
Expand Down Expand Up @@ -286,7 +286,7 @@ Task<Optional<DiscordEmoji>> IArgumentConverter<DiscordEmoji>.ConvertAsync(strin

return !ulong.TryParse(sid, NumberStyles.Integer, CultureInfo.InvariantCulture, out ulong id)
? Task.FromResult(Optional.FromNoValue<DiscordEmoji>())
: DiscordEmoji.TryFromGuildEmote(ctx.Client, id, out emoji)
: DiscordEmoji.TryFromGuildEmoteAsync(ctx.Client, id, out emoji)
? Task.FromResult(Optional.FromValue(emoji))
: Task.FromResult(Optional.FromValue(new DiscordEmoji
{
Expand Down
20 changes: 6 additions & 14 deletions DSharpPlus.Rest/DiscordRestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,10 @@

namespace DSharpPlus;

using Caching;

public class DiscordRestClient : BaseDiscordClient
{
/// <summary>
/// Gets the dictionary of guilds cached by this client.
/// </summary>
public override IReadOnlyDictionary<ulong, DiscordGuild> Guilds
=> this._guilds_lazy.Value;

internal Dictionary<ulong, DiscordGuild> _guilds = new();
private Lazy<IReadOnlyDictionary<ulong, DiscordGuild>> _guilds_lazy;

public DiscordRestClient(DiscordConfiguration config) : base(config) => this._disposed = false;

/// <summary>
Expand All @@ -31,11 +24,11 @@ public override IReadOnlyDictionary<ulong, DiscordGuild> Guilds
public async Task InitializeCacheAsync()
{
await base.InitializeAsync();
this._guilds_lazy = new Lazy<IReadOnlyDictionary<ulong, DiscordGuild>>(() => new ReadOnlyDictionary<ulong, DiscordGuild>(this._guilds));
IReadOnlyList<DiscordGuild> gs = await this.ApiClient.GetCurrentUserGuildsAsync(100, null, null);
foreach (DiscordGuild g in gs)
foreach (DiscordGuild guild in gs)
{
this._guilds[g.Id] = g;
this._guildIds.Add(guild.Id);
await this.Cache.AddGuildAsync(guild);
}
}

Expand Down Expand Up @@ -412,7 +405,7 @@ public async Task<IReadOnlyList<DiscordMember>> ListGuildMembersAsync(ulong guil
Discord = this
};

this.UpdateUserCache(usr);
await this.Cache.AddUserAsync(usr);
}

recmbr.AddRange(tms.Select(xtm => new DiscordMember(xtm) { Discord = this, _guild_id = guild_id }));
Expand Down Expand Up @@ -2312,7 +2305,6 @@ public override void Dispose()
}

this._disposed = true;
this._guilds = null;
this.ApiClient?._rest?.Dispose();
}
}
2 changes: 1 addition & 1 deletion DSharpPlus.VoiceNext/VoiceNextConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -960,7 +960,7 @@ private async Task HandleDispatch(JObject jo)
// No longer spam, Discord supposedly doesn't send many of these
this.Discord.Logger.LogTrace(VoiceNextEvents.VoiceDispatch, "Received SPEAKING (OP5)");
VoiceSpeakingPayload spd = opp.ToDiscordObject<VoiceSpeakingPayload>();
bool foundUserInCache = this.Discord.TryGetCachedUserInternal(spd.UserId.Value, out DiscordUser? resolvedUser);
bool foundUserInCache = this.Discord.TryGetCachedUserInternalAsync(spd.UserId.Value, out DiscordUser? resolvedUser);
UserSpeakingEventArgs spk = new UserSpeakingEventArgs
{
Speaking = spd.Speaking,
Expand Down
22 changes: 22 additions & 0 deletions DSharpPlus/Caching/CacheConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace DSharpPlus.Caching;

using System;
using System.Collections.Generic;
using DSharpPlus.Entities;

/// <summary>
/// Configuration for the cache how long to keep items in the cache. This configuration is only used by <see cref="DiscordMemoryCache"/> and is ignored if you provide your own implementation of <see cref="IDiscordCache"/>.
/// </summary>
/// <remarks>The default implementation of <see cref="IDiscordCache"/> only supports timebased expiration </remarks>
public record CacheConfiguration
{
public Dictionary<Type, CacheEntryOptions> MemoryCacheEntryOptions { get; set; } = new()
{
{typeof(DiscordGuild), new CacheEntryOptions(){SlidingExpiration = TimeSpan.FromMinutes(60)}},
{typeof(DiscordChannel), new CacheEntryOptions(){SlidingExpiration = TimeSpan.FromMinutes(60)}},
{typeof(DiscordMessage), new CacheEntryOptions(){SlidingExpiration = TimeSpan.FromMinutes(60)}},
{typeof(DiscordMember), new CacheEntryOptions(){SlidingExpiration = TimeSpan.FromMinutes(60)}},
{typeof(DiscordUser), new CacheEntryOptions(){SlidingExpiration = TimeSpan.FromMinutes(60)}},
{typeof(DiscordPresence), new CacheEntryOptions(){SlidingExpiration = TimeSpan.FromMinutes(60)}}
};
}
54 changes: 54 additions & 0 deletions DSharpPlus/Caching/CacheEntryOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
namespace DSharpPlus.Caching;

using System;
using Microsoft.Extensions.Caching.Memory;

public class CacheEntryOptions
{
/// <summary>
/// Sliding expiration for the cache entry
/// </summary>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public TimeSpan? SlidingExpiration { get; set; }


/// <summary>
/// Absolute expiration for the cache entry relative to creation
/// </summary>
/// <exception cref="ArgumentOutOfRangeException"></exception>

public TimeSpan? AbsoluteExpirationRelativeToCreation { get; set; }


internal MemoryCacheEntryOptions ToMemoryCacheEntryOptions()
{
if (this.AbsoluteExpirationRelativeToCreation is null && this.SlidingExpiration is null)
{
throw new ArgumentException("Either SlidingExpiration or AbsoluteExpirationRelativeToCreation must be set");
}

if
(
this.AbsoluteExpirationRelativeToCreation is not null &&
this.SlidingExpiration is not null &&
this.AbsoluteExpirationRelativeToCreation < this.SlidingExpiration
)
{
throw new ArgumentException("AbsoluteExpirationRelativeToCreation must be greater than SlidingExpiration");
}

MemoryCacheEntryOptions options = new();

if (this.AbsoluteExpirationRelativeToCreation is not null)
{
options.AbsoluteExpirationRelativeToNow = this.AbsoluteExpirationRelativeToCreation;
}

if (this.SlidingExpiration is not null)
{
options.SlidingExpiration = this.SlidingExpiration;
}

return options;
}
}
Loading