Skip to content

Commit

Permalink
Beta344 (Hoshinonyaruko#351)
Browse files Browse the repository at this point in the history
* beta338

* beta319

* beta340

* beta341

* actionfix

* beta342

* beta342

* beta342

* beta344
  • Loading branch information
Hoshinonyaruko authored Mar 18, 2024
1 parent 4482e73 commit 302bdae
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 68 deletions.
65 changes: 65 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ type Settings struct {
ImgUpApiVtv2 bool `yaml:"img_up_api_ntv2"`
Fix11300 bool `yaml:"fix_11300"`
LotusWithoutIdmaps bool `yaml:"lotus_without_idmaps"`
GetGroupListAllGuilds bool `yaml:"get_g_list_all_guilds"`
GetGroupListGuilds string `yaml:"get_g_list_guilds"`
GetGroupListReturnGuilds bool `yaml:"get_g_list_return_guilds"`
GetGroupListGuidsType int `yaml:"get_g_list_guilds_type"`
GetGroupListDelay int `yaml:"get_g_list_delay"`
}

// LoadConfig 从文件中加载配置并初始化单例配置
Expand Down Expand Up @@ -1896,3 +1901,63 @@ func GetLotusWithoutIdmaps() bool {
}
return instance.Settings.LotusWithoutIdmaps
}

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

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

// 获取 GetGroupListGuilds 数量
func GetGetGroupListGuilds() string {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to get GetGroupListGuilds.")
return "10"
}
return instance.Settings.GetGroupListGuilds
}

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

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

