Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions NetCord/Application.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,14 @@ public Application(JsonModels.JsonApplication jsonModel, RestClient client) : ba
if (integrationTypesConfiguration is not null)
IntegrationTypesConfiguration = integrationTypesConfiguration.ToDictionary(i => i.Key, i => new ApplicationIntegrationTypeConfiguration(i.Value));
}

public ImageUrl? GetIconUrl(ImageFormat format) => IconHash is string hash ? ImageUrl.ApplicationIcon(Id, hash, format) : null;

public ImageUrl? GetCoverUrl(ImageFormat format) => CoverImageHash is string hash ? ImageUrl.ApplicationCover(Id, hash, format) : null;

public ImageUrl? GetAssetUrl(ulong assetId, ImageFormat format) => ImageUrl.ApplicationAsset(Id, assetId, format);

public ImageUrl? GetAchievementIconUrl(ulong achievementId, string iconHash, ImageFormat format) => ImageUrl.AchievementIcon(Id, achievementId, iconHash, format);

public ImageUrl? GetStorePageAssetUrl(ulong assetId, ImageFormat format) => ImageUrl.StorePageAsset(Id, assetId, format);
}
2 changes: 2 additions & 0 deletions NetCord/CustomEmoji.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public CustomEmoji(JsonEmoji jsonModel, RestClient client) : base(jsonModel)

public bool? Available => _jsonModel.Available;

public ImageUrl GetImageUrl(ImageFormat format) => ImageUrl.CustomEmoji(Id, format);

public override string ToString() => Animated ? $"<a:{Name}:{Id}>" : $"<:{Name}:{Id}>";

public string ToString(string? format, IFormatProvider? formatProvider) => ToString();
Expand Down
12 changes: 12 additions & 0 deletions NetCord/GuildScheduledEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,24 @@ public partial class GuildScheduledEvent : ClientEntity, IJsonModel<JsonModels.J

public int? UserCount => _jsonModel.UserCount;

public string? CoverImageHash => _jsonModel.CoverImageHash;

public GuildScheduledEventRecurrenceRule? RecurrenceRule { get; }

public GuildScheduledEvent(JsonModels.JsonGuildScheduledEvent jsonModel, RestClient client) : base(client)
{
_jsonModel = jsonModel;

var creator = _jsonModel.Creator;
if (creator is not null)
Creator = new(creator, client);

var recurrenceRule = _jsonModel.RecurrenceRule;
if (recurrenceRule is not null)
RecurrenceRule = new(recurrenceRule);
}

public bool HasCoverImage => CoverImageHash is not null;

public ImageUrl? GetCoverImageUrl(ImageFormat format) => _jsonModel.CoverImageHash is string hash ? ImageUrl.GuildScheduledEventCover(Id, hash, format) : null;
}
28 changes: 28 additions & 0 deletions NetCord/GuildScheduledEventRecurrenceRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using NetCord.JsonModels;

namespace NetCord;

public class GuildScheduledEventRecurrenceRule(JsonGuildScheduledEventRecurrenceRule jsonModel) : IJsonModel<JsonGuildScheduledEventRecurrenceRule>
{
JsonGuildScheduledEventRecurrenceRule IJsonModel<JsonGuildScheduledEventRecurrenceRule>.JsonModel => jsonModel;

public DateTimeOffset? StartAt => jsonModel.StartAt;

public DateTimeOffset? EndAt => jsonModel.EndAt;

public GuildScheduledEventRecurrenceRuleFrequency Frequency => jsonModel.Frequency;

public int Interval => jsonModel.Interval;

public GuildScheduledEventRecurrenceRuleWeekday? ByWeekday => jsonModel.ByWeekday;

public GuildScheduledEventRecurrenceRuleNWeekday ByNWeekday { get; } = new(jsonModel.ByNWeekday);

public GuildScheduledEventRecurrenceRuleMonth? ByMonth => jsonModel.ByMonth;

public IReadOnlyList<int>? ByMonthDay => jsonModel.ByMonthDay;

public IReadOnlyList<int>? ByYearDay => jsonModel.ByYearDay;

public int? Count => jsonModel.Count;
}
9 changes: 9 additions & 0 deletions NetCord/GuildScheduledEventRecurrenceRuleFrequency.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace NetCord;

