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

Beta347 #355

Merged
merged 13 commits into from
Mar 23, 2024
Merged
37 changes: 37 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -158,6 +158,9 @@ type Settings struct {
GetGroupListReturnGuilds bool `yaml:"get_g_list_return_guilds"`
GetGroupListGuidsType int `yaml:"get_g_list_guilds_type"`
GetGroupListDelay int `yaml:"get_g_list_delay"`
GlobalServerTempQQguild bool `yaml:"global_server_temp_qqguild"`
ServerTempQQguild string `yaml:"server_temp_qqguild"`
ServerTempQQguildPool []string `yaml:"server_temp_qqguild_pool"`
}

// LoadConfig 从文件中加载配置并初始化单例配置
@@ -1961,3 +1964,37 @@ func GetGroupListDelay() int {
}
return instance.Settings.GetGroupListDelay
}

// 获取GetGlobalServerTempQQguild开关
func GetGlobalServerTempQQguild() bool {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to GlobalServerTempQQguild value.")
return false
}
return instance.Settings.GlobalServerTempQQguild
}

// 获取ServerTempQQguild
func GetServerTempQQguild() string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to ServerTempQQguild value.")
return "0"
}
return instance.Settings.ServerTempQQguild
}

// 获取ServerTempQQguildPool
func GetServerTempQQguildPool() []string {
mu.Lock()
defer mu.Unlock()
if instance != nil {
return instance.Settings.ServerTempQQguildPool
}
return nil // 返回nil,如果instance为nil
}
9 changes: 7 additions & 2 deletions handlers/send_group_msg.go
Original file line number Diff line number Diff line change
@@ -76,7 +76,12 @@ func HandleSendGroupMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openap
if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) {
msgType = GetMessageTypeByUseridV2(message.Params.UserID)
}

