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 6f57e84..7542b9c 100644
--- a/AuroraNative/API/Api.cs
+++ b/AuroraNative/API/Api.cs
@@ -1,7 +1,11 @@
using AuroraNative.EventArgs;
+using AuroraNative.Exceptions;
using AuroraNative.WebSockets;
+using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
@@ -10,7 +14,7 @@ namespace AuroraNative
///
/// API 类
///
- public class Api
+ public sealed class Api
{
#region --变量--
@@ -18,20 +22,37 @@ public class Api
/// 任务队列
///
internal static JObject TaskList = new JObject();
+ internal static MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
private readonly BaseWebSocket WebSocket;
#endregion
+ #region --属性--
+
+ ///
+ /// 获取API实例
+ ///
+ public static Api CurrentApi => (Api)Cache.Get($"API{AppDomain.CurrentDomain.Id}");
+
+ #endregion
+
#region --构造函数--
///
/// 构建函数
///
/// WebSocket句柄
- public Api(BaseWebSocket WebSocket)
+ private Api(BaseWebSocket WebSocket)
{
- this.WebSocket = WebSocket;
+ if (WebSocket != null)
+ {
+ this.WebSocket = WebSocket;
+ }
+ else
+ {
+ throw new WebSocketException(-1, "传入的WebSocket不可为空");
+ }
}
#endregion
@@ -41,15 +62,15 @@ public Api(BaseWebSocket WebSocket)
///
/// 发送私聊消息
///
- /// 接受者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 }
};
@@ -89,7 +110,7 @@ public void SendGroupForwardMessage(long GroupID, JArray Message)
{ "group_id", GroupID },
{ "messages", Message }
};
-
+ //TODO 需要做CQ码转换
SendCallVoid(new BaseAPI("send_group_forward_msg", Params, "SendGroupForwardMessage:" + Utils.NowTimeSteamp()));
}
@@ -98,11 +119,11 @@ public void SendGroupForwardMessage(long GroupID, JArray Message)
///
/// 信息内容
/// 信息类型私聊: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},
@@ -112,21 +133,23 @@ public async Task SendMsg(string Message, string MessageType = null, lon
switch (MessageType)
{
case "private":
- Params.Add("user_id", QID);
+ Params.Add("user_id", UserID);
break;
case "group":
Params.Add("group_id", GroupID);
break;
- default:
- if (QID != 0)
+ case null:
+ if (UserID != 0)
{
- Params.Add("user_id", QID);
+ Params.Add("user_id", UserID);
}
else if (GroupID != 0)
{
Params.Add("group_id", GroupID);
}
break;
+ default:
+ throw new Exceptions.JsonException(-1, "传入的参数不符合预期");
}
return await SendCallMessageID(new BaseAPI("send_msg", Params, "SendMsg:" + Utils.NowTimeSteamp()));
@@ -146,9 +169,18 @@ public void DeleteMessage(int MessageID)
///
/// 消息ID
/// 错误返回null,成功返回JObject
- public async Task GetMsg(string MessageID)
+ public async Task> GetMsg(string MessageID)
{
- return await SendCallObject(new BaseAPI("get_msg", new JObject() { { "message_id", MessageID } }, "GetMsg:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("get_msg", new JObject() { { "message_id", MessageID } }, "GetMsg:" + Utils.NowTimeSteamp()));
+
+ return new Dictionary() {
+ {"MessageID",Json.Value("message_id")},
+ {"RealID",Json.Value("real_id")},
+ {"Sender",Json.Value("sender")},
+ {"Time",Json.Value("time")},
+ {"Message",Json.Value("message")},
+ {"RawMessage",Json.Value("raw_message")}
+ };
}
///
@@ -158,6 +190,7 @@ public async Task GetMsg(string MessageID)
/// 错误返回null,成功返回JObject
public async Task GetForwardMsg(string MessageID)
{
+ //TODO 等转发合并消息做完后需要修改这个方法的返回类型
return await SendCallObject(new BaseAPI("get_forward_msg", new JObject() { { "message_id", MessageID } }, "GetForwardMsg:" + Utils.NowTimeSteamp()));
}
@@ -166,26 +199,33 @@ public async Task GetForwardMsg(string MessageID)
///
/// 图片缓存文件名,带不带后缀你喜欢就好
/// 错误返回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 }
};
@@ -197,13 +237,13 @@ public void SetGroupKick(long GroupID, long QID, bool RejectAddRequest = false)
/// 群组单人禁言
///
/// 群号
- /// 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 }
};
@@ -258,13 +298,13 @@ public void SetGroupWholeBan(long GroupID, bool Enable = true)
/// 设置群管理员
///
/// 群号
- /// 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 }
};
@@ -276,13 +316,13 @@ public void SetGroupAdmin(long GroupID, long QID, bool Enable = true)
/// 设置群名片
///
/// 群号
- /// 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 }
};
@@ -326,14 +366,14 @@ public void SetGroupLeave(long GroupID, bool IsDismiss = false)
/// 设置群组专属头衔
///
/// 群号
- /// 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 }
@@ -384,35 +424,48 @@ public void SetGroupAddRequest(string Flag, string SubType, bool Approve = true,
/// 获取登录号信息
///
/// 错误返回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>();
}
///
@@ -421,7 +474,7 @@ public async Task GetFriendList()
/// 群号
/// 是否使用缓存,使用缓存响应快但是可能更新不及时默认:false
/// 错误返回null,成功返回JObject
- public async Task GetGroupInfo(long GroupID, bool Cache = false)
+ public async Task GetGroupInfo(long GroupID, bool Cache = false)
{
JObject Params = new JObject
{
@@ -429,35 +482,35 @@ public async Task GetGroupInfo(long GroupID, bool Cache = false)
{ "no_cache ", Cache }
};
- return await SendCallObject(new BaseAPI("get_group_info", Params, "GetGroupInfo:" + Utils.NowTimeSteamp()));
+ return (await SendCallObject(new BaseAPI("get_group_info", Params, "GetGroupInfo:" + Utils.NowTimeSteamp()))).ToObject();
}
///
/// 获取群列表
///
/// 错误返回null,成功返回JObject
- public async Task GetGroupList()
+ public async Task> GetGroupList()
{
- return await SendCallObject(new BaseAPI("get_group_list", null, "GetGroupList:" + Utils.NowTimeSteamp()));
+ return (await SendCallObject(new BaseAPI("get_group_list", null, "GetGroupList:" + Utils.NowTimeSteamp()))).ToObject>();
}
///
/// 获取群成员信息
///
/// 群号
- /// 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 }
};
- return await SendCallObject(new BaseAPI("get_group_member_info", Params, "GetGroupMemberInfo:" + Utils.NowTimeSteamp()));
+ return (await SendCallObject(new BaseAPI("get_group_member_info", Params, "GetGroupMemberInfo:" + Utils.NowTimeSteamp()))).ToObject();
}
///
@@ -465,9 +518,9 @@ public async Task GetGroupMemberInfo(long GroupID, long QID, bool Cache
///
/// 群号
/// 错误返回null,成功返回JObject
- public async Task GetGroupMemberList(long GroupID)
+ public async Task> GetGroupMemberList(long GroupID)
{
- return await SendCallObject(new BaseAPI("get_group_member_info", new JObject { { "group_id", GroupID } }, "GetGroupMemberInfo:" + Utils.NowTimeSteamp()));
+ return (await SendCallObject(new BaseAPI("get_group_member_info", new JObject { { "group_id", GroupID } }, "GetGroupMemberInfo:" + Utils.NowTimeSteamp()))).ToObject>();
}
///
@@ -476,7 +529,7 @@ public async Task GetGroupMemberList(long GroupID)
/// 群号
/// 要获取的群荣誉类型talkative/performer/legend/strong_newbie/emotion/all
/// 错误返回null,成功返回JObject
- public async Task GetGroupHonorInfo(long GroupID, string Type)
+ public async Task> GetGroupHonorInfo(long GroupID, string Type)
{
JObject Params = new JObject
{
@@ -484,7 +537,22 @@ public async Task GetGroupHonorInfo(long GroupID, string Type)
{ "type ", Type }
};
- return await SendCallObject(new BaseAPI("get_group_honor_info", Params, "GetGroupHonorInfo:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("get_group_honor_info", Params, "GetGroupHonorInfo:" + Utils.NowTimeSteamp()));
+ List Result = new List();
+
+ foreach (string i in new string[] { "talkative", "performer", "legend", "strong_newbie", "emotion" })
+ {
+ if (Json.TryGetValue("current_talkative", out JToken Cache))
+ {
+ Result.Add(Cache.ToObject());
+ }
+ if (Json.TryGetValue(i + "_list", out Cache))
+ {
+ Result.Add(Cache.ToObject());
+ }
+ }
+
+ return Result;
}
///
@@ -509,9 +577,26 @@ public async Task CanSendRecord()
/// 获取版本信息
///
/// 错误返回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")}
+ };
}
///
@@ -556,18 +641,20 @@ public async Task GetWordSlices(string Content)
///
/// 图片ID
/// 错误返回null,成功返回JObject
- public async Task OCRImage(string Image)
+ public async Task<(List, string)> OCRImage(string Image)
{
- return await SendCallObject(new BaseAPI("ocr_image", new JObject { { "image", Image } }, "OCRImage:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("ocr_image", new JObject { { "image", Image } }, "OCRImage:" + Utils.NowTimeSteamp()));
+ return (Json.Value("texts").ToObject>(), Json.Value("language"));
}
///
/// 获取群系统消息
///
/// 错误或不存在任何消息返回null,成功返回JObject
- public async Task GetGroupSystemMsg()
+ public async Task<(List, List)> GetGroupSystemMsg()
{
- return await SendCallObject(new BaseAPI("get_group_system_msg", null, "GetGroupSystemMsg:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("get_group_system_msg", null, "GetGroupSystemMsg:" + Utils.NowTimeSteamp()));
+ return (Json.Value("invited_requests").ToObject>(), Json.Value("join_requests").ToObject>());
}
///
@@ -595,9 +682,16 @@ public void UploadGroupFile(long GroupID, string FilePath, string SaveName, stri
///
/// 群号
/// 错误返回null,成功返回JObject
- public async Task GetGroupFileSystemInfo(long GroupID)
+ public async Task> GetGroupFileSystemInfo(long GroupID)
{
- return await SendCallObject(new BaseAPI("get_group_file_system_info", new JObject { { "group_id", GroupID } }, "GetGroupFileSystemInfo:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("get_group_file_system_info", new JObject { { "group_id", GroupID } }, "GetGroupFileSystemInfo:" + Utils.NowTimeSteamp()));
+
+ return new Dictionary {
+ { "FileCount",Json.Value("file_count")},
+ { "LimitCount",Json.Value("limit_count")},
+ { "UsedSpace",Json.Value("used_space")},
+ { "TotalSpace",Json.Value("total_space")}
+ };
}
///
@@ -605,9 +699,11 @@ public async Task GetGroupFileSystemInfo(long GroupID)
///
/// 群号
/// 错误返回null,成功返回JObject
- public async Task GetGroupRootFiles(long GroupID)
+ public async Task<(List, List)> GetGroupRootFiles(long GroupID)
{
- return await SendCallObject(new BaseAPI("get_group_root_files", new JObject { { "group_id", GroupID } }, "GetGroupRootFiles:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("get_group_root_files", new JObject { { "group_id", GroupID } }, "GetGroupRootFiles:" + Utils.NowTimeSteamp()));
+
+ return (Json.Value("files").ToObject>(), Json.Value("folders").ToObject>());
}
///
@@ -616,7 +712,7 @@ public async Task GetGroupRootFiles(long GroupID)
/// 群号
/// 文件夹ID
/// 错误返回null,成功返回JObject
- public async Task GetGroupFilesByFolder(long GroupID, string FolderID)
+ public async Task<(List, List)> GetGroupFilesByFolder(long GroupID, string FolderID)
{
JObject Params = new JObject
{
@@ -624,7 +720,9 @@ public async Task GetGroupFilesByFolder(long GroupID, string FolderID)
{ "folder_id ", FolderID }
};
- return await SendCallObject(new BaseAPI("get_group_files_by_folder", Params, "GetGroupFilesByFolder:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("get_group_files_by_folder", Params, "GetGroupFilesByFolder:" + Utils.NowTimeSteamp()));
+
+ return (Json.Value("files").ToObject>(), Json.Value("folders").ToObject>());
}
///
@@ -650,9 +748,10 @@ public async Task GetGroupFilesURL(long GroupID, string FileID, int BusI
/// 获取状态
///
/// 错误返回null,成功返回JObject
- public async Task GetStatus()
+ public async Task<(bool, Statistics)> GetStatus()
{
- return await SendCallObject(new BaseAPI("get_group_info", null, "GetGroupInfo:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("get_group_info", null, "GetGroupInfo:" + Utils.NowTimeSteamp()));
+ return (Json.Value("online"), Json.Value("stat"));
}
///
@@ -660,9 +759,15 @@ public async Task GetStatus()
///
/// 群号
/// 错误返回null,成功返回JObject
- public async Task GetGroupAtAllRemain(long GroupID)
+ public async Task> GetGroupAtAllRemain(long GroupID)
{
- return await SendCallObject(new BaseAPI("get_group_at_all_remain", new JObject { { "group_id", GroupID } }, "GetGroupAtAllRemain:" + Utils.NowTimeSteamp()));
+ JObject Json = await SendCallObject(new BaseAPI("get_group_at_all_remain", new JObject { { "group_id", GroupID } }, "GetGroupAtAllRemain:" + Utils.NowTimeSteamp()));
+
+ return new Dictionary() {
+ { "CanAtAll",Json.Value("can_at_all")},
+ { "GroupAdminAtAllCount",Json.Value("remain_at_all_count_for_group")},
+ { "BotAtAllCount",Json.Value("remain_at_all_count_for_uin")}
+ };
}
///
@@ -684,11 +789,21 @@ public void HandleQuickOperation(object Context, object Operation)
///
/// 获取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()));
+ JObject Json = await SendCallObject(new BaseAPI("_get_vip_info", new JObject { { "user_id", UserID } }, "GetGroupAtAllRemain:" + Utils.NowTimeSteamp()));
+
+ return new Dictionary() {
+ { "UserID",Json.Value("user_id")},
+ { "NickName",Json.Value("nickname")},
+ { "Level",Json.Value("level")},
+ { "LevelSpeed",Json.Value("level_speed")},
+ { "VipLevel",Json.Value("vip_level")},
+ { "VipGrowthSpeed",Json.Value("vip_growth_speed")},
+ { "VipGrowthTotal",Json.Value("vip_growth_total")}
+ };
}
///
@@ -739,9 +854,9 @@ public async Task DownloadFile(string URL, int ThreadCount, string[] Hea
///
/// 是否无视缓存
/// 错误返回null,成功返回JObject
- public async Task GetOnlineClients(bool Cache)
+ public async Task> GetOnlineClients(bool Cache)
{
- return await SendCallObject(new BaseAPI("get_online_clients", new JObject { { "no_cache ", Cache } }, "GetOnlineClients:" + Utils.NowTimeSteamp()));
+ return (await SendCallObject(new BaseAPI("get_online_clients", new JObject { { "no_cache ", Cache } }, "GetOnlineClients:" + Utils.NowTimeSteamp()))).Value("clients").ToObject>();
}
///
@@ -750,15 +865,21 @@ public async Task GetOnlineClients(bool Cache)
/// 起始消息序号
/// 群号
/// 错误返回null,成功返回JObject
- public async Task GetGroupMsgHistory(long MessageSeq, long GroupID)
+ public async Task> GetGroupMsgHistory(long GroupID, long MessageSeq = 0)
{
JObject Params = new JObject
{
{ "message_seq", MessageSeq },
- { "group_id ", GroupID }
+ { "group_id", GroupID }
};
- return await SendCallObject(new BaseAPI("get_group_msg_history", Params, "GetGroupMsgHistory:" + Utils.NowTimeSteamp()));
+ if (MessageSeq == 0)
+ {
+ Params.Remove("message_seq");
+ }
+
+ JObject Json = await SendCallObject(new BaseAPI("get_group_msg_history", Params, "GetGroupMsgHistory:" + Utils.NowTimeSteamp()));
+ return Json.Value("messages").ToObject>();
}
///
@@ -784,9 +905,9 @@ public void DelEssenceMsg(string MessageID)
///
/// 群号
/// 错误返回null,成功返回JObject
- public async Task GetEssenceMsgList(long GroupID)
+ public async Task> GetEssenceMsgList(long GroupID)
{
- return await SendCallObject(new BaseAPI("get_essence_msg_list", new JObject { { "group_id", GroupID } }, "GetEssenceMsgList:" + Utils.NowTimeSteamp()));
+ return (await SendCallObject(new BaseAPI("get_essence_msg_list", new JObject { { "group_id", GroupID } }, "GetEssenceMsgList:" + Utils.NowTimeSteamp()))).ToObject>();
}
///
@@ -807,8 +928,7 @@ public async Task CheckURLSafely(string URL)
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); });
@@ -817,14 +937,32 @@ private async Task SendCallMessageID(BaseAPI Params)
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);
@@ -834,7 +972,7 @@ private void SendCallVoid(BaseAPI Params)
private static string FeedbackMessageID(string UniqueCode)
{
- JObject FBJson = GetFeedback(UniqueCode);
+ JToken FBJson = GetFeedback(UniqueCode);
//判断返回
if (FBJson["status"].ToString() == "ok")
@@ -846,7 +984,7 @@ private static string FeedbackMessageID(string UniqueCode)
private static JObject FeedbackObject(string UniqueCode)
{
- JObject FBJson = GetFeedback(UniqueCode);
+ JToken FBJson = GetFeedback(UniqueCode);
//判断返回
if (FBJson["status"].ToString() == "ok")
@@ -856,21 +994,63 @@ private static JObject FeedbackObject(string UniqueCode)
return null;
}
- private static JObject GetFeedback(string UniqueCode) {
- JObject FBJson = new JObject();
+ private static JArray FeedbackArray(string UniqueCode)
+ {
+ JToken FBJson = GetFeedback(UniqueCode);
+
+ //判断返回
+ if (FBJson["status"].ToString() == "ok")
+ {
+ return JArray.Parse(FBJson["data"].ToString());
+ }
+ return null;
+ }
+
+ private static JToken GetFeedback(string UniqueCode)
+ {
+ JToken FBJson = null;
do
{
if (TaskList[UniqueCode].ToString() != "Sended")
{
- FBJson = JObject.Parse(TaskList[UniqueCode].ToString());
+ FBJson = TaskList[UniqueCode];
TaskList.Remove(UniqueCode);
break;
}
Thread.Sleep(10);
- }while (FBJson["status"] == null);
+ } while (FBJson == null);
return FBJson;
}
+
+ internal static Api Create(BaseWebSocket WebSocket)
+ {
+ try
+ {
+ 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)
+ {
+ Logger.Warning("警告,传入的WebSocket有误。错误代码: " + e.ErrorCode);
+ }
+ return null;
+ }
+
+ internal static void Destroy()
+ {
+ Cache.Remove($"API{AppDomain.CurrentDomain.Id}");
+ }
+
#endregion
}
}
diff --git a/AuroraNative/EventArgs/Basic/Device.cs b/AuroraNative/Abstract/Device.cs
similarity index 97%
rename from AuroraNative/EventArgs/Basic/Device.cs
rename to AuroraNative/Abstract/Device.cs
index 0f42780..ab91fae 100644
--- a/AuroraNative/EventArgs/Basic/Device.cs
+++ b/AuroraNative/Abstract/Device.cs
@@ -1,6 +1,6 @@
using Newtonsoft.Json;
-namespace AuroraNative.EventArgs
+namespace AuroraNative
{
///
/// 提供用于描述事件参数的基础类, 该类是抽象的
diff --git a/AuroraNative/Abstract/Essences.cs b/AuroraNative/Abstract/Essences.cs
new file mode 100644
index 0000000..b2365ac
--- /dev/null
+++ b/AuroraNative/Abstract/Essences.cs
@@ -0,0 +1,56 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 精华消息 抽象类
+ ///
+ public sealed class Essences
+ {
+ #region --属性--
+
+ ///
+ /// 发送者QQ 号
+ ///
+ [JsonProperty(PropertyName = "sender_id")]
+ public long SenderID { get; private set; }
+
+ ///
+ /// 发送者昵称
+ ///
+ [JsonProperty(PropertyName = "sender_nick")]
+ public string SenderNickName { get; private set; }
+
+ ///
+ /// 消息发送时间
+ ///
+ [JsonProperty(PropertyName = "sender_time")]
+ public string SenderTime { get; private set; }
+
+ ///
+ /// 操作者QQ 号
+ ///
+ [JsonProperty(PropertyName = "operator_id")]
+ public string OperatorID { get; private set; }
+
+ ///
+ /// 操作者昵称
+ ///
+ [JsonProperty(PropertyName = "operator_nick")]
+ public string OperatorNickName { get; private set; }
+
+ ///
+ /// 精华设置时间
+ ///
+ [JsonProperty(PropertyName = "operator_time")]
+ public string OperatorTime { get; private set; }
+
+ ///
+ /// 消息ID
+ ///
+ [JsonProperty(PropertyName = "message_id")]
+ public string MessageID { get; private set; }
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Groups/Files/File.cs b/AuroraNative/Abstract/Groups/Files/File.cs
new file mode 100644
index 0000000..03ed694
--- /dev/null
+++ b/AuroraNative/Abstract/Groups/Files/File.cs
@@ -0,0 +1,74 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 群文件 抽象类
+ ///
+ public sealed class File
+ {
+ #region --属性--
+
+ ///
+ /// 文件ID
+ ///
+ [JsonProperty(PropertyName = "file_id")]
+ public string FileID;
+
+ ///
+ /// 文件名称
+ ///
+ [JsonProperty(PropertyName = "file_name")]
+ public string FileName;
+
+ ///
+ /// 文件类型
+ ///
+ [JsonProperty(PropertyName = "busid")]
+ public long BusID;
+
+ ///
+ /// 文件大小
+ ///
+ [JsonProperty(PropertyName = "file_size")]
+ public long FileSize;
+
+ ///
+ /// 上传时间
+ ///
+ [JsonProperty(PropertyName = "upload_time")]
+ public string UploadTime;
+
+ ///
+ /// 过期时间,永久为零
+ ///
+ [JsonProperty(PropertyName = "dead_time")]
+ public int DeadTime;
+
+ ///
+ /// 最后修改时间
+ ///
+ [JsonProperty(PropertyName = "modify_time")]
+ public int ModifyTime;
+
+ ///
+ /// 下载次数
+ ///
+ [JsonProperty(PropertyName = "download_times")]
+ public int DownloadsCount;
+
+ ///
+ /// 上传者ID
+ ///
+ [JsonProperty(PropertyName = "uploader")]
+ public int Uploader;
+
+ ///
+ /// 上传者名字
+ ///
+ [JsonProperty(PropertyName = "uploader_name")]
+ public int UploaderName;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Groups/Files/Folder.cs b/AuroraNative/Abstract/Groups/Files/Folder.cs
new file mode 100644
index 0000000..4b17f83
--- /dev/null
+++ b/AuroraNative/Abstract/Groups/Files/Folder.cs
@@ -0,0 +1,50 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 群文件夹 抽象类
+ ///
+ public sealed class Folder
+ {
+ #region --属性--
+
+ ///
+ /// 文件夹ID
+ ///
+ [JsonProperty(PropertyName = "folder_id")]
+ public string FolderID;
+
+ ///
+ /// 文件夹名称
+ ///
+ [JsonProperty(PropertyName = "folder_name")]
+ public string FolderName;
+
+ ///
+ /// 创建时间
+ ///
+ [JsonProperty(PropertyName = "create_time")]
+ public long CreateTime;
+
+ ///
+ /// 创建者
+ ///
+ [JsonProperty(PropertyName = "creator")]
+ public long Creator;
+
+ ///
+ /// 创建者名称
+ ///
+ [JsonProperty(PropertyName = "creator_name")]
+ public string CreatoName;
+
+ ///
+ /// 子文件数量
+ ///
+ [JsonProperty(PropertyName = "total_file_count")]
+ public int TotalFilesCount;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Groups/GroupMember.cs b/AuroraNative/Abstract/Groups/GroupMember.cs
new file mode 100644
index 0000000..205add0
--- /dev/null
+++ b/AuroraNative/Abstract/Groups/GroupMember.cs
@@ -0,0 +1,104 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 群成员信息 抽象类
+ ///
+ public sealed class GroupMember
+ {
+ #region --属性--
+
+ ///
+ /// 群号
+ ///
+ [JsonProperty(PropertyName = "group_id", NullValueHandling = NullValueHandling.Include)]
+ public long GroupID;
+
+ ///
+ /// QQ号
+ ///
+ [JsonProperty(PropertyName = "user_id", NullValueHandling = NullValueHandling.Include)]
+ public long UserID;
+
+ ///
+ /// 昵称
+ ///
+ [JsonProperty(PropertyName = "nickname", NullValueHandling = NullValueHandling.Include)]
+ public string NickName;
+
+ ///
+ /// 群名片
+ ///
+ [JsonProperty(PropertyName = "card", NullValueHandling = NullValueHandling.Include)]
+ public string Card;
+
+ ///
+ /// 现在人数
+ ///
+ [JsonProperty(PropertyName = "sex", NullValueHandling = NullValueHandling.Include)]
+ public string Sex;
+
+ ///
+ /// 最大人数
+ ///
+ [JsonProperty(PropertyName = "age", NullValueHandling = NullValueHandling.Include)]
+ public int MaxMemberCount;
+
+ ///
+ /// 地区
+ ///
+ [JsonProperty(PropertyName = "area", NullValueHandling = NullValueHandling.Include)]
+ public string Area;
+
+ ///
+ /// 加群时间戳
+ ///
+ [JsonProperty(PropertyName = "join_time", NullValueHandling = NullValueHandling.Include)]
+ public int JoinTime;
+
+ ///
+ /// 最后发言时间戳
+ ///
+ [JsonProperty(PropertyName = "last_sent_time", NullValueHandling = NullValueHandling.Include)]
+ public int LastSentTime;
+
+ ///
+ /// 成员等级
+ ///
+ [JsonProperty(PropertyName = "level", NullValueHandling = NullValueHandling.Include)]
+ public int Level;
+
+ ///
+ /// 角色
+ ///
+ [JsonProperty(PropertyName = "role", NullValueHandling = NullValueHandling.Include)]
+ public int Role;
+
+ ///
+ /// 是否不良记录成员
+ ///
+ [JsonProperty(PropertyName = "unfriendly", NullValueHandling = NullValueHandling.Include)]
+ public bool UnFriendly;
+
+ ///
+ /// 专属头衔
+ ///
+ [JsonProperty(PropertyName = "title", NullValueHandling = NullValueHandling.Include)]
+ public string ExclusiveTitle;
+
+ ///
+ /// 专属头衔过期时间戳
+ ///
+ [JsonProperty(PropertyName = "title_expire_time", NullValueHandling = NullValueHandling.Include)]
+ public long ExclusiveTitleTime;
+
+ ///
+ /// 是否允许修改群名片
+ ///
+ [JsonProperty(PropertyName = "card_changeable", NullValueHandling = NullValueHandling.Include)]
+ public bool IsChangeCard;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Groups/Groups.cs b/AuroraNative/Abstract/Groups/Groups.cs
new file mode 100644
index 0000000..ccb8dab
--- /dev/null
+++ b/AuroraNative/Abstract/Groups/Groups.cs
@@ -0,0 +1,38 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 群组 抽象类
+ ///
+ public sealed class Groups
+ {
+ #region --属性--
+
+ ///
+ /// 群号
+ ///
+ [JsonProperty(PropertyName = "group_id")]
+ public long GroupID;
+
+ ///
+ /// 群名称
+ ///
+ [JsonProperty(PropertyName = "group_name")]
+ public string GroupName;
+
+ ///
+ /// 现在人数
+ ///
+ [JsonProperty(PropertyName = "member_count")]
+ public int MemberCount;
+
+ ///
+ /// 最大人数
+ ///
+ [JsonProperty(PropertyName = "max_member_count")]
+ public int MaxMemberCount;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Groups/HonorListInfo.cs b/AuroraNative/Abstract/Groups/HonorListInfo.cs
new file mode 100644
index 0000000..e0747e9
--- /dev/null
+++ b/AuroraNative/Abstract/Groups/HonorListInfo.cs
@@ -0,0 +1,44 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 群荣誉详细信息 抽象类
+ ///
+ public sealed class HonorListInfo
+ {
+ #region --属性--
+
+ ///
+ /// QQ号
+ ///
+ [JsonProperty(PropertyName = "user_id")]
+ public long UserID;
+
+ ///
+ /// 昵称
+ ///
+ [JsonProperty(PropertyName = "nickname")]
+ public string NickName;
+
+ ///
+ /// 头像URL
+ ///
+ [JsonProperty(PropertyName = "avatar")]
+ public string Avater;
+
+ ///
+ /// 荣誉描述
+ ///
+ [JsonProperty(PropertyName = "description", NullValueHandling = NullValueHandling.Ignore)]
+ public string Description;
+
+ ///
+ /// 持续天数
+ ///
+ [JsonProperty(PropertyName = "day_count", NullValueHandling = NullValueHandling.Ignore)]
+ public string DayCount;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Groups/SystemMessage/BaseRequest.cs b/AuroraNative/Abstract/Groups/SystemMessage/BaseRequest.cs
new file mode 100644
index 0000000..7c36b7e
--- /dev/null
+++ b/AuroraNative/Abstract/Groups/SystemMessage/BaseRequest.cs
@@ -0,0 +1,44 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 群系统消息 - 消息列表 基抽象类
+ ///
+ public abstract class BaseRequest
+ {
+ #region --属性--
+
+ ///
+ /// 请求ID
+ ///
+ [JsonProperty(PropertyName = "request_id")]
+ public long RequestID;
+
+ ///
+ /// 群号
+ ///
+ [JsonProperty(PropertyName = "group_id")]
+ public long GroupID;
+
+ ///
+ /// 群名称
+ ///
+ [JsonProperty(PropertyName = "group_name")]
+ public string GroupName;
+
+ ///
+ /// 是否已处理
+ ///
+ [JsonProperty(PropertyName = "checked")]
+ public bool Checked;
+
+ ///
+ /// 处理者,未处理是0
+ ///
+ [JsonProperty(PropertyName = "actor")]
+ public long Actor;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Groups/SystemMessage/InvitedRequest.cs b/AuroraNative/Abstract/Groups/SystemMessage/InvitedRequest.cs
new file mode 100644
index 0000000..df275cb
--- /dev/null
+++ b/AuroraNative/Abstract/Groups/SystemMessage/InvitedRequest.cs
@@ -0,0 +1,26 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 群系统消息 - 邀请消息列表 抽象类
+ ///
+ public sealed class InvitedRequest : BaseRequest
+ {
+ #region --属性--
+
+ ///
+ /// 邀请者
+ ///
+ [JsonProperty(PropertyName = "invitor_uin")]
+ public long InvitorUserID;
+
+ ///
+ /// 邀请者昵称
+ ///
+ [JsonProperty(PropertyName = "invitor_nick")]
+ public string InvitorNickName;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Groups/SystemMessage/JoinRequest.cs b/AuroraNative/Abstract/Groups/SystemMessage/JoinRequest.cs
new file mode 100644
index 0000000..495ceeb
--- /dev/null
+++ b/AuroraNative/Abstract/Groups/SystemMessage/JoinRequest.cs
@@ -0,0 +1,32 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 群系统消息 - 进群消息列表 抽象类
+ ///
+ public sealed class JoinRequest : BaseRequest
+ {
+ #region --属性--
+
+ ///
+ /// 请求者
+ ///
+ [JsonProperty(PropertyName = "requester_uin")]
+ public long RequesterUserID;
+
+ ///
+ /// 请求者昵称
+ ///
+ [JsonProperty(PropertyName = "requester_nick")]
+ public string RequesterNickName;
+
+ ///
+ /// 验证信息
+ ///
+ [JsonProperty(PropertyName = "message")]
+ public long Message;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Messages.cs b/AuroraNative/Abstract/Messages.cs
new file mode 100644
index 0000000..9b4f6ec
--- /dev/null
+++ b/AuroraNative/Abstract/Messages.cs
@@ -0,0 +1,98 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 消息 抽象类
+ ///
+ public sealed class Messages
+ {
+ #region --属性--
+
+ ///
+ /// 匿名信息
+ ///
+ [JsonProperty(PropertyName = "anonymous")]
+ public Anonymous Anonymous;
+
+ ///
+ /// 字体
+ ///
+ [JsonProperty(PropertyName = "font")]
+ public int Font;
+
+ ///
+ /// 群号
+ ///
+ [JsonProperty(PropertyName = "group_id")]
+ public long GroupID;
+
+ ///
+ /// 消息内容
+ ///
+ [JsonProperty(PropertyName = "message")]
+ public string Message;
+
+ ///
+ /// 原始消息内容
+ ///
+ [JsonProperty(PropertyName = "raw_message")]
+ public string RawMessage;
+
+ ///
+ /// 消息ID
+ ///
+ [JsonProperty(PropertyName = "message_id")]
+ public int MessageID;
+
+ ///
+ /// 消息序号
+ ///
+ [JsonProperty(PropertyName = "message_seq")]
+ public long MessageSeq;
+
+ ///
+ /// 消息类型
+ ///
+ [JsonProperty(PropertyName = "message_type")]
+ public string MessageType;
+
+ ///
+ /// 消息事件主类型
+ ///
+ [JsonProperty(PropertyName = "post_type")]
+ public string PostType;
+
+ ///
+ /// 消息事件子类型
+ ///
+ [JsonProperty(PropertyName = "sub_type")]
+ public string SubType;
+
+ ///
+ /// 收到事件的机器人QQ号
+ ///
+ [JsonProperty(PropertyName = "self_id")]
+ public int SelfID;
+
+ ///
+ /// 发送者
+ ///
+ [JsonProperty(PropertyName = "sender")]
+ public Sender Sender;
+
+ ///
+ /// 消息时间戳
+ ///
+ [JsonProperty(PropertyName = "time")]
+ public long TimeStamp;
+
+ ///
+ /// 发送者QQ号
+ ///
+ [JsonProperty(PropertyName = "user_id")]
+ public long UserID;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/OCRTextDetection.cs b/AuroraNative/Abstract/OCRTextDetection.cs
new file mode 100644
index 0000000..94dd71a
--- /dev/null
+++ b/AuroraNative/Abstract/OCRTextDetection.cs
@@ -0,0 +1,33 @@
+using Newtonsoft.Json;
+using System.Numerics;
+
+namespace AuroraNative
+{
+ ///
+ /// OCR结果信息 抽象类
+ ///
+ public sealed class OCRTextDetection
+ {
+ #region --属性--
+
+ ///
+ /// 文本
+ ///
+ [JsonProperty(PropertyName = "text")]
+ public string Text;
+
+ ///
+ /// 置信度
+ ///
+ [JsonProperty(PropertyName = "confidence")]
+ public int Confidence;
+
+ ///
+ /// 坐标
+ ///
+ [JsonProperty(PropertyName = "coordinates")]
+ public Vector2 Coordinates;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/Abstract/Statistics.cs b/AuroraNative/Abstract/Statistics.cs
new file mode 100644
index 0000000..481bc0c
--- /dev/null
+++ b/AuroraNative/Abstract/Statistics.cs
@@ -0,0 +1,57 @@
+using Newtonsoft.Json;
+
+namespace AuroraNative
+{
+ ///
+ /// 运行统计 抽象类
+ ///
+ public sealed class Statistics
+ {
+ #region --属性--
+
+ ///
+ /// 收到的数据包总数
+ ///
+ [JsonProperty(PropertyName = "packet_received")]
+ public ulong PacketReceived;
+
+ ///
+ /// 发送的数据包总数
+ ///
+ [JsonProperty(PropertyName = "packet_sent")]
+ public ulong PacketSent;
+
+ ///
+ /// 数据包丢失总数
+ ///
+ [JsonProperty(PropertyName = "packet_lost")]
+ public uint PacketLost;
+
+ ///
+ /// 接受信息总数
+ ///
+ [JsonProperty(PropertyName = "message_received")]
+ public ulong MessageReceived;
+
+ ///
+ /// 发送信息总数
+ ///
+ [JsonProperty(PropertyName = "message_sent")]
+ public ulong MessageSent;
+
+ ///
+ /// TCP 链接断开次数
+ ///
+ [JsonProperty(PropertyName = "disconnect_times")]
+ public uint DisconnectsCount;
+
+
+ ///
+ /// 账号掉线次数
+ ///
+ [JsonProperty(PropertyName = "lost_times")]
+ public uint LostsCount;
+
+ #endregion
+ }
+}
diff --git a/AuroraNative/EventArgs/Basic/Anonymous.cs b/AuroraNative/Abstract/Users/Anonymous.cs
similarity index 97%
rename from AuroraNative/EventArgs/Basic/Anonymous.cs
rename to AuroraNative/Abstract/Users/Anonymous.cs
index 4cb522d..895bc76 100644
--- a/AuroraNative/EventArgs/Basic/Anonymous.cs
+++ b/AuroraNative/Abstract/Users/Anonymous.cs
@@ -1,6 +1,6 @@
using Newtonsoft.Json;
-namespace AuroraNative.EventArgs
+namespace AuroraNative
{
///
/// 提供用于描述匿名信息的基础类, 该类是抽象的
diff --git a/AuroraNative/Abstract/Users/Friends.cs b/AuroraNative/Abstract/Users/Friends.cs
new file mode 100644
index 0000000..c1dc2f3
--- /dev/null
+++ b/AuroraNative/Abstract/Users/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/EventArgs/Basic/Sender.cs b/AuroraNative/Abstract/Users/Sender.cs
similarity index 98%
rename from AuroraNative/EventArgs/Basic/Sender.cs
rename to AuroraNative/Abstract/Users/Sender.cs
index ef0404f..6bfb011 100644
--- a/AuroraNative/EventArgs/Basic/Sender.cs
+++ b/AuroraNative/Abstract/Users/Sender.cs
@@ -1,6 +1,6 @@
using Newtonsoft.Json;
-namespace AuroraNative.EventArgs
+namespace AuroraNative
{
///
/// 提供用于描述发送者信息的基础类, 该类是抽象的
diff --git a/AuroraNative/AuroraNative.csproj b/AuroraNative/AuroraNative.csproj
index 20db5b0..e90a043 100644
--- a/AuroraNative/AuroraNative.csproj
+++ b/AuroraNative/AuroraNative.csproj
@@ -15,13 +15,13 @@
false
false
true
- 0.1.0.0311
- 0.1.0.0311
+ 1.0.0.0315
+ 1.0.0.0315
Icon.png
false
AuroraNative
AuroraNative
- 0.1.0-alpha
+ 1.0.0-Beta
true
@@ -40,8 +40,14 @@
-
+
+
+
+
+
+
+
diff --git a/AuroraNative/AuroraNative.xml b/AuroraNative/AuroraNative.xml
index 7163e89..79ebc0a 100644
--- a/AuroraNative/AuroraNative.xml
+++ b/AuroraNative/AuroraNative.xml
@@ -4,6 +4,611 @@
AuroraNative
+
+
+ 提供用于描述事件参数的基础类, 该类是抽象的
+
+
+
+
+ 客户端ID
+
+
+
+
+ 设备名称
+
+
+
+
+ 设备类型
+
+
+
+
+ 初始化 类的新实例
+
+ 客户端ID
+ 设备名称
+ 设备类型
+
+
+
+ 精华消息 抽象类
+
+
+
+
+ 发送者QQ 号
+
+
+
+
+ 发送者昵称
+
+
+
+
+ 消息发送时间
+
+
+
+
+ 操作者QQ 号
+
+
+
+
+ 操作者昵称
+
+
+
+
+ 精华设置时间
+
+
+
+
+ 消息ID
+
+
+
+
+ 群文件 抽象类
+
+
+
+
+ 文件ID
+
+
+
+
+ 文件名称
+
+
+
+
+ 文件类型
+
+
+
+
+ 文件大小
+
+
+
+
+ 上传时间
+
+
+
+
+ 过期时间,永久为零
+
+
+
+
+ 最后修改时间
+
+
+
+
+ 下载次数
+
+
+
+
+ 上传者ID
+
+
+
+
+ 上传者名字
+
+
+
+
+ 群文件夹 抽象类
+
+
+
+
+ 文件夹ID
+
+
+
+
+ 文件夹名称
+
+
+
+
+ 创建时间
+
+
+
+
+ 创建者
+
+
+
+
+ 创建者名称
+
+
+
+
+ 子文件数量
+
+
+
+
+ 群成员信息 抽象类
+
+
+
+
+ 群号
+
+
+
+
+ QQ号
+
+
+
+
+ 昵称
+
+
+
+
+ 群名片
+
+
+
+
+ 现在人数
+
+
+
+
+ 最大人数
+
+
+
+
+ 地区
+
+
+
+
+ 加群时间戳
+
+
+
+
+ 最后发言时间戳
+
+
+
+
+ 成员等级
+
+
+
+
+ 角色
+
+
+
+
+ 是否不良记录成员
+
+
+
+
+ 专属头衔
+
+
+
+
+ 专属头衔过期时间戳
+
+
+
+
+ 是否允许修改群名片
+
+
+
+
+ 群组 抽象类
+
+
+
+
+ 群号
+
+
+
+
+ 群名称
+
+
+
+
+ 现在人数
+
+
+
+
+ 最大人数
+
+
+
+
+ 群荣誉详细信息 抽象类
+
+
+
+
+ QQ号
+
+
+
+
+ 昵称
+
+
+
+
+ 头像URL
+
+
+
+
+ 荣誉描述
+
+
+
+
+ 持续天数
+
+
+
+
+ 群系统消息 - 消息列表 基抽象类
+
+
+
+
+ 请求ID
+
+
+
+
+ 群号
+
+
+
+
+ 群名称
+
+
+
+
+ 是否已处理
+
+
+
+
+ 处理者,未处理是0
+
+
+
+
+ 群系统消息 - 邀请消息列表 抽象类
+
+
+
+
+ 邀请者
+
+
+
+
+ 邀请者昵称
+
+
+
+
+ 群系统消息 - 进群消息列表 抽象类
+
+
+
+
+ 请求者
+
+
+
+
+ 请求者昵称
+
+
+
+
+ 验证信息
+
+
+
+
+ 消息 抽象类
+
+
+
+
+ 匿名信息
+
+
+
+
+ 字体
+
+
+
+
+ 群号
+
+
+
+
+ 消息内容
+
+
+
+
+ 原始消息内容
+
+
+
+
+ 消息ID
+
+
+
+
+ 消息序号
+
+
+
+
+ 消息类型
+
+
+
+
+ 消息事件主类型
+
+
+
+
+ 消息事件子类型
+
+
+
+
+ 收到事件的机器人QQ号
+
+
+
+
+ 发送者
+
+
+
+
+ 消息时间戳
+
+
+
+
+ 发送者QQ号
+
+
+
+
+ OCR结果信息 抽象类
+
+
+
+
+ 文本
+
+
+
+
+ 置信度
+
+
+
+
+ 坐标
+
+
+
+
+ 运行统计 抽象类
+
+
+
+
+ 收到的数据包总数
+
+
+
+
+ 发送的数据包总数
+
+
+
+
+ 数据包丢失总数
+
+
+
+
+ 接受信息总数
+
+
+
+
+ 发送信息总数
+
+
+
+
+ TCP 链接断开次数
+
+
+
+
+ 账号掉线次数
+
+
+
+
+ 提供用于描述匿名信息的基础类, 该类是抽象的
+
+
+
+
+ 匿名用户 ID
+
+
+
+
+ 匿名用户名称
+
+
+
+
+ 匿名用户 flag, 在调用禁言 API 时需要传入
+
+
+
+
+ 初始化 类的新实例
+
+ 匿名用户 ID
+ 匿名用户名称
+ 匿名用户 flag, 在调用禁言 API 时需要传入
+
+
+
+ 好友 抽象类
+
+
+
+
+ QQ号
+
+
+
+
+ 昵称
+
+
+
+
+ 备注
+
+
+
+
+ 提供用于描述发送者信息的基础类, 该类是抽象的
+
+
+
+
+ 发送者 QQ 号
+
+
+
+
+ 昵称
+
+
+
+
+ 性别
+
+
+
+
+ 年龄
+
+
+
+
+ 群名片/备注
+
+
+
+
+ 地区
+
+
+
+
+ 成员等级
+
+
+
+
+ 角色
+
+
+
+
+ 专属头衔
+
+
+
+
+ 初始化 类的新实例
+
+ 发送者 QQ 号
+ 昵称
+ 群名片/备注
+ 性别
+ 年龄
+ 地区
+ 成员等级
+ 角色
+ 专属头衔
+
API 类
@@ -14,6 +619,11 @@
任务队列
+
+
+ 获取API实例
+
+
构建函数
@@ -24,7 +634,7 @@
发送私聊消息
- 接受者QQ号
+ 接受者QQ号
信息内容
是否转义默认:false
返回消息ID,错误返回-1
@@ -52,7 +662,7 @@
信息内容
信息类型私聊:private群聊:group
- QQ号
+ QQ号
群号
是否转义默认:false
错误返回-1,成功返回信息ID
@@ -89,7 +699,7 @@
群组踢人
群号
- QQ号
+ QQ号
是否自动拒绝此人加群申请默认:false
@@ -97,10 +707,10 @@
群组单人禁言
群号
- QQ号
+ QQ号
禁言时间,单位秒默认:30分钟(1800秒)
-
+
群组匿名用户禁言
@@ -121,7 +731,7 @@
设置群管理员
群号
- QQ号
+ QQ号
是否设置为管理员默认:true
@@ -129,7 +739,7 @@
设置群名片
群号
- QQ号
+ QQ号
群名片内容默认:null(删除群名片)
@@ -151,7 +761,7 @@
设置群组专属头衔
群号
- QQ号
+ QQ号
群名片内容默认:null(删除群名片)
专属头衔有效期, 单位秒, 不过此项似乎没有效果, 可能是只有某些特殊的时间长度有效, 有待测试默认:-1(永久)
@@ -182,7 +792,7 @@
获取陌生人信息
- QQ号
+ QQ号
是否使用缓存,使用缓存响应快但是可能更新不及时默认:false
错误返回null,成功返回JObject
@@ -211,7 +821,7 @@
获取群成员信息
群号
- QQ号
+ QQ号
是否使用缓存,使用缓存响应快但是可能更新不及时默认:false
错误返回null,成功返回JObject
@@ -346,7 +956,7 @@
获取VIP信息
- QQ号
+ QQ号
错误返回null,成功返回JObject
@@ -695,178 +1305,38 @@
- 请求事件
-
-
-
-
- 事件类
-
-
-
-
- 元事件 - 生命周期
-
- 生命周期事件参数
-
-
-
- 元事件 - 心跳
-
- 心跳事件参数
-
-
-
- 消息事件 - 私聊消息
-
- 私聊消息参数
-
-
-
- 消息事件 - 群消息
-
- 群消息参数
-
-
-
- 请求事件 - 好友请求
-
- 好友请求参数
-
-
-
- 请求事件 - 群请求
-
- 群请求参数
-
-
-
- 通知事件 - 群文件上传
-
- 群文件上传参数
-
-
-
- 通知事件 - 群管理员变动
-
- 群管理员变动参数
-
-
-
- 通知事件 - 群成员减少
-
- 群成员减少参数
-
-
-
- 通知事件 - 群成员增加
-
- 群成员增加参数
-
-
-
- 通知事件 - 群禁言
-
- 群禁言参数
-
-
-
- 通知事件 - 好友添加
-
- 好友添加参数
-
-
-
- 通知事件 - 群消息撤回
-
- 群消息撤回参数
-
-
-
- 通知事件 - 好友消息撤回
-
- 好友消息撤回参数
-
-
-
- 通知事件 - 群内戳一戳
-
- 群内戳一戳参数
-
-
-
- 通知事件 - 好友戳一戳
-
- 群内戳一戳参数
-
-
-
- 通知事件 - 群红包运气王提示
-
- 群红包运气王提示参数
-
-
-
- 通知事件 - 群成员荣誉变更提示
-
- 群成员荣誉变更提示参数
-
-
-
- 通知事件 - 群成员名片更新(核验)
-
- 群成员名片更新(核验)参数
-
-
-
- 通知事件 - 接收到离线文件
-
- 接收到离线文件参数
-
-
-
- 通知事件 - 其他客户端在线状态变更
-
- 其他客户端在线状态变更参数
-
-
-
- 通知事件 - 精华消息变更
+ 请求事件
- 精华消息变更参数
-
+
- 请勿使用,用于子事件分发
+ 表示日志信息等级的枚举
-
+
- 提供用于描述匿名信息的基础类, 该类是抽象的
+ 表示输出日志的等级是 "调试" 级别
-
+
- 匿名用户 ID
+ 表示输出日志的等级是 "信息" 级别
-
+
- 匿名用户名称
+ 表示输出日志的等级是 "警告" 级别
-
+
- 匿名用户 flag, 在调用禁言 API 时需要传入
+ 表示输出日志的等级是 "错误" 级别
-
+
- 初始化 类的新实例
+ 表示不输出日志
- 匿名用户 ID
- 匿名用户名称
- 匿名用户 flag, 在调用禁言 API 时需要传入
@@ -896,37 +1366,9 @@
收到事件的机器人QQ号
上报类型
-
-
- 提供用于描述事件参数的基础类, 该类是抽象的
-
-
-
-
- 客户端ID
-
-
-
-
- 设备名称
-
-
-
-
- 设备类型
-
-
-
-
- 初始化 类的新实例
-
- 客户端ID
- 设备名称
- 设备类型
-
- 提供用于描述匿名信息的基础类, 该类是抽象的
+ 提供用于描述文件数据的基础类, 该类是抽象的
@@ -964,70 +1406,6 @@
下载链接
busid ( 目前不清楚有什么作用 )
-
-
- 提供用于描述发送者信息的基础类, 该类是抽象的
-
-
-
-
- 发送者 QQ 号
-
-
-
-
- 昵称
-
-
-
-
- 性别
-
-
-
-
- 年龄
-
-
-
-
- 群名片/备注
-
-
-
-
- 地区
-
-
-
-
- 成员等级
-
-
-
-
- 角色
-
-
-
-
- 专属头衔
-
-
-
-
- 初始化 类的新实例
-
- 发送者 QQ 号
- 昵称
- 群名片/备注
- 性别
- 年龄
- 地区
- 成员等级
- 角色
- 专属头衔
-
提供用于描述消息事件中群聊消息事件参数的类
@@ -1043,7 +1421,7 @@
匿名消息
-
+
初始化 类的新实例
@@ -1106,7 +1484,7 @@
发送者信息
-
+
初始化 类的新实例
@@ -1127,7 +1505,7 @@
提供用于描述消息事件中私聊消息事件参数的类
-
+
初始化 类的新实例
@@ -1223,7 +1601,7 @@
当前是否在线
-
+
初始化 类的新实例
@@ -1784,6 +2162,186 @@
异常 类 -- 关于WebSocket异常
+
+
+ 事件类
+
+
+
+
+ 元事件 - 生命周期
+
+ 生命周期事件参数
+
+
+
+ 元事件 - 心跳
+
+ 心跳事件参数
+
+
+
+ 消息事件 - 私聊消息
+
+ 私聊消息参数
+
+
+
+ 消息事件 - 群消息
+
+ 群消息参数
+
+
+
+ 请求事件 - 好友请求
+
+ 好友请求参数
+
+
+
+ 请求事件 - 群请求
+
+ 群请求参数
+
+
+
+ 通知事件 - 群文件上传
+
+ 群文件上传参数
+
+
+
+ 通知事件 - 群管理员变动
+
+ 群管理员变动参数
+
+
+
+ 通知事件 - 群成员减少
+
+ 群成员减少参数
+
+
+
+ 通知事件 - 群成员增加
+
+ 群成员增加参数
+
+
+
+ 通知事件 - 群禁言
+
+ 群禁言参数
+
+
+
+ 通知事件 - 好友添加
+
+ 好友添加参数
+
+
+
+ 通知事件 - 群消息撤回
+
+ 群消息撤回参数
+
+
+
+ 通知事件 - 好友消息撤回
+
+ 好友消息撤回参数
+
+
+
+ 通知事件 - 群内戳一戳
+
+ 群内戳一戳参数
+
+
+
+ 通知事件 - 好友戳一戳
+
+ 群内戳一戳参数
+
+
+
+ 通知事件 - 群红包运气王提示
+
+ 群红包运气王提示参数
+
+
+
+ 通知事件 - 群成员荣誉变更提示
+
+ 群成员荣誉变更提示参数
+
+
+
+ 通知事件 - 群成员名片更新(核验)
+
+ 群成员名片更新(核验)参数
+
+
+
+ 通知事件 - 接收到离线文件
+
+ 接收到离线文件参数
+
+
+
+ 通知事件 - 其他客户端在线状态变更
+
+ 其他客户端在线状态变更参数
+
+
+
+ 通知事件 - 精华消息变更
+
+ 精华消息变更参数
+
+
+
+ 请勿使用,用于子事件分发
+
+
+
+
+ 彩色日志输出类
+
+
+
+
+ 日志级别设定默认 Info
+
+
+
+
+ 输出一个等级为 调试 的信息
+
+ 要输出的信息
+ 输出的方法名,可选传入
+
+
+
+ 输出一个等级为 信息 的信息
+
+ 要输出的信息
+ 输出的方法名,可选传入
+
+
+
+ 输出一个等级为 警告 的信息
+
+ 要输出的信息
+ 输出的方法名,可选传入
+
+
+
+ 输出一个等级为 错误 的信息
+
+ 要输出的信息
+ 输出的方法名,可选传入
+
通用方法 类
@@ -1794,7 +2352,7 @@
通过 枚举Description 转为枚举
枚举
- 需要转换的Description
+ 需要转换的Description
返回该枚举
@@ -1815,14 +2373,14 @@
WebSocket 基础类
-
+
- Websocket句柄
+ 客户端创建 抽象方法
-
+
- 事件钩子
+ 客户端销毁 抽象方法
@@ -1839,8 +2397,19 @@
- WebSocket服务端地址请记得带端口号
+ WebSocket服务端地址
+
+
+
+
+ WebSocket服务端端口号
+
+
+
+
+ 创建一个 实例
+ 重写后的事件类实例
@@ -1863,6 +2432,12 @@
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/EventArgs/Basic/File.cs b/AuroraNative/EventArgs/Basic/File.cs
index d0eb1d2..db42ca3 100644
--- a/AuroraNative/EventArgs/Basic/File.cs
+++ b/AuroraNative/EventArgs/Basic/File.cs
@@ -3,7 +3,7 @@
namespace AuroraNative.EventArgs
{
///
- /// 提供用于描述匿名信息的基础类, 该类是抽象的
+ /// 提供用于描述文件数据的基础类, 该类是抽象的
///
public sealed class File
{
diff --git a/AuroraNative/README.md b/AuroraNative/README.md
deleted file mode 100644
index e69de29..0000000
diff --git a/AuroraNative/Event.cs b/AuroraNative/Utils/Event.cs
similarity index 89%
rename from AuroraNative/Event.cs
rename to AuroraNative/Utils/Event.cs
index 186fe40..57ececb 100644
--- a/AuroraNative/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 @@ public void RouterNotify(JObject Json)
#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
new file mode 100644
index 0000000..20a93cb
--- /dev/null
+++ b/AuroraNative/Utils/Logger.cs
@@ -0,0 +1,104 @@
+using System;
+
+namespace AuroraNative
+{
+ ///
+ /// 彩色日志输出类
+ ///
+ public static class Logger
+ {
+ #region --属性--
+
+ ///
+ /// 日志级别设定默认 Info
+ ///
+ public static LogLevel LogLevel = LogLevel.Info;
+
+ #endregion
+
+ #region --公开函数--
+
+ ///
+ /// 输出一个等级为 调试 的信息
+ ///
+ /// 要输出的信息
+ /// 输出的方法名,可选传入
+ public static void Debug(string Message, string MethodName = null)
+ {
+ if (LogLevel <= LogLevel.Debug)
+ {
+ Output(Message, ConsoleColor.Gray, LogLevel.Debug, MethodName, true);
+ }
+ }
+
+ ///
+ /// 输出一个等级为 信息 的信息
+ ///
+ /// 要输出的信息
+ /// 输出的方法名,可选传入
+ public static void Info(string Message, string MethodName = null)
+ {
+ if (LogLevel <= LogLevel.Info)
+ {
+ Output(Message, ConsoleColor.White, LogLevel.Info, MethodName);
+ }
+ }
+
+ ///
+ /// 输出一个等级为 警告 的信息
+ ///
+ /// 要输出的信息
+ /// 输出的方法名,可选传入
+ public static void Warning(string Message, string MethodName = null)
+ {
+ if (LogLevel <= LogLevel.Warning)
+ {
+ Output(Message, ConsoleColor.Yellow, LogLevel.Warning, MethodName);
+ }
+ }
+
+ ///
+ /// 输出一个等级为 错误 的信息
+ ///
+ /// 要输出的信息
+ /// 输出的方法名,可选传入
+ public static void Error(string Message, string MethodName = null)
+ {
+ if (LogLevel <= LogLevel.Error)
+ {
+ Output(Message, ConsoleColor.Red, LogLevel.Error, MethodName);
+ }
+ }
+
+ #endregion
+
+ #region --私有函数--
+
+ internal static void Output(string Message, ConsoleColor Color, LogLevel Level, string MethodName, bool IsFine = false)
+ {
+ Console.ForegroundColor = Color;
+ string NowTime;
+
+ if (!IsFine)
+ {
+ NowTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
+ }
+ else
+ {
+ 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
+ }
+}
diff --git a/AuroraNative/Utils.cs b/AuroraNative/Utils/Utils.cs
similarity index 90%
rename from AuroraNative/Utils.cs
rename to AuroraNative/Utils/Utils.cs
index 3bbf6d0..b16bef7 100644
--- a/AuroraNative/Utils.cs
+++ b/AuroraNative/Utils/Utils.cs
@@ -13,21 +13,21 @@ public class Utils
/// 通过 枚举Description 转为枚举
///
/// 枚举
- /// 需要转换的Description
+ /// 需要转换的Description
/// 返回该枚举
- public static T GetEnumByDescription(string description) where T : Enum
+ public static T GetEnumByDescription(string Description) where T : Enum
{
System.Reflection.FieldInfo[] fields = typeof(T).GetFields();
foreach (System.Reflection.FieldInfo field in fields)
{
object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
- if (objs.Length > 0 && (objs[0] as DescriptionAttribute).Description == description)
+ if (objs.Length > 0 && (objs[0] as DescriptionAttribute).Description == Description)
{
return (T)field.GetValue(null);
}
}
- throw new ArgumentException(string.Format("{0} 未能找到对应的枚举.", description), "Description");
+ throw new ArgumentException(string.Format("{0} 未能找到对应的枚举.", Description), nameof(Description));
}
///
diff --git a/AuroraNative/WebSockets/BaseWebSocket.cs b/AuroraNative/WebSockets/BaseWebSocket.cs
index 4c14c56..0bac87f 100644
--- a/AuroraNative/WebSockets/BaseWebSocket.cs
+++ b/AuroraNative/WebSockets/BaseWebSocket.cs
@@ -17,40 +17,59 @@ public abstract class BaseWebSocket
{
#region --变量--
- ///
- /// Websocket句柄
- ///
+ internal int Port = 6700;
internal WebSocket WebSocket;
- ///
- /// 事件钩子
- ///
- public Event EventHook;
-
+ 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)
{
- WebSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(Json, Formatting.None))), WebSocketMessageType.Text, true, CancellationToken.None);
+ try
+ {
+ WebSocket.SendAsync(new ArraySegment(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(Json, Formatting.None))), WebSocketMessageType.Text, true, CancellationToken.None);
+ }
+ catch (Exception e)
+ {
+ Logger.Error("调用API出现未知错误!\n" + e.Message, $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ }
}
internal async Task GetEventAsync()
{
- ArraySegment BytesReceived = new ArraySegment(new byte[5120]);
+ ArraySegment BytesReceived = new ArraySegment(new byte[10240]);
WebSocketReceiveResult Result = await WebSocket.ReceiveAsync(BytesReceived, CancellationToken.None);
- Json = JObject.Parse(Encoding.UTF8.GetString(BytesReceived.Array, 0, Result.Count));
+ if (Result.Count == 0) {return;}
+ Json = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(BytesReceived.Array, 0, Result.Count));
if (Json.TryGetValue("echo", out JToken Token))
{
- Api.TaskList[Json["echo"].ToString()] = Json;
+ if (Json.TryGetValue("status", out JToken Cache) && Cache.ToString() != "ok") {
+ Logger.Warning(Json.ToString(), $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ }
+
+ Api.TaskList[Token.ToString()] = Json;
}
else
{
@@ -64,7 +83,7 @@ internal async Task GetEventAsync()
{
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 812510f..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,24 +15,46 @@ public class Client : BaseWebSocket
{
#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();
- }
+ ///
+ /// 创建一个 实例
+ ///
+ /// 重写后的事件类实例
+ public Client(Event Event) => EventHook = Event;
#endregion
@@ -41,31 +63,69 @@ static Client()
///
/// 创建并连接到WebSocket服务器
///
- public void Create()
+ public override void Create()
{
- WebSocket = new ClientWebSocket();
- Task Connect = ((ClientWebSocket)WebSocket).ConnectAsync(new Uri("ws://" + Host + "/"), CancellationToken.None);
- Connect.Wait();
- if (WebSocket.State == WebSocketState.Open)
+ 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++)
{
- Task.Run(Feedback);
+ try
+ {
+ WebSocket = new ClientWebSocket();
+ if (WebSocket is ClientWebSocket socket)
+ {
+ 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)
+ {
+ Logger.Info("已连接至 go-cqhttp 服务器!");
+ Logger.Debug("防止由于go-cqhttp未初始化异常,连接后需等待2秒...");
+ Thread.Sleep(2000);
+ Logger.Debug("go-cqhttp 初始化完毕!");
+ Task.Run(Feedback);
+ Api.Create(this);
+ return;
+ }
+ }
+ }
+ catch (AggregateException)
+ {
+ Logger.Warning($"连接到 go-cqhttp 服务器失败!五秒后重试(重试次数:{i})...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ Thread.Sleep(5000);
+ }
}
+ Logger.Error("连接到 go-cqhttp 服务器失败!请检查IP是否正确(需要携带端口号)或确认服务器是否启动和初始化完毕!", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
}
///
/// 立刻中断并释放连接注意!断开后需要重新Create
///
- public void Dispose()
+ public override void Dispose()
{
- WebSocket.Dispose();
- WebSocket.Abort();
+ Logger.Debug($"准备销毁正向WebSocket...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ try
+ {
+ WebSocket.Dispose();
+ WebSocket.Abort();
+ Api.Destroy();
+ Logger.Info("已销毁正向WebSocket");
+ }
+ catch (Exception e)
+ {
+ Logger.Error("销毁正向WebSocket失败!\n" + e.Message, $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ }
}
#endregion
#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 87f1f77..ef5a104 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 @@ public class Server : BaseWebSocket
{
#region --变量--
- private string Port = "6700";
///
/// WebSocket监听端口
///
- public string port
+ public int port
{
private get { return Port; }
set { Port = value; }
@@ -33,10 +31,11 @@ public string port
#region --构造函数--
- static Server()
- {
- AttributeTypes = Assembly.GetExecutingAssembly().GetTypes().Where(p => p.IsAbstract == false && p.IsInterface == false && typeof(Attribute).IsAssignableFrom(p)).ToArray();
- }
+ ///
+ /// 创建一个 实例
+ ///
+ /// 重写后的事件类实例
+ public Server(Event Event) => EventHook = Event;
#endregion
@@ -45,47 +44,80 @@ static Server()
///
/// 创建WebSocket服务器并监听端口
///
- public void Create()
+ public override void Create()
{
- Listener = new HttpListener();
- Listener.Prefixes.Add("http://*:" + Port + "/");
- Listener.Start();
- Task.Run(Feedback);
- while (!IsConnect)
+ try
+ {
+ Logger.Debug("反向WebSocket已创建,准备监听...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ Listener = new HttpListener();
+ Listener.Prefixes.Add("http://*:" + Port.ToString() + "/");
+ Listener.Start();
+ Logger.Info("开始监听来自 go-cqhttp 客户端的连接...");
+ Task.Run(Feedback);
+ while (!IsConnect)
+ {
+ Thread.Sleep(100);
+ }
+ }
+ catch (HttpListenerException)
{
- Thread.Sleep(100);
+ Logger.Error("无法启动监听服务器,请确保使用管理员权限运行。否则无法监听!", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ Console.ReadKey();
+ Environment.Exit(0);
}
}
///
/// 立刻中断并释放连接注意!断开后需要重新Create
///
- public void Dispose()
+ public override void Dispose()
{
- Listener.Stop();
- WebSocket.Dispose();
- WebSocket.Abort();
+ Logger.Debug($"准备销毁反向WebSocket...", $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ try
+ {
+ Listener.Stop();
+ WebSocket.Dispose();
+ WebSocket.Abort();
+ Api.Destroy();
+ Logger.Info("已销毁反向WebSocket");
+ }
+ catch (Exception e)
+ {
+ Logger.Error("销毁反向WebSocket失败!\n" + e.Message, $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ }
}
#endregion
#region --私有函数--
- private async void Feedback()
+ internal override async void Feedback()
{
while (true)
{
- HttpListenerContext Context = await Listener.GetContextAsync();
- if (Context.Request.IsWebSocketRequest)
+ try
{
- HttpListenerWebSocketContext SocketContext = await Context.AcceptWebSocketAsync(null);
- WebSocket = SocketContext.WebSocket;
- IsConnect = true;
- while (WebSocket.State == WebSocketState.Open)
+ HttpListenerContext Context = await Listener.GetContextAsync();
+ if (Context.Request.IsWebSocketRequest)
{
- await GetEventAsync();
+ Logger.Info("收到来自 go-cqhttp 客户端的连接!连接已建立!");
+ HttpListenerWebSocketContext SocketContext = await Context.AcceptWebSocketAsync(null);
+ WebSocket = SocketContext.WebSocket;
+ Logger.Debug("防止由于go-cqhttp未初始化异常,连接后需等待5秒...");
+ Thread.Sleep(5000);
+ Logger.Debug("go-cqhttp 初始化完毕!");
+ IsConnect = true;
+ Api.Create(this);
+ while (WebSocket.State == WebSocketState.Open)
+ {
+ await GetEventAsync();
+ }
}
}
+ catch (Exception e)
+ {
+ Logger.Error("反向WebSocket出现未知错误!\n" + e.Message, $"{MethodBase.GetCurrentMethod().DeclaringType.Name}.{MethodBase.GetCurrentMethod().Name}");
+ }
}
}
diff --git a/README.md b/README.md
index cc619c7..8fb50fd 100644
--- a/README.md
+++ b/README.md
@@ -39,9 +39,15 @@
- 优化内部算法或修改类型(如将返回的JObject类型抽象为新自定义类型) - vX.X.X+1
- 重命名/删除/新增 文件/命名空间/API - vX.X+1.X
+## 文档
+
+开发文档:[点我查看](https://auroranative.mikuy.cn)
+
+> 开发文档是与框架一起更新的,因此文档也处于快速迭代状态。
+
## 兼容性
-### 接口
+### 通讯方式
- [ ] HTTP API
- [ ] 反向 HTTP POST
@@ -50,7 +56,7 @@
## 关于 ISSUE
-如果没有大问题请到 Discussions 处提问
+如果没有大问题请到 [Discussions](https://github.com/timi137137/AuroraNative/discussions) 处提问
以下 ISSUE 会被直接关闭
@@ -69,4 +75,4 @@
### 使用到的开源库
-[Newtonsoft.Json](https://www.newtonsoft.com/json)
+[Newtonsoft.Json](https://www.newtonsoft.com/json) | [Microsoft.Extensions.Caching.Memory](https://www.nuget.org/packages/Microsoft.Extensions.Caching.Memory/5.0.0)