diff --git a/samples/QQBot.Net.Samples.SimpleBot/Program.cs b/samples/QQBot.Net.Samples.SimpleBot/Program.cs index 0a7c606..29b479c 100644 --- a/samples/QQBot.Net.Samples.SimpleBot/Program.cs +++ b/samples/QQBot.Net.Samples.SimpleBot/Program.cs @@ -1,6 +1,7 @@ // See https://aka.ms/new-console-template for more information using QQBot; +using QQBot.Rest; using QQBot.WebSocket; QQBotSocketClient client = new(new QQBotSocketConfig @@ -19,13 +20,21 @@ client.MessageReceived += async message => { if (message.Source is not MessageSource.User) return; - IUserMessage msg = await message.ReplyAsync($""" - [Content] {message.Content} - [Content] {Format.Escape(message.Content)} - [Content] {Format.Sanitize(message.Content)} - [Attachments] {message.Attachments.Count} - """ - ); + if (message.Channel is SocketTextChannel textChannel) + { + var channel = await textChannel.Guild.CreateApplicationChannelAsync(message.Content, x => + { + x.ApplicationType = ChannelApplication.GameForPeace; + }); + } + +// IUserMessage msg = await message.ReplyAsync( +// $""" +// [Content] {message.Content} +// [Content] {Format.Escape(message.Content)} +// [Content] {Format.Sanitize(message.Content)} +// [Attachments] {message.Attachments.Count} +// """); }; await client.LoginAsync(0, TokenType.BotToken, ""); await client.StartAsync(); diff --git a/src/QQBot.Net.Core/Entities/Channels/ChannelType.cs b/src/QQBot.Net.Core/Entities/Channels/ChannelType.cs index b4b6abb..7e3320e 100644 --- a/src/QQBot.Net.Core/Entities/Channels/ChannelType.cs +++ b/src/QQBot.Net.Core/Entities/Channels/ChannelType.cs @@ -38,5 +38,10 @@ public enum ChannelType /// /// 论坛子频道。 /// - Forum = 10007 + Forum = 10007, + + /// + /// 日程子频道。 + /// + Schedule = 10011, } diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateApplicationChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateApplicationChannelProperties.cs new file mode 100644 index 0000000..a329d6a --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateApplicationChannelProperties.cs @@ -0,0 +1,13 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +/// +public class CreateApplicationChannelProperties : CreateNestedChannelProperties +{ + /// + /// 获取或设置要设置到此频道的应用频道类型。 + /// + public ChannelApplication? ApplicationType { get; set; } +} \ No newline at end of file diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateCategoryChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateCategoryChannelProperties.cs new file mode 100644 index 0000000..6069b4a --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateCategoryChannelProperties.cs @@ -0,0 +1,17 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +/// +public class CreateCategoryChannelProperties : CreateGuildChannelProperties +{ + /// + /// 获取或设置要设置到此频道的位置。 + /// + /// + /// 更小的数值表示更靠近列表顶部的位置。设置为与同分组下的其他频道相同的值,将会使当前频道排列于与该频道相邻更靠近列表顶部的位置。 + /// 分组频道的位置顺序号至少为 2。 + /// + public int Position { get; set; } = 2; +} diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateForumChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateForumChannelProperties.cs new file mode 100644 index 0000000..2d32a68 --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateForumChannelProperties.cs @@ -0,0 +1,7 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +/// +public class CreateForumChannelProperties : CreateNestedChannelProperties; \ No newline at end of file diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateGuildChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateGuildChannelProperties.cs new file mode 100644 index 0000000..a1cc462 --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateGuildChannelProperties.cs @@ -0,0 +1,6 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +public class CreateGuildChannelProperties; \ No newline at end of file diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateLiveStreamChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateLiveStreamChannelProperties.cs new file mode 100644 index 0000000..45d3d28 --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateLiveStreamChannelProperties.cs @@ -0,0 +1,7 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +/// +public class CreateLiveStreamChannelProperties : CreateNestedChannelProperties; diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateNestedChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateNestedChannelProperties.cs new file mode 100644 index 0000000..33cbf91 --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateNestedChannelProperties.cs @@ -0,0 +1,26 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +public class CreateNestedChannelProperties : CreateGuildChannelProperties +{ + // /// + // /// 获取或设置要设置到此频道的所属分组频道的 ID。 + // /// + // /// + // /// 将此值设置为某分组频道的 ID 可以使新建频道位于该分组频道下;将此值设置为 null + // /// 可以使新建频道位于服务器所有分组频道的上方,即不属于任何分组频道。 + // /// + // public ulong? CategoryId { get; set; } + + /// + /// 获取或设置要设置到此频道的私有频道类型。 + /// + public PrivateType? PrivateType { get; set; } + + /// + /// 获取或设置要设置到此频道的发言权限。 + /// + public SpeakPermission? SpeakPermission { get; set; } +} \ No newline at end of file diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateScheduleChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateScheduleChannelProperties.cs new file mode 100644 index 0000000..058ef81 --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateScheduleChannelProperties.cs @@ -0,0 +1,7 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +/// +public class CreateScheduleChannelProperties : CreateNestedChannelProperties; \ No newline at end of file diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateTextChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateTextChannelProperties.cs new file mode 100644 index 0000000..1787c42 --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateTextChannelProperties.cs @@ -0,0 +1,13 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +/// +public class CreateTextChannelProperties : CreateNestedChannelProperties +{ + /// + /// 获取或设置要设置到此频道的子频道二级分类。 + /// + public ChannelSubType? SubType { get; set; } +} diff --git a/src/QQBot.Net.Core/Entities/Channels/CreateVoiceChannelProperties.cs b/src/QQBot.Net.Core/Entities/Channels/CreateVoiceChannelProperties.cs new file mode 100644 index 0000000..8e9c935 --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/CreateVoiceChannelProperties.cs @@ -0,0 +1,7 @@ +namespace QQBot; + +/// +/// 提供用于创建 的属性。 +/// +/// +public class CreateVoiceChannelProperties : CreateNestedChannelProperties; \ No newline at end of file diff --git a/src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs b/src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs index daa1dff..5b95ddd 100644 --- a/src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs +++ b/src/QQBot.Net.Core/Entities/Channels/ICategoryChannel.cs @@ -3,7 +3,4 @@ namespace QQBot; /// /// 表示一个分组子频道。 /// -public interface ICategoryChannel : IGuildChannel -{ - -} +public interface ICategoryChannel : IGuildChannel; diff --git a/src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs b/src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs index 1d925a6..7064813 100644 --- a/src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs +++ b/src/QQBot.Net.Core/Entities/Channels/IForumChannel.cs @@ -3,7 +3,4 @@ namespace QQBot; /// /// 表示一个论坛子频道。 /// -public interface IForumChannel : INestedChannel -{ - -} +public interface IForumChannel : INestedChannel; diff --git a/src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs b/src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs index 0f3ef1c..7f1edce 100644 --- a/src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs +++ b/src/QQBot.Net.Core/Entities/Channels/ILiveStreamChannel.cs @@ -3,7 +3,4 @@ namespace QQBot; /// /// 表示一个直播子频道。 /// -public interface ILiveStreamChannel : INestedChannel -{ - -} +public interface ILiveStreamChannel : INestedChannel; diff --git a/src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs b/src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs index 270dff4..eef615b 100644 --- a/src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs +++ b/src/QQBot.Net.Core/Entities/Channels/INestedChannel.cs @@ -14,7 +14,7 @@ public interface INestedChannel : IGuildChannel /// /// 获取此子频道的私密类型。 /// - ChannelPrivateType? PrivateType { get; } + PrivateType? PrivateType { get; } /// /// 获取此子频道的发言权限。 diff --git a/src/QQBot.Net.Core/Entities/Channels/IScheduleChannel.cs b/src/QQBot.Net.Core/Entities/Channels/IScheduleChannel.cs new file mode 100644 index 0000000..249643c --- /dev/null +++ b/src/QQBot.Net.Core/Entities/Channels/IScheduleChannel.cs @@ -0,0 +1,6 @@ +namespace QQBot; + +/// +/// 表示一个日程子频道。 +/// +public interface IScheduleChannel : INestedChannel; diff --git a/src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs b/src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs index d53ad20..d64799f 100644 --- a/src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs +++ b/src/QQBot.Net.Core/Entities/Channels/IVoiceChannel.cs @@ -3,7 +3,4 @@ namespace QQBot; /// /// 表示一个语音子频道。 /// -public interface IVoiceChannel : INestedChannel -{ - -} +public interface IVoiceChannel : INestedChannel; diff --git a/src/QQBot.Net.Core/Entities/Channels/ChannelPrivateType.cs b/src/QQBot.Net.Core/Entities/Channels/PrivateType.cs similarity index 92% rename from src/QQBot.Net.Core/Entities/Channels/ChannelPrivateType.cs rename to src/QQBot.Net.Core/Entities/Channels/PrivateType.cs index c9c4177..8b3fec5 100644 --- a/src/QQBot.Net.Core/Entities/Channels/ChannelPrivateType.cs +++ b/src/QQBot.Net.Core/Entities/Channels/PrivateType.cs @@ -3,7 +3,7 @@ /// /// 表示一个子频道的私密类型。 /// -public enum ChannelPrivateType +public enum PrivateType { /// /// 公开子频道。 diff --git a/src/QQBot.Net.Core/Entities/Guilds/IGuild.cs b/src/QQBot.Net.Core/Entities/Guilds/IGuild.cs index 87876aa..0a3d34b 100644 --- a/src/QQBot.Net.Core/Entities/Guilds/IGuild.cs +++ b/src/QQBot.Net.Core/Entities/Guilds/IGuild.cs @@ -160,6 +160,23 @@ public interface IGuild : IEntity /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的具有语音聊天能力的子频道;如果未找到,则返回 null Task GetVoiceChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); + /// + /// 获取此频道的所有直播子频道。 + /// + /// 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。 + /// 发送请求时要使用的选项。 + /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。 + Task> GetLiveStreamChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); + + /// + /// 获取此频道内的直播子频道。 + /// + /// 要获取的直播子频道的 ID。 + /// 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。 + /// 发送请求时要使用的选项。 + /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的直播子频道;如果未找到,则返回 null + Task GetLiveStreamChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); + /// /// 获取此频道的所有应用子频道。 /// @@ -195,21 +212,21 @@ public interface IGuild : IEntity Task GetForumChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); /// - /// 获取此频道的所有直播子频道。 + /// 获取此频道的所有日程子频道。 /// /// 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。 /// 发送请求时要使用的选项。 - /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。 - Task> GetLiveStreamChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); + /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有日程子频道。 + Task> GetScheduleChannelsAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); /// - /// 获取此频道内的直播子频道。 + /// 获取此频道内的日程子频道。 /// - /// 要获取的直播子频道的 ID。 + /// 要获取的日程子频道的 ID。 /// 指示当前方法是否应该仅从缓存中获取结果,还是可以通过 API 请求获取数据。 /// 发送请求时要使用的选项。 - /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的直播子频道;如果未找到,则返回 null - Task GetLiveStreamChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); + /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的日程子频道;如果未找到,则返回 null + Task GetScheduleChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); /// /// 获取此频道的所有分组子频道。 @@ -228,5 +245,68 @@ public interface IGuild : IEntity /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的分组子频道;如果未找到,则返回 null Task GetCategoryChannelAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions? options = null); + /// + /// 在此服务器内创建一个新的文字子频道。 + /// + /// 频道的名称。 + /// 一个包含要应用到新创建频道的配置的委托。 + /// 发送请求时要使用的选项。 + /// 一个表示异步创建操作的任务。任务的结果包含新创建的文字频道。 + Task CreateTextChannelAsync(string name, Action? func = null, RequestOptions? options = null); + + /// + /// 在此服务器内创建一个新的语音子频道。 + /// + /// 频道的名称。 + /// 一个包含要应用到新创建频道的配置的委托。 + /// 发送请求时要使用的选项。 + /// 一个表示异步创建操作的任务。任务的结果包含新创建的语音频道。 + Task CreateVoiceChannelAsync(string name, Action? func = null, RequestOptions? options = null); + + /// + /// 在此服务器内创建一个新的直播子频道。 + /// + /// 频道的名称。 + /// 一个包含要应用到新创建频道的配置的委托。 + /// 发送请求时要使用的选项。 + /// 一个表示异步创建操作的任务。任务的结果包含新创建的直播频道。 + Task CreateLiveStreamChannelAsync(string name, Action? func = null, RequestOptions? options = null); + + /// + /// 在此服务器内创建一个新的应用子频道。 + /// + /// 频道的名称。 + /// 一个包含要应用到新创建频道的配置的委托。 + /// 发送请求时要使用的选项。 + /// 一个表示异步创建操作的任务。任务的结果包含新创建的应用频道。 + Task CreateApplicationChannelAsync(string name, Action? func = null, RequestOptions? options = null); + + /// + /// 在此服务器内创建一个新的论坛子频道。 + /// + /// 频道的名称。 + /// 一个包含要应用到新创建频道的配置的委托。 + /// 发送请求时要使用的选项。 + /// 一个表示异步创建操作的任务。任务的结果包含新创建的论坛频道。 + Task CreateForumChannelAsync(string name, Action? func = null, RequestOptions? options = null); + + /// + /// 在此服务器内创建一个新的日程子频道。 + /// + /// 频道的名称。 + /// 一个包含要应用到新创建频道的配置的委托。 + /// 发送请求时要使用的选项。 + /// 一个表示异步创建操作的任务。任务的结果包含新创建的日程频道。 + Task CreateScheduleChannelAsync(string name, Action? func = null, RequestOptions? options = null); + + /// + /// 在此服务器内创建一个新的分组子频道。 + /// + /// 频道的名称。 + /// 一个包含要应用到新创建频道的配置的委托。 + /// 发送请求时要使用的选项。 + /// 一个表示异步创建操作的任务。任务的结果包含新创建的分组频道。 + Task CreateCategoryChannelAsync(string name, Action? func = null, RequestOptions? options = null); + #endregion } diff --git a/src/QQBot.Net.Core/Net/HttpException.cs b/src/QQBot.Net.Core/Net/HttpException.cs index 6b33ee7..cad6371 100644 --- a/src/QQBot.Net.Core/Net/HttpException.cs +++ b/src/QQBot.Net.Core/Net/HttpException.cs @@ -68,6 +68,6 @@ private static string CreateMessage(HttpStatusCode httpCode, QQBotErrorCode? qqB string closeInfo = qqBotCode.HasValue && qqBotCode != 0 ? qqBotCode.Value.ToString() : httpCode.ToString(); - return $"The server responded with error {closeInfo}: {reason ?? httpCode.ToString()} ({closeCode}, {traceId})"; + return $"The server responded with error {closeInfo}: {reason ?? httpCode.ToString()} ({closeCode}{(traceId is not null ? $", trace ID: {traceId}" : string.Empty)})"; } } diff --git a/src/QQBot.Net.Core/QQBotErrorCode.cs b/src/QQBot.Net.Core/QQBotErrorCode.cs index 006fb91..4573bed 100644 --- a/src/QQBot.Net.Core/QQBotErrorCode.cs +++ b/src/QQBot.Net.Core/QQBotErrorCode.cs @@ -87,6 +87,16 @@ public enum QQBotErrorCode #endregion + #region SubChannel (200XXX) + + CreateChannelSecurityHit = 200011, + CreateChannelSuccessButGetInfoError = 200013, + NameEmpty = 200016, + PositionError = 200017, + CreateChannelCategoryError = 200019, + + #endregion + #region SubChannel Permission Errors (301XXX) SubChannelInvalidParameter = 301000, diff --git a/src/QQBot.Net.Core/Utils/Preconditions.cs b/src/QQBot.Net.Core/Utils/Preconditions.cs index f629c14..d25e206 100644 --- a/src/QQBot.Net.Core/Utils/Preconditions.cs +++ b/src/QQBot.Net.Core/Utils/Preconditions.cs @@ -13,7 +13,7 @@ internal static class Preconditions #region Objects /// 不可为 null. - public static void NotNull([NotNull] T? obj, string name, string? msg = null) where T : class + public static void NotNull([NotNull] T? obj, string name, string? msg = null) { if (obj == null) throw CreateNotNullException(name, msg); diff --git a/src/QQBot.Net.Rest/API/Common/Channel.cs b/src/QQBot.Net.Rest/API/Common/Channel.cs index 7b6cd9d..7eba56f 100644 --- a/src/QQBot.Net.Rest/API/Common/Channel.cs +++ b/src/QQBot.Net.Rest/API/Common/Channel.cs @@ -30,7 +30,7 @@ internal class Channel public required ulong OwnerId { get; set; } [JsonPropertyName("private_type")] - public ChannelPrivateType? PrivateType { get; set; } + public PrivateType? PrivateType { get; set; } [JsonPropertyName("speak_permission")] public SpeakPermission? SpeakPermission { get; set; } diff --git a/src/QQBot.Net.Rest/API/Rest/CreateChannelParams.cs b/src/QQBot.Net.Rest/API/Rest/CreateChannelParams.cs index 8026cc5..d91f062 100644 --- a/src/QQBot.Net.Rest/API/Rest/CreateChannelParams.cs +++ b/src/QQBot.Net.Rest/API/Rest/CreateChannelParams.cs @@ -15,19 +15,19 @@ internal class CreateChannelParams public ChannelSubType? SubType { get; set; } [JsonPropertyName("position")] - public int Position { get; set; } + public int? Position { get; set; } [JsonPropertyName("parent_id")] public ulong? CategoryId { get; set; } [JsonPropertyName("private_type")] - public ChannelPrivateType? PrivateType { get; set; } + public PrivateType? PrivateType { get; set; } [JsonPropertyName("private_user_ids")] public ulong[]? PrivateUserIds { get; set; } [JsonPropertyName("speak_permission")] - public SpeakPermission SpeakPermission { get; set; } + public SpeakPermission? SpeakPermission { get; set; } [JsonPropertyName("application_id")] [JsonConverter(typeof(ChannelApplicationJsonConverter))] diff --git a/src/QQBot.Net.Rest/API/Rest/ModifyChannelParams.cs b/src/QQBot.Net.Rest/API/Rest/ModifyChannelParams.cs index 8bae73c..72aafcf 100644 --- a/src/QQBot.Net.Rest/API/Rest/ModifyChannelParams.cs +++ b/src/QQBot.Net.Rest/API/Rest/ModifyChannelParams.cs @@ -14,7 +14,7 @@ internal class ModifyChannelParams public ulong? CategoryId { get; set; } [JsonPropertyName("private_type")] - public ChannelPrivateType? PrivateType { get; set; } + public PrivateType? PrivateType { get; set; } [JsonPropertyName("speak_permission")] public SpeakPermission SpeakPermission { get; set; } diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestApplicationChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestApplicationChannel.cs index a00762b..1071ed9 100644 --- a/src/QQBot.Net.Rest/Entities/Channels/RestApplicationChannel.cs +++ b/src/QQBot.Net.Rest/Entities/Channels/RestApplicationChannel.cs @@ -13,7 +13,7 @@ public class RestApplicationChannel : RestGuildChannel, IApplicationChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestForumChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestForumChannel.cs index ab180bb..10e50a1 100644 --- a/src/QQBot.Net.Rest/Entities/Channels/RestForumChannel.cs +++ b/src/QQBot.Net.Rest/Entities/Channels/RestForumChannel.cs @@ -13,7 +13,7 @@ public class RestForumChannel : RestGuildChannel, IForumChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestGuildChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestGuildChannel.cs index f08fc3a..db66a4e 100644 --- a/src/QQBot.Net.Rest/Entities/Channels/RestGuildChannel.cs +++ b/src/QQBot.Net.Rest/Entities/Channels/RestGuildChannel.cs @@ -45,6 +45,7 @@ internal static RestGuildChannel Create(BaseQQBotClient client, IGuild guild, Mo ChannelType.LiveStream => RestLiveStreamChannel.Create(client, guild, model), ChannelType.Application => RestApplicationChannel.Create(client, guild, model), ChannelType.Forum => RestForumChannel.Create(client, guild, model), + ChannelType.Schedule => RestScheduleChannel.Create(client, guild, model), _ => new RestGuildChannel(client, model.Id, guild) }; diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestLiveStreamChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestLiveStreamChannel.cs index 0d5c9c0..d0431ab 100644 --- a/src/QQBot.Net.Rest/Entities/Channels/RestLiveStreamChannel.cs +++ b/src/QQBot.Net.Rest/Entities/Channels/RestLiveStreamChannel.cs @@ -13,7 +13,7 @@ public class RestLiveStreamChannel : RestGuildChannel, ILiveStreamChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestScheduleChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestScheduleChannel.cs new file mode 100644 index 0000000..83bdc95 --- /dev/null +++ b/src/QQBot.Net.Rest/Entities/Channels/RestScheduleChannel.cs @@ -0,0 +1,47 @@ +using System.Diagnostics; +using QQBot.API; + +namespace QQBot.Rest; + +/// +/// 表示频道中的一个基于 REST 的日程子频道。 +/// +[DebuggerDisplay("{DebuggerDisplay,nq}")] +public class RestScheduleChannel : RestGuildChannel, IScheduleChannel +{ + /// + public ulong? CategoryId { get; private set; } + + /// + public PrivateType? PrivateType { get; private set; } + + /// + public SpeakPermission? SpeakPermission { get; private set; } + + /// + public ChannelPermission? Permission { get; private set; } + + internal RestScheduleChannel(BaseQQBotClient client, ulong id, IGuild guild) + : base(client, id, guild) + { + Type = ChannelType.Schedule; + } + + internal static new RestScheduleChannel Create(BaseQQBotClient client, IGuild guild, Channel model) + { + RestScheduleChannel entity = new(client, model.Id, guild); + entity.Update(model); + return entity; + } + + internal override void Update(Channel model) + { + base.Update(model); + CategoryId = model.ParentId; + PrivateType = model.PrivateType; + SpeakPermission = model.SpeakPermission; + Permission = model.Permissions is not null ? Enum.Parse(model.Permissions) : null; // TODO + } + + private string DebuggerDisplay => $"{Name} ({Id}, Schedule)"; +} diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestTextChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestTextChannel.cs index c1b3968..e81e993 100644 --- a/src/QQBot.Net.Rest/Entities/Channels/RestTextChannel.cs +++ b/src/QQBot.Net.Rest/Entities/Channels/RestTextChannel.cs @@ -17,7 +17,7 @@ public class RestTextChannel : RestGuildChannel, ITextChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.Rest/Entities/Channels/RestVoiceChannel.cs b/src/QQBot.Net.Rest/Entities/Channels/RestVoiceChannel.cs index 56771de..bb456ba 100644 --- a/src/QQBot.Net.Rest/Entities/Channels/RestVoiceChannel.cs +++ b/src/QQBot.Net.Rest/Entities/Channels/RestVoiceChannel.cs @@ -13,7 +13,7 @@ public class RestVoiceChannel : RestGuildChannel, IVoiceChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/QQBot.Net.Rest/Entities/Guilds/GuildHelper.cs index ce42ff5..7e1dc66 100644 --- a/src/QQBot.Net.Rest/Entities/Guilds/GuildHelper.cs +++ b/src/QQBot.Net.Rest/Entities/Guilds/GuildHelper.cs @@ -5,10 +5,14 @@ namespace QQBot.Rest; internal static class GuildHelper { - public static async Task> GetChannelsAsync(IGuild guild, BaseQQBotClient client, + #region Channels + + public static async Task> GetChannelsAsync(IGuild guild, + BaseQQBotClient client, RequestOptions? options) { - IReadOnlyCollection models = await client.ApiClient.GetChannelsAsync(guild.Id, options).ConfigureAwait(false); + IReadOnlyCollection models = + await client.ApiClient.GetChannelsAsync(guild.Id, options).ConfigureAwait(false); return [..models.Select(x => RestGuildChannel.Create(client, guild, x))]; } @@ -19,6 +23,129 @@ public static async Task GetChannelAsync(IGuild guild, BaseQQB return RestGuildChannel.Create(client, guild, model); } + public static async Task CreateTextChannelAsync(IGuild guild, BaseQQBotClient client, + string name, Action? func, RequestOptions? options) + { + CreateTextChannelProperties props = new(); + func?.Invoke(props); + CreateChannelParams args = new() + { + Name = name, + Type = ChannelType.Text, + // Position = props.Position, + SubType = props.SubType, + PrivateType = props.PrivateType, + SpeakPermission = props.SpeakPermission, + }; + Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false); + return RestTextChannel.Create(client, guild, model); + } + + public static async Task CreateVoiceChannelAsync(IGuild guild, BaseQQBotClient client, + string name, Action? func, RequestOptions? options) + { + CreateVoiceChannelProperties props = new(); + func?.Invoke(props); + CreateChannelParams args = new() + { + Name = name, + Type = ChannelType.Voice, + // Position = props.Position, + PrivateType = props.PrivateType, + SpeakPermission = props.SpeakPermission, + }; + Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false); + return RestVoiceChannel.Create(client, guild, model); + } + + public static async Task CreateLiveStreamChannelAsync(IGuild guild, BaseQQBotClient client, + string name, Action? func, RequestOptions? options) + { + CreateLiveStreamChannelProperties props = new(); + func?.Invoke(props); + CreateChannelParams args = new() + { + Name = name, + Type = ChannelType.LiveStream, + // Position = props.Position, + PrivateType = props.PrivateType, + SpeakPermission = props.SpeakPermission, + }; + Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false); + return RestLiveStreamChannel.Create(client, guild, model); + } + + public static async Task CreateApplicationChannelAsync(IGuild guild, BaseQQBotClient client, + string name, Action? func, RequestOptions? options) + { + CreateApplicationChannelProperties props = new(); + func?.Invoke(props); + CreateChannelParams args = new() + { + Name = name, + Type = ChannelType.Application, + // Position = props.Position, + PrivateType = props.PrivateType, + SpeakPermission = props.SpeakPermission, + ApplicationId = props.ApplicationType, + }; + Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false); + return RestApplicationChannel.Create(client, guild, model); + } + + public static async Task CreateForumChannelAsync(IGuild guild, BaseQQBotClient client, + string name, Action? func, RequestOptions? options) + { + CreateForumChannelProperties props = new(); + func?.Invoke(props); + CreateChannelParams args = new() + { + Name = name, + Type = ChannelType.Forum, + // Position = props.Position, + PrivateType = props.PrivateType, + SpeakPermission = props.SpeakPermission, + }; + Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false); + return RestForumChannel.Create(client, guild, model); + } + + public static async Task CreateScheduleChannelAsync(IGuild guild, BaseQQBotClient client, + string name, Action? func, RequestOptions? options) + { + CreateScheduleChannelProperties props = new(); + func?.Invoke(props); + CreateChannelParams args = new() + { + Name = name, + Type = ChannelType.Schedule, + // Position = props.Position, + PrivateType = props.PrivateType, + SpeakPermission = props.SpeakPermission, + }; + Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false); + return RestScheduleChannel.Create(client, guild, model); + } + + public static async Task CreateCategoryChannelAsync(IGuild guild, BaseQQBotClient client, + string name, Action? func, RequestOptions? options) + { + CreateCategoryChannelProperties props = new(); + func?.Invoke(props); + CreateChannelParams args = new() + { + Name = name, + Type = ChannelType.Category, + Position = props.Position + }; + Channel model = await client.ApiClient.CreateChannelAsync(guild.Id, args, options).ConfigureAwait(false); + return RestCategoryChannel.Create(client, guild, model); + } + + #endregion + + #region Users + public static async Task GetUserAsync(IGuild guild, BaseQQBotClient client, ulong id, RequestOptions? options) { @@ -54,4 +181,6 @@ public static IAsyncEnumerable> GetMembersAsync( count: limit ); } + + #endregion } diff --git a/src/QQBot.Net.Rest/Entities/Guilds/RestGuild.cs b/src/QQBot.Net.Rest/Entities/Guilds/RestGuild.cs index 4dcae79..6b0e520 100644 --- a/src/QQBot.Net.Rest/Entities/Guilds/RestGuild.cs +++ b/src/QQBot.Net.Rest/Entities/Guilds/RestGuild.cs @@ -126,6 +126,29 @@ public async Task> GetVoiceChannelsAsync(Requ return channel as IVoiceChannel; } + /// + /// 获取此频道的所有直播子频道。 + /// + /// 发送请求时要使用的选项。 + /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。 + public async Task> GetLiveStreamChannelsAsync(RequestOptions? options = null) + { + IReadOnlyCollection channels = await GuildHelper.GetChannelsAsync(this, Client, options).ConfigureAwait(false); + return channels.OfType().ToArray(); + } + + /// + /// 获取此频道内的直播子频道。 + /// + /// 要获取的直播子频道的 ID。 + /// 发送请求时要使用的选项。 + /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的直播子频道;如果未找到,则返回 null + public async Task GetLiveStreamChannelAsync(ulong id, RequestOptions? options = null) + { + RestGuildChannel channel = await GuildHelper.GetChannelAsync(this, Client, id, options).ConfigureAwait(false); + return channel as ILiveStreamChannel; + } + /// /// 获取此频道的所有应用子频道。 /// @@ -173,26 +196,26 @@ public async Task> GetForumChannelsAsync(Requ } /// - /// 获取此频道的所有直播子频道。 + /// 获取此频道的所有日程子频道。 /// /// 发送请求时要使用的选项。 - /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有直播子频道。 - public async Task> GetLiveStreamChannelsAsync(RequestOptions? options = null) + /// 一个表示异步获取操作的任务。任务的结果包含此频道的所有日程子频道。 + public async Task> GetScheduleChannelsAsync(RequestOptions? options = null) { IReadOnlyCollection channels = await GuildHelper.GetChannelsAsync(this, Client, options).ConfigureAwait(false); - return channels.OfType().ToArray(); + return channels.OfType().ToArray(); } /// - /// 获取此频道内的直播子频道。 + /// 获取此频道内的日程子频道。 /// - /// 要获取的直播子频道的 ID。 + /// 要获取的论坛子频道的 ID。 /// 发送请求时要使用的选项。 - /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的直播子频道;如果未找到,则返回 null - public async Task GetLiveStreamChannelAsync(ulong id, RequestOptions? options = null) + /// 一个表示异步获取操作的任务。任务的结果包含与指定的 关联的日程子频道;如果未找到,则返回 null + public async Task GetScheduleChannelAsync(ulong id, RequestOptions? options = null) { RestGuildChannel channel = await GuildHelper.GetChannelAsync(this, Client, id, options).ConfigureAwait(false); - return channel as ILiveStreamChannel; + return channel as IScheduleChannel; } /// @@ -218,6 +241,41 @@ public async Task> GetCategoryChannelsAsyn return channel as ICategoryChannel; } + /// + public Task CreateTextChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateTextChannelAsync(this, Client, name, func, options); + + /// + public Task CreateVoiceChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateVoiceChannelAsync(this, Client, name, func, options); + + /// + public Task CreateLiveStreamChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateLiveStreamChannelAsync(this, Client, name, func, options); + + /// + public Task CreateApplicationChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateApplicationChannelAsync(this, Client, name, func, options); + + /// + public Task CreateForumChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateForumChannelAsync(this, Client, name, func, options); + + /// + public Task CreateScheduleChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateScheduleChannelAsync(this, Client, name, func, options); + + /// + public Task CreateCategoryChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateCategoryChannelAsync(this, Client, name, func, options); + #endregion #region Roles @@ -271,6 +329,14 @@ async Task> IGuild.GetVoiceChannelsAsync(Cach async Task IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => mode == CacheMode.AllowDownload ? await GetVoiceChannelAsync(id, options).ConfigureAwait(false) : null; + /// + async Task> IGuild.GetLiveStreamChannelsAsync(CacheMode mode, RequestOptions? options) => + mode == CacheMode.AllowDownload ? await GetLiveStreamChannelsAsync(options).ConfigureAwait(false) : []; + + /// + async Task IGuild.GetLiveStreamChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => + mode == CacheMode.AllowDownload ? await GetLiveStreamChannelAsync(id, options).ConfigureAwait(false) : null; + /// async Task> IGuild.GetApplicationChannelsAsync(CacheMode mode, RequestOptions? options) => mode == CacheMode.AllowDownload ? await GetApplicationChannelsAsync(options).ConfigureAwait(false) : []; @@ -288,12 +354,12 @@ async Task> IGuild.GetForumChannelsAsync(Cach mode == CacheMode.AllowDownload ? await GetForumChannelAsync(id, options).ConfigureAwait(false) : null; /// - async Task> IGuild.GetLiveStreamChannelsAsync(CacheMode mode, RequestOptions? options) => - mode == CacheMode.AllowDownload ? await GetLiveStreamChannelsAsync(options).ConfigureAwait(false) : []; + async Task> IGuild.GetScheduleChannelsAsync(CacheMode mode, RequestOptions? options) => + mode == CacheMode.AllowDownload ? await GetScheduleChannelsAsync(options).ConfigureAwait(false) : []; /// - async Task IGuild.GetLiveStreamChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => - mode == CacheMode.AllowDownload ? await GetLiveStreamChannelAsync(id, options).ConfigureAwait(false) : null; + async Task IGuild.GetScheduleChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => + mode == CacheMode.AllowDownload ? await GetScheduleChannelAsync(id, options).ConfigureAwait(false) : null; /// async Task> IGuild.GetCategoryChannelsAsync(CacheMode mode, RequestOptions? options) => @@ -307,5 +373,26 @@ async Task> IGuild.GetCategoryChannelsAsyn async Task IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions? options) => mode == CacheMode.AllowDownload ? await GetUserAsync(id, options).ConfigureAwait(false) : null; + async Task IGuild.CreateTextChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateTextChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateVoiceChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateVoiceChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateLiveStreamChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateLiveStreamChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateApplicationChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateApplicationChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateForumChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateForumChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateScheduleChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateScheduleChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateCategoryChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateCategoryChannelAsync(name, action, options).ConfigureAwait(false); + #endregion } diff --git a/src/QQBot.Net.Rest/QQBotRestApiClient.cs b/src/QQBot.Net.Rest/QQBotRestApiClient.cs index 6ddfa8a..10bc11a 100644 --- a/src/QQBot.Net.Rest/QQBotRestApiClient.cs +++ b/src/QQBot.Net.Rest/QQBotRestApiClient.cs @@ -428,6 +428,13 @@ public async Task GetChannelAsync(ulong channelId, RequestOptions? opti public async Task CreateChannelAsync(ulong guildId, CreateChannelParams args, RequestOptions? options = null) { Preconditions.NotEqual(guildId, 0, nameof(guildId)); + Preconditions.NotNullOrEmpty(args.Name, nameof(args.Name)); + if (args.Type is ChannelType.Category) + { + Preconditions.NotNull(args.Position, nameof(args.Position)); + Preconditions.AtLeast(args.Position.Value, 2, nameof(args.Position)); + } + options = RequestOptions.CreateOrClone(options); BucketIds ids = new(guildId); diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketApplicationChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketApplicationChannel.cs index a4d6b88..e03c238 100644 --- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketApplicationChannel.cs +++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketApplicationChannel.cs @@ -13,7 +13,7 @@ public class SocketApplicationChannel : SocketGuildChannel, IApplicationChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketForumChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketForumChannel.cs index 6ed5e09..fd90a53 100644 --- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketForumChannel.cs +++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketForumChannel.cs @@ -13,7 +13,7 @@ public class SocketForumChannel : SocketGuildChannel, IForumChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs index 4f76244..9b7f6b7 100644 --- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs +++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs @@ -45,6 +45,7 @@ internal static SocketGuildChannel Create(SocketGuild guild, ClientState state, ChannelType.LiveStream => SocketLiveStreamChannel.Create(guild, state, model), ChannelType.Application => SocketApplicationChannel.Create(guild, state, model), ChannelType.Forum => SocketForumChannel.Create(guild, state, model), + ChannelType.Schedule => SocketScheduleChannel.Create(guild, state, model), _ => new SocketGuildChannel(guild.Client, model.Id, guild) }; diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketLiveStreamChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketLiveStreamChannel.cs index d89f62d..88d94e0 100644 --- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketLiveStreamChannel.cs +++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketLiveStreamChannel.cs @@ -13,7 +13,7 @@ public class SocketLiveStreamChannel : SocketGuildChannel, ILiveStreamChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketScheduleChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketScheduleChannel.cs new file mode 100644 index 0000000..03d2ca2 --- /dev/null +++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketScheduleChannel.cs @@ -0,0 +1,47 @@ +using System.Diagnostics; +using QQBot.API; + +namespace QQBot.WebSocket; + +/// +/// 表示频道中的一个基于网关的直播子频道。 +/// +[DebuggerDisplay("{DebuggerDisplay,nq}")] +public class SocketScheduleChannel : SocketGuildChannel, IScheduleChannel +{ + /// + public ulong? CategoryId { get; private set; } + + /// + public PrivateType? PrivateType { get; private set; } + + /// + public SpeakPermission? SpeakPermission { get; private set; } + + /// + public ChannelPermission? Permission { get; private set; } + + internal SocketScheduleChannel(QQBotSocketClient client, ulong id, SocketGuild guild) + : base(client, id, guild) + { + Type = ChannelType.Schedule; + } + + internal static new SocketScheduleChannel Create(SocketGuild guild, ClientState state, Channel model) + { + SocketScheduleChannel entity = new(guild.Client, model.Id, guild); + entity.Update(state, model); + return entity; + } + + internal override void Update(ClientState state, Channel model) + { + base.Update(state, model); + CategoryId = model.ParentId; + PrivateType = model.PrivateType; + SpeakPermission = model.SpeakPermission; + Permission = model.Permissions is not null ? Enum.Parse(model.Permissions) : null; // TODO + } + + private string DebuggerDisplay => $"{Name} ({Id}, Schedule)"; +} diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketTextChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketTextChannel.cs index 8dcd914..744cfbc 100644 --- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketTextChannel.cs +++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketTextChannel.cs @@ -19,7 +19,7 @@ public class SocketTextChannel : SocketGuildChannel, ITextChannel, ISocketMessag public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs b/src/QQBot.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs index fa817b1..d530b04 100644 --- a/src/QQBot.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs +++ b/src/QQBot.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs @@ -13,7 +13,7 @@ public class SocketVoiceChannel : SocketGuildChannel, IVoiceChannel public ulong? CategoryId { get; private set; } /// - public ChannelPrivateType? PrivateType { get; private set; } + public PrivateType? PrivateType { get; private set; } /// public SpeakPermission? SpeakPermission { get; private set; } diff --git a/src/QQBot.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/QQBot.Net.WebSocket/Entities/Guilds/SocketGuild.cs index 12195b7..b70539a 100644 --- a/src/QQBot.Net.WebSocket/Entities/Guilds/SocketGuild.cs +++ b/src/QQBot.Net.WebSocket/Entities/Guilds/SocketGuild.cs @@ -79,6 +79,11 @@ public class SocketGuild : SocketEntity, IGuild, IUpdateable /// public IReadOnlyCollection VoiceChannels => [..Channels.OfType()]; + /// + /// 获取此频道中所有直播子频道。 + /// + public IReadOnlyCollection LiveStreamChannels => [..Channels.OfType()]; + /// /// 获取此频道中所有应用程序子频道。 /// @@ -90,9 +95,9 @@ public class SocketGuild : SocketEntity, IGuild, IUpdateable public IReadOnlyCollection ForumChannels => [..Channels.OfType()]; /// - /// 获取此频道中所有直播子频道。 + /// 获取此频道中所有日程子频道。 /// - public IReadOnlyCollection LiveStreamChannels => [..Channels.OfType()]; + public IReadOnlyCollection ScheduleChannels => [..Channels.OfType()]; /// /// 获取此频道中的所有分组子频道。 @@ -245,6 +250,13 @@ public async Task DownloadUsersAsync(RequestOptions? options = null) => /// 与指定的 关联的具有语音聊天能力的子频道;如果未找到,则返回 null public SocketVoiceChannel? GetVoiceChannel(ulong id) => GetChannel(id) as SocketVoiceChannel; + /// + /// 获取此子频道中的直播子频道。 + /// + /// 要获取的子频道的 ID。 + /// 与指定的 关联的直播子频道;如果未找到,则返回 null + public SocketLiveStreamChannel? GetLiveStreamChannel(ulong id) => GetChannel(id) as SocketLiveStreamChannel; + /// /// 获取此子频道中的应用程序子频道。 /// @@ -260,11 +272,11 @@ public async Task DownloadUsersAsync(RequestOptions? options = null) => public SocketForumChannel? GetForumChannel(ulong id) => GetChannel(id) as SocketForumChannel; /// - /// 获取此子频道中的直播子频道。 + /// 获取此子频道中的日程子频道。 /// /// 要获取的子频道的 ID。 - /// 与指定的 关联的直播子频道;如果未找到,则返回 null - public SocketLiveStreamChannel? GetLiveStreamChannel(ulong id) => GetChannel(id) as SocketLiveStreamChannel; + /// 与指定的 关联的日程子频道;如果未找到,则返回 null + public SocketScheduleChannel? GetScheduleChannel(ulong id) => GetChannel(id) as SocketScheduleChannel; /// /// 获取此子频道中的分组子频道。 @@ -273,6 +285,41 @@ public async Task DownloadUsersAsync(RequestOptions? options = null) => /// 与指定的 关联的分组子频道;如果未找到,则返回 null public SocketCategoryChannel? GetCategoryChannel(ulong id) => GetChannel(id) as SocketCategoryChannel; + /// + public Task CreateTextChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateTextChannelAsync(this, Client, name, func, options); + + /// + public Task CreateVoiceChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateVoiceChannelAsync(this, Client, name, func, options); + + /// + public Task CreateLiveStreamChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateLiveStreamChannelAsync(this, Client, name, func, options); + + /// + public Task CreateApplicationChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateApplicationChannelAsync(this, Client, name, func, options); + + /// + public Task CreateForumChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateForumChannelAsync(this, Client, name, func, options); + + /// + public Task CreateScheduleChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateScheduleChannelAsync(this, Client, name, func, options); + + /// + public Task CreateCategoryChannelAsync(string name, + Action? func = null, RequestOptions? options = null) => + GuildHelper.CreateCategoryChannelAsync(this, Client, name, func, options); + #endregion #region IGuild @@ -301,6 +348,14 @@ Task> IGuild.GetVoiceChannelsAsync(CacheMode Task IGuild.GetVoiceChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => Task.FromResult(GetVoiceChannel(id)); + /// + Task> IGuild.GetLiveStreamChannelsAsync(CacheMode mode, RequestOptions? options) => + Task.FromResult>(LiveStreamChannels); + + /// + Task IGuild.GetLiveStreamChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => + Task.FromResult(GetLiveStreamChannel(id)); + /// Task> IGuild.GetApplicationChannelsAsync(CacheMode mode, RequestOptions? options) => Task.FromResult>(ApplicationChannels); @@ -318,12 +373,12 @@ Task> IGuild.GetForumChannelsAsync(CacheMode Task.FromResult(GetForumChannel(id)); /// - Task> IGuild.GetLiveStreamChannelsAsync(CacheMode mode, RequestOptions? options) => - Task.FromResult>(LiveStreamChannels); + Task> IGuild.GetScheduleChannelsAsync(CacheMode mode, RequestOptions? options) => + Task.FromResult>(ScheduleChannels); /// - Task IGuild.GetLiveStreamChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => - Task.FromResult(GetLiveStreamChannel(id)); + Task IGuild.GetScheduleChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => + Task.FromResult(GetScheduleChannel(id)); /// Task> IGuild.GetCategoryChannelsAsync(CacheMode mode, RequestOptions? options) => @@ -333,6 +388,27 @@ Task> IGuild.GetCategoryChannelsAsync(Cach Task IGuild.GetCategoryChannelAsync(ulong id, CacheMode mode, RequestOptions? options) => Task.FromResult(GetCategoryChannel(id)); + async Task IGuild.CreateTextChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateTextChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateVoiceChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateVoiceChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateLiveStreamChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateLiveStreamChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateApplicationChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateApplicationChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateForumChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateForumChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateScheduleChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateScheduleChannelAsync(name, action, options).ConfigureAwait(false); + + async Task IGuild.CreateCategoryChannelAsync(string name, Action? action, RequestOptions? options) => + await CreateCategoryChannelAsync(name, action, options).ConfigureAwait(false); + /// async Task IGuild.GetUserAsync(ulong id, CacheMode mode, RequestOptions? options) {