diff --git a/LOG/log.go b/LOG/log.go index 4bb9f23..e92c112 100644 --- a/LOG/log.go +++ b/LOG/log.go @@ -1,40 +1,153 @@ package LOG import ( + "context" "fmt" + "github.com/cloudwego/hertz/pkg/common/hlog" + "io" "log" "runtime" ) -func DEBUG(text string, msg ...interface{}) { +func Trace(text string, msg ...interface{}) { pc, file, line, ok := runtime.Caller(3) if !ok { pc, file, line, ok = runtime.Caller(2) } if ok { funcName := runtime.FuncForPC(pc).Name() - log.Printf("[DEBUG] [%s:%d %s()] %s\n", file, line, funcName, fmt.Sprintf(text, msg...)) + log.Printf("[Trace] [%s:%d %s()] %s\n", file, line, funcName, fmt.Sprintf(text, msg...)) } else { - log.Printf("[DEBUG] %s\n", fmt.Sprintf(text, msg...)) + log.Printf("[Trace] %s\n", fmt.Sprintf(text, msg...)) } } -func INFO(text string, msg ...interface{}) { - msgText := fmt.Sprintf(text, msg...) - log.Println("[INFO] ", msgText) +func Debug(text string, msg ...interface{}) { + log.Printf("[Debug] %s\n", fmt.Sprintf(text, msg...)) } -func WARN(text string, msg ...interface{}) { +func Info(text string, msg ...interface{}) { msgText := fmt.Sprintf(text, msg...) - log.Println("[WARN] ", msgText) + log.Println("[Info] ", msgText) } -func ERROR(text string, msg ...interface{}) { +func Notice(text string, msg ...interface{}) { msgText := fmt.Sprintf(text, msg...) - log.Println("[ERROR] ", msgText) + log.Println("[Notice]", msgText) } -func FATAL(text string, msg ...interface{}) { +func Warn(text string, msg ...interface{}) { msgText := fmt.Sprintf(text, msg...) - log.Fatalln("[FATAL] ", msgText) + log.Println("[Warn] ", msgText) +} + +func Error(text string, msg ...interface{}) { + msgText := fmt.Sprintf(text, msg...) + log.Println("[Error] ", msgText) +} + +func Fatal(text string, msg ...interface{}) { + msgText := fmt.Sprintf(text, msg...) + log.Fatalln("[Fatal] ", msgText) +} + +// CustomLogger 是一个实现了 hlog.Logger 接口的自定义日志记录器 +type CustomLogger struct{} + +func (c *CustomLogger) Trace(v ...interface{}) { + Trace(fmt.Sprint(v...)) +} + +func (c *CustomLogger) Debug(v ...interface{}) { + Debug(fmt.Sprint(v...)) +} + +func (c *CustomLogger) Info(v ...interface{}) { + Info(fmt.Sprint(v...)) +} + +func (c *CustomLogger) Notice(v ...interface{}) { + Info(fmt.Sprint(v...)) +} + +func (c *CustomLogger) Warn(v ...interface{}) { + Warn(fmt.Sprint(v...)) +} + +func (c *CustomLogger) Error(v ...interface{}) { + Error(fmt.Sprint(v...)) +} + +func (c *CustomLogger) Fatal(v ...interface{}) { + Fatal(fmt.Sprint(v...)) +} + +func (c *CustomLogger) CtxTracef(ctx context.Context, format string, v ...interface{}) { + +} + +func (c *CustomLogger) CtxDebugf(ctx context.Context, format string, v ...interface{}) { + +} + +func (c *CustomLogger) CtxInfof(ctx context.Context, format string, v ...interface{}) { + +} + +func (c *CustomLogger) CtxNoticef(ctx context.Context, format string, v ...interface{}) { + +} + +func (c *CustomLogger) CtxWarnf(ctx context.Context, format string, v ...interface{}) { + +} + +func (c *CustomLogger) CtxErrorf(ctx context.Context, format string, v ...interface{}) { + +} + +func (c *CustomLogger) CtxFatalf(ctx context.Context, format string, v ...interface{}) { + +} + +func (c *CustomLogger) SetLevel(level hlog.Level) { + +} + +func (c *CustomLogger) SetOutput(writer io.Writer) { + +} + +// Tracef 实现 hlog.Logger 接口的 Tracef 方法 +func (c *CustomLogger) Tracef(format string, args ...interface{}) { + Trace(format, args...) +} + +// Debugf 实现 hlog.Logger 接口的 Debugf 方法 +func (c *CustomLogger) Debugf(format string, args ...interface{}) { + Debug(format, args...) +} + +// Infof 实现 hlog.Logger 接口的 Infof 方法 +func (c *CustomLogger) Infof(format string, args ...interface{}) { + Info(format, args...) +} + +// Warnf 实现 hlog.Logger 接口的 Warnf 方法 +func (c *CustomLogger) Warnf(format string, args ...interface{}) { + Warn(format, args...) +} + +// Errorf 实现 hlog.Logger 接口的 Errorf 方法 +func (c *CustomLogger) Errorf(format string, args ...interface{}) { + Error(format, args...) +} + +// Fatalf 实现 hlog.Logger 接口的 Fatalf 方法 +func (c *CustomLogger) Fatalf(format string, args ...interface{}) { + Fatal(format, args...) +} + +func (c *CustomLogger) Noticef(format string, args ...interface{}) { + Info(format, args...) } diff --git a/core/api.go b/core/api.go index e4ed3bf..5c144b7 100644 --- a/core/api.go +++ b/core/api.go @@ -5,6 +5,7 @@ import ( "ProjectWIND/wba" "crypto/rand" "fmt" + "strings" ) type apiInfo struct{} @@ -23,8 +24,8 @@ type apiInfo struct{} //1.无响应API,使用ws协议处理 -// SendMsg 发送消息(自动判断消息类型) -func (a *apiInfo) SendMsg(messageType string, groupId int64, userId int64, message string, autoEscape bool) { +// UnsafelySendMsg 发送消息(自动判断消息类型) +func (a *apiInfo) UnsafelySendMsg(messageType string, groupId int64, userId int64, message string, autoEscape bool) { // 构建发送消息的JSON数据 var messageData wba.APIRequestInfo messageData.Action = "send_msg" @@ -41,7 +42,7 @@ func (a *apiInfo) SendMsg(messageType string, groupId int64, userId int64, messa } default: { - LOG.ERROR("发送消息(SendMsg)时,消息类型错误: %v", messageType) + LOG.Error("发送消息(UnsafelySendMsg)时,消息类型错误: %v", messageType) } } messageData.Params.Message = message @@ -49,15 +50,15 @@ func (a *apiInfo) SendMsg(messageType string, groupId int64, userId int64, messa // 发送消息 _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("发送消息时,发送失败: %v", err) + LOG.Error("发送消息时,发送失败: %v", err) return } - LOG.INFO("发送消息(SendMsg)(至:%v-%v:%v):%v", messageType, groupId, userId, message) + LOG.Info("发送消息(UnsafelySendMsg)(至:%v-%v:%v):%v", messageType, groupId, userId, message) return } -// SendPrivateMsg 发送私聊消息 -func (a *apiInfo) SendPrivateMsg(userId int64, message string, autoEscape bool) { +// UnsafelySendPrivateMsg 发送私聊消息 +func (a *apiInfo) UnsafelySendPrivateMsg(userId int64, message string, autoEscape bool) { // 构建发送消息的JSON数据 var messageData wba.APIRequestInfo messageData.Action = "send_private_msg" @@ -67,15 +68,15 @@ func (a *apiInfo) SendPrivateMsg(userId int64, message string, autoEscape bool) // 发送消息 _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("发送私聊消息(SendPrivateMsg)时,发送失败: %v", err) + LOG.Error("发送私聊消息(UnsafelySendPrivateMsg)时,发送失败: %v", err) return } - LOG.INFO("发送私聊消息(SendPrivateMsg)(至:%v):%v", userId, message) + LOG.Info("发送私聊消息(UnsafelySendPrivateMsg)(至:%v):%v", userId, message) return } -// SendGroupMsg 发送群消息 -func (a *apiInfo) SendGroupMsg(groupId int64, message string, autoEscape bool) { +// UnsafelySendGroupMsg 发送群消息 +func (a *apiInfo) UnsafelySendGroupMsg(groupId int64, message string, autoEscape bool) { // 构建发送消息的JSON数据 var messageData wba.APIRequestInfo messageData.Action = "send_group_msg" @@ -85,15 +86,15 @@ func (a *apiInfo) SendGroupMsg(groupId int64, message string, autoEscape bool) { // 发送消息 _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("发送群消息(SendGroupMsg)时,发送失败: %v", err) + LOG.Error("发送群消息(UnsafelySendGroupMsg)时,发送失败: %v", err) return } - LOG.INFO("发送群消息(SendGroupMsg)(至:%v):%v", groupId, message) + LOG.Info("发送群消息(UnsafelySendGroupMsg)(至:%v):%v", groupId, message) return } -// ReplyMsg 回复消息(自动判断消息类型) -func (a *apiInfo) ReplyMsg(msg wba.MessageEventInfo, message string, autoEscape bool) { +// SendMsg 回复消息(自动判断消息类型) +func (a *apiInfo) SendMsg(msg wba.MessageEventInfo, message string, autoEscape bool) { // 构建发送消息的JSON数据 var messageData wba.APIRequestInfo @@ -113,7 +114,7 @@ func (a *apiInfo) ReplyMsg(msg wba.MessageEventInfo, message string, autoEscape } default: { - LOG.ERROR("回复消息(ReplyMsg)时,消息类型错误: %v", messageType) + LOG.Error("回复消息(SendMsg)时,消息类型错误: %v", messageType) } } messageData.Params.Message = message @@ -121,15 +122,15 @@ func (a *apiInfo) ReplyMsg(msg wba.MessageEventInfo, message string, autoEscape // 发送消息 _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("回复消息时,发送失败: %v", err) + LOG.Error("回复消息时,发送失败: %v", err) return } - LOG.INFO("回复消息(ReplyMsg)(至:%v-%v:%v-%v):%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, message) + LOG.Info("回复消息(SendMsg)(至:%v-%v:%v-%v):%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, message) return } -// ReplyPrivateMsg 回复私聊消息 -func (a *apiInfo) ReplyPrivateMsg(msg wba.MessageEventInfo, message string, autoEscape bool) { +// SendPrivateMsg 回复私聊消息 +func (a *apiInfo) SendPrivateMsg(msg wba.MessageEventInfo, message string, autoEscape bool) { // 构建发送消息的JSON数据 var messageData wba.APIRequestInfo messageData.Action = "send_private_msg" @@ -139,15 +140,15 @@ func (a *apiInfo) ReplyPrivateMsg(msg wba.MessageEventInfo, message string, auto // 发送消息 _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("回复消息(ReplyPrivateMsg)时,发送失败: %v", err) + LOG.Error("回复消息(SendPrivateMsg)时,发送失败: %v", err) return } - LOG.INFO("回复消息(ReplyPrivateMsg)(至:%v-%v:%v-%v):%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, message) + LOG.Info("回复消息(SendPrivateMsg)(至:%v-%v:%v-%v):%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, message) return } -// ReplyGroupMsg 回复群消息 -func (a *apiInfo) ReplyGroupMsg(msg wba.MessageEventInfo, message string, autoEscape bool) { +// SendGroupMsg 回复群消息 +func (a *apiInfo) SendGroupMsg(msg wba.MessageEventInfo, message string, autoEscape bool) { // 构建发送消息的JSON数据 var messageData wba.APIRequestInfo messageData.Action = "send_group_msg" @@ -157,10 +158,25 @@ func (a *apiInfo) ReplyGroupMsg(msg wba.MessageEventInfo, message string, autoEs // 发送消息 _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("回复消息(ReplyGroupMsg)时,发送失败: %v", err) + LOG.Error("回复消息(SendGroupMsg)时,发送失败: %v", err) return } - LOG.INFO("回复消息(ReplyGroupMsg)(至:%v-%v:%v-%v):%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, message) + LOG.Info("回复消息(SendGroupMsg)(至:%v-%v:%v-%v):%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, message) + return +} + +// UnsafelyDeleteMsg 撤回消息 +func (a *apiInfo) UnsafelyDeleteMsg(messageId int32) { + // 构建删除消息的JSON数据 + var messageData wba.APIRequestInfo + messageData.Action = "delete_msg" + messageData.Params.MessageId = messageId + _, err := wsAPI(messageData) + if err != nil { + LOG.Error("撤回消息(UnsafeDeleteMsg)时,发送失败: %v", err) + return + } + LOG.Info("撤回消息(UnsafeDeleteMsg):[id:%v]", messageId) return } @@ -172,10 +188,10 @@ func (a *apiInfo) DeleteMsg(msg wba.MessageEventInfo) { messageData.Params.MessageId = msg.MessageId _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("撤回消息(DeleteMsg)时,发送失败: %v", err) + LOG.Error("撤回消息(DeleteMsg)时,发送失败: %v", err) return } - LOG.INFO("撤回消息(DeleteMsg):[id:%v]%v", msg.MessageId, msg.RawMessage) + LOG.Info("撤回消息(DeleteMsg):[id:%v]%v", msg.MessageId, msg.RawMessage) return } @@ -188,10 +204,10 @@ func (a *apiInfo) SendLike(userId int64, times int) { messageData.Params.Times = times _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("发送赞(SendLike)时,发送失败: %v", err) + LOG.Error("发送赞(SendLike)时,发送失败: %v", err) return } - LOG.INFO("发送赞(SendLike)(至:%v):%v", userId, times) + LOG.Info("发送赞(SendLike)(至:%v):%v", userId, times) return } @@ -204,10 +220,10 @@ func (a *apiInfo) SetGroupKick(groupId int64, userId int64, rejectAddRequest boo messageData.Params.RejectAddRequest = rejectAddRequest _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("移出群聊(SetGroupKick)时,发送失败: %v", err) + LOG.Error("移出群聊(SetGroupKick)时,发送失败: %v", err) return } - LOG.INFO("移出群聊(SetGroupKick)(从:%v-%v):%v", groupId, userId, rejectAddRequest) + LOG.Info("移出群聊(SetGroupKick)(从:%v-%v):%v", groupId, userId, rejectAddRequest) return } @@ -220,10 +236,10 @@ func (a *apiInfo) SetGroupBan(groupId int64, userId int64, duration int32) { messageData.Params.Duration = duration _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("禁言群成员(SetGroupBan)时,执行失败: %v", err) + LOG.Error("禁言群成员(SetGroupBan)时,执行失败: %v", err) return } - LOG.INFO("禁言群成员(SetGroupBan)(在:%v-%v):%v", groupId, userId, duration) + LOG.Info("禁言群成员(SetGroupBan)(在:%v-%v):%v", groupId, userId, duration) return } @@ -235,10 +251,10 @@ func (a *apiInfo) SetGroupWholeBan(groupId int64, enable bool) { messageData.Params.Enable = enable _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("设置全员禁言(SetGroupWholeBan)时,执行失败: %v", err) + LOG.Error("设置全员禁言(SetGroupWholeBan)时,执行失败: %v", err) return } - LOG.INFO("设置全员禁言(SetGroupWholeBan)(在:%v):%v", groupId, enable) + LOG.Info("设置全员禁言(SetGroupWholeBan)(在:%v):%v", groupId, enable) return } @@ -251,10 +267,10 @@ func (a *apiInfo) SetGroupAdmin(groupId int64, userId int64, enable bool) { messageData.Params.Enable = enable _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("设置群管理员(SetGroupAdmin)时,执行失败: %v", err) + LOG.Error("设置群管理员(SetGroupAdmin)时,执行失败: %v", err) return } - LOG.INFO("设置群管理员(SetGroupAdmin)(在:%v-%v):%v", groupId, userId, enable) + LOG.Info("设置群管理员(SetGroupAdmin)(在:%v-%v):%v", groupId, userId, enable) return } @@ -267,10 +283,10 @@ func (a *apiInfo) SetGroupCard(groupId int64, userId int64, card string) { messageData.Params.Card = card _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("设置群名片(SetGroupCard)时,执行失败: %v", err) + LOG.Error("设置群名片(SetGroupCard)时,执行失败: %v", err) return } - LOG.INFO("设置群名片(SetGroupCard)(在:%v-%v):%v", groupId, userId, card) + LOG.Info("设置群名片(SetGroupCard)(在:%v-%v):%v", groupId, userId, card) return } @@ -282,10 +298,10 @@ func (a *apiInfo) SetGroupName(groupId int64, groupName string) { messageData.Params.GroupName = groupName _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("设置群名称(SetGroupName)时,执行失败: %v", err) + LOG.Error("设置群名称(SetGroupName)时,执行失败: %v", err) return } - LOG.INFO("设置群名称(SetGroupName)(在:%v):%v", groupId, groupName) + LOG.Info("设置群名称(SetGroupName)(在:%v):%v", groupId, groupName) return } @@ -297,27 +313,27 @@ func (a *apiInfo) SetGroupLeave(groupId int64, isDismiss bool) { messageData.Params.IsDismiss = isDismiss _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("退出群聊(SetGroupLeave)时,执行失败: %v", err) + LOG.Error("退出群聊(SetGroupLeave)时,执行失败: %v", err) return } - LOG.INFO("退出群聊(SetGroupLeave)(在:%v):%v", groupId, isDismiss) + LOG.Info("退出群聊(SetGroupLeave)(在:%v):%v", groupId, isDismiss) return } // SetGroupSpecialTitle 设置群专属头衔(需要群主权限) -func (a *apiInfo) SetGroupSpecialTitle(groupId int64, userId int64, specialTitle string, duration int32) { +func (a *apiInfo) SetGroupSpecialTitle(groupId int64, userId int64, specialTitle string) { var messageData wba.APIRequestInfo messageData.Action = "set_group_special_title" messageData.Params.GroupId = groupId messageData.Params.UserId = userId messageData.Params.SpecialTitle = specialTitle - messageData.Params.Duration = duration + messageData.Params.Duration = -1 _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("设置群特殊头衔(SetGroupSpecialTitle)时,执行失败: %v", err) + LOG.Error("设置群特殊头衔(SetGroupSpecialTitle)时,执行失败: %v", err) return } - LOG.INFO("设置群特殊头衔(SetGroupSpecialTitle)(在:%v-%v):%v-%v", groupId, userId, specialTitle, duration) + LOG.Info("设置群特殊头衔(SetGroupSpecialTitle)(在:%v-%v):%v-%v", groupId, userId, specialTitle) return } @@ -330,10 +346,10 @@ func (a *apiInfo) SetFriendAddRequest(flag string, approve bool, remark string) messageData.Params.Remark = remark _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("处理加好友请求(SetFriendAddRequest)时,执行失败: %v", err) + LOG.Error("处理加好友请求(SetFriendAddRequest)时,执行失败: %v", err) return } - LOG.INFO("处理加好友请求(SetFriendAddRequest)(在:%v):%v-%v-%v", flag, approve, remark) + LOG.Info("处理加好友请求(SetFriendAddRequest)(在:%v):%v-%v-%v", flag, approve, remark) return } @@ -347,10 +363,10 @@ func (a *apiInfo) SetGroupAddRequest(flag string, subType string, approve bool, messageData.Params.Reason = reason _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("处理加群请求/邀请(SetGroupAddRequest)时,执行失败: %v", err) + LOG.Error("处理加群请求/邀请(SetGroupAddRequest)时,执行失败: %v", err) return } - LOG.INFO("处理加群请求/邀请(SetGroupAddRequest)(在:%v-%v-%v):%v", flag, subType, approve, reason) + LOG.Info("处理加群请求/邀请(SetGroupAddRequest)(在:%v-%v-%v):%v", flag, subType, approve, reason) return } @@ -361,10 +377,10 @@ func (a *apiInfo) SetRestart(delay int32) { messageData.Params.Delay = delay _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("设置重启(SetRestart)时,执行失败: %v", err) + LOG.Error("设置重启(SetRestart)时,执行失败: %v", err) return } - LOG.INFO("设置重启(SetRestart):%v", delay) + LOG.Info("设置重启(SetRestart):%v", delay) return } @@ -374,10 +390,10 @@ func (a *apiInfo) CleanCache() { messageData.Action = "clean_cache" _, err := wsAPI(messageData) if err != nil { - LOG.ERROR("清理缓存(CleanCache)时,执行失败: %v", err) + LOG.Error("清理缓存(CleanCache)时,执行失败: %v", err) return } - LOG.INFO("清理缓存(CleanCache)") + LOG.Info("清理缓存(CleanCache)") return } @@ -385,18 +401,18 @@ func (a *apiInfo) CleanCache() { // GetLoginInfo 获取登录信息 func (a *apiInfo) GetLoginInfo() (Response wba.APIResponseInfo) { - LOG.INFO("获取登录信息(GetLoginInfo)") + LOG.Info("获取登录信息(GetLoginInfo)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_login_info" messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取登录信息(GetLoginInfo)时,生成UUID失败: %v", err) + LOG.Error("获取登录信息(GetLoginInfo)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取登录信息(GetLoginInfo)时,执行失败: %v", err) + LOG.Error("获取登录信息(GetLoginInfo)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -404,18 +420,18 @@ func (a *apiInfo) GetLoginInfo() (Response wba.APIResponseInfo) { // GetVersionInfo 获取协议信息 func (a *apiInfo) GetVersionInfo() (Response wba.APIResponseInfo) { - LOG.INFO("获取协议信息(GetVersionInfo)") + LOG.Info("获取协议信息(GetVersionInfo)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_version_info" messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取协议信息(GetVersionInfo)时,生成UUID失败: %v", err) + LOG.Error("获取协议信息(GetVersionInfo)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取登录信息(GetVersionInfo)时,执行失败: %v", err) + LOG.Error("获取登录信息(GetVersionInfo)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -423,19 +439,19 @@ func (a *apiInfo) GetVersionInfo() (Response wba.APIResponseInfo) { // GetMsg 获取消息 func (a *apiInfo) GetMsg(messageId int32) (Response wba.APIResponseInfo) { - LOG.INFO("获取消息(GetMsg)") + LOG.Info("获取消息(GetMsg)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_msg" messageData.Params.MessageId = messageId messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取消息(GetMsg)时,生成UUID失败: %v", err) + LOG.Error("获取消息(GetMsg)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取消息(GetMsg)时,执行失败: %v", err) + LOG.Error("获取消息(GetMsg)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -443,19 +459,19 @@ func (a *apiInfo) GetMsg(messageId int32) (Response wba.APIResponseInfo) { // GetForwardMsg 获取合并转发消息 func (a *apiInfo) GetForwardMsg(id string) (Response wba.APIResponseInfo) { - LOG.INFO("获取合并转发消息(GetForwardMsg)") + LOG.Info("获取合并转发消息(GetForwardMsg)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_forward_msg" messageData.Params.Id = id messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取合并转发消息(GetForwardMsg)时,生成UUID失败: %v", err) + LOG.Error("获取合并转发消息(GetForwardMsg)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取合并转发消息(GetForwardMsg)时,执行失败: %v", err) + LOG.Error("获取合并转发消息(GetForwardMsg)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -463,7 +479,7 @@ func (a *apiInfo) GetForwardMsg(id string) (Response wba.APIResponseInfo) { // GetStrangerInfo 获取陌生人信息 func (a *apiInfo) GetStrangerInfo(userId int64, noCache bool) (Response wba.APIResponseInfo) { - LOG.INFO("获取陌生人信息(GetStrangerInfo)") + LOG.Info("获取陌生人信息(GetStrangerInfo)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_stranger_info" @@ -471,12 +487,12 @@ func (a *apiInfo) GetStrangerInfo(userId int64, noCache bool) (Response wba.APIR messageData.Params.NoCache = noCache messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取陌生人信息(GetStrangerInfo)时,生成UUID失败: %v", err) + LOG.Error("获取陌生人信息(GetStrangerInfo)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取陌生人信息(GetStrangerInfo)时,执行失败: %v", err) + LOG.Error("获取陌生人信息(GetStrangerInfo)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -484,18 +500,18 @@ func (a *apiInfo) GetStrangerInfo(userId int64, noCache bool) (Response wba.APIR // GetFriendList 获取好友列表 func (a *apiInfo) GetFriendList() (Response wba.APIResponseInfo) { - LOG.INFO("获取好友列表(GetFriendList)") + LOG.Info("获取好友列表(GetFriendList)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_friend_list" messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取好友列表(GetFriendList)时,生成UUID失败: %v", err) + LOG.Error("获取好友列表(GetFriendList)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取好友列表(GetFriendList)时,执行失败: %v", err) + LOG.Error("获取好友列表(GetFriendList)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -503,18 +519,18 @@ func (a *apiInfo) GetFriendList() (Response wba.APIResponseInfo) { // GetGroupList 获取群列表 func (a *apiInfo) GetGroupList() (Response wba.APIResponseInfo) { - LOG.INFO("获取群列表(GetGroupList)") + LOG.Info("获取群列表(GetGroupList)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_group_list" messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取群列表(GetGroupList)时,生成UUID失败: %v", err) + LOG.Error("获取群列表(GetGroupList)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取群列表(GetGroupList)时,执行失败: %v", err) + LOG.Error("获取群列表(GetGroupList)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -522,7 +538,7 @@ func (a *apiInfo) GetGroupList() (Response wba.APIResponseInfo) { // GetGroupInfo 获取群信息 func (a *apiInfo) GetGroupInfo(groupId int64, noCache bool) (Response wba.APIResponseInfo) { - LOG.INFO("获取群信息(GetGroupInfo)") + LOG.Info("获取群信息(GetGroupInfo)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_group_info" @@ -530,12 +546,12 @@ func (a *apiInfo) GetGroupInfo(groupId int64, noCache bool) (Response wba.APIRes messageData.Params.NoCache = noCache messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取群信息(GetGroupInfo)时,生成UUID失败: %v", err) + LOG.Error("获取群信息(GetGroupInfo)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取群信息(GetGroupInfo)时,执行失败: %v", err) + LOG.Error("获取群信息(GetGroupInfo)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -543,7 +559,7 @@ func (a *apiInfo) GetGroupInfo(groupId int64, noCache bool) (Response wba.APIRes // GetGroupMemberInfo 获取群成员信息 func (a *apiInfo) GetGroupMemberInfo(groupId int64, userId int64, noCache bool) (Response wba.APIResponseInfo) { - LOG.INFO("获取群成员信息(GetGroupMemberInfo)") + LOG.Info("获取群成员信息(GetGroupMemberInfo)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_group_member_info" @@ -552,12 +568,12 @@ func (a *apiInfo) GetGroupMemberInfo(groupId int64, userId int64, noCache bool) messageData.Params.NoCache = noCache messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取群成员信息(GetGroupMemberInfo)时,生成UUID失败: %v", err) + LOG.Error("获取群成员信息(GetGroupMemberInfo)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取群成员信息(GetGroupMemberInfo)时,执行失败: %v", err) + LOG.Error("获取群成员信息(GetGroupMemberInfo)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -565,19 +581,19 @@ func (a *apiInfo) GetGroupMemberInfo(groupId int64, userId int64, noCache bool) // GetGroupMemberList 获取群成员列表 func (a *apiInfo) GetGroupMemberList(groupId int64) (Response wba.APIResponseInfo) { - LOG.INFO("获取群成员列表(GetGroupMemberList)") + LOG.Info("获取群成员列表(GetGroupMemberList)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_group_member_list" messageData.Params.GroupId = groupId messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取群成员列表(GetGroupMemberList)时,生成UUID失败: %v", err) + LOG.Error("获取群成员列表(GetGroupMemberList)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取群成员列表(GetGroupMemberList)时,执行失败: %v", err) + LOG.Error("获取群成员列表(GetGroupMemberList)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -585,7 +601,7 @@ func (a *apiInfo) GetGroupMemberList(groupId int64) (Response wba.APIResponseInf // GetGroupHonorInfo 获取群荣誉信息 func (a *apiInfo) GetGroupHonorInfo(groupId int64, Type string) (Response wba.APIResponseInfo) { - LOG.INFO("获取群荣誉信息(GetGroupHonorInfo)") + LOG.Info("获取群荣誉信息(GetGroupHonorInfo)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_group_honor_info" @@ -593,12 +609,12 @@ func (a *apiInfo) GetGroupHonorInfo(groupId int64, Type string) (Response wba.AP messageData.Params.Type = Type messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取群荣誉信息(GetGroupHonorInfo)时,生成UUID失败: %v", err) + LOG.Error("获取群荣誉信息(GetGroupHonorInfo)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取群荣誉信息(GetGroupHonorInfo)时,执行失败: %v", err) + LOG.Error("获取群荣誉信息(GetGroupHonorInfo)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -606,19 +622,19 @@ func (a *apiInfo) GetGroupHonorInfo(groupId int64, Type string) (Response wba.AP // GetCookies 获取Cookies func (a *apiInfo) GetCookies(domain string) (Response wba.APIResponseInfo) { - LOG.INFO("获取Cookies(GetCookies)") + LOG.Info("获取Cookies(GetCookies)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_cookies" messageData.Params.Domain = domain messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取Cookies(GetCookies)时,生成UUID失败: %v", err) + LOG.Error("获取Cookies(GetCookies)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取Cookies(GetCookies)时,执行失败: %v", err) + LOG.Error("获取Cookies(GetCookies)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -626,18 +642,18 @@ func (a *apiInfo) GetCookies(domain string) (Response wba.APIResponseInfo) { // GetCSRFToken 获取CSRF Token func (a *apiInfo) GetCSRFToken() (Response wba.APIResponseInfo) { - LOG.INFO("获取CSRF Token(GetCSRFToken)") + LOG.Info("获取CSRF Token(GetCSRFToken)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_csrf_token" messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取CSRF Token(GetCSRFToken)时,生成UUID失败: %v", err) + LOG.Error("获取CSRF Token(GetCSRFToken)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取CSRF Token(GetCSRFToken)时,执行失败: %v", err) + LOG.Error("获取CSRF Token(GetCSRFToken)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -645,19 +661,19 @@ func (a *apiInfo) GetCSRFToken() (Response wba.APIResponseInfo) { // GetCredentials 获取登录令牌 func (a *apiInfo) GetCredentials(domain string) (Response wba.APIResponseInfo) { - LOG.INFO("获取登录令牌(GetCredentials)") + LOG.Info("获取登录令牌(GetCredentials)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_credentials" messageData.Params.Domain = domain messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取登录令牌(GetCredentials)时,生成UUID失败: %v", err) + LOG.Error("获取登录令牌(GetCredentials)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取登录令牌(GetCredentials)时,执行失败: %v", err) + LOG.Error("获取登录令牌(GetCredentials)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -665,7 +681,7 @@ func (a *apiInfo) GetCredentials(domain string) (Response wba.APIResponseInfo) { // GetRecord 获取语音 func (a *apiInfo) GetRecord(file string, outFormat string) (Response wba.APIResponseInfo) { - LOG.INFO("获取语音(GetRecord)") + LOG.Info("获取语音(GetRecord)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_record" @@ -673,12 +689,12 @@ func (a *apiInfo) GetRecord(file string, outFormat string) (Response wba.APIResp messageData.Params.OutFormat = outFormat messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取语音(GetRecord)时,生成UUID失败: %v", err) + LOG.Error("获取语音(GetRecord)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取语音(GetRecord)时,执行失败: %v", err) + LOG.Error("获取语音(GetRecord)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -686,19 +702,19 @@ func (a *apiInfo) GetRecord(file string, outFormat string) (Response wba.APIResp // GetImage 获取图片 func (a *apiInfo) GetImage(file string) (Response wba.APIResponseInfo) { - LOG.INFO("获取图片(GetImage)") + LOG.Info("获取图片(GetImage)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_image" messageData.Params.File = file messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取图片(GetImage)时,生成UUID失败: %v", err) + LOG.Error("获取图片(GetImage)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取图片(GetImage)时,执行失败: %v", err) + LOG.Error("获取图片(GetImage)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -706,18 +722,18 @@ func (a *apiInfo) GetImage(file string) (Response wba.APIResponseInfo) { // CanSendImage 检查是否可以发送图片 func (a *apiInfo) CanSendImage() (Response wba.APIResponseInfo) { - LOG.INFO("检查是否可以发送图片(CanSendImage)") + LOG.Info("检查是否可以发送图片(CanSendImage)") var messageData wba.APIRequestInfo var err error messageData.Action = "can_send_image" messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("检查是否可以发送图片(CanSendImage)时,生成UUID失败: %v", err) + LOG.Error("检查是否可以发送图片(CanSendImage)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("检查是否可以发送图片(CanSendImage)时,执行失败: %v", err) + LOG.Error("检查是否可以发送图片(CanSendImage)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -725,18 +741,18 @@ func (a *apiInfo) CanSendImage() (Response wba.APIResponseInfo) { // CanSendRecord 检查是否可以发送语音 func (a *apiInfo) CanSendRecord() (Response wba.APIResponseInfo) { - LOG.INFO("检查是否可以发送语音(CanSendRecord)") + LOG.Info("检查是否可以发送语音(CanSendRecord)") var messageData wba.APIRequestInfo var err error messageData.Action = "can_send_record" messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("检查是否可以发送语音(CanSendRecord)时,生成UUID失败: %v", err) + LOG.Error("检查是否可以发送语音(CanSendRecord)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("检查是否可以发送语音(CanSendRecord)时,执行失败: %v", err) + LOG.Error("检查是否可以发送语音(CanSendRecord)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -744,18 +760,18 @@ func (a *apiInfo) CanSendRecord() (Response wba.APIResponseInfo) { // GetStatus 获取状态 func (a *apiInfo) GetStatus() (Response wba.APIResponseInfo) { - LOG.INFO("获取状态(GetStatus)") + LOG.Info("获取状态(GetStatus)") var messageData wba.APIRequestInfo var err error messageData.Action = "get_status" messageData.Echo, err = GenerateUUID() if err != nil { - LOG.ERROR("获取状态(GetStatus)时,生成UUID失败: %v", err) + LOG.Error("获取状态(GetStatus)时,生成UUID失败: %v", err) return wba.APIResponseInfo{} } Response, err = wsAPI(messageData) if err != nil { - LOG.ERROR("获取状态(GetStatus)时,执行失败: %v", err) + LOG.Error("获取状态(GetStatus)时,执行失败: %v", err) return wba.APIResponseInfo{} } return Response @@ -766,7 +782,7 @@ func (a *apiInfo) GetStatus() (Response wba.APIResponseInfo) { /* 关于LOG模块的说明 -1.日志模块使用go-logging库,日志级别分为DEBUG、INFO、WARN、ERROR。 +1.日志模块使用go-logging库,日志级别分为DEBUG、Info、Warn、Error。 2.日志模块提供LogWith方法,可以自定义日志级别,调用级别为DEBUG时,会打印输出调用者的文件名、函数名、行号。 @@ -774,24 +790,31 @@ func (a *apiInfo) GetStatus() (Response wba.APIResponseInfo) { */ func (a *apiInfo) LogWith(level string, content string, args ...interface{}) { + level = strings.ToLower(level) switch level { - case "DEBUG": - LOG.DEBUG(content, args...) + case "trace": + LOG.Trace(content, args...) return - case "WARN": - LOG.WARN(content, args...) + case "debug": + LOG.Debug(content, args...) return - case "ERROR": - LOG.ERROR(content, args...) + case "notice": + LOG.Notice(content, args...) + return + case "warn": + LOG.Warn(content, args...) + return + case "error": + LOG.Error(content, args...) return default: - LOG.INFO(content, args...) + LOG.Info(content, args...) return } } func (a *apiInfo) Log(content string, args ...interface{}) { - LOG.INFO(content, args...) + LOG.Info(content, args...) } //database模块 diff --git a/core/app_admin_unix.go b/core/app_admin_unix.go index c493784..cf80fb5 100644 --- a/core/app_admin_unix.go +++ b/core/app_admin_unix.go @@ -19,7 +19,7 @@ func ReloadApps() (total int, success int) { total = 0 success = 0 if err != nil { - LOG.ERROR("加载应用所在目录失败:%v", err) + LOG.Error("加载应用所在目录失败:%v", err) return } @@ -42,23 +42,23 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i pluginPath := filepath.Join(appsDir, file.Name()) p, err := plugin.Open(pluginPath) if err != nil { - LOG.ERROR("打开应用 %s 时发生错误: %v", pluginPath, err) + LOG.Error("打开应用 %s 时发生错误: %v", pluginPath, err) return 1, 0 } AppInit, err := p.Lookup("AppInit") if err != nil { - LOG.ERROR("找不到应用 %s 提供的 AppInit 接口: %v", pluginPath, err) + LOG.Error("找不到应用 %s 提供的 AppInit 接口: %v", pluginPath, err) return 1, 0 } app := AppInit.(func() wba.AppInfo)() err = app.Init(&AppApi) if err != nil { - LOG.ERROR("初始化应用 %s 失败: %v", pluginPath, err) + LOG.Error("初始化应用 %s 失败: %v", pluginPath, err) } CmdMap = mergeMaps(CmdMap, app.Get().CmdMap) - LOG.INFO("应用 %s 加载成功", pluginPath) + LOG.Info("应用 %s 加载成功", pluginPath) return 1, 1 } diff --git a/core/app_admin_windows.go b/core/app_admin_windows.go index 5d4d4f3..837afd5 100644 --- a/core/app_admin_windows.go +++ b/core/app_admin_windows.go @@ -21,7 +21,7 @@ func ReloadApps() (total int, success int) { total = 0 success = 0 if err != nil { - LOG.ERROR("加载应用所在目录失败:%v", err) + LOG.Error("加载应用所在目录失败:%v", err) return } @@ -43,13 +43,13 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i pluginPath := filepath.Join(appsDir, file.Name()) lib, err := syscall.LoadLibrary(pluginPath) if err != nil { - LOG.ERROR("加载应用 %s 失败: %v", pluginPath, err) + LOG.Error("加载应用 %s 失败: %v", pluginPath, err) return 1, 0 } defer func(handle syscall.Handle) { err := syscall.FreeLibrary(handle) if err != nil { - LOG.ERROR("释放应用 %s 时发生错误: %v", pluginPath, err) + LOG.Error("释放应用 %s 时发生错误: %v", pluginPath, err) } }(lib) @@ -68,11 +68,11 @@ func reloadAPP(file os.DirEntry, appsDir string) (totalDelta int, successDelta i err = app.Init(&AppApi) if err != nil { - LOG.ERROR("初始化应用 %s 失败: %v", pluginPath, err) + LOG.Error("初始化应用 %s 失败: %v", pluginPath, err) } CmdMap = mergeMaps(CmdMap, app.Get().CmdMap) - LOG.INFO("应用 %s 加载成功", pluginPath) + LOG.Info("应用 %s 加载成功", pluginPath) return 1, 1 } diff --git a/core/app_core.go b/core/app_core.go index 7905462..bf2a114 100644 --- a/core/app_core.go +++ b/core/app_core.go @@ -25,7 +25,7 @@ func (app *AppInfo) Run(cmd string, args []string, msg wba.MessageEventInfo) err return nil } -func (app *AppInfo) Init(Api wba.WindAPI) error { +func (app *AppInfo) Init(Api wba.WindStandardProtocolAPI) error { return nil } @@ -47,8 +47,8 @@ var AppCore = AppInfo{ "bot", "显示WIND版本信息", func(args []string, msg wba.MessageEventInfo) { - AppApi.ReplyMsg(msg, "WIND 0.1.0", false) - LOG.INFO("发送核心版本信息:(至:%v-%v:%v-%v)", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname) + AppApi.SendMsg(msg, "WIND 0.1.0", false) + LOG.Info("发送核心版本信息:(至:%v-%v:%v-%v)", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname) }, ), }, diff --git a/core/cron.go b/core/cron.go index 9890be6..2f76b45 100644 --- a/core/cron.go +++ b/core/cron.go @@ -11,8 +11,8 @@ func RegisterCron(task wba.ScheduledTaskInfo) { c := cron.New(cron.WithSeconds()) _, err := c.AddFunc(task.Cron, task.Task) if err != nil { - LOG.ERROR("添加定时任务 %s 时出错%v:", task.Name, err) + LOG.Error("添加定时任务 %s 时出错%v:", task.Name, err) } c.Start() - LOG.INFO("定时任务 %s 注册成功", task.Name) + LOG.Info("定时任务 %s 注册成功", task.Name) } diff --git a/core/events_handler.go b/core/events_handler.go index 2292206..66c701b 100644 --- a/core/events_handler.go +++ b/core/events_handler.go @@ -12,15 +12,15 @@ func HandleMessage(msgJson []byte) { var msg wba.MessageEventInfo err := json.Unmarshal(msgJson, &msg) if err != nil { - LOG.ERROR("消息事件反序列化失败: %v", err) + LOG.Error("消息事件反序列化失败: %v", err) } // 处理消息 - LOG.INFO("收到消息:(来自:%v-%v:%v-%v)%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, msg.RawMessage) + LOG.Info("收到消息:(来自:%v-%v:%v-%v)%v", msg.MessageType, msg.GroupId, msg.UserId, msg.Sender.Nickname, msg.RawMessage) //如果消息文本内容为bot,发送框架信息。 cmd, args := CmdSplit(msg) _, ok := CmdMap[cmd] if ok { - LOG.DEBUG("执行命令:%v %v", cmd, args) + LOG.Debug("执行命令:%v %v", cmd, args) CmdMap[cmd].SOLVE(args, msg) } // TODO: 处理消息内容 @@ -30,7 +30,7 @@ func HandleNotice(msgJson []byte) { var notice wba.NoticeEventInfo err := json.Unmarshal(msgJson, ¬ice) if err != nil { - LOG.ERROR("通知事件反序列化失败: %v", err) + LOG.Error("通知事件反序列化失败: %v", err) } // TODO: 处理通知 } @@ -39,7 +39,7 @@ func HandleRequest(msgJson []byte) { var request wba.NoticeEventInfo err := json.Unmarshal(msgJson, &request) if err != nil { - LOG.ERROR("请求事件反序列化失败: %v", err) + LOG.Error("请求事件反序列化失败: %v", err) } // TODO: 处理请求 } @@ -48,7 +48,7 @@ func HandleMetaEvent(msgJson []byte) { var meta wba.NoticeEventInfo err := json.Unmarshal(msgJson, &meta) if err != nil { - LOG.ERROR("元事件反序列化失败: %v", err) + LOG.Error("元事件反序列化失败: %v", err) } // TODO: 处理元事件 } diff --git a/core/web_service.go b/core/web_service.go new file mode 100644 index 0000000..cb95f69 --- /dev/null +++ b/core/web_service.go @@ -0,0 +1,46 @@ +package core + +import ( + "ProjectWIND/LOG" + "context" + "github.com/cloudwego/hertz/pkg/app" + "github.com/cloudwego/hertz/pkg/app/server" + "github.com/cloudwego/hertz/pkg/common/hlog" + "github.com/cloudwego/hertz/pkg/protocol/consts" +) + +func WebServer(port string) *server.Hertz { + // 创建自定义日志记录器实例 + customLogger := &LOG.CustomLogger{} + // 设置自定义日志记录器 + hlog.SetLogger(customLogger) + h := server.Default(server.WithHostPorts("0.0.0.0:" + port)) + h.Use(LoggingMiddleware()) + h.GET("/index", func(ctx context.Context, c *app.RequestContext) { + //返回webui/index.html + c.File("./webui/index.html") + }) + h.GET("/app/api/:appName/*action", func(ctx context.Context, c *app.RequestContext) { + appName := c.Param("appName") + action := c.Param("action") + message := appName + "-" + action + "\n" + c.String(consts.StatusOK, message) + }) + return h +} + +// LoggingMiddleware 是一个中间件函数,用于记录请求信息 +func LoggingMiddleware() app.HandlerFunc { + return func(c context.Context, ctx *app.RequestContext) { + // 获取客户端 IP + clientIP := ctx.ClientIP() + // 获取请求完整路径 + fullPath := ctx.Request.URI().PathOriginal() + // 继续处理请求 + ctx.Next(c) + // 获取请求处理状态码 + statusCode := ctx.Response.StatusCode() + // 在请求处理后记录结束信息 + hlog.Debugf("收到网络请求 | IP: %s | Path: %s | Status: %d ", clientIP, fullPath, statusCode) + } +} diff --git a/core/web_socket.go b/core/web_socket.go index 2d98337..eb36408 100644 --- a/core/web_socket.go +++ b/core/web_socket.go @@ -21,14 +21,14 @@ func WebSocketHandler(protocolAddr string, token string) error { // 解析连接URL u, err := url.Parse(protocolAddr) if err != nil { - LOG.ERROR("Parse URL error: %v", err) + LOG.Error("Parse URL error: %v", err) return err } // 创建一个带有Authorization头的HTTP请求 req, err := http.NewRequest("GET", u.String(), nil) if err != nil { - LOG.FATAL("创建请求出错:%v", err) + LOG.Fatal("创建请求出错:%v", err) } req.Header.Set("Authorization", "Bearer "+token) // 配置WebSocket连接升级器 @@ -36,19 +36,19 @@ func WebSocketHandler(protocolAddr string, token string) error { // 使用升级器建立WebSocket连接 conn, _, err := dialer.Dial(req.URL.String(), req.Header) if err != nil { - LOG.FATAL("建立WebSocket连接出错:%v", err) + LOG.Fatal("建立WebSocket连接出错:%v", err) } defer func(conn *websocket.Conn) { err := conn.Close() if err != nil { - LOG.ERROR("Close error: %v", err) + LOG.Error("Close error: %v", err) } }(conn) - LOG.INFO("已连接到WebSocket服务器: %v", u.String()) + LOG.Info("已连接到WebSocket服务器: %v", u.String()) ProtocolInfo := AppApi.GetVersionInfo() - LOG.INFO("协议端信息: %v-%v", ProtocolInfo.Data.AppName, ProtocolInfo.Data.AppVersion) + LOG.Info("协议端信息: %v-%v", ProtocolInfo.Data.AppName, ProtocolInfo.Data.AppVersion) logInfo := AppApi.GetLoginInfo() - LOG.INFO("连接到账号: %v(%v)", logInfo.Data.Nickname, logInfo.Data.UserId) + LOG.Info("连接到账号: %v(%v)", logInfo.Data.Nickname, logInfo.Data.UserId) // 定义通道,缓存消息和消息类型,防止消息处理阻塞 messageChan := make(chan []byte, 32) @@ -57,7 +57,7 @@ func WebSocketHandler(protocolAddr string, token string) error { // 接收消息并放入通道 messageType, message, err := conn.ReadMessage() if err != nil { - LOG.ERROR("ReadMessage error: %v", err) + LOG.Error("ReadMessage error: %v", err) return err } messageChan <- message @@ -78,14 +78,14 @@ func WebSocketHandler(protocolAddr string, token string) error { // processMessage 处理接收到的消息 func processMessage(messageType int, message []byte) { if messageType != websocket.TextMessage { - LOG.ERROR("Invalid message type: %v", messageType) + LOG.Error("Invalid message type: %v", messageType) return } //message json解析 var messageMap map[string]interface{} err := json.Unmarshal(message, &messageMap) if err != nil { - LOG.ERROR("Unmarshal error: %v", err) + LOG.Error("Unmarshal error: %v", err) return } // 处理接收到的消息 @@ -128,13 +128,13 @@ func wsAPI(body wba.APIRequestInfo) (Response wba.APIResponseInfo, err error) { // 解析连接URL u, err := url.Parse(gProtocolAddr) if err != nil { - LOG.ERROR("Parse URL error: %v", err) + LOG.Error("Parse URL error: %v", err) return wba.APIResponseInfo{}, err } // 创建一个带有Authorization头的HTTP请求 req, err := http.NewRequest("GET", u.String(), nil) if err != nil { - LOG.FATAL("创建请求出错:%v", err) + LOG.Fatal("创建请求出错:%v", err) } req.Header.Set("Authorization", "Bearer "+gToken) // 配置WebSocket连接升级器 @@ -142,12 +142,12 @@ func wsAPI(body wba.APIRequestInfo) (Response wba.APIResponseInfo, err error) { // 使用升级器建立WebSocket连接 conn, _, err := dialer.Dial(req.URL.String(), req.Header) if err != nil { - LOG.FATAL("建立WebSocket连接出错:%v", err) + LOG.Fatal("建立WebSocket连接出错:%v", err) } defer func(conn *websocket.Conn) { err := conn.Close() if err != nil { - LOG.ERROR("Close error: %v", err) + LOG.Error("Close error: %v", err) } }(conn) err = conn.WriteMessage(websocket.TextMessage, bodyBytes) diff --git a/database/database.go b/database/database.go index 8df7d75..340c3a2 100644 --- a/database/database.go +++ b/database/database.go @@ -42,7 +42,7 @@ func folderCheck(filename string) { if _, err := os.Stat(filename); os.IsNotExist(err) { err := os.MkdirAll(filename, 0755) if err != nil { - LOG.FATAL("[ERROR]Error occured while create folder: %v", err) + LOG.Fatal("[Error]Error occured while create folder: %v", err) } } } @@ -54,12 +54,12 @@ func fileCheck(filename string) { if _, err := os.Stat(filename); os.IsNotExist(err) { file, err := os.Create(filename) if err != nil { - LOG.FATAL("[ERROR]Error occured while create file: %v", err) + LOG.Fatal("[Error]Error occured while create file: %v", err) } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("[ERROR]Error occured while close file: %v", err) + LOG.Fatal("[Error]Error occured while close file: %v", err) } }(file) } @@ -68,13 +68,13 @@ func fileCheck(filename string) { func writeContent(f *os.File, str string) error { // 写入内容到文件 if f == nil { - // log.Printf("[ERROR]file is nil") - LOG.ERROR("[ERROR]file is nil") + // log.Printf("[Error]file is nil") + LOG.Error("[Error]file is nil") return errors.New("file is nil") } _, err := f.Write([]byte(str)) if err != nil { - LOG.ERROR("[ERROR]Error while write content to file: %v", err) + LOG.Error("[Error]Error while write content to file: %v", err) return err } return nil @@ -94,13 +94,13 @@ func saveData(db *Database) error { // 保存数据到文件 dataJson, err := json.Marshal(db) if err != nil { - LOG.ERROR("[ERROR]:Error while marshal data: %v", err) + LOG.Error("[Error]:Error while marshal data: %v", err) return err } filename := "./database/" + db.Id + ".wdb" file, err := os.Create(filename) if err != nil { - LOG.ERROR("[ERROR]:Error while create file %s: %v", filename, err) + LOG.Error("[Error]:Error while create file %s: %v", filename, err) return err } writeContent(file, string(dataJson)) @@ -113,14 +113,14 @@ func loadData(db *Database) error { fileCheck(filename) dataJson, err := printContent(filename) if err != nil { - // log.Printf("[ERROR]:Error while read file %s: %v", filename, err) - LOG.ERROR("[ERROR]:Error while read file %s: %v", filename, err) + // log.Printf("[Error]:Error while read file %s: %v", filename, err) + LOG.Error("[Error]:Error while read file %s: %v", filename, err) return err } err = json.Unmarshal([]byte(dataJson), db) if err != nil { - // log.Printf("[ERROR]:Error while unmarshal data: %v", err) - LOG.WARN("[WARNING]:Error while unmarshal data: %v", err) + // log.Printf("[Error]:Error while unmarshal data: %v", err) + LOG.Warn("[WARNING]:Error while unmarshal data: %v", err) return err } return nil @@ -134,53 +134,53 @@ func dataGet(db *Database, category string, id string, key string) (string, bool case "user": user, ok := db.Users[id] if !ok { - LOG.WARN("[WARNING]:User %s not found", id) + LOG.Warn("[WARNING]:User %s not found", id) return "", false } if user.Data == nil { - LOG.WARN("[WARNING]:User %s's data is nil", id) + LOG.Warn("[WARNING]:User %s's data is nil", id) return "", false } value, ok := user.Data[key] if !ok { - LOG.WARN("[WARNING]:User %s's data %s not found", id, key) + LOG.Warn("[WARNING]:User %s's data %s not found", id, key) return "", false } return value, true case "group": group, ok := db.Groups[id] if !ok { - LOG.WARN("[WARNING]:Group %s not found", id) + LOG.Warn("[WARNING]:Group %s not found", id) return "", false } if group.Data == nil { - LOG.WARN("[WARNING]:Group %s's data is nil", id) + LOG.Warn("[WARNING]:Group %s's data is nil", id) return "", false } value, ok := group.Data[key] if !ok { - LOG.WARN("[WARNING]:Group %s's data %s not found", id, key) + LOG.Warn("[WARNING]:Group %s's data %s not found", id, key) return "", false } return value, true case "global": global, ok := db.Global[id] if !ok { - LOG.WARN("[WARNING]:Global %s not found", id) + LOG.Warn("[WARNING]:Global %s not found", id) return "", false } if global.Data == nil { - LOG.WARN("[WARNING]:Global data of %s is nil", id) + LOG.Warn("[WARNING]:Global data of %s is nil", id) return "", false } value, ok := global.Data[key] if !ok { - LOG.WARN("[WARNING]:Global data of %s's %s not found", id, key) + LOG.Warn("[WARNING]:Global data of %s's %s not found", id, key) return "", false } return value, true default: - LOG.ERROR("[ERROR]:Invalid category %s", category) + LOG.Error("[Error]:Invalid category %s", category) return "", false } } @@ -228,16 +228,16 @@ func dataSet(db *Database, category string, id string, key string, value string) } global.Data[key] = value default: - LOG.ERROR("[ERROR]:Invalid category %s", category) + LOG.Error("[Error]:Invalid category %s", category) } } func initializeDatabase() *Database { // 启动并检查程序 - LOG.INFO("Starting database ...") + LOG.Info("正在启动数据库 ...") db := newDatabase("datamap") loadData(&db) - LOG.INFO("Database started successfully.") + LOG.Info("数据库启动成功") return &db } @@ -258,13 +258,21 @@ func Start() { select { case <-dataChan: // 接收到信号,保存数据并退出程序 - LOG.INFO("Received signal, saving data and exiting...") - saveData(DB) + LOG.Info("即将退出程序,正在保存数据...") + err := saveData(DB) + if err != nil { + LOG.Error("退出程序时保存数据出错: %v", err) + return + } os.Exit(0) case <-saveTicker.C: // 定时保存数据 - LOG.INFO("Saving data automatically...") - saveData(DB) + LOG.Info("自动保存") + err := saveData(DB) + if err != nil { + LOG.Error("自动保存出错: %v", err) + return + } } } }() diff --git a/database/datamap.wdb b/database/datamap.wdb new file mode 100644 index 0000000..049d915 --- /dev/null +++ b/database/datamap.wdb @@ -0,0 +1 @@ +{"Id":"datamap","Users":{},"Groups":{},"Global":{}} \ No newline at end of file diff --git a/go.mod b/go.mod index 8f1057a..0ba0ac9 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,28 @@ module ProjectWIND go 1.23.2 -require github.com/gorilla/websocket v1.5.3 +require ( + github.com/cloudwego/hertz v0.9.5 + github.com/gorilla/websocket v1.5.3 + github.com/robfig/cron/v3 v3.0.1 +) require ( - github.com/robfig/cron/v3 v3.0.1 // indirect + github.com/bytedance/gopkg v0.1.0 // indirect + github.com/bytedance/sonic v1.12.0 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cloudwego/netpoll v0.6.4 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/golang/protobuf v1.5.0 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/nyaruka/phonenumbers v1.0.55 // indirect + github.com/tidwall/gjson v1.14.4 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect golang.org/x/sys v0.29.0 // indirect + google.golang.org/protobuf v1.27.1 // indirect ) diff --git a/go.sum b/go.sum index e5b26db..37ed100 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,85 @@ +github.com/bytedance/gopkg v0.1.0 h1:aAxB7mm1qms4Wz4sp8e1AtKDOeFLtdqvGiUe7aonRJs= +github.com/bytedance/gopkg v0.1.0/go.mod h1:FtQG3YbQG9L/91pbKSw787yBQPutC+457AvDW77fgUQ= +github.com/bytedance/mockey v1.2.12 h1:aeszOmGw8CPX8CRx1DZ/Glzb1yXvhjDh6jdFBNZjsU4= +github.com/bytedance/mockey v1.2.12/go.mod h1:3ZA4MQasmqC87Tw0w7Ygdy7eHIc2xgpZ8Pona5rsYIk= +github.com/bytedance/sonic v1.12.0 h1:YGPgxF9xzaCNvd/ZKdQ28yRovhfMFZQjuk6fKBzZ3ls= +github.com/bytedance/sonic v1.12.0/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= +github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/hertz v0.9.5 h1:FXV2YFLrNHRdpwT+OoIvv0wEHUC0Bo68CDPujr6VnWo= +github.com/cloudwego/hertz v0.9.5/go.mod h1:UUBt8N8hSTStz7NEvLZ5mnALpBSofNL4DoYzIIp8UaY= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cloudwego/netpoll v0.6.4 h1:z/dA4sOTUQof6zZIO4QNnLBXsDFFFEos9OOGloR6kno= +github.com/cloudwego/netpoll v0.6.4/go.mod h1:BtM+GjKTdwKoC8IOzD08/+8eEn2gYoiNLipFca6BVXQ= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/nyaruka/phonenumbers v1.0.55 h1:bj0nTO88Y68KeUQ/n3Lo2KgK7lM1hF7L9NFuwcCl3yg= +github.com/nyaruka/phonenumbers v1.0.55/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/main.go b/main.go index 6ba8769..1292143 100644 --- a/main.go +++ b/main.go @@ -12,8 +12,14 @@ func main() { //如果没有参数,则启动WebUI if len(os.Args) <= 1 { initCore() - fmt.Println("请修改配置文件后,使用-p参数连接协议端开始运行。") - return + // 启动WebUI + h := core.WebServer("8080") + go h.Spin() + // 连接到数据库 + go startDatabase() + // 连接到协议端 + go startProtocol() + select {} } cmdArgs := os.Args[1:] if cmdArgs[0] == "-h" || cmdArgs[0] == "--help" { @@ -42,17 +48,6 @@ func main() { registerService() return } - if cmdArgs[0] == "-p" || cmdArgs[0] == "--protocol" { - // 连接到协议端 - go AutoSave() - startProtocol() - return - } - if cmdArgs[0] == "-d" || cmdArgs[0] == "--database" { - // 连接到数据库 - startDatabase() - return - } fmt.Println("未知命令,请使用-h查看帮助。") return } diff --git a/typed/typed.go b/typed/typed.go index 738008e..698cc04 100644 --- a/typed/typed.go +++ b/typed/typed.go @@ -1,10 +1,17 @@ package typed type CoreConfigInfo struct { - CoreName string `json:"core_name"` - ProtocolAddr string `json:"protocol_addr"` - Token string `json:"token"` - WebUIPort uint16 `json:"webui_port"` - PasswordHash string `json:"password_hash"` - ServiceName string `json:"service_name"` + CoreName string `json:"core_name"` + Protocols []Protocol `json:"protocols"` + WebUIPort uint16 `json:"webui_port"` + PasswordHash string `json:"password_hash"` + ServiceName string `json:"service_name"` +} + +type Protocol struct { + ProtocolName string `json:"protocol_name"` + ProtocolPlatform string `json:"protocol_platform"` + ProtocolAddr string `json:"protocol_addr"` + Token string `json:"token"` + Enable bool `json:"enable"` } diff --git a/utils.go b/utils.go index 1f623d0..f0ed031 100644 --- a/utils.go +++ b/utils.go @@ -19,11 +19,11 @@ func initCore() string { log.SetFlags(log.Ldate | log.Ltime) log.SetPrefix("[WIND] ") - LOG.INFO("正在初始化WIND配置文件...") + LOG.Info("正在初始化WIND配置文件...") err := checkAndUpdateConfig("./data/core.json") if err != nil { - LOG.FATAL("初始化时,加载配置文件 ./data/core.json 失败: %v", err) + LOG.Fatal("初始化时,加载配置文件 ./data/core.json 失败: %v", err) } // 创建日志文件 logFile := fmt.Sprintf("./data/log/WIND_CORE_%s.log", time.Now().Format("20060102150405")) @@ -31,30 +31,30 @@ func initCore() string { if os.IsNotExist(err) { file, err := os.Create(logFile) if err != nil { - LOG.FATAL("初始化时,创建日志文件失败: %v", err) + LOG.Fatal("初始化时,创建日志文件失败: %v", err) } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("无法关闭日志文件: %v", err) + LOG.Fatal("无法关闭日志文件: %v", err) } }(file) } file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { - LOG.FATAL("初始化时,无法打开日志文件: %v", err) + LOG.Fatal("初始化时,无法打开日志文件: %v", err) } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("无法关闭日志文件: %v", err) + LOG.Fatal("无法关闭日志文件: %v", err) } }(file) // 设置日志输出到文件 log.SetOutput(io.MultiWriter(os.Stdout, file)) - LOG.INFO("WIND配置文件初始化完成!") + LOG.Info("WIND配置文件初始化完成!") return logFile } @@ -64,7 +64,7 @@ func checkAndUpdateConfig(configPath string) error { // 如果不存在,则创建该文件夹 err := os.Mkdir("./data/", 0755) if err != nil { - LOG.FATAL("初始化时,创建data文件夹失败: %v", err) + LOG.Fatal("初始化时,创建data文件夹失败: %v", err) } } @@ -73,12 +73,12 @@ func checkAndUpdateConfig(configPath string) error { // 如果不存在,则创建该文件 file, err := os.Create("./data/core.json") if err != nil { - LOG.FATAL("初始化时,创建 ./data/core.json 配置文件失败: %v", err) + LOG.Fatal("初始化时,创建 ./data/core.json 配置文件失败: %v", err) } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("关闭 ./data/core.json 配置文件失败: %v", err) + LOG.Fatal("关闭 ./data/core.json 配置文件失败: %v", err) } }(file) } @@ -86,11 +86,17 @@ func checkAndUpdateConfig(configPath string) error { // 检查并更新配置文件 var coreConfig typed.CoreConfigInfo - // 定义默认配置 + var defaultProtocol typed.Protocol + defaultProtocol.ProtocolName = "EXAMPLE" + defaultProtocol.ProtocolPlatform = "在这里输入协议平台" + defaultProtocol.ProtocolAddr = "在这里输入协议地址,如'ws://127.0.0.1:8080'" + defaultProtocol.Token = "在这里输入协议的Token" + defaultProtocol.Enable = true + var defaultConfig typed.CoreConfigInfo defaultConfig.CoreName = "windCore" defaultConfig.WebUIPort = 3211 - defaultConfig.ProtocolAddr = "" + defaultConfig.Protocols = []typed.Protocol{defaultProtocol} defaultConfig.ServiceName = "wind" // 读取配置文件 file, err := os.Open(configPath) @@ -100,7 +106,7 @@ func checkAndUpdateConfig(configPath string) error { defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("无法关闭配置文件 ./data/core.json: %v", err) + LOG.Fatal("无法关闭配置文件 ./data/core.json: %v", err) } }(file) @@ -114,8 +120,11 @@ func checkAndUpdateConfig(configPath string) error { } // 检查并更新配置 - if coreConfig.ProtocolAddr == "" { - coreConfig.ProtocolAddr = defaultConfig.ProtocolAddr + //if coreConfig.ProtocolAddr == "" { + // coreConfig.ProtocolAddr = defaultConfig.ProtocolAddr + //} + if coreConfig.Protocols == nil || len(coreConfig.Protocols) == 0 { + coreConfig.Protocols = defaultConfig.Protocols } if coreConfig.WebUIPort == 0 { coreConfig.WebUIPort = defaultConfig.WebUIPort @@ -129,9 +138,9 @@ func checkAndUpdateConfig(configPath string) error { if coreConfig.PasswordHash == "" { coreConfig.PasswordHash = "" } - if coreConfig.Token == "" { - coreConfig.Token = "" - } + //if coreConfig.Token == "" { + // coreConfig.Token = "" + //} formattedJSON, err := json.MarshalIndent(coreConfig, "", " ") if err != nil { @@ -141,19 +150,19 @@ func checkAndUpdateConfig(configPath string) error { // 将格式化后的JSON字符串写入文件 file, err = os.Create("./data/core.json") if err != nil { - LOG.FATAL("初始化时,创建 ./data/core.json 配置文件失败: %v", err) + LOG.Fatal("初始化时,创建 ./data/core.json 配置文件失败: %v", err) return err } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("无法关闭配置文件 ./data/core.json: %v", err) + LOG.Fatal("无法关闭配置文件 ./data/core.json: %v", err) } }(file) _, err = file.Write(formattedJSON) if err != nil { - LOG.FATAL("初始化时,写入 ./data/core.json 配置文件失败: %v", err) + LOG.Fatal("初始化时,写入 ./data/core.json 配置文件失败: %v", err) return err } @@ -170,42 +179,42 @@ func checkAndUpdateConfig(configPath string) error { err = checkDataFolderExistence("./data/app/") if err != nil { - LOG.FATAL("创建应用文件夹 ./data/app/ 失败: %v", err) + LOG.Fatal("创建应用文件夹 ./data/app/ 失败: %v", err) return err } err = checkDataFolderExistence("./data/images/") if err != nil { - LOG.FATAL("创建图片文件夹 ./data/images/ 失败: %v", err) + LOG.Fatal("创建图片文件夹 ./data/images/ 失败: %v", err) return err } err = checkDataFolderExistence("./data/files/") if err != nil { - LOG.FATAL("创建文件文件夹 ./data/files/ 失败: %v", err) + LOG.Fatal("创建文件文件夹 ./data/files/ 失败: %v", err) return err } err = checkDataFolderExistence("./data/videos/") if err != nil { - LOG.FATAL("创建视频文件夹 ./data/videos/ 失败: %v", err) + LOG.Fatal("创建视频文件夹 ./data/videos/ 失败: %v", err) return err } err = checkDataFolderExistence("./data/audios/") if err != nil { - LOG.FATAL("创建音频文件夹 ./data/audios/ 失败: %v", err) + LOG.Fatal("创建音频文件夹 ./data/audios/ 失败: %v", err) return err } err = checkDataFolderExistence("./data/database/") if err != nil { - LOG.FATAL("创建数据库文件夹 ./data/database/ 失败: %v", err) + LOG.Fatal("创建数据库文件夹 ./data/database/ 失败: %v", err) return err } err = checkDataFolderExistence("./data/log/") if err != nil { - LOG.FATAL("创建日志文件夹 ./data/log/ 失败: %v", err) + LOG.Fatal("创建日志文件夹 ./data/log/ 失败: %v", err) return err } err = checkDataFolderExistence("./data/app/configs/") if err != nil { - LOG.FATAL("创建应用配置文件夹 ./data/app/configs/ 失败: %v", err) + LOG.Fatal("创建应用配置文件夹 ./data/app/configs/ 失败: %v", err) } return nil @@ -221,18 +230,18 @@ func startWebUI() { // 打开日志文件 file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { - LOG.FATAL("打开日志文件失败: %v", err) + LOG.Fatal("打开日志文件失败: %v", err) } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("无法关闭日志文件: %v", err) + LOG.Fatal("无法关闭日志文件: %v", err) } }(file) // 设置日志输出到文件 log.SetOutput(io.MultiWriter(os.Stdout, file)) - LOG.INFO("正在启动WIND核心服务...") + LOG.Info("正在启动WIND核心服务...") // 启动 WebSocket 处理程序 //TODO: 这里要添加webUI的启动代码 @@ -248,17 +257,18 @@ func registerService() { // 打开日志文件 file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { - LOG.FATAL("无法打开日志文件: %v", err) + LOG.Fatal("无法打开日志文件: %v", err) } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("无法关闭日志文件: %v", err) + LOG.Fatal("无法关闭日志文件: %v", err) } }(file) // 设置日志输出到文件 log.SetOutput(io.MultiWriter(os.Stdout, file)) - //TODO: 这里要添加注册服务的代码 + //在/etc/systemd/system/下创建服务文件 + } func startProtocol() { @@ -270,63 +280,81 @@ func startProtocol() { // 打开日志文件 file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { - LOG.FATAL("无法打开日志文件: %v", err) + LOG.Fatal("无法打开日志文件: %v", err) } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("无法关闭日志文件: %v", err) + LOG.Fatal("无法关闭日志文件: %v", err) } }(file) // 设置日志输出到文件 log.SetOutput(io.MultiWriter(os.Stdout, file)) ReloadApps() //从配置文件中读取配置信息 - LOG.INFO("正在启动WIND协议服务...") + LOG.Info("正在启动WIND协议服务...") var config typed.CoreConfigInfo file, err = os.Open("./data/core.json") if err != nil { - LOG.FATAL("无法打开配置文件 ./data/core.json: %v", err) + LOG.Fatal("无法打开配置文件 ./data/core.json: %v", err) } defer func(file *os.File) { err := file.Close() if err != nil { - LOG.FATAL("无法关闭配置文件 ./data/core.json: %v", err) + LOG.Fatal("无法关闭配置文件 ./data/core.json: %v", err) } }(file) decoder := json.NewDecoder(file) err = decoder.Decode(&config) if err != nil { - LOG.FATAL("连接协议时,解析配置文件 ./data/core.json 失败: %v", err) + LOG.Fatal("连接协议时,解析配置文件 ./data/core.json 失败: %v", err) } - //获取协议地址 - protocolAddr := config.ProtocolAddr - //获取token - token := config.Token - //链接协议 - // 启动 WebSocket 处理程序 - LOG.INFO("正在启动WebSocket链接程序...") - err = core.WebSocketHandler(protocolAddr, token) - if err != nil { - // 如果发生错误,记录错误并退出程序 - LOG.FATAL("连接协议时,启动 WebSocket 处理程序失败: %v", err) - } - return -} - -func AutoSave() { - for { - time.Sleep(time.Second * 60) - LOG.INFO("自动保存") - //TODO: 这里要添加自动保存的代码 + LOG.Info("正在启动WebSocket链接程序...") + protocolNum := 0 + breakNum := 0 + UnenableProtocolNum := 0 + for _, protocol := range config.Protocols { + protocolName := protocol.ProtocolName + if protocolName == "EXAMPLE" { + continue + } + if protocolName == "" { + LOG.Warn("连接协议 %s 时,协议名称为空,跳过该协议", protocolName) + breakNum++ + continue + } + //获取协议地址 + protocolAddr := protocol.ProtocolAddr + if protocolAddr == "" { + LOG.Warn("连接协议 %s 时,协议地址为空,跳过该协议", protocolName) + breakNum++ + continue + } + if protocol.Enable == false { + LOG.Warn("连接协议 %s 时,协议已禁用,跳过该协议", protocolName) + UnenableProtocolNum++ + continue + } + //获取token + token := protocol.Token + // 启动 WebSocket 处理程序 + go func() { + err := core.WebSocketHandler(protocolAddr, token) + if err != nil { + LOG.Error("连接协议时,启动 WebSocket 处理程序失败: %v", err) + } + }() + protocolNum++ } + LOG.Info(" %d 个协议服务启动完成, %d 个协议服务已禁用, %d 个协议服务因为配置错误被跳过。", protocolNum, UnenableProtocolNum, breakNum) + select {} } func ReloadApps() { - LOG.INFO("正在重新加载应用...") + LOG.Info("正在重新加载应用...") total, success := core.ReloadApps() - LOG.INFO("应用重新加载完成,共加载%d个应用,成功加载%d个应用。", total, success) + LOG.Info("应用重新加载完成,共加载%d个应用,成功加载%d个应用。", total, success) } func startDatabase() { @@ -336,10 +364,10 @@ func startDatabase() { // for i := 0; i < 10; i++ { // data, ok := database.Get("user", "test", "test"+fmt.Sprintf("%d", i)) // if !ok { - // LOG.ERROR("Failed to get data from database") + // LOG.Error("Failed to get data from database") // continue // } - // LOG.INFO("Get data from database: %v", data) + // LOG.Info("Get data from database: %v", data) // time.Sleep(time.Second * 1) // } // time.Sleep(time.Second * 1) @@ -351,10 +379,10 @@ func startDatabase() { // for i := 0; i < 10; i++ { // data, ok := database.Get("user", "test", "test"+fmt.Sprintf("%d", i)) // if !ok { - // LOG.ERROR("Failed to get data from database") + // LOG.Error("Failed to get data from database") // continue // } - // LOG.INFO("Get data from database: %v", data) + // LOG.Info("Get data from database: %v", data) // time.Sleep(time.Second * 1) // } select {} diff --git a/wba/wind.go b/wba/wind.go index 450fbb5..3b9da01 100644 --- a/wba/wind.go +++ b/wba/wind.go @@ -6,50 +6,262 @@ import ( type APP interface { Get() AppInfo - Init(api WindAPI) error + Init(api WindStandardProtocolAPI) error } -type WindAPI interface { - SendMsg(msgType string, groupId int64, userId int64, message string, autoEscape bool) - SendPrivateMsg(userId int64, message string, autoEscape bool) - SendGroupMsg(groupId int64, message string, autoEscape bool) - ReplyMsg(msg MessageEventInfo, message string, autoEscape bool) - ReplyPrivateMsg(msg MessageEventInfo, message string, autoEscape bool) - ReplyGroupMsg(msg MessageEventInfo, message string, autoEscape bool) +// WindStandardProtocolAPI Wind标准协议API,提供了onebot11标准中的API接口。 +type WindStandardProtocolAPI interface { + // UnsafelySendMsg [不安全][需要master权限]按照QQ号或群号发送消息到指定的群组或用户。 + // 参数: + // - msgType: 消息类型,如 "group" 或 "private"。 + // - groupId: 群组 ID,若为私聊则为 0。 + // - userId: 用户 ID,若为群聊则为 0。 + // - message: 要发送的消息内容。 + // - autoEscape: 消息内容是否作为纯文本发送(即不解析 CQ 码)。 + UnsafelySendMsg(msgType string, groupId int64, userId int64, message string, autoEscape bool) + + // UnsafelySendPrivateMsg [不安全][需要master权限]按照QQ号发送私聊消息给指定用户。 + // 参数: + // - userId: 用户 ID。 + // - message: 要发送的消息内容。 + // - autoEscape: 消息内容是否作为纯文本发送(即不解析 CQ 码)。 + UnsafelySendPrivateMsg(userId int64, message string, autoEscape bool) + + // UnsafelySendGroupMsg [不安全][需要master权限]按照群号发送群聊消息到指定群组。 + // 参数: + // - groupId: 群组 ID。 + // - message: 要发送的消息内容。 + // - autoEscape: 消息内容是否作为纯文本发送(即不解析 CQ 码)。 + UnsafelySendGroupMsg(groupId int64, message string, autoEscape bool) + + // SendMsg 按照提供的消息事件信息回复指定消息。 + // 参数: + // - msg: 消息事件信息。 + // - message: 要回复的消息内容。 + // - autoEscape: 是否自动转义消息内容。 + SendMsg(msg MessageEventInfo, message string, autoEscape bool) + + // SendPrivateMsg 按照提供的消息事件信息回复私聊消息。 + // 参数: + // - msg: 消息事件信息。 + // - message: 要回复的消息内容。 + // - autoEscape: 消息内容是否作为纯文本发送(即不解析 CQ 码)。 + SendPrivateMsg(msg MessageEventInfo, message string, autoEscape bool) + + // SendGroupMsg 按照提供的消息事件信息回复群聊消息。 + // 参数: + // - msg: 消息事件信息。 + // - message: 要回复的消息内容。 + // - autoEscape: 消息内容是否作为纯文本发送(即不解析 CQ 码)。 + SendGroupMsg(msg MessageEventInfo, message string, autoEscape bool) + + // UnsafelyDeleteMsg [不安全][需要master权限]撤回指定消息。 + // 参数: + // - msgId: 消息 ID。 + UnsafelyDeleteMsg(msgId int32) + + // DeleteMsg 按照提供的消息事件信息撤回指定的消息。 + // 参数: + // - msg: 消息事件信息。 DeleteMsg(msg MessageEventInfo) + + // SendLike 给指定用户发送点赞,支持指定点赞次数。 + // 参数: + // - userId: 用户 ID。 + // - times: 赞的次数,每个好友每天最多 10 次。 SendLike(userId int64, times int) + + // SetGroupKick 将指定用户踢出指定群组,支持拒绝该用户再次加入。 + // 参数: + // - groupId: 群组 ID。 + // - userId: 用户 ID。 + // - rejectAddRequest: 是否拒绝该用户再次加入。 SetGroupKick(groupId int64, userId int64, rejectAddRequest bool) + + // SetGroupBan 禁言指定用户在指定群组的发言,支持指定禁言时长。 + // 参数: + // - groupId: 群组 ID。 + // - userId: 用户 ID。 + // - duration: 禁言时长,单位为秒,0 表示取消禁言。 SetGroupBan(groupId int64, userId int64, duration int32) + + // SetGroupWholeBan 开启或关闭指定群组的全员禁言。 + // 参数: + // - groupId: 群组 ID。 + // - enable: 是否开启全员禁言。 SetGroupWholeBan(groupId int64, enable bool) + + // SetGroupAdmin 设置或取消指定用户在指定群组的管理员权限。 + // 参数: + // - groupId: 群组 ID。 + // - userId: 用户 ID。 + // - enable: 是否设置为管理员。 SetGroupAdmin(groupId int64, userId int64, enable bool) + + // SetGroupLeave 退出指定群组。 + // 参数: + // - groupId: 群组 ID。 + // - isDismiss: 是否解散,如果登录号是群主,则仅在此项为 true 时能够解散。 SetGroupLeave(groupId int64, isDismiss bool) + + // SetGroupCard 设置指定用户在指定群组的群名片。 + // 参数: + // - groupId: 群组 ID。 + // - userId: 用户 ID。 + // - card: 群名片内容。 SetGroupCard(groupId int64, userId int64, card string) + + // SetGroupName 设置指定群组的名称。 + // 参数: + // - groupId: 群组 ID。 + // - groupName: 群组名称。 SetGroupName(groupId int64, groupName string) - SetGroupSpecialTitle(groupId int64, userId int64, specialTitle string, duration int32) + + // SetGroupSpecialTitle 设置指定用户在指定群组的专属头衔,支持指定头衔有效期。 + // 参数: + // - groupId: 群组 ID。 + // - userId: 用户 ID。 + // - specialTitle: 专属头衔内容。 + SetGroupSpecialTitle(groupId int64, userId int64, specialTitle string) + + // SetFriendAddRequest 处理好友添加请求,支持同意或拒绝并添加备注。 + // 参数: + // - flag: 请求标识(需从上报的数据中获得)。 + // - approve: 是否同意请求。 + // - remark: 备注信息(仅在同意时有效)。 SetFriendAddRequest(flag string, approve bool, remark string) + + // SetGroupAddRequest 处理群组添加请求,支持同意或拒绝并添加理由。 + // 参数: + // - flag: 请求标识。 + // - subType: 请求子类型。 + // - approve: 是否同意请求。 + // - reason: 拒绝理由。 SetGroupAddRequest(flag string, subType string, approve bool, reason string) + + // GetLoginInfo 获取当前登录的账号信息。 + // 返回: API 响应信息。 GetLoginInfo() APIResponseInfo + + // GetVersionInfo 获取当前程序的版本信息。 + // 返回: API 响应信息。 GetVersionInfo() APIResponseInfo + + // GetMsg 获取指定消息 ID 的消息内容。 + // 参数: + // - msgId: 消息 ID。 + // 返回: API 响应信息。 GetMsg(msgId int32) APIResponseInfo + + // GetForwardMsg 获取指定转发消息 ID 的消息内容。 + // 参数: + // - msgId: 转发消息 ID。 + // 返回: API 响应信息。 GetForwardMsg(msgId string) APIResponseInfo + + // GetGroupList 获取当前登录账号加入的所有群组列表。 + // 返回: API 响应信息。 GetGroupList() APIResponseInfo + + // GetGroupMemberList 获取指定群组的所有成员列表。 + // 参数: + // - groupId: 群组 ID。 + // 返回: API 响应信息。 GetGroupMemberList(groupId int64) APIResponseInfo + + // GetGroupMemberInfo 获取指定群组中指定用户的详细信息,支持缓存控制。 + // 参数: + // - groupId: 群组 ID。 + // - userId: 用户 ID。 + // - noCache: 是否不使用缓存。 + // 返回: API 响应信息。 GetGroupMemberInfo(groupId int64, userId int64, noCache bool) APIResponseInfo + + // GetFriendList 获取当前登录账号的所有好友列表。 + // 返回: API 响应信息。 GetFriendList() APIResponseInfo + + // GetStrangerInfo 获取指定用户的详细信息,支持缓存控制。 + // 参数: + // - userId: 用户 ID。 + // - noCache: 是否不使用缓存。 + // 返回: API 响应信息。 GetStrangerInfo(userId int64, noCache bool) APIResponseInfo + + // GetGroupInfo 获取指定群组的详细信息,支持缓存控制。 + // 参数: + // - groupId: 群组 ID。 + // - noCache: 是否不使用缓存。 + // 返回: API 响应信息。 GetGroupInfo(groupId int64, noCache bool) APIResponseInfo + + // GetGroupHonorInfo 获取指定群组的荣誉信息。 + // 参数: + // - groupId: 群组 ID。 + // - Type: 荣誉类型。 + // 返回: API 响应信息。 GetGroupHonorInfo(groupId int64, Type string) APIResponseInfo + + // GetStatus 获取当前程序的运行状态信息。 + // 返回: API 响应信息。 GetStatus() APIResponseInfo + + // // GetCookies 获取指定域名的 Cookies 信息。 + // 参数: + // - domain: 域名。 + // 返回: API 响应信息。 GetCookies(domain string) APIResponseInfo + + // GetCSRFToken 获取 CSRF 令牌。 + // 返回: API 响应信息。 GetCSRFToken() APIResponseInfo + + // GetCredentials 获取指定域名的凭证信息。 + // 参数: + // - domain: 域名。 + // 返回: API 响应信息。 GetCredentials(domain string) APIResponseInfo + + // GetImage 获取指定文件的图片信息。 + // 参数: + // - file: 文件路径或标识符。 + // 返回: API 响应信息。 GetImage(file string) APIResponseInfo + + // GetRecord 获取指定文件的语音记录信息,支持指定输出格式。 + // 参数: + // - file: 文件路径或标识符。 + // - outFormat: 输出格式。 + // 返回: API 响应信息。 GetRecord(file string, outFormat string) APIResponseInfo + + // CanSendImage 检查是否可以发送图片。 + // 返回: API 响应信息。 CanSendImage() APIResponseInfo + + // CanSendRecord 检查是否可以发送语音记录。 + // 返回: API 响应信息。 CanSendRecord() APIResponseInfo + + // SetRestart 设置程序在指定延迟后重启。 + // 参数: + // - delay: 延迟时间,单位为秒。 SetRestart(delay int32) + + // CleanCache 清理程序的缓存。 CleanCache() + + // LogWith 使用指定日志级别记录日志,支持可变参数占位符。 + // 参数: + // - level: 日志级别: "trace", "debug", "info", "notice", "warn", "error"。 + // - log: 日志内容。 + // - args: 可变参数,用于格式化日志内容。 LogWith(level string, log string, args ...interface{}) + + // Log 记录日志,级别为 "info",支持可变参数占位符。 + // 参数: + // - log: 日志内容。 + // - args: 可变参数,用于格式化日志内容。 Log(log string, args ...interface{}) } @@ -76,8 +288,8 @@ func (ai AppInfo) Get() AppInfo { return ai } -func (ai *AppInfo) Init(api WindAPI) error { - Wind = api +func (ai *AppInfo) Init(api WindStandardProtocolAPI) error { + WSP = api return nil } @@ -147,9 +359,9 @@ func WithRule(rule string) AppInfoOption { func NewApp(opts ...AppInfoOption) AppInfo { Ext := AppInfo{ - Name: "Wind", + Name: "WSP", Version: "v1.0.0", - Author: "Wind", + Author: "WSP", Description: "A simple and easy-to-use bot framework", Namespace: "PUBLIC", Homepage: "https://github.com/Sheyiyuan/wind_app_model", @@ -425,4 +637,4 @@ type ScheduledTaskInfo struct { Cron string `json:"cron,omitempty"` } -var Wind WindAPI +var WSP WindStandardProtocolAPI diff --git a/webui/index.html.hertz.gz b/webui/index.html.hertz.gz new file mode 100644 index 0000000..7858670 Binary files /dev/null and b/webui/index.html.hertz.gz differ