Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test4 #26

Merged
merged 35 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
fad0d50
Compiled main.go and pushed changes
Hoshinonyaruko Oct 23, 2023
fda2572
test
Hoshinonyaruko Oct 23, 2023
34cfac1
适配了频道私聊,用bolt数据库取代ini
Hoshinonyaruko Oct 23, 2023
7fc1f10
适配了nonebot2
Hoshinonyaruko Oct 24, 2023
28f9a73
Merge branch 'main' of https://github.com/Hoshinonyaruko/Gensokyo
Hoshinonyaruko Oct 24, 2023
9fadda4
适配私域
Hoshinonyaruko Oct 24, 2023
1336c6a
add license
Hoshinonyaruko Oct 24, 2023
b094949
add a lot
Hoshinonyaruko Oct 25, 2023
f4787f5
Resolved merge conflicts
Hoshinonyaruko Oct 25, 2023
86698c6
trss support
Hoshinonyaruko Oct 26, 2023
045f3e9
fix
Hoshinonyaruko Oct 26, 2023
618561c
add action
Hoshinonyaruko Oct 26, 2023
7e803aa
add action
Hoshinonyaruko Oct 26, 2023
ece4cef
add action
Hoshinonyaruko Oct 26, 2023
f864a50
fixbug
Hoshinonyaruko Oct 26, 2023
4564731
add wss
Hoshinonyaruko Oct 26, 2023
070e4df
merge
Hoshinonyaruko Oct 26, 2023
84e8fe9
bugfix
Hoshinonyaruko Oct 26, 2023
0e4fd50
fix action
Hoshinonyaruko Oct 26, 2023
fe2234a
fix action again
Hoshinonyaruko Oct 26, 2023
cf67a11
fix action againnn
Hoshinonyaruko Oct 26, 2023
0875837
fa
Hoshinonyaruko Oct 26, 2023
3a3c33f
fix
Hoshinonyaruko Oct 26, 2023
8789fa8
add a lot
Hoshinonyaruko Oct 27, 2023
7943466
add ws server token
Hoshinonyaruko Oct 28, 2023
4660983
merge
Hoshinonyaruko Oct 28, 2023
2a1026a
bugifx
Hoshinonyaruko Oct 28, 2023
4186970
fix
Hoshinonyaruko Oct 28, 2023
2f26828
fixat
Hoshinonyaruko Oct 28, 2023
007e1af
bugfix
Hoshinonyaruko Oct 28, 2023
c41fd77
bugfix
Hoshinonyaruko Oct 28, 2023
d8354b7
test
Hoshinonyaruko Oct 28, 2023
6e3c63c
test
Hoshinonyaruko Oct 28, 2023
f08d9d7
test2
Hoshinonyaruko Oct 28, 2023
4dd6e15
add url service
Hoshinonyaruko Oct 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions callapi/callapi.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ type Client interface {
// 为了解决processor和server循环依赖设计的接口
type WebSocketServerClienter interface {
SendMessage(message map[string]interface{}) error
Close() error
}

// 根据action订阅handler处理api
Expand Down
39 changes: 39 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ type Settings struct {
MasterID []string `yaml:"master_id,omitempty"` // 如果需要在群权限判断是管理员是,将user_id填入这里,master_id是一个文本数组
EnableWsServer bool `yaml:"enable_ws_server,omitempty"` //正向ws开关
WsServerToken string `yaml:"ws_server_token,omitempty"` //正向ws token
IdentifyFile bool `yaml:"identify_file"` // 域名校验文件
Crt string `yaml:"crt"`
Key string `yaml:"key"`
}

// LoadConfig 从文件中加载配置并初始化单例配置
Expand Down Expand Up @@ -182,3 +185,39 @@ func GetWsServerToken() string {
}
return instance.Settings.WsServerToken
}

// 获取identify_file的值
func GetIdentifyFile() bool {
mu.Lock()
defer mu.Unlock()

if instance == nil {
log.Println("Warning: instance is nil when trying to get identify file name.")
return false
}
return instance.Settings.IdentifyFile
}

// 获取crt路径
func GetCrtPath() string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
log.Println("Warning: instance is nil when trying to get crt path.")
return ""
}
return instance.Settings.Crt
}