// 获取 GetGroupListGuidsType 数量
func GetGroupListGuidsType() int {
mu.Lock()
defer mu.Unlock()

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

// 获取 GetGroupListDelay 数量
func GetGroupListDelay() int {
mu.Lock()
defer mu.Unlock()

if instance == nil {
mylog.Println("Warning: instance is nil when trying to get GetGroupListDelay.")
return 0
}
return instance.Settings.GetGroupListDelay
}
190 changes: 122 additions & 68 deletions handlers/get_group_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/hoshinonyaruko/gensokyo/callapi"
"github.com/hoshinonyaruko/gensokyo/config"
"github.com/hoshinonyaruko/gensokyo/idmap"
"github.com/hoshinonyaruko/gensokyo/mylog"
"github.com/tencent-connect/botgo/dto"
Expand Down Expand Up @@ -59,82 +60,67 @@ func GetGroupList(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Open

// 初始化 groupList.Data 为一个空数组
groupList.Data = []Group{}
// 检查时间差异
if time.Since(lastCallTime) > 5*time.Minute {
// 如果超过5分钟,则重置分页状态
globalPager = &dto.GuildPager{Limit: "10"}
}
// 全局pager
guilds, err := api.MeGuilds(context.TODO(), globalPager)
if err != nil {
mylog.Println("Error fetching guild list:", err)
return "", nil
}
if len(guilds) > 0 {
// 更新Pager的After为最后一个元素的ID
globalPager.After = guilds[len(guilds)-1].ID
}
lastCallTime = time.Now() // 更新上次调用API的时间
//如果为空 则不使用分页
if len(guilds) == 0 {
Pager := &dto.GuildPager{Limit: "10"}
guilds, err = api.MeGuilds(context.TODO(), Pager)
if err != nil {
mylog.Println("Error fetching guild list2:", err)
return "", nil
}
}
for _, guild := range guilds {
joinedAtTime, err := guild.JoinedAt.Time()
if err != nil {
mylog.Println("Error parsing JoinedAt timestamp:", err)
continue
}
groupID, _ := strconv.ParseInt(guild.ID, 10, 64)
joinedAtTimestamp := int32(joinedAtTime.Unix()) // 获取 10 位时间戳并转换为 int32 类型
group := Group{
GroupCreateTime: joinedAtTimestamp,
GroupID: groupID,
GroupLevel: 0,
GroupMemo: guild.Desc,
GroupName: "*" + guild.Name,
MaxMemberCount: int32(guild.MaxMembers), // 确保这里也是 int32 类型
MemberCount: int32(guild.MemberCount), // 将这里也转换为 int32 类型
}
groupList.Data = append(groupList.Data, group)
// 获取每个guild的channel信息
channels, err := api.Channels(context.TODO(), guild.ID) // 使用guild.ID作为参数
if err != nil {
mylog.Println("Error fetching channels list:", err)
continue
}
// 将channel信息转换为Group对象并添加到groups
for _, channel := range channels {
// 转换ChannelID64
ChannelID64, err := idmap.StoreIDv2(channel.ID)
if config.GetGroupListAllGuilds() {
pager := &dto.GuildPager{Limit: "100"}
totalFetched := 0

for {
guilds, err := api.MeGuilds(context.TODO(), pager)
if err != nil {
mylog.Printf("Error storing ID: %v", err)
mylog.Println("Error fetching guild list:", err)
break
}

// 根据channel.Type添加前缀
groupName := channel.Name
if channel.Type == dto.ChannelTypeText {
groupName = "&" + groupName
fetched := len(guilds)
if fetched == 0 {
break // 没有更多数据时退出循环
}

channelGroup := Group{
GroupCreateTime: 0, // 频道没有直接对应的创建时间字段
GroupID: ChannelID64,
GroupLevel: 0, // 频道没有直接对应的级别字段
GroupMemo: "", // 频道没有直接对应的描述字段
GroupName: groupName,
MaxMemberCount: 0, // 频道没有直接对应的最大成员数字段
MemberCount: 0, // 频道没有直接对应的成员数字段
}
totalFetched += fetched
requestCount := totalFetched / 100
mylog.Printf("Fetched %d guilds in request %d, total %d guilds\n", fetched, requestCount, totalFetched)

// 更新after,准备下一次请求
pager.After = guilds[fetched-1].ID

groupList.Data = append(groupList.Data, channelGroup)
for _, guild := range guilds {
ProcessGuildAndChannels(guild, api, &groupList.Data)
}
delay := config.GetGroupListDelay() // 获取配置中的延迟时间,单位为毫秒
time.Sleep(time.Duration(delay) * time.Millisecond) // 使用配置的延迟时间
}
} else if config.GetGroupListReturnGuilds() {
// 检查时间差异
if time.Since(lastCallTime) > 5*time.Minute {
// 如果超过5分钟,则重置分页状态
guildsLimit := config.GetGetGroupListGuilds()
globalPager = &dto.GuildPager{Limit: guildsLimit}
}
// 全局pager
guilds, err := api.MeGuilds(context.TODO(), globalPager)
if err != nil {
mylog.Println("Error fetching guild list:", err)
return "", nil
}
if len(guilds) > 0 {
// 更新Pager的After为最后一个元素的ID
globalPager.After = guilds[len(guilds)-1].ID
}
lastCallTime = time.Now() // 更新上次调用API的时间
//如果为空 则不使用分页
if len(guilds) == 0 {
Pager := &dto.GuildPager{Limit: "10"}
guilds, err = api.MeGuilds(context.TODO(), Pager)
if err != nil {
mylog.Println("Error fetching guild list2:", err)
return "", nil
}
}
for _, guild := range guilds {
ProcessGuildAndChannels(guild, api, &groupList.Data)
}
}

//从idmaps数据库找群,组合成群列表需要的格式
groupIDs, err := idmap.FindKeysBySubAndType("group", "type")
if err != nil {
Expand Down Expand Up @@ -189,3 +175,71 @@ func GetGroupList(client callapi.Client, api openapi.OpenAPI, apiv2 openapi.Open
mylog.Printf("get_group_list: %s", result)
return string(result), nil
}

// ProcessGuildAndChannels 处理单个guild及其channels,并将结果添加到groupList.Data
func ProcessGuildAndChannels(guild *dto.Guild, api openapi.OpenAPI, groupListData *[]Group) {
joinedAtTime, err := guild.JoinedAt.Time()
if err != nil {
mylog.Println("Error parsing JoinedAt timestamp:", err)
return
}
groupID, _ := strconv.ParseInt(guild.ID, 10, 64)
joinedAtTimestamp := int32(joinedAtTime.Unix()) // 获取 10 位时间戳并转换为 int32 类型
group := Group{
GroupCreateTime: joinedAtTimestamp,
GroupID: groupID,
GroupLevel: 0,
GroupMemo: guild.Desc,
GroupName: "*" + guild.Name,
MaxMemberCount: int32(guild.MaxMembers),
MemberCount: int32(guild.MemberCount),
}
*groupListData = append(*groupListData, group)

channels, err := api.Channels(context.TODO(), guild.ID)
if err != nil {
mylog.Println("Error fetching channels list:", err)
return
}

guidsType := config.GetGroupListGuidsType()
textChannelCount := 0 // 用于记录dto.ChannelTypeText类型的频道数量

for _, channel := range channels {
ChannelID64, err := idmap.StoreIDv2(channel.ID)
if err != nil {
mylog.Printf("Error storing ID: %v", err)
}

// 当guidsType不为0时,对频道类型进行特殊处理
if guidsType != 0 {
if channel.Type == dto.ChannelTypeText {
textChannelCount++
// 当guidsType为1但textChannelCount大于1时,或当guidsType为2但textChannelCount大于2时,跳过当前频道
if (guidsType == 1 && textChannelCount > 1) || (guidsType == 2 && textChannelCount > 2) {
continue
}
} else {
// 如果频道类型不是dto.ChannelTypeText,则根据guidsType丢弃
continue
}
}

groupName := channel.Name
if channel.Type == dto.ChannelTypeText {
groupName = "&" + groupName
}

channelGroup := Group{
GroupCreateTime: 0,
GroupID: ChannelID64,
GroupLevel: 0,
GroupMemo: "",
GroupName: groupName,
MaxMemberCount: 0,
MemberCount: 0,
}

*groupListData = append(*groupListData, channelGroup)
}
}
6 changes: 6 additions & 0 deletions template/config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ settings:
fix_11300: false #修复11300报错,需要在develop_bot_id填入自己机器人的appid. 11300原因暂时未知,临时修复方案.
lotus_without_idmaps: false #lotus只通过url,图片上传,语音,不通过id转换,在本地当前gsk维护idmaps转换.
get_g_list_all_guilds : false #在获取群列表api时,轮询获取全部的频道列表(api一次只能获取100个),建议仅在广播公告通知等特别场景时开启.
get_g_list_delay : 500 #轮询时的延迟时间,毫秒数.
get_g_list_guilds_type : 0 #0=全部返回,1=获取第1个子频道.以此类推.可以缩减返回值的大小.
get_g_list_guilds : "10" #在获取群列表api时,一次返回的频道数量.这里是string,不要去掉引号.最大100(5分钟内连续请求=翻页),获取全部请开启get_g_list_return_guilds.
get_g_list_return_guilds : true #获取群列表时是否返回频道列表.
title : "Gensokyo © 2023 - Hoshinonyaruko" #程序的标题 如果多个机器人 可根据标题区分
custom_bot_name : "Gensokyo全域机器人" #自定义机器人名字,会在api调用中返回,默认Gensokyo全域机器人
Expand Down

0 comments on commit 302bdae

Please sign in to comment.