// New checks for UserID and GroupID being nil or 0
if (message.Params.UserID == nil || !checkZeroUserID(message.Params.UserID)) &&
(message.Params.GroupID == nil || !checkZeroGroupID(message.Params.GroupID)) {
mylog.Printf("send_group_msgs接收到错误action: %v", message)
return "", nil
}
mylog.Printf("send_group_msg获取到信息类型:%v", msgType)
var idInt64 int64
var err error
@@ -1116,7 +1121,7 @@ func SendStackMessages(apiv2 openapi.OpenAPI, messageid string, GroupID string)
mylog.Printf("取出数量: %v", count)
pairs := echo.PopGlobalStackMulti(count)
for i, pair := range pairs {
mylog.Printf("发送栈中的消息匹配 %v: %v", pair.Group, GroupID)
//mylog.Printf("发送栈中的消息匹配 %v: %v", pair.Group, GroupID)
if pair.Group == GroupID {
// 发送消息
msgseq := echo.GetMappingSeq(messageid)
6 changes: 6 additions & 0 deletions handlers/send_msg.go
Original file line number Diff line number Diff line change
@@ -65,6 +65,12 @@ func HandleSendMsg(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Ope
if msgType == "" && message.Params.UserID != nil && checkZeroUserID(message.Params.UserID) {
msgType = GetMessageTypeByUseridV2(message.Params.UserID)
}
// New checks for UserID and GroupID being nil or 0
if (message.Params.UserID == nil || !checkZeroUserID(message.Params.UserID)) &&
(message.Params.GroupID == nil || !checkZeroGroupID(message.Params.GroupID)) {
mylog.Printf("send_group_msgs接收到错误action: %v", message)
return "", nil
}

var idInt64, idInt642 int64
var err error
7 changes: 7 additions & 0 deletions handlers/send_private_msg.go
Original file line number Diff line number Diff line change
@@ -67,6 +67,13 @@ func HandleSendPrivateMsg(client callapi.Client, api openapi.OpenAPI, apiv2 open
if msgType == "" && message.Params.GroupID != nil && checkZeroGroupID(message.Params.GroupID) {
msgType = GetMessageTypeByGroupidV2(message.Params.GroupID)
}
// New checks for UserID and GroupID being nil or 0
if (message.Params.UserID == nil || !checkZeroUserID(message.Params.UserID)) &&
(message.Params.GroupID == nil || !checkZeroGroupID(message.Params.GroupID)) {
mylog.Printf("send_group_msgs接收到错误action: %v", message)
return "", nil
}

var idInt64 int64
var err error

103 changes: 103 additions & 0 deletions images/upload_api.go
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ import (
"net/url"
"regexp"
"strings"
"sync"

"github.com/hoshinonyaruko/gensokyo/config"
"github.com/hoshinonyaruko/gensokyo/echo"
@@ -24,6 +25,12 @@ import (
"google.golang.org/protobuf/proto"
)

// 包级私有变量,用于存储当前URL索引
var (
currentURLIndex int
urlsMutex sync.Mutex
)

// uploadMedia 上传媒体并返回FileInfo
func uploadMedia(ctx context.Context, groupID string, richMediaMessage *dto.RichMediaMessage, apiv2 openapi.OpenAPI) (string, error) {
// 调用API来上传媒体
@@ -55,6 +62,17 @@ func isNumeric(s string) bool {
func UploadBase64ImageToServer(msgid string, base64Image string, groupID string, apiv2 openapi.OpenAPI) (string, uint64, uint32, uint32, error) {
var picURL string
var err error
// 检查是否应该使用全局服务器临时QQ群的特殊上传行为
if config.GetGlobalServerTempQQguild() {
// 直接调用UploadBehaviorV3
downloadURL, width, height, err := UploadBehaviorV3(base64Image)
if err != nil {
log.Printf("Error UploadBehaviorV3: %v", err)
return "", 0, 0, 0, nil
}
return downloadURL, 0, width, height, nil
}

extraPicAuditingType := config.GetOssType()

switch extraPicAuditingType {
@@ -200,6 +218,51 @@ func originalUploadBehavior(base64Image string) (string, error) {
return "", errors.New("local server uses a private address; image upload failed")
}

func UploadBehaviorV3(base64Image string) (string, uint32, uint32, error) {
urls := config.GetServerTempQQguildPool()
if len(urls) > 0 {
urlsMutex.Lock()
url := urls[currentURLIndex]
currentURLIndex = (currentURLIndex + 1) % len(urls)
urlsMutex.Unlock()

resp, width, height, err := postImageToServerV3(base64Image, url)
if err != nil {
return "", 0, 0, err
}
return resp, width, height, nil
} else {
protocol := "http"
serverPort := config.GetPortValue()
if serverPort == "443" {
protocol = "https"
}

serverDir := config.GetServer_dir()
url := fmt.Sprintf("%s://%s:%s/uploadpicv3", protocol, serverDir, serverPort)

if config.GetLotusValue() {
resp, width, height, err := postImageToServerV3(base64Image, url)
if err != nil {
return "", 0, 0, err
}
return resp, width, height, nil
} else {
if serverPort == "443" {
protocol = "http"
serverPort = "444"
}
url = fmt.Sprintf("%s://127.0.0.1:%s/uploadpicv3", protocol, serverPort)

resp, width, height, err := postImageToServerV3(base64Image, url)
if err != nil {
return "", 0, 0, err
}
return resp, width, height, nil
}
}
}

// 将base64语音通过lotus转换成url
func originalUploadBehaviorRecord(base64Image string) (string, error) {
// 根据serverPort确定协议
@@ -271,6 +334,46 @@ func postImageToServer(base64Image, targetURL string) (string, error) {
return "", fmt.Errorf("URL not found in response")
}

// 请求图床api(图床就是lolus为false的gensokyo)
func postImageToServerV3(base64Image, targetURL string) (string, uint32, uint32, error) {
data := url.Values{}
channelID := config.GetServerTempQQguild()
data.Set("base64Image", base64Image) // 修改字段名以与服务器匹配
data.Set("channelID", channelID) // 修改字段名以与服务器匹配

resp, err := http.PostForm(targetURL, data)
if err != nil {
return "", 0, 0, fmt.Errorf("failed to send request: %v", err)
}
defer resp.Body.Close()

if resp.StatusCode != http.StatusOK {
return "", 0, 0, fmt.Errorf("error response from server: %s", resp.Status)
}

body, err := io.ReadAll(resp.Body)
if err != nil {
return "", 0, 0, fmt.Errorf("failed to read response body: %v", err)
}

var responseMap map[string]interface{}
if err := json.Unmarshal(body, &responseMap); err != nil {
return "", 0, 0, fmt.Errorf("failed to unmarshal response: %v", err)
}

url, okURL := responseMap["url"].(string)
width, okWidth := responseMap["width"].(float64) // JSON numbers are decoded as float64
height, okHeight := responseMap["height"].(float64)
if !okURL {
return "", 0, 0, fmt.Errorf("uRL not found in response")
}
if !okWidth || !okHeight {
return "", 0, 0, fmt.Errorf("width or Height not found in response")
}

return url, uint32(width), uint32(height), nil
}

// 请求语音床api(图床就是lolus为false的gensokyo)
func postRecordToServer(base64Image, targetURL string) (string, error) {
data := url.Values{}
6 changes: 5 additions & 1 deletion template/config_template.go
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ settings:
record_bitRate : 24000 #语音文件的比特率 默认25000 代表 25 kbps 最高无限 请根据带宽 您发送的实际码率调整
card_nick : "" #默认为空,连接mirai-overflow时,请设置为非空,这里是机器人对用户称谓,为空为插件获取,mirai不支持
auto_bind : true #测试功能,后期会移除
AMsgRetryAsPMsg_Count : 1 #当主动信息发送失败时,自动转为后续的被动信息发送,需要开启Lazy message id,该配置项为每次跟随被动信息发送的信息数量,最大5,建议1-3
AMsgRetryAsPMsg_Count : 30 #当主动信息发送失败时,自动转为后续的被动信息发送,需要开启Lazy message id,该配置项为所有群、频道的主动转被动消息队列最大长度,建议30-100,无上限
reconnect_times : 100 #反向ws连接失败后的重试次数,希望一直重试,可设置9999
heart_beat_interval : 10 #反向ws心跳间隔 单位秒 推荐5-10
launch_reconnect_times : 1 #启动时尝试反向ws连接次数,建议先打开应用端再开启gensokyo,因为启动时连接会阻塞webui启动,默认只连接一次,可自行增大
@@ -144,6 +144,10 @@ settings:
get_g_list_guilds : "10" #在获取群列表api时,一次返回的频道数量.这里是string,不要去掉引号.最大100(5分钟内连续请求=翻页),获取全部请开启get_g_list_return_guilds.
get_g_list_return_guilds : true #获取群列表时是否返回频道列表.

global_server_temp_qqguild : false #需设置server_temp_qqguild,公域私域均可用,以频道为底层发图,速度快,该接口为进阶接口,使用有一定难度.
server_temp_qqguild : "0" #在v3图片接口采用固定的子频道号,可以是帖子子频道 https://www.yuque.com/km57bt/hlhnxg/uqmnsno3vx1ytp2q
server_temp_qqguild_pool : [] #填写v3发图接口的endpoint http://127.0.0.1:12345/uploadpicv3 当填写多个时采用循环方式负载均衡,注,不包括自身,如需要自身也要填写

title : "Gensokyo © 2023 - Hoshinonyaruko" #程序的标题 如果多个机器人 可根据标题区分
custom_bot_name : "Gensokyo全域机器人" #自定义机器人名字,会在api调用中返回,默认Gensokyo全域机器人