// 获取key路径
func GetKeyPath() string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
log.Println("Warning: instance is nil when trying to get key path.")
return ""
}
return instance.Settings.Key
}
4 changes: 4 additions & 0 deletions config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ settings:
master_id : ["1","2"] #群场景尚未开放获取管理员和列表能力,手动从日志中获取需要设置为管理,的user_id并填入(适用插件有权限判断场景)
enable_ws_server: true #是否启用正向ws服务器 监听server_dir:port/ws
ws_server_token : "12345" #正向ws的token 不启动正向ws可忽略
ws_server_token : "12345" #正向ws的token 不启动正向ws可忽略
identify_file: true #自动生成域名校验文件,在q.qq.com配置信息URL,在server_dir填入自己已备案域名,正确解析到机器人所在服务器ip地址,机器人即可发送链接
crt: "" #证书路径 从你的域名服务商或云服务商申请签发SSL证书(qq要求SSL)
key: "" #密钥路径 Apache(crt文件、key文件)示例: "C:\\123.key" \需要双写成\\
`
6 changes: 5 additions & 1 deletion config_template.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,8 @@ settings:
ws_token: ["",""] #连接wss地址时服务器所需的token,如果是ws,可留空,按顺序一一对应
master_id : ["1","2"] #群场景尚未开放获取管理员和列表能力,手动从日志中获取需要设置为管理,的user_id并填入(适用插件有权限判断场景)
enable_ws_server: true #是否启用正向ws服务器 监听server_dir:port/ws
ws_server_token : "12345" #正向ws的token 不启动正向ws可忽略
ws_server_token : "12345" #正向ws的token 不启动正向ws可忽略
ws_server_token : "12345" #正向ws的token 不启动正向ws可忽略
identify_file: true #自动生成域名校验文件,在q.qq.com配置信息URL,在server_dir填入自己已备案域名,正确解析到机器人所在服务器ip地址,机器人即可发送链接
crt: "" #证书路径 从你的域名服务商或云服务商申请签发SSL证书(qq要求SSL)
key: "" #密钥路径 Apache(crt文件、key文件)示例: "C:\\123.key" \需要双写成\\
6 changes: 3 additions & 3 deletions echo/echo.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@ var globalEchoMapping = &EchoMapping{
msgIDMapping: make(map[string]string),
}

func (e *EchoMapping) generateKey(appid string, s int64) string {
func (e *EchoMapping) GenerateKey(appid string, s int64) string {
return appid + "_" + strconv.FormatInt(s, 10)
}

// 添加echo对应的类型
func AddMsgType(appid string, s int64, msgType string) {
key := globalEchoMapping.generateKey(appid, s)
key := globalEchoMapping.GenerateKey(appid, s)
globalEchoMapping.mu.Lock()
defer globalEchoMapping.mu.Unlock()
globalEchoMapping.msgTypeMapping[key] = msgType
}

// 添加echo对应的messageid
func AddMsgID(appid string, s int64, msgID string) {
key := globalEchoMapping.generateKey(appid, s)
key := globalEchoMapping.GenerateKey(appid, s)
globalEchoMapping.mu.Lock()
defer globalEchoMapping.mu.Unlock()
globalEchoMapping.msgIDMapping[key] = msgID
Expand Down
Binary file added gensokyo.db
Binary file not shown.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ require (
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
mvdan.cc/xurls v1.1.0
mvdan.cc/xurls/v2 v2.5.0 // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
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=
mvdan.cc/xurls v1.1.0 h1:kj0j2lonKseISJCiq1Tfk+iTv65dDGCl0rTbanXJGGc=
mvdan.cc/xurls v1.1.0/go.mod h1:TNWuhvo+IqbUCmtUIb/3LJSQdrzel8loVpgFm0HikbI=
mvdan.cc/xurls/v2 v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8=
mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
9 changes: 5 additions & 4 deletions handlers/get_group_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"log"
"strconv"

"github.com/hoshinonyaruko/gensokyo/callapi"
"github.com/hoshinonyaruko/gensokyo/idmap"
Expand All @@ -28,11 +27,13 @@ type OnebotGroupInfo struct {
}

func ConvertGuildToGroupInfo(guild *dto.Guild, GroupId string) *OnebotGroupInfo {
groupidstr, err := strconv.ParseInt(GroupId, 10, 64)
// 使用idmap.StoreIDv2映射GroupId到一个int64的值
groupid64, err := idmap.StoreIDv2(GroupId)
if err != nil {
log.Printf("groupidstr: %v", err)
log.Printf("Error storing GroupID: %v", err)
return nil
}

ts, err := guild.JoinedAt.Time()
if err != nil {
log.Printf("转换JoinedAt失败: %v", err)
Expand All @@ -41,7 +42,7 @@ func ConvertGuildToGroupInfo(guild *dto.Guild, GroupId string) *OnebotGroupInfo
groupCreateTime := uint32(ts.Unix())

return &OnebotGroupInfo{
GroupID: groupidstr,
GroupID: groupid64,
GroupName: guild.Name,
GroupMemo: guild.Desc,
GroupCreateTime: groupCreateTime,
Expand Down
15 changes: 13 additions & 2 deletions handlers/message_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ import (

"github.com/hoshinonyaruko/gensokyo/callapi"
"github.com/hoshinonyaruko/gensokyo/idmap"
"github.com/hoshinonyaruko/gensokyo/url"
"github.com/tencent-connect/botgo/dto"
"mvdan.cc/xurls" //xurls是一个从文本提取url的库 适用于多种场景
)

var BotID string
Expand Down Expand Up @@ -58,6 +60,7 @@ func SendResponse(client callapi.Client, err error, message *callapi.ActionMessa
return nil
}

// 信息处理函数
func parseMessageContent(paramsMessage callapi.ParamsContent) (string, map[string][]string) {
messageText := ""

Expand Down Expand Up @@ -156,11 +159,11 @@ func parseMessageContent(paramsMessage callapi.ParamsContent) (string, map[strin
return messageText, foundItems
}

// at处理和链接处理
func transformMessageText(messageText string) string {
// 使用正则表达式来查找所有[CQ:at,qq=数字]的模式
re := regexp.MustCompile(`\[CQ:at,qq=(\d+)\]`)
// 使用正则表达式来替换找到的模式为<@!数字>
return re.ReplaceAllStringFunc(messageText, func(m string) string {
messageText = re.ReplaceAllStringFunc(messageText, func(m string) string {
submatches := re.FindStringSubmatch(m)
if len(submatches) > 1 {
realUserID, err := idmap.RetrieveRowByIDv2(submatches[1])
Expand All @@ -172,6 +175,14 @@ func transformMessageText(messageText string) string {
}
return m
})

// 使用xurls来查找和替换所有的URL
messageText = xurls.Relaxed.ReplaceAllStringFunc(messageText, func(originalURL string) string {
shortURL := url.GenerateShortURL(originalURL)
// 使用getBaseURL函数来获取baseUrl并与shortURL组合
return url.GetBaseURL() + "/url/" + shortURL
})
return messageText
}

// 处理at和其他定形文到onebotv11格式(cq码)
Expand Down
5 changes: 5 additions & 0 deletions handlers/send_guild_channel_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ func handleSendGuildChannelMsg(client callapi.Client, api openapi.OpenAPI, apiv2
messageID = echo.GetMsgIDByKey(echoStr)
log.Println("echo取频道发信息对应的message_id:", messageID)
}
// 如果messageID为空,通过函数获取
if messageID == "" {
messageID = GetMessageIDByUseridOrGroupid(config.GetAppIDStr(), channelID)
log.Println("通过GetMessageIDByUserid函数获取的message_id:", messageID)
}
log.Println("频道发信息messageText:", messageText)
log.Println("foundItems:", foundItems)
var err error
Expand Down
5 changes: 5 additions & 0 deletions handlers/send_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ func handleSendMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Ope
messageID = echo.GetMsgIDByKey(echoStr)
log.Println("echo取私聊发信息对应的message_id:", messageID)
}
// 如果messageID为空,通过函数获取
if messageID == "" {
messageID = GetMessageIDByUseridOrGroupid(config.GetAppIDStr(), UserID)
log.Println("通过GetMessageIDByUserid函数获取的message_id:", messageID)
}
log.Println("私聊发信息messageText:", messageText)
log.Println("foundItems:", foundItems)

Expand Down
10 changes: 10 additions & 0 deletions handlers/send_private_msg.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ func handleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open
messageID = echo.GetMsgIDByKey(echoStr)
log.Println("echo取私聊发信息对应的message_id:", messageID)
}
// 如果messageID仍然为空,尝试使用config.GetAppID和UserID的组合来获取messageID
// 如果messageID为空,通过函数获取
if messageID == "" {
messageID = GetMessageIDByUseridOrGroupid(config.GetAppIDStr(), UserID)
log.Println("通过GetMessageIDByUserid函数获取的message_id:", messageID)
}
log.Println("私聊发信息messageText:", messageText)
log.Println("foundItems:", foundItems)

Expand All @@ -66,6 +72,8 @@ func handleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open
if err != nil {
log.Printf("发送文本私聊信息失败: %v", err)
}
//发送成功回执
SendResponse(client, err, &message)
}

// 遍历 foundItems 并发送每种信息
Expand All @@ -85,6 +93,8 @@ func handleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open
if err != nil {
log.Printf("发送 %s 私聊信息失败: %v", key, err)
}
//发送成功回执
SendResponse(client, err, &message)
}
case "guild_private":
//当收到发私信调用 并且来源是频道
Expand Down
40 changes: 0 additions & 40 deletions idmap/cMapping.go

This file was deleted.

58 changes: 57 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"syscall"
Expand All @@ -16,6 +17,7 @@ import (
"github.com/hoshinonyaruko/gensokyo/handlers"
"github.com/hoshinonyaruko/gensokyo/idmap"
"github.com/hoshinonyaruko/gensokyo/server"
"github.com/hoshinonyaruko/gensokyo/url"
"github.com/hoshinonyaruko/gensokyo/wsclient"

"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -169,13 +171,49 @@ func main() {
//是否启动服务器
shouldStartServer := !conf.Settings.Lotus || conf.Settings.EnableWsServer
//如果连接到其他gensokyo,则不需要启动服务器
var httpServer *http.Server
if shouldStartServer {
r := gin.Default()
r.GET("/getid", server.GetIDHandler)
r.POST("/uploadpic", server.UploadBase64ImageHandler(rateLimiter))
r.Static("/channel_temp", "./channel_temp")
r.GET("/ws", server.WsHandlerWithDependencies(api, apiV2, p))
r.Run("0.0.0.0:" + conf.Settings.Port) // 监听0.0.0.0地址的Port端口
r.POST("/url", url.CreateShortURLHandler)
r.GET("/url/:shortURL", url.RedirectFromShortURLHandler)
if config.GetIdentifyFile() {
appIDStr := config.GetAppIDStr()
fileName := appIDStr + ".json"
r.GET("/"+fileName, func(c *gin.Context) {
content := fmt.Sprintf(`{"bot_appid":%d}`, config.GetAppID())
c.Header("Content-Type", "application/json")
c.String(200, content)
})
}
// 创建一个http.Server实例
httpServer = &http.Server{
Addr: "0.0.0.0:" + conf.Settings.Port,
Handler: r,
}
// 在一个新的goroutine中启动Gin服务器
go func() {
if conf.Settings.Port == "443" {
// 使用HTTPS
crtPath := config.GetCrtPath()
keyPath := config.GetKeyPath()
if crtPath == "" || keyPath == "" {
log.Fatalf("crt or key path is missing for HTTPS")
return
}
if err := httpServer.ListenAndServeTLS(crtPath, keyPath); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen (HTTPS): %s\n", err)
}
} else {
// 使用HTTP
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
}
}()
}

// 使用通道来等待信号
Expand All @@ -193,6 +231,24 @@ func main() {
fmt.Printf("Error closing WebSocket connection: %v\n", err)
}
}

// 关闭BoltDB数据库
url.CloseDB()
idmap.CloseDB()

// 在关闭WebSocket客户端之前
for _, wsClient := range p.WsServerClients {
if err := wsClient.Close(); err != nil {
log.Printf("Error closing WebSocket server client: %v\n", err)
}
}

// 使用一个5秒的超时优雅地关闭Gin服务器
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := httpServer.Shutdown(ctx); err != nil {
log.Fatal("Server forced to shutdown:", err)
}
}

// ReadyHandler 自定义 ReadyHandler 感知连接成功事件
Expand Down
Loading
Loading