public enum GuildScheduledEventRecurrenceRuleFrequency : byte
{
Yearly = 0,
Monthly = 1,
Weekly = 2,
Daily = 3,
}
17 changes: 17 additions & 0 deletions NetCord/GuildScheduledEventRecurrenceRuleMonth.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace NetCord;

public enum GuildScheduledEventRecurrenceRuleMonth
{
January = 1,
February = 2,
March = 3,
April = 4,
May = 5,
June = 6,
July = 7,
August = 8,
September = 9,
October = 10,
November = 11,
December = 12,
}
12 changes: 12 additions & 0 deletions NetCord/GuildScheduledEventRecurrenceRuleNWeekday.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using NetCord.JsonModels;

namespace NetCord;

public class GuildScheduledEventRecurrenceRuleNWeekday(JsonGuildScheduledEventRecurrenceRuleNWeekday jsonModel) : IJsonModel<JsonGuildScheduledEventRecurrenceRuleNWeekday>
{
JsonGuildScheduledEventRecurrenceRuleNWeekday IJsonModel<JsonGuildScheduledEventRecurrenceRuleNWeekday>.JsonModel => jsonModel;

public int N => jsonModel.N;

public GuildScheduledEventRecurrenceRuleWeekday Day => jsonModel.Day;
}
12 changes: 12 additions & 0 deletions NetCord/GuildScheduledEventRecurrenceRuleWeekday.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace NetCord;

