From f6c1e9f115bf30358014c83ea4bc16175c23284e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=82=A0=E9=9D=99=E8=90=9D=E8=8E=89?= Date: Sun, 14 Mar 2021 20:27:46 +0800 Subject: [PATCH] 03/14 Last Update --- .gitignore | 3 +- AuroraNative/API/Api.cs | 164 +++++--- AuroraNative/Abstract/Friends.cs | 32 ++ AuroraNative/AuroraNative.xml | 364 ++++++++++-------- AuroraNative/Enum/LogLevel.cs | 29 ++ .../Utils/EnumDescriptionConverter.cs | 61 --- AuroraNative/Utils/Event.cs | 22 +- AuroraNative/Utils/Logger.cs | 44 +-- AuroraNative/WebSockets/BaseWebSocket.cs | 20 +- AuroraNative/WebSockets/Client.cs | 52 ++- AuroraNative/WebSockets/Server.cs | 17 +- 11 files changed, 479 insertions(+), 329 deletions(-) create mode 100644 AuroraNative/Abstract/Friends.cs create mode 100644 AuroraNative/Enum/LogLevel.cs delete mode 100644 AuroraNative/Utils/EnumDescriptionConverter.cs diff --git a/.gitignore b/.gitignore index d36957e..12e22ad 100644 --- a/.gitignore +++ b/.gitignore @@ -340,4 +340,5 @@ ASALocalRun/ healthchecksdb DevIcon.* Test -nuget.config \ No newline at end of file +nuget.config +*.cd \ No newline at end of file diff --git a/AuroraNative/API/Api.cs b/AuroraNative/API/Api.cs index 420c42f..1434752 100644 --- a/AuroraNative/API/Api.cs +++ b/AuroraNative/API/Api.cs @@ -62,15 +62,15 @@ namespace AuroraNative /// /// 发送私聊消息 /// - /// 接受者QQ号 + /// 接受者QQ号 /// 信息内容 /// 是否转义默认:false /// 返回消息ID,错误返回-1 - public async Task SendPrivateMessage(long QID, string Message, bool AutoEscape = false) + public async Task SendPrivateMessage(long UserID, string Message, bool AutoEscape = false) { JObject Params = new JObject { - { "user_id", QID }, + { "user_id", UserID }, { "message", Message }, { "auto_escape", AutoEscape } }; @@ -119,11 +119,11 @@ namespace AuroraNative /// /// 信息内容 /// 信息类型私聊:private群聊:group - /// QQ号 + /// QQ号 /// 群号 /// 是否转义默认:false /// 错误返回-1,成功返回信息ID - public async Task SendMsg(string Message, string MessageType = null, long QID = 0, long GroupID = 0, bool AutoEscape = false) + public async Task SendMsg(string Message, string MessageType = null, long UserID = 0, long GroupID = 0, bool AutoEscape = false) { JObject Params = new JObject() { { "message", Message}, @@ -133,15 +133,15 @@ namespace AuroraNative switch (MessageType) { case "private": - Params.Add("user_id", QID); + Params.Add("user_id", UserID); break; case "group": Params.Add("group_id", GroupID); break; case null: - if (QID != 0) + if (UserID != 0) { - Params.Add("user_id", QID); + Params.Add("user_id", UserID); } else if (GroupID != 0) { @@ -199,26 +199,33 @@ namespace AuroraNative /// /// 图片缓存文件名,带不带后缀你喜欢就好 /// 错误返回null,成功返回JObject - public async Task GetImage(string Filename) + public async Task> GetImage(string Filename) { if (!Filename.Contains(".image")) { Filename += ".image"; } - return await SendCallObject(new BaseAPI("get_image", new JObject() { { "file", Filename } }, "GetImage:" + Utils.NowTimeSteamp())); + + JObject Json = await SendCallObject(new BaseAPI("get_image", new JObject() { { "file", Filename } }, "GetImage:" + Utils.NowTimeSteamp())); + + return new Dictionary() { + {"Size",Json.Value("size")}, + {"FileName",Json.Value("filename")}, + {"Url",Json.Value("url")} + }; } /// /// 群组踢人 /// /// 群号 - /// QQ号 + /// QQ号 /// 是否自动拒绝此人加群申请默认:false - public void SetGroupKick(long GroupID, long QID, bool RejectAddRequest = false) + public void SetGroupKick(long GroupID, long UserID, bool RejectAddRequest = false) { JObject Params = new JObject { - { "user_id", QID }, + { "user_id", UserID }, { "group_id", GroupID }, { "reject_add_request", RejectAddRequest } }; @@ -230,13 +237,13 @@ namespace AuroraNative /// 群组单人禁言 /// /// 群号 - /// QQ号 + /// QQ号 /// 禁言时间,单位秒默认:30分钟(1800秒) - public void SetGroupBan(long GroupID, long QID, int Duration = 1800) + public void SetGroupBan(long GroupID, long UserID, int Duration = 1800) { JObject Params = new JObject { - { "user_id", QID }, + { "user_id", UserID }, { "group_id", GroupID }, { "duration", Duration } }; @@ -291,13 +298,13 @@ namespace AuroraNative /// 设置群管理员 /// /// 群号 - /// QQ号 + /// QQ号 /// 是否设置为管理员默认:true - public void SetGroupAdmin(long GroupID, long QID, bool Enable = true) + public void SetGroupAdmin(long GroupID, long UserID, bool Enable = true) { JObject Params = new JObject { - { "user_id", QID }, + { "user_id", UserID }, { "group_id", GroupID }, { "enable", Enable } }; @@ -309,13 +316,13 @@ namespace AuroraNative /// 设置群名片 /// /// 群号 - /// QQ号 + /// QQ号 /// 群名片内容默认:null(删除群名片) - public void SetGroupCard(long GroupID, long QID, string Card = null) + public void SetGroupCard(long GroupID, long UserID, string Card = null) { JObject Params = new JObject { - { "user_id", QID }, + { "user_id", UserID }, { "group_id", GroupID }, { "card", Card } }; @@ -359,14 +366,14 @@ namespace AuroraNative /// 设置群组专属头衔 /// /// 群号 - /// QQ号 + /// QQ号 /// 群名片内容默认:null(删除群名片) /// 专属头衔有效期, 单位秒, 不过此项似乎没有效果, 可能是只有某些特殊的时间长度有效, 有待测试默认:-1(永久) - public void SetGroupSpecialTitle(long GroupID, long QID, string SpecialTitle = null, int Duration = -1) + public void SetGroupSpecialTitle(long GroupID, long UserID, string SpecialTitle = null, int Duration = -1) { JObject Params = new JObject { - { "user_id", QID }, + { "user_id", UserID }, { "group_id", GroupID }, { "duration", Duration }, { "special_title", SpecialTitle } @@ -417,35 +424,48 @@ namespace AuroraNative /// 获取登录号信息 /// /// 错误返回null,成功返回JObject - public async Task GetLoginInfo() + public async Task> GetLoginInfo() { - return await SendCallObject(new BaseAPI("get_login_info", null, "GetLoginInfo:" + Utils.NowTimeSteamp())); + JObject Json = await SendCallObject(new BaseAPI("get_login_info", null, "GetLoginInfo:" + Utils.NowTimeSteamp())); + + return new Dictionary() { + {"UserID",Json.Value("user_id")}, + {"NickName",Json.Value("nickname")} + }; } /// /// 获取陌生人信息 /// - /// QQ号 + /// QQ号 /// 是否使用缓存,使用缓存响应快但是可能更新不及时默认:false /// 错误返回null,成功返回JObject - public async Task GetStrangerInfo(long QID, bool Cache = false) + public async Task> GetStrangerInfo(long UserID, bool Cache = false) { JObject Params = new JObject { - { "user_id", QID }, + { "user_id", UserID }, { "no_cache ", Cache } }; - return await SendCallObject(new BaseAPI("get_stranger_info", Params, "GetStrangerInfo:" + Utils.NowTimeSteamp())); + JObject Json = await SendCallObject(new BaseAPI("get_stranger_info", Params, "GetStrangerInfo:" + Utils.NowTimeSteamp())); + + return new Dictionary() { + {"UserID",Json.Value("user_id")}, + {"NickName",Json.Value("nickname")}, + {"Sex",Json.Value("sex")}, + {"Age",Json.Value("age")}, + {"QID",Json.Value("qid")} + }; } /// /// 获取好友列表 /// /// 错误返回null,成功返回JObject - public async Task GetFriendList() + public async Task> GetFriendList() { - return await SendCallObject(new BaseAPI("get_friend_list", null, "GetFriendList:" + Utils.NowTimeSteamp())); + return (await SendCallArray(new BaseAPI("get_friend_list", null, "GetFriendList:" + Utils.NowTimeSteamp()))).ToObject>(); } /// @@ -478,15 +498,15 @@ namespace AuroraNative /// 获取群成员信息 /// /// 群号 - /// QQ号 + /// QQ号 /// 是否使用缓存,使用缓存响应快但是可能更新不及时默认:false /// 错误返回null,成功返回JObject - public async Task GetGroupMemberInfo(long GroupID, long QID, bool Cache = false) + public async Task GetGroupMemberInfo(long GroupID, long UserID, bool Cache = false) { JObject Params = new JObject { { "group_id", GroupID }, - { "user_id", QID }, + { "user_id", UserID }, { "no_cache ", Cache } }; @@ -542,9 +562,26 @@ namespace AuroraNative /// 获取版本信息 /// /// 错误返回null,成功返回JObject - public async Task GetVersionInfo() + public async Task> GetVersionInfo() { - return await SendCallObject(new BaseAPI("get_version_info", null, "GetVersionInfo:" + Utils.NowTimeSteamp())); + JObject Json = await SendCallObject(new BaseAPI("get_version_info", null, "GetVersionInfo:" + Utils.NowTimeSteamp())); + + return new Dictionary() { + {"AppFullName",Json.Value("app_full_name")}, + {"AppName",Json.Value("app_name")}, + {"AppVersion",Json.Value("app_version")}, + {"CQDirectory",Json.Value("coolq_directory")}, + {"CQEdition",Json.Value("coolq_edition")}, + {"IsGoCqhttp",Json.Value("go-cqhttp")}, + {"PluginBuildConfiguration",Json.Value("plugin_build_configuration")}, + {"PluginBuildNumber",Json.Value("plugin_build_number")}, + {"PluginVersion",Json.Value("plugin_version")}, + {"Protocol",Json.Value("protocol")}, + {"ProtocolVersion",Json.Value("protocol_version")}, + {"RuntimeOS",Json.Value("runtime_os")}, + {"RuntimeVersion",Json.Value("runtime_version")}, + {"Version",Json.Value("version")} + }; } /// @@ -717,11 +754,11 @@ namespace AuroraNative /// /// 获取VIP信息 /// - /// QQ号 + /// QQ号 /// 错误返回null,成功返回JObject - public async Task GetVIPInfo(long QID) + public async Task GetVIPInfo(long UserID) { - return await SendCallObject(new BaseAPI("_get_vip_info", new JObject { { "user_id", QID } }, "GetGroupAtAllRemain:" + Utils.NowTimeSteamp())); + return await SendCallObject(new BaseAPI("_get_vip_info", new JObject { { "user_id", UserID } }, "GetGroupAtAllRemain:" + Utils.NowTimeSteamp())); } /// @@ -840,8 +877,7 @@ namespace AuroraNative private async Task SendCallMessageID(BaseAPI Params) { - WebSocket.Send(Params); - TaskList.Add(Params.UniqueCode, "Sended"); + SendCall(Params); string Result = "-1"; await Task.Run(() => { Result = FeedbackMessageID(Params.UniqueCode); }); @@ -850,14 +886,32 @@ namespace AuroraNative private async Task SendCallObject(BaseAPI Params) { - WebSocket.Send(Params); - TaskList.Add(Params.UniqueCode, "Sended"); + SendCall(Params); JObject Result = null; await Task.Run(() => { Result = FeedbackObject(Params.UniqueCode); }); return Result; } + private async Task SendCallArray(BaseAPI Params) + { + SendCall(Params); + + JArray Result = null; + await Task.Run(() => { Result = FeedbackArray(Params.UniqueCode); }); + return Result; + } + + private void SendCall(BaseAPI Params) + { + Logger.Debug($"API调用:\n请求的接口:{Params.Action}\n请求的唯一码:{Params.UniqueCode}\n请求的参数:\n{Params.Params}"); + WebSocket.Send(Params); + if (!TaskList.TryGetValue(Params.UniqueCode, out _)) + { + TaskList.Add(Params.UniqueCode, "Sended"); + } + } + private void SendCallVoid(BaseAPI Params) { WebSocket.Send(Params); @@ -889,6 +943,18 @@ namespace AuroraNative return null; } + private static JArray FeedbackArray(string UniqueCode) + { + JObject FBJson = GetFeedback(UniqueCode); + + //判断返回 + if (FBJson["status"].ToString() == "ok") + { + return JArray.Parse(FBJson["data"].ToString()); + } + return null; + } + private static JObject GetFeedback(string UniqueCode) { JObject FBJson = new JObject(); @@ -912,6 +978,14 @@ namespace AuroraNative { Api api = new Api(WebSocket); Cache.Set($"API{AppDomain.CurrentDomain.Id}", api); + Task.Run(() => + { + Thread.Sleep(5000); + if (!BaseWebSocket.IsCheckVersion) + { + Event.CheckVersion(); + } + }); return api; } catch (WebSocketException e) diff --git a/AuroraNative/Abstract/Friends.cs b/AuroraNative/Abstract/Friends.cs new file mode 100644 index 0000000..c1dc2f3 --- /dev/null +++ b/AuroraNative/Abstract/Friends.cs @@ -0,0 +1,32 @@ +using Newtonsoft.Json; + +namespace AuroraNative +{ + /// + /// 好友 抽象类 + /// + public sealed class Friends + { + #region --属性-- + + /// + /// QQ号 + /// + [JsonProperty(PropertyName = "user_id")] + public long UserID; + + /// + /// 昵称 + /// + [JsonProperty(PropertyName = "nickname")] + public string NickName; + + /// + /// 备注 + /// + [JsonProperty(PropertyName = "remark")] + public string Remark; + + #endregion + } +} diff --git a/AuroraNative/AuroraNative.xml b/AuroraNative/AuroraNative.xml index cc8acbe..53e026a 100644 --- a/AuroraNative/AuroraNative.xml +++ b/AuroraNative/AuroraNative.xml @@ -4,6 +4,26 @@ AuroraNative + + + 好友 抽象类 + + + + + QQ号 + + + + + 昵称 + + + + + 备注 + + API 类 @@ -29,7 +49,7 @@ 发送私聊消息 - 接受者QQ号 + 接受者QQ号 信息内容 是否转义默认:false 返回消息ID,错误返回-1 @@ -43,7 +63,7 @@ 是否转义默认:false 返回消息ID,错误返回-1 - + 转发合并消息 - 群 @@ -57,7 +77,7 @@ 信息内容 信息类型私聊:private群聊:group - QQ号 + QQ号 群号 是否转义默认:false 错误返回-1,成功返回信息ID @@ -94,7 +114,7 @@ 群组踢人 群号 - QQ号 + QQ号 是否自动拒绝此人加群申请默认:false @@ -102,7 +122,7 @@ 群组单人禁言 群号 - QQ号 + QQ号 禁言时间,单位秒默认:30分钟(1800秒) @@ -126,7 +146,7 @@ 设置群管理员 群号 - QQ号 + QQ号 是否设置为管理员默认:true @@ -134,7 +154,7 @@ 设置群名片 群号 - QQ号 + QQ号 群名片内容默认:null(删除群名片) @@ -156,7 +176,7 @@ 设置群组专属头衔 群号 - QQ号 + QQ号 群名片内容默认:null(删除群名片) 专属头衔有效期, 单位秒, 不过此项似乎没有效果, 可能是只有某些特殊的时间长度有效, 有待测试默认:-1(永久) @@ -187,7 +207,7 @@ 获取陌生人信息 - QQ号 + QQ号 是否使用缓存,使用缓存响应快但是可能更新不及时默认:false 错误返回null,成功返回JObject @@ -216,7 +236,7 @@ 获取群成员信息 群号 - QQ号 + QQ号 是否使用缓存,使用缓存响应快但是可能更新不及时默认:false 错误返回null,成功返回JObject @@ -351,7 +371,7 @@ 获取VIP信息 - QQ号 + QQ号 错误返回null,成功返回JObject @@ -703,146 +723,34 @@ 请求事件 - + - 事件类 + 表示日志信息等级的枚举 - + - 元事件 - 生命周期 + 表示输出日志的等级是 "调试" 级别 - 生命周期事件参数 - + - 元事件 - 心跳 + 表示输出日志的等级是 "信息" 级别 - 心跳事件参数 - + - 消息事件 - 私聊消息 + 表示输出日志的等级是 "警告" 级别 - 私聊消息参数 - + - 消息事件 - 群消息 + 表示输出日志的等级是 "错误" 级别 - 群消息参数 - + - 请求事件 - 好友请求 - - 好友请求参数 - - - - 请求事件 - 群请求 - - 群请求参数 - - - - 通知事件 - 群文件上传 - - 群文件上传参数 - - - - 通知事件 - 群管理员变动 - - 群管理员变动参数 - - - - 通知事件 - 群成员减少 - - 群成员减少参数 - - - - 通知事件 - 群成员增加 - - 群成员增加参数 - - - - 通知事件 - 群禁言 - - 群禁言参数 - - - - 通知事件 - 好友添加 - - 好友添加参数 - - - - 通知事件 - 群消息撤回 - - 群消息撤回参数 - - - - 通知事件 - 好友消息撤回 - - 好友消息撤回参数 - - - - 通知事件 - 群内戳一戳 - - 群内戳一戳参数 - - - - 通知事件 - 好友戳一戳 - - 群内戳一戳参数 - - - - 通知事件 - 群红包运气王提示 - - 群红包运气王提示参数 - - - - 通知事件 - 群成员荣誉变更提示 - - 群成员荣誉变更提示参数 - - - - 通知事件 - 群成员名片更新(核验) - - 群成员名片更新(核验)参数 - - - - 通知事件 - 接收到离线文件 - - 接收到离线文件参数 - - - - 通知事件 - 其他客户端在线状态变更 - - 其他客户端在线状态变更参数 - - - - 通知事件 - 精华消息变更 - - 精华消息变更参数 - - - - 请勿使用,用于子事件分发 + 表示不输出日志 @@ -1789,6 +1697,148 @@ 异常 类 -- 关于WebSocket异常 + + + 事件类 + + + + + 元事件 - 生命周期 + + 生命周期事件参数 + + + + 元事件 - 心跳 + + 心跳事件参数 + + + + 消息事件 - 私聊消息 + + 私聊消息参数 + + + + 消息事件 - 群消息 + + 群消息参数 + + + + 请求事件 - 好友请求 + + 好友请求参数 + + + + 请求事件 - 群请求 + + 群请求参数 + + + + 通知事件 - 群文件上传 + + 群文件上传参数 + + + + 通知事件 - 群管理员变动 + + 群管理员变动参数 + + + + 通知事件 - 群成员减少 + + 群成员减少参数 + + + + 通知事件 - 群成员增加 + + 群成员增加参数 + + + + 通知事件 - 群禁言 + + 群禁言参数 + + + + 通知事件 - 好友添加 + + 好友添加参数 + + + + 通知事件 - 群消息撤回 + + 群消息撤回参数 + + + + 通知事件 - 好友消息撤回 + + 好友消息撤回参数 + + + + 通知事件 - 群内戳一戳 + + 群内戳一戳参数 + + + + 通知事件 - 好友戳一戳 + + 群内戳一戳参数 + + + + 通知事件 - 群红包运气王提示 + + 群红包运气王提示参数 + + + + 通知事件 - 群成员荣誉变更提示 + + 群成员荣誉变更提示参数 + + + + 通知事件 - 群成员名片更新(核验) + + 群成员名片更新(核验)参数 + + + + 通知事件 - 接收到离线文件 + + 接收到离线文件参数 + + + + 通知事件 - 其他客户端在线状态变更 + + 其他客户端在线状态变更参数 + + + + 通知事件 - 精华消息变更 + + 精华消息变更参数 + + + + 请勿使用,用于子事件分发 + + 彩色日志输出类 @@ -1827,31 +1877,6 @@ 要输出的信息 输出的方法名,可选传入 - - - 表示日志信息等级的枚举 - - - - - 表示输出日志的等级是 "调试" 级别 - - - - - 表示输出日志的等级是 "信息" 级别 - - - - - 表示输出日志的等级是 "警告" 级别 - - - - - 表示输出日志的等级是 "错误" 级别 - - 通用方法 类 @@ -1862,7 +1887,7 @@ 通过 枚举Description 转为枚举 枚举 - 需要转换的Description + 需要转换的Description 返回该枚举 @@ -1883,6 +1908,16 @@ WebSocket 基础类 + + + 客户端创建 抽象方法 + + + + + 客户端销毁 抽象方法 + + 发送数据到服务端/客户端 @@ -1897,7 +1932,12 @@ - WebSocket服务端地址请记得带端口号 + WebSocket服务端地址 + + + + + WebSocket服务端端口号 diff --git a/AuroraNative/Enum/LogLevel.cs b/AuroraNative/Enum/LogLevel.cs new file mode 100644 index 0000000..ba0c67b --- /dev/null +++ b/AuroraNative/Enum/LogLevel.cs @@ -0,0 +1,29 @@ +namespace AuroraNative +{ + /// + /// 表示日志信息等级的枚举 + /// + public enum LogLevel + { + /// + /// 表示输出日志的等级是 "调试" 级别 + /// + Debug = 0, + /// + /// 表示输出日志的等级是 "信息" 级别 + /// + Info = 1, + /// + /// 表示输出日志的等级是 "警告" 级别 + /// + Warning = 2, + /// + /// 表示输出日志的等级是 "错误" 级别 + /// + Error = 3, + /// + /// 表示不输出日志 + /// + Off = 4 + } +} diff --git a/AuroraNative/Utils/EnumDescriptionConverter.cs b/AuroraNative/Utils/EnumDescriptionConverter.cs deleted file mode 100644 index db13b5c..0000000 --- a/AuroraNative/Utils/EnumDescriptionConverter.cs +++ /dev/null @@ -1,61 +0,0 @@ -using AuroraNative.EventArgs; -using Newtonsoft.Json; -using System; -using System.ComponentModel; -using System.Linq; -using System.Reflection; - -namespace AuroraNative -{ - /// - /// Enum和Description特性互转 转换器 - /// - internal class EnumDescriptionConverter : JsonConverter - { - /// - /// 当属性的值为枚举类型时才使用转换器 - /// - /// 目标类型 - /// 返回布尔值 - public override bool CanConvert(Type objectType) => objectType == typeof(Enum); - - /// - /// 获取枚举的描述值 - /// - public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) - { - if (string.IsNullOrEmpty(value.ToString())) - { - writer.WriteValue(""); - return; - } - - FieldInfo fieldInfo = value.GetType().GetField(value.ToString()); - if (fieldInfo == null) - { - writer.WriteValue(""); - return; - } - - DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); - writer.WriteValue(attributes.Length > 0 ? attributes[0].Description : ""); - } - - /// - /// 通过Description获取枚举值 - /// - public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) - { - foreach (FieldInfo field in objectType.GetFields()) - { - object[] objects = field.GetCustomAttributes(typeof(DescriptionAttribute), false); - if (objects.Any(item => (item as DescriptionAttribute)?.Description == reader.Value?.ToString())) - { - return Convert.ChangeType(field.GetValue(-1), objectType); - } - } - - return CQCodeType.Unknown; - } - } -} diff --git a/AuroraNative/Utils/Event.cs b/AuroraNative/Utils/Event.cs index 186fe40..57ececb 100644 --- a/AuroraNative/Utils/Event.cs +++ b/AuroraNative/Utils/Event.cs @@ -1,12 +1,14 @@ using AuroraNative.EventArgs; +using AuroraNative.WebSockets; using Newtonsoft.Json.Linq; +using System; namespace AuroraNative { /// /// 事件类 /// - public class Event + public abstract class Event { #region --公开函数-- @@ -230,5 +232,23 @@ namespace AuroraNative #endregion #endregion + + #region --私有函数-- + + internal static async void CheckVersion() + { + Logger.Debug("开始检查 go-cqhttp 版本是否符合最低版本..."); + if ((await Api.CurrentApi.GetVersionInfo()).TryGetValue("AppVersion", out object Version) && new Version(Version.ToString().Substring(1, Version.ToString().IndexOf('-') - 1)) < BaseWebSocket.DependencyVersion) + { + Logger.Warning($"框架最低依赖版本与 go-cqhttp 不符!请检查是否为最新的框架或符合的 go-cqhttp\ngo-cqhttp版本:{Version}\n框架最低依赖版本:v{BaseWebSocket.DependencyVersion}"); + } + else + { + Logger.Debug("go-cqhttp 版本符合最低版本!"); + } + BaseWebSocket.IsCheckVersion = true; + } + + #endregion } } diff --git a/AuroraNative/Utils/Logger.cs b/AuroraNative/Utils/Logger.cs index 6460410..20a93cb 100644 --- a/AuroraNative/Utils/Logger.cs +++ b/AuroraNative/Utils/Logger.cs @@ -27,7 +27,7 @@ namespace AuroraNative { if (LogLevel <= LogLevel.Debug) { - Output(Message, ConsoleColor.Gray, LogLevel.Debug, MethodName); + Output(Message, ConsoleColor.Gray, LogLevel.Debug, MethodName, true); } } @@ -74,43 +74,31 @@ namespace AuroraNative #region --私有函数-- - internal static void Output(string Message, ConsoleColor Color, LogLevel Level, string MethodName) + internal static void Output(string Message, ConsoleColor Color, LogLevel Level, string MethodName, bool IsFine = false) { Console.ForegroundColor = Color; - if (MethodName != null) + string NowTime; + + if (!IsFine) { - Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff") + $" [{Level}]" + $" [{MethodName}] " + Message); + NowTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss"); } else { - Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + $" [{Level}] " + Message); + NowTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss fff"); + } + + if (MethodName != null) + { + Console.WriteLine($"[{NowTime}]" + $" [{Level}]" + $" [{MethodName}]: " + Message); + } + else + { + Console.WriteLine($"[{NowTime}]" + $" [{Level}]: " + Message); } Console.ForegroundColor = ConsoleColor.White; } #endregion } - - /// - /// 表示日志信息等级的枚举 - /// - public enum LogLevel - { - /// - /// 表示输出日志的等级是 "调试" 级别 - /// - Debug = 0, - /// - /// 表示输出日志的等级是 "信息" 级别 - /// - Info = 1, - /// - /// 表示输出日志的等级是 "警告" 级别 - /// - Warning = 2, - /// - /// 表示输出日志的等级是 "错误" 级别 - /// - Error = 3 - } } diff --git a/AuroraNative/WebSockets/BaseWebSocket.cs b/AuroraNative/WebSockets/BaseWebSocket.cs index b87626b..32af9e4 100644 --- a/AuroraNative/WebSockets/BaseWebSocket.cs +++ b/AuroraNative/WebSockets/BaseWebSocket.cs @@ -17,20 +17,34 @@ namespace AuroraNative.WebSockets { #region --变量-- + internal int Port = 6700; internal WebSocket WebSocket; internal Event EventHook; internal JObject Json; - internal static Type[] AttributeTypes; + internal static readonly Type[] AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray(); + internal static readonly Version DependencyVersion = new Version("0.9.40"); + internal static bool IsCheckVersion = false; #endregion #region --公开函数-- + /// + /// 客户端创建 抽象方法 + /// + public abstract void Create(); + /// + /// 客户端销毁 抽象方法 + /// + public abstract void Dispose(); + + internal abstract void Feedback(); + /// /// 发送数据到服务端/客户端 /// /// 传输Json格式的文本 - public void Send(BaseAPI Json) + internal void Send(BaseAPI Json) { try { @@ -64,7 +78,7 @@ namespace AuroraNative.WebSockets { foreach (MethodInfo Method in EventHook.GetType().GetMethods().Where(p => p.GetCustomAttribute() != null)) { - if (Method.GetCustomAttribute(Type) is BaseAttribute attribute && attribute.Type == (string)Json.GetValue(Utils.GetChildTypeByPostType(Json))) + if (Method.GetCustomAttribute(Type) is BaseAttribute Attribute && Attribute.Type == (string)Json.GetValue(Utils.GetChildTypeByPostType(Json))) { ParameterInfo Parameter = Method.GetParameters().SingleOrDefault(); diff --git a/AuroraNative/WebSockets/Client.cs b/AuroraNative/WebSockets/Client.cs index 948bc90..d2157a1 100644 --- a/AuroraNative/WebSockets/Client.cs +++ b/AuroraNative/WebSockets/Client.cs @@ -1,7 +1,7 @@ using System; -using System.Linq; using System.Net.WebSockets; using System.Reflection; +using System.Text; using System.Threading; using System.Threading.Tasks; @@ -15,25 +15,41 @@ namespace AuroraNative.WebSockets { #region --变量-- - private string Host = "127.0.0.1:6700"; + private string Host = "127.0.0.1"; + /// - /// WebSocket服务端地址请记得带端口号 + /// WebSocket服务端地址 /// public string host { private get { return Host; } - set { Host = value; } + set + { + if (value.Contains(":")) + { + string[] Cache = value.Split(':'); + Host = Cache[0]; + Port = int.Parse(Cache[1]); + } + else + { + Host = value; + } + } + } + /// + /// WebSocket服务端端口号 + /// + public int port + { + private get { return Port; } + set { Port = value; } } #endregion #region --构造函数-- - static Client() - { - AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray(); - } - /// /// 创建一个 实例 /// @@ -47,8 +63,13 @@ namespace AuroraNative.WebSockets /// /// 创建并连接到WebSocket服务器 /// - public bool Create() + public override void Create() { + StringBuilder Cache = new StringBuilder(); + Cache.Append(Host); + Cache.Append(':'); + Cache.Append(Port); + Logger.Debug("正向WebSocket已创建,准备连接...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}"); for (int i = 1; i < 4; i++) { @@ -57,8 +78,8 @@ namespace AuroraNative.WebSockets WebSocket = new ClientWebSocket(); if (WebSocket is ClientWebSocket socket) { - Logger.Debug($"准备连接至IP:{Host}", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}"); - Task Connect = socket.ConnectAsync(new Uri("ws://" + Host + "/"), CancellationToken.None); + Logger.Debug($"准备连接至IP:{Cache}", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}"); + Task Connect = socket.ConnectAsync(new Uri("ws://" + Cache.ToString() + "/"), CancellationToken.None); Connect.Wait(); if (WebSocket.State == WebSocketState.Open) { @@ -68,7 +89,7 @@ namespace AuroraNative.WebSockets Logger.Debug("go-cqhttp 初始化完毕!"); Task.Run(Feedback); Api.Create(this); - return true; + return; } } } @@ -79,13 +100,12 @@ namespace AuroraNative.WebSockets } } Logger.Error("连接到 go-cqhttp 服务器失败!请检查IP是否正确(需要携带端口号)或确认服务器是否启动和初始化完毕!", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}"); - return false; } /// /// 立刻中断并释放连接注意!断开后需要重新Create /// - public void Dispose() + public override void Dispose() { Logger.Debug($"准备销毁正向WebSocket...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}"); try @@ -105,7 +125,7 @@ namespace AuroraNative.WebSockets #region --私有函数-- - private async void Feedback() + internal override async void Feedback() { while (true) { diff --git a/AuroraNative/WebSockets/Server.cs b/AuroraNative/WebSockets/Server.cs index 9e8fc97..e04eade 100644 --- a/AuroraNative/WebSockets/Server.cs +++ b/AuroraNative/WebSockets/Server.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using System.Net; using System.Net.WebSockets; using System.Reflection; @@ -16,11 +15,10 @@ namespace AuroraNative.WebSockets { #region --变量-- - private string Port = "6700"; /// /// WebSocket监听端口 /// - public string port + public int port { private get { return Port; } set { Port = value; } @@ -33,11 +31,6 @@ namespace AuroraNative.WebSockets #region --构造函数-- - static Server() - { - AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray(); - } - /// /// 创建一个 实例 /// @@ -51,13 +44,13 @@ namespace AuroraNative.WebSockets /// /// 创建WebSocket服务器并监听端口 /// - public void Create() + public override void Create() { try { Logger.Debug("反向WebSocket已创建,准备监听...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}"); Listener = new HttpListener(); - Listener.Prefixes.Add("http://*:" + Port + "/"); + Listener.Prefixes.Add("http://*:" + Port.ToString() + "/"); Listener.Start(); Logger.Info("开始监听来自 go-cqhttp 客户端的连接..."); Task.Run(Feedback); @@ -77,7 +70,7 @@ namespace AuroraNative.WebSockets /// /// 立刻中断并释放连接注意!断开后需要重新Create /// - public void Dispose() + public override void Dispose() { Logger.Debug($"准备销毁反向WebSocket...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}"); try @@ -98,7 +91,7 @@ namespace AuroraNative.WebSockets #region --私有函数-- - private async void Feedback() + internal override async void Feedback() { while (true) {