public enum GuildScheduledEventRecurrenceRuleWeekday : byte
{
Monday = 0,
Tuesday = 1,
Wednesday = 2,
Thursday = 3,
Friday = 4,
Saturday = 5,
Sunday = 6,
}
13 changes: 7 additions & 6 deletions NetCord/GuildUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,21 @@ public partial class GuildUser(JsonGuildUser jsonModel, ulong guildId, RestClien
/// <summary>
/// The ID of the guild the <see cref="GuildUser"/> object belongs to.
/// </summary>
public ulong GuildId { get; } = guildId;
public ulong GuildId => guildId;

/// <summary>
/// Gets the <see cref="ImageUrl"/> of the user's guild avatar.
/// </summary>
/// <param name="format">The format of the returned <see cref="ImageUrl"/>. Defaults to <see cref="ImageFormat.Png"/> (or <see cref="ImageFormat.Gif"/> for animated avatars).</param>
/// <returns>An <see cref="ImageUrl"/> pointing to the user's guild avatar. If the user does not have one set, returns <see langword="null"/>.</returns>
public ImageUrl? GetGuildAvatarUrl(ImageFormat? format = null) => GuildAvatarHash is string hash ? ImageUrl.GuildUserAvatar(GuildId, Id, hash, format) : null;
public ImageUrl? GetGuildAvatarUrl(ImageFormat? format = null) => GuildAvatarHash is string hash ? ImageUrl.GuildUserAvatar(guildId, Id, hash, format) : null;

/// <summary>
/// Gets the <see cref="ImageUrl"/> of the user's guild avatar decoration.
/// Gets the <see cref="ImageUrl"/> of the user's guild banner.
/// </summary>
/// <returns>An <see cref="ImageUrl"/> pointing to the user's guild avatar decoration. If the user does not have one set, returns <see langword="null"/>.</returns>
public ImageUrl? GetGuildAvatarDecorationUrl() => GuildAvatarDecorationData is { Hash: var hash } ? ImageUrl.AvatarDecoration(hash) : null;
/// <param name="format">The format of the returned <see cref="ImageUrl"/>. Defaults to <see cref="ImageFormat.Png"/> (or <see cref="ImageFormat.Gif"/> for animated banners).</param>
/// <returns>An <see cref="ImageUrl"/> pointing to the user's guild banner. If the user does not have one set, returns <see langword="null"/>.</returns>
public ImageUrl? GetGuildBannerUrl(ImageFormat? format = null) => GuildBannerHash is string hash ? ImageUrl.GuildUserBanner(guildId, Id, hash, format) : null;

/// <summary>
/// Applies a timeout to the <see cref="GuildUser"/> for a specified <see cref="DateTimeOffset"/>.
Expand All @@ -41,7 +42,7 @@ public partial class GuildUser(JsonGuildUser jsonModel, ulong guildId, RestClien
/// <exception cref="EntityNotFoundException"/>
public async Task<GuildUserInfo> GetInfoAsync(RestRequestProperties? properties = null)
{
await foreach (var info in _client.SearchGuildUsersAsync(GuildId, new() { Limit = 1, AndQuery = [new UserIdsGuildUsersSearchQuery([Id])] }, properties).ConfigureAwait(false))
await foreach (var info in _client.SearchGuildUsersAsync(guildId, new() { Limit = 1, AndQuery = [new UserIdsGuildUsersSearchQuery([Id])] }, properties).ConfigureAwait(false))
return info;

throw new EntityNotFoundException("The user was not found.");
Expand Down
2 changes: 1 addition & 1 deletion NetCord/ImageFormat.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace NetCord;

public enum ImageFormat
public enum ImageFormat : byte
{
Jpeg,
Png,
Expand Down
11 changes: 6 additions & 5 deletions NetCord/ImageUrl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ public bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan

private protected virtual bool IsSizeValid(ReadOnlySpan<char> format)
{
for (int i = 0; i < format.Length; i++)
int length = format.Length;
for (int i = 0; i < length; i++)
{
if (!char.IsAsciiDigit(format[i]))
return false;
Expand Down Expand Up @@ -202,14 +203,14 @@ public static ImageUrl Sticker(ulong stickerId, ImageFormat format)
return new($"/stickers/{stickerId}", GetFormat(format), Discord.MediaUrl);
}

public static ImageUrl RoleIcon(ulong roleId, ImageFormat format)
public static ImageUrl RoleIcon(ulong roleId, string iconHash, ImageFormat format)
{
return new($"/role-icons/{roleId}/role_icon", GetFormat(format));
return new($"/role-icons/{roleId}/{iconHash}", GetFormat(format));
}

public static ImageUrl GuildScheduledEventCover(ulong scheduledEventId, string coverHash, ImageFormat format)
public static ImageUrl GuildScheduledEventCover(ulong scheduledEventId, string coverImageHash, ImageFormat format)
{
return new($"/guild-events/{scheduledEventId}/{coverHash}", GetFormat(format));
return new($"/guild-events/{scheduledEventId}/{coverImageHash}", GetFormat(format));
}

public static ImageUrl GuildUserBanner(ulong guildId, ulong userId, string bannerHash, ImageFormat? format)
Expand Down
6 changes: 6 additions & 0 deletions NetCord/JsonModels/JsonGuildScheduledEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,10 @@ public class JsonGuildScheduledEvent : JsonEntity

[JsonPropertyName("user_count")]
public int? UserCount { get; set; }

[JsonPropertyName("image")]
public string? CoverImageHash { get; set; }

[JsonPropertyName("recurrence_rule")]
public JsonGuildScheduledEventRecurrenceRule? RecurrenceRule { get; set; }
}
36 changes: 36 additions & 0 deletions NetCord/JsonModels/JsonGuildScheduledEventRecurrenceRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Text.Json.Serialization;

namespace NetCord.JsonModels;

public class JsonGuildScheduledEventRecurrenceRule
{
[JsonPropertyName("start")]
public DateTimeOffset? StartAt { get; set; }

[JsonPropertyName("end")]
public DateTimeOffset? EndAt { get; set; }

[JsonPropertyName("frequency")]
public GuildScheduledEventRecurrenceRuleFrequency Frequency { get; set; }

[JsonPropertyName("interval")]
public int Interval { get; set; }

[JsonPropertyName("by_weekday")]
public GuildScheduledEventRecurrenceRuleWeekday? ByWeekday { get; set; }

[JsonPropertyName("by_n_weekday")]
public JsonGuildScheduledEventRecurrenceRuleNWeekday ByNWeekday { get; set; }

[JsonPropertyName("by_month")]
public GuildScheduledEventRecurrenceRuleMonth? ByMonth { get; set; }

[JsonPropertyName("by_month_day")]
public int[]? ByMonthDay { get; set; }

[JsonPropertyName("by_year_day")]
public int[]? ByYearDay { get; set; }

[JsonPropertyName("count")]
public int? Count { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System.Text.Json.Serialization;

namespace NetCord.JsonModels;

public class JsonGuildScheduledEventRecurrenceRuleNWeekday
{
[JsonPropertyName("n")]
public int N { get; set; }

[JsonPropertyName("day")]
public GuildScheduledEventRecurrenceRuleWeekday Day { get; set; }
}
3 changes: 3 additions & 0 deletions NetCord/JsonModels/JsonGuildUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public class JsonGuildUser
[JsonPropertyName("avatar")]
public string? GuildAvatarHash { get; set; }

[JsonPropertyName("banner")]
public string? GuildBannerHash { get; set; }

[JsonPropertyName("roles")]
public ulong[] RoleIds { get; set; }

Expand Down
16 changes: 16 additions & 0 deletions NetCord/PartialGuildUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ public PartialGuildUser(JsonGuildUser jsonModel, RestClient client) : base(jsonM
/// </summary>
public string? GuildAvatarHash => _jsonModel.GuildAvatarHash;

/// <summary>
/// The user's guild banner hash.
/// </summary>
public string? GuildBannerHash => _jsonModel.GuildBannerHash;

/// <summary>
/// A list of <see cref="ulong"/> IDs representing the user's current roles.
/// </summary>
Expand Down Expand Up @@ -85,8 +90,19 @@ public PartialGuildUser(JsonGuildUser jsonModel, RestClient client) : base(jsonM
/// </summary>
public bool HasGuildAvatar => GuildAvatarHash is not null;

/// <summary>
/// Whether the user has a guild banner set.
/// </summary>
public bool HasGuildBanner => GuildBannerHash is not null;

/// <summary>
/// Whether the user has a set avatar decoration.
/// </summary>
public bool HasGuildAvatarDecoration => GuildAvatarDecorationData is not null;

/// <summary>
/// Gets the <see cref="ImageUrl"/> of the user's guild avatar decoration.
/// </summary>
/// <returns>An <see cref="ImageUrl"/> pointing to the user's guild avatar decoration. If the user does not have one set, returns <see langword="null"/>.</returns>
public ImageUrl? GetGuildAvatarDecorationUrl() => GuildAvatarDecorationData is { Hash: var hash } ? ImageUrl.AvatarDecoration(hash) : null;
}
3 changes: 2 additions & 1 deletion NetCord/PartialGuildUserExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public static Permissions GetPermissions(this PartialGuildUser user, RestGuild g
if (user.Id == guild.OwnerId)
return (Permissions)ulong.MaxValue;

var permissions = guild.EveryoneRole.Permissions;
if (guild.EveryoneRole is not { Permissions: var permissions })
throw new InvalidOperationException("Cannot calculate permissions based on a partial guild.");

foreach (var role in user.GetRoles(guild))
permissions |= role.Permissions;
Expand Down
13 changes: 8 additions & 5 deletions NetCord/Rest/RestGuild.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,9 @@ int GetHighestRolePosition(PartialGuildUser user)
/// <summary>
/// Gets the <see cref="ImageUrl"/> of the <see cref="RestGuild"/>'s splash.
/// </summary>
/// <param name="format">The format of the returned <see cref="ImageUrl"/>. Defaults to <see cref="ImageFormat.Png"/>.</param>
/// <param name="format">The format of the returned <see cref="ImageUrl"/>.</param>
/// <returns>An <see cref="ImageUrl"/> pointing to the guild's splash. If the guild does not have one set, returns <see langword="null"/>.</returns>
public ImageUrl? GetSplashUrl(ImageFormat format = ImageFormat.Png) => SplashHash is string hash ? ImageUrl.GuildSplash(Id, hash, format) : null;
public ImageUrl? GetSplashUrl(ImageFormat format) => SplashHash is string hash ? ImageUrl.GuildSplash(Id, hash, format) : null;

/// <summary>
/// Whether the <see cref="RestGuild"/> has a set discovery splash.
Expand All @@ -121,9 +121,9 @@ int GetHighestRolePosition(PartialGuildUser user)
/// <summary>
/// Gets the <see cref="ImageUrl"/> of the <see cref="RestGuild"/>'s discovery splash.
/// </summary>
/// <param name="format">The format of the returned <see cref="ImageUrl"/>. Defaults to <see cref="ImageFormat.Png"/>.</param>
/// <param name="format">The format of the returned <see cref="ImageUrl"/>.</param>
/// <returns>An <see cref="ImageUrl"/> pointing to the guild's discovery splash. If the guild does not have one set, returns <see langword="null"/>.</returns>
public ImageUrl? GetDiscoverySplashUrl(ImageFormat format = ImageFormat.Png) => DiscoverySplashHash is string hash ? ImageUrl.GuildDiscoverySplash(Id, hash, format) : null;
public ImageUrl? GetDiscoverySplashUrl(ImageFormat format) => DiscoverySplashHash is string hash ? ImageUrl.GuildDiscoverySplash(Id, hash, format) : null;

/// <summary>
/// <see langword="true"/> if the user is the owner of the <see cref="RestGuild"/>.
Expand Down Expand Up @@ -329,5 +329,8 @@ int GetHighestRolePosition(PartialGuildUser user)
/// <summary>
/// The guild's base role, applied to all users.
/// </summary>
public Role EveryoneRole => Roles[Id];
/// <returns>The guild's base role, applied to all users or <see langword="null"/> if the guild is partial.</returns>
public Role? EveryoneRole => Roles.GetValueOrDefault(Id);

public ImageUrl GetWidgetUrl(GuildWidgetStyle? style = null, string? hostname = null, ApiVersion? version = null) => ImageUrl.GuildWidget(Id, style, hostname, version);
}
2 changes: 2 additions & 0 deletions NetCord/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public Role(JsonRole jsonModel, ulong guildId, RestClient client) : base(client)
GuildId = guildId;
}

public ImageUrl? GetIconUrl(ImageFormat format) => IconHash is string hash ? ImageUrl.RoleIcon(Id, hash, format) : null;

public override string ToString() => $"<@&{Id}>";

public override bool TryFormat(Span<char> destination, out int charsWritten, ReadOnlySpan<char> format = default, IFormatProvider? provider = null) => Mention.TryFormatRole(destination, out charsWritten, Id);
Expand Down
2 changes: 2 additions & 0 deletions NetCord/Sticker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ private protected Sticker(JsonModels.JsonSticker jsonModel)
_jsonModel = jsonModel;
Tags = _jsonModel.Tags.Split(',');
}

public ImageUrl GetImageUrl(ImageFormat format) => ImageUrl.Sticker(Id, format);
}
2 changes: 2 additions & 0 deletions NetCord/Team.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ public class Team(JsonModels.JsonTeam jsonModel, RestClient client) : Entity, IJ
public string Name => jsonModel.Name;

public ulong OwnerId => jsonModel.OwnerId;

public ImageUrl? GetIconUrl(ImageFormat format) => IconHash is string hash ? ImageUrl.TeamIcon(Id, hash, format) : null;
}