From bc3c4303be7ff84fa17c34d945290b74d50e8887 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=B2=E5=AE=9D=E5=9D=8F=E5=9D=8F=E5=9D=8F?= <2758988938@qq.com> Date: Sat, 18 Mar 2023 00:28:31 +0800 Subject: [PATCH 01/11] fix jiami api (#624) --- plugin/jiami/jiami.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/jiami/jiami.go b/plugin/jiami/jiami.go index 290bc02afc..9849054c13 100644 --- a/plugin/jiami/jiami.go +++ b/plugin/jiami/jiami.go @@ -13,8 +13,8 @@ import ( ) const ( - jiami1 = "http://ovooa.com/API/sho_u/?msg=%v" // 加密api地址 - jiami2 = "http://ovooa.com/API/sho_u/?format=1&msg=%v" // 解密api地址 + jiami1 = "http://ovooa.caonm.net/API/sho_u/?msg=%v" // 加密api地址 + jiami2 = "http://ovooa.caonm.net/API/sho_u/?format=1&msg=%v" // 解密api地址 ) From f1dba97922a66c3206c7f3b0d4793a6132ef45ab Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Sat, 18 Mar 2023 00:30:22 +0800 Subject: [PATCH 02/11] feat: steam plugin (#621) --- README.md | 18 +++- main.go | 1 + plugin/bilibili/bilibili.go | 2 +- plugin/steam/listenter.go | 134 ++++++++++++++++++++++++++++++ plugin/steam/steam.go | 158 ++++++++++++++++++++++++++++++++++++ plugin/steam/store.go | 117 ++++++++++++++++++++++++++ 6 files changed, 428 insertions(+), 2 deletions(-) create mode 100644 plugin/steam/listenter.go create mode 100644 plugin/steam/steam.go create mode 100644 plugin/steam/store.go diff --git a/README.md b/README.md index 0d8904085e..b1a594aeca 100644 --- a/README.md +++ b/README.md @@ -559,7 +559,7 @@ print("run[CQ:image,file="+j["img"]+"]") - [x] b站推送列表 - - [x] 拉取b站推送 (使用job执行定时任务------记录在"@every 10s"触发的指令) + - [x] 拉取b站推送 (使用job执行定时任务------记录在"@every 5m"触发的指令)
@@ -1283,6 +1283,22 @@ print("run[CQ:image,file="+j["img"]+"]") - [x] 黄油角色[@xxx] +
+
+ steam + + `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/steam"` + + - [x] steam[添加|删除]订阅xxxxx + + - [x] steam查看订阅 + + - [x] steam绑定 api key xxxxxxx + + - [x] 查看apikey + + - [x] 拉取steam订阅 (使用job执行定时任务------记录在"@every 1m"触发的指令) +
抽塔罗牌 diff --git a/main.go b/main.go index 58308ab389..b6edd3cd20 100644 --- a/main.go +++ b/main.go @@ -131,6 +131,7 @@ import ( _ "github.com/FloatTech/ZeroBot-Plugin/plugin/setutime" // 来份涩图 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/shadiao" // 沙雕app _ "github.com/FloatTech/ZeroBot-Plugin/plugin/shindan" // 测定 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/steam" // steam相关 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/tarot" // 抽塔罗牌 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/tiangou" // 舔狗日记 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/tracemoe" // 搜番 diff --git a/plugin/bilibili/bilibili.go b/plugin/bilibili/bilibili.go index f6de28e712..60250b2d8d 100644 --- a/plugin/bilibili/bilibili.go +++ b/plugin/bilibili/bilibili.go @@ -56,7 +56,7 @@ func init() { "- 查成分 [xxx]\n" + "- 查弹幕 [xxx]\n" + "- 设置b站cookie b_ut=7;buvid3=0;i-wanna-go-back=-1;innersign=0;\n" + - "- 更新vup" + + "- 更新vup\n" + "Tips: (412就是拦截的意思,建议私聊把cookie设全)\n", PublicDataFolder: "Bilibili", }) diff --git a/plugin/steam/listenter.go b/plugin/steam/listenter.go new file mode 100644 index 0000000000..4e76f597c5 --- /dev/null +++ b/plugin/steam/listenter.go @@ -0,0 +1,134 @@ +package steam + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/FloatTech/floatbox/binary" + "github.com/FloatTech/floatbox/web" + ctrl "github.com/FloatTech/zbpctrl" + "github.com/tidwall/gjson" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +// ----------------------- 远程调用 ---------------------- +const ( + URL = "https://api.steampowered.com/" // steam API 调用地址 + StatusURL = "ISteamUser/GetPlayerSummaries/v2/?key=%+v&steamids=%+v" // 根据用户steamID获取用户状态 + steamapikeygid = 3 +) + +var apiKey string + +func init() { + engine.OnRegex(`^steam绑定\s*api\s*key\s*(.*)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { + apiKey = ctx.State["regex_matched"].([]string)[1] + m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + _ = m.Manager.Response(steamapikeygid) + err := m.Manager.SetExtra(steamapikeygid, apiKey) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: 保存apikey失败!")) + return + } + ctx.SendChain(message.Text("保存apikey成功!")) + }) + engine.OnFullMatch("查看apikey", zero.OnlyPrivate, zero.SuperUserPermission, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + ctx.SendChain(message.Text("apikey为: ", apiKey)) + }) + engine.OnFullMatch("拉取steam订阅", getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + su := zero.BotConfig.SuperUsers[0] + // 获取所有处于监听状态的用户信息 + infos, err := database.findAll() + if err != nil { + // 挂了就给管理员发消息 + ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err)) + return + } + if len(infos) == 0 { + return + } + // 收集这波用户的streamId,然后查当前的状态,并建立信息映射表 + streamIds := make([]string, len(infos)) + localPlayerMap := make(map[int64]*player) + for i, info := range infos { + streamIds[i] = strconv.FormatInt(info.SteamID, 10) + localPlayerMap[info.SteamID] = info + } + // 将所有用户状态查一遍 + playerStatus, err := getPlayerStatus(streamIds...) + if err != nil { + // 出错就发消息 + ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err)) + return + } + // 遍历返回的信息做对比,假如信息有变化则发消息 + now := time.Now() + msg := make(message.Message, 0, len(playerStatus)) + for _, playerInfo := range playerStatus { + msg = msg[:0] + localInfo := localPlayerMap[playerInfo.SteamID] + // 排除不需要处理的情况 + if localInfo.GameID == 0 && playerInfo.GameID == 0 { + continue + } + // 打开游戏 + if localInfo.GameID == 0 && playerInfo.GameID != 0 { + msg = append(msg, message.Text(playerInfo.PersonaName, "正在玩", playerInfo.GameExtraInfo)) + localInfo.LastUpdate = now.Unix() + } + // 更换游戏 + if localInfo.GameID != 0 && playerInfo.GameID != localInfo.GameID && playerInfo.GameID != 0 { + msg = append(msg, message.Text(playerInfo.PersonaName, "玩了", (now.Unix()-localInfo.LastUpdate)/60, "分钟后, 丢下了", localInfo.GameExtraInfo, ", 转头去玩", playerInfo.GameExtraInfo)) + localInfo.LastUpdate = now.Unix() + } + // 关闭游戏 + if playerInfo.GameID != localInfo.GameID && playerInfo.GameID == 0 { + msg = append(msg, message.Text(playerInfo.PersonaName, "玩了", (now.Unix()-localInfo.LastUpdate)/60, "分钟后, 关掉了", localInfo.GameExtraInfo)) + localInfo.LastUpdate = 0 + } + if len(msg) != 0 { + groups := strings.Split(localInfo.Target, ",") + for _, groupString := range groups { + group, err := strconv.ParseInt(groupString, 10, 64) + if err != nil { + ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err, "\nOTHER: SteamID ", localInfo.SteamID)) + continue + } + ctx.SendGroupMessage(group, msg) + } + } + // 更新数据 + localInfo.GameID = playerInfo.GameID + localInfo.GameExtraInfo = playerInfo.GameExtraInfo + if err = database.update(localInfo); err != nil { + ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err, "\nEXP: 更新数据失败\nOTHER: SteamID ", localInfo.SteamID)) + } + } + }) +} + +// getPlayerStatus 获取用户状态 +func getPlayerStatus(streamIds ...string) ([]*player, error) { + players := make([]*player, 0) + // 拼接请求地址 + url := fmt.Sprintf(URL+StatusURL, apiKey, strings.Join(streamIds, ",")) + // 拉取并解析数据 + data, err := web.GetData(url) + if err != nil { + return players, err + } + dataStr := binary.BytesToString(data) + index := gjson.Get(dataStr, "response.players.#").Uint() + for i := uint64(0); i < index; i++ { + players = append(players, &player{ + SteamID: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.steamid", i)).Int(), + PersonaName: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.personaname", i)).String(), + GameID: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.gameid", i)).Int(), + GameExtraInfo: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.gameextrainfo", i)).String(), + }) + } + return players, nil +} diff --git a/plugin/steam/steam.go b/plugin/steam/steam.go new file mode 100644 index 0000000000..ac9f3f116c --- /dev/null +++ b/plugin/steam/steam.go @@ -0,0 +1,158 @@ +// Package steam 获取steam用户状态 +package steam + +import ( + "strconv" + "strings" + "time" + + "github.com/FloatTech/floatbox/binary" + "github.com/FloatTech/floatbox/math" + ctrl "github.com/FloatTech/zbpctrl" + "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" + "github.com/FloatTech/zbputils/img/text" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +var ( + engine = control.Register("steam", &ctrl.Options[*zero.Ctx]{ + DisableOnDefault: false, + Brief: "steam相关插件", + Help: "- steam添加订阅 xxxxxxx (可输入需要绑定的 steamid)\n" + + "- steam删除订阅 xxxxxxx (删除你创建的对于 steamid 的绑定)\n" + + "- steam查询订阅 (查询本群内所有的绑定对象)\n" + + "-----------------------\n" + + "- steam绑定 api key xxxxxxx (密钥在steam网站申请, 申请地址: https://steamcommunity.com/dev/registerkey)\n" + + "- 查看apikey (查询已经绑定的密钥)\n" + + "- 拉取steam订阅 (使用插件定时任务开始)\n" + + "-----------------------\n" + + "Tips: steamID在用户资料页的链接上面, 形如7656119820673xxxx\n" + + "需要先私聊绑定apikey, 订阅用户之后使用job插件设置定时, 例: \n" + + "记录在\"@every 1m\"触发的指令\n" + + "拉取steam订阅", + PrivateDataFolder: "steam", + }).ApplySingle(ctxext.DefaultSingle) +) + +func init() { + // 创建绑定流程 + engine.OnRegex(`^steam添加订阅\s*(\d+)$`, zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + steamidstr := ctx.State["regex_matched"].([]string)[1] + steamID := math.Str2Int64(steamidstr) + // 获取用户状态 + playerStatus, err := getPlayerStatus(steamidstr) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 添加失败, 获取用户信息错误")) + return + } + if len(playerStatus) == 0 { + ctx.SendChain(message.Text("[steam] ERROR: 需要添加的用户不存在, 请检查id或url")) + return + } + playerData := playerStatus[0] + // 判断用户是否已经初始化:若未初始化,通过用户的steamID获取当前状态并初始化;若已经初始化则更新用户信息 + info, err := database.find(steamID) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 添加失败,数据库错误")) + return + } + // 处理数据 + groupID := strconv.FormatInt(ctx.Event.GroupID, 10) + if info.Target == "" { + info = player{ + SteamID: steamID, + PersonaName: playerData.PersonaName, + Target: groupID, + GameID: playerData.GameID, + GameExtraInfo: playerData.GameExtraInfo, + LastUpdate: time.Now().Unix(), + } + } else if !strings.Contains(info.Target, groupID) { + info.Target = strings.Join([]string{info.Target, groupID}, ",") + } + // 更新数据库 + if err = database.update(&info); err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 更新数据库失败")) + return + } + ctx.SendChain(message.Text("添加成功")) + }) + // 删除绑定流程 + engine.OnRegex(`^steam删除订阅\s*(\d+)$`, zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + steamID := math.Str2Int64(ctx.State["regex_matched"].([]string)[1]) + groupID := strconv.FormatInt(ctx.Event.GroupID, 10) + // 判断是否已经绑定该steamID,若已绑定就将群列表从推送群列表钟去除 + info, err := database.findWithGroupID(steamID, groupID) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) + return + } + if info.SteamID == 0 { + ctx.SendChain(message.Text("[steam] ERROR: 所需要删除的用户不存在。")) + return + } + // 从绑定列表中剔除需要删除的对象 + targets := strings.Split(info.Target, ",") + newTargets := make([]string, 0) + for _, target := range targets { + if target == groupID { + continue + } + newTargets = append(newTargets, target) + } + if len(newTargets) == 0 { + if err = database.del(steamID); err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) + return + } + } else { + info.Target = strings.Join(newTargets, ",") + if err = database.update(&info); err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) + return + } + } + ctx.SendChain(message.Text("删除成功")) + }) + // 查询当前群绑定信息 + engine.OnFullMatch("steam查询订阅", zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + // 获取群信息 + groupID := strconv.FormatInt(ctx.Event.GroupID, 10) + // 获取所有绑定信息 + infos, err := database.findAll() + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 查询订阅失败, 数据库错误")) + return + } + if len(infos) == 0 { + ctx.SendChain(message.Text("[steam] ERROR: 还未订阅过用户关系!")) + return + } + // 遍历所有信息,如果包含该群就收集对应的steamID + var sb strings.Builder + head := " 查询steam订阅成功, 该群订阅的用户有: \n" + sb.WriteString(head) + for _, info := range infos { + if strings.Contains(info.Target, groupID) { + sb.WriteString(" ") + sb.WriteString(info.PersonaName) + sb.WriteString(":") + sb.WriteString(strconv.FormatInt(info.SteamID, 10)) + sb.WriteString("\n") + } + } + if sb.String() == head { + ctx.SendChain(message.Text("查询成功,该群暂时还没有被绑定的用户!")) + return + } + // 组装并返回结果 + data, err := text.RenderToBase64(sb.String(), text.FontFile, 400, 18) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err)) + return + } + ctx.SendChain(message.Image("base64://" + binary.BytesToString(data))) + }) +} diff --git a/plugin/steam/store.go b/plugin/steam/store.go new file mode 100644 index 0000000000..b175fb2164 --- /dev/null +++ b/plugin/steam/store.go @@ -0,0 +1,117 @@ +package steam + +import ( + "strconv" + "sync" + "time" + + fcext "github.com/FloatTech/floatbox/ctxext" + sql "github.com/FloatTech/sqlite" + ctrl "github.com/FloatTech/zbpctrl" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +var ( + database streamDB + // 开启并检查数据库链接 + getDB = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { + database.db.DBPath = engine.DataFolder() + "steam.db" + err := database.db.Open(time.Hour * 24) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err)) + return false + } + if err = database.db.Create(TableListenPlayer, &player{}); err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err)) + return false + } + // 校验密钥是否初始化 + m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + _ = m.Manager.Response(steamapikeygid) + _ = m.Manager.GetExtra(steamapikeygid, &apiKey) + if apiKey == "" { + ctx.SendChain(message.Text("ERROR: 未设置steam apikey")) + return false + } + return true + }) +) + +// streamDB 继承方法的存储结构 +type streamDB struct { + sync.RWMutex + db sql.Sqlite +} + +const ( + // TableListenPlayer 存储查询用户信息 + TableListenPlayer = "listen_player" +) + +// player 用户状态存储结构体 +type player struct { + SteamID int64 `json:"steam_id"` // 绑定用户标识ID + PersonaName string `json:"persona_name"` // 用户昵称 + Target string `json:"target"` // 信息推送群组 + GameID int64 `json:"game_id"` // 游戏ID + GameExtraInfo string `json:"game_extra_info"` // 游戏信息 + LastUpdate int64 `json:"last_update"` // 更新时间 +} + +// update 如果主键不存在则插入一条新的数据,如果主键存在直接复写 +func (sql *streamDB) update(dbInfo *player) error { + sql.Lock() + defer sql.Unlock() + return sql.db.Insert(TableListenPlayer, dbInfo) +} + +// find 根据主键查信息 +func (sql *streamDB) find(steamID int64) (dbInfo player, err error) { + sql.Lock() + defer sql.Unlock() + condition := "where steam_id = " + strconv.FormatInt(steamID, 10) + if !sql.db.CanFind(TableListenPlayer, condition) { + return player{}, nil // 规避没有该用户数据的报错 + } + err = sql.db.Find(TableListenPlayer, &dbInfo, condition) + return +} + +// findWithGroupID 根据用户steamID和groupID查询信息 +func (sql *streamDB) findWithGroupID(steamID int64, groupID string) (dbInfo player, err error) { + sql.Lock() + defer sql.Unlock() + condition := "where steam_id = " + strconv.FormatInt(steamID, 10) + " AND target LIKE '%" + groupID + "%'" + if !sql.db.CanFind(TableListenPlayer, condition) { + return player{}, nil // 规避没有该用户数据的报错 + } + err = sql.db.Find(TableListenPlayer, &dbInfo, condition) + return +} + +// findAll 查询所有库信息 +func (sql *streamDB) findAll() (dbInfos []*player, err error) { + sql.Lock() + defer sql.Unlock() + var info player + num, err := sql.db.Count(TableListenPlayer) + if err != nil || num == 0 { + return + } + dbInfos = make([]*player, 0, num) + err = sql.db.FindFor(TableListenPlayer, &info, "", func() error { + if info.SteamID != 0 { + dbInfos = append(dbInfos, &info) + } + return nil + }) + return +} + +// del 删除指定数据 +func (sql *streamDB) del(steamID int64) error { + sql.Lock() + defer sql.Unlock() + return sql.db.Del(TableListenPlayer, "where steam_id = "+strconv.FormatInt(steamID, 10)) +} From 107149892c517ca07b9c02ba12e42ef8313c0ed9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 18 Mar 2023 00:32:36 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=F0=9F=8E=A8=20=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=A0=B7=E5=BC=8F=20(#625)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- plugin/steam/listenter.go | 268 ++++++++++++++++---------------- plugin/steam/steam.go | 316 +++++++++++++++++++------------------- plugin/steam/store.go | 234 ++++++++++++++-------------- 3 files changed, 409 insertions(+), 409 deletions(-) diff --git a/plugin/steam/listenter.go b/plugin/steam/listenter.go index 4e76f597c5..9cf2ca3431 100644 --- a/plugin/steam/listenter.go +++ b/plugin/steam/listenter.go @@ -1,134 +1,134 @@ -package steam - -import ( - "fmt" - "strconv" - "strings" - "time" - - "github.com/FloatTech/floatbox/binary" - "github.com/FloatTech/floatbox/web" - ctrl "github.com/FloatTech/zbpctrl" - "github.com/tidwall/gjson" - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" -) - -// ----------------------- 远程调用 ---------------------- -const ( - URL = "https://api.steampowered.com/" // steam API 调用地址 - StatusURL = "ISteamUser/GetPlayerSummaries/v2/?key=%+v&steamids=%+v" // 根据用户steamID获取用户状态 - steamapikeygid = 3 -) - -var apiKey string - -func init() { - engine.OnRegex(`^steam绑定\s*api\s*key\s*(.*)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { - apiKey = ctx.State["regex_matched"].([]string)[1] - m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) - _ = m.Manager.Response(steamapikeygid) - err := m.Manager.SetExtra(steamapikeygid, apiKey) - if err != nil { - ctx.SendChain(message.Text("[steam] ERROR: 保存apikey失败!")) - return - } - ctx.SendChain(message.Text("保存apikey成功!")) - }) - engine.OnFullMatch("查看apikey", zero.OnlyPrivate, zero.SuperUserPermission, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { - ctx.SendChain(message.Text("apikey为: ", apiKey)) - }) - engine.OnFullMatch("拉取steam订阅", getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { - su := zero.BotConfig.SuperUsers[0] - // 获取所有处于监听状态的用户信息 - infos, err := database.findAll() - if err != nil { - // 挂了就给管理员发消息 - ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err)) - return - } - if len(infos) == 0 { - return - } - // 收集这波用户的streamId,然后查当前的状态,并建立信息映射表 - streamIds := make([]string, len(infos)) - localPlayerMap := make(map[int64]*player) - for i, info := range infos { - streamIds[i] = strconv.FormatInt(info.SteamID, 10) - localPlayerMap[info.SteamID] = info - } - // 将所有用户状态查一遍 - playerStatus, err := getPlayerStatus(streamIds...) - if err != nil { - // 出错就发消息 - ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err)) - return - } - // 遍历返回的信息做对比,假如信息有变化则发消息 - now := time.Now() - msg := make(message.Message, 0, len(playerStatus)) - for _, playerInfo := range playerStatus { - msg = msg[:0] - localInfo := localPlayerMap[playerInfo.SteamID] - // 排除不需要处理的情况 - if localInfo.GameID == 0 && playerInfo.GameID == 0 { - continue - } - // 打开游戏 - if localInfo.GameID == 0 && playerInfo.GameID != 0 { - msg = append(msg, message.Text(playerInfo.PersonaName, "正在玩", playerInfo.GameExtraInfo)) - localInfo.LastUpdate = now.Unix() - } - // 更换游戏 - if localInfo.GameID != 0 && playerInfo.GameID != localInfo.GameID && playerInfo.GameID != 0 { - msg = append(msg, message.Text(playerInfo.PersonaName, "玩了", (now.Unix()-localInfo.LastUpdate)/60, "分钟后, 丢下了", localInfo.GameExtraInfo, ", 转头去玩", playerInfo.GameExtraInfo)) - localInfo.LastUpdate = now.Unix() - } - // 关闭游戏 - if playerInfo.GameID != localInfo.GameID && playerInfo.GameID == 0 { - msg = append(msg, message.Text(playerInfo.PersonaName, "玩了", (now.Unix()-localInfo.LastUpdate)/60, "分钟后, 关掉了", localInfo.GameExtraInfo)) - localInfo.LastUpdate = 0 - } - if len(msg) != 0 { - groups := strings.Split(localInfo.Target, ",") - for _, groupString := range groups { - group, err := strconv.ParseInt(groupString, 10, 64) - if err != nil { - ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err, "\nOTHER: SteamID ", localInfo.SteamID)) - continue - } - ctx.SendGroupMessage(group, msg) - } - } - // 更新数据 - localInfo.GameID = playerInfo.GameID - localInfo.GameExtraInfo = playerInfo.GameExtraInfo - if err = database.update(localInfo); err != nil { - ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err, "\nEXP: 更新数据失败\nOTHER: SteamID ", localInfo.SteamID)) - } - } - }) -} - -// getPlayerStatus 获取用户状态 -func getPlayerStatus(streamIds ...string) ([]*player, error) { - players := make([]*player, 0) - // 拼接请求地址 - url := fmt.Sprintf(URL+StatusURL, apiKey, strings.Join(streamIds, ",")) - // 拉取并解析数据 - data, err := web.GetData(url) - if err != nil { - return players, err - } - dataStr := binary.BytesToString(data) - index := gjson.Get(dataStr, "response.players.#").Uint() - for i := uint64(0); i < index; i++ { - players = append(players, &player{ - SteamID: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.steamid", i)).Int(), - PersonaName: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.personaname", i)).String(), - GameID: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.gameid", i)).Int(), - GameExtraInfo: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.gameextrainfo", i)).String(), - }) - } - return players, nil -} +package steam + +import ( + "fmt" + "strconv" + "strings" + "time" + + "github.com/FloatTech/floatbox/binary" + "github.com/FloatTech/floatbox/web" + ctrl "github.com/FloatTech/zbpctrl" + "github.com/tidwall/gjson" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +// ----------------------- 远程调用 ---------------------- +const ( + URL = "https://api.steampowered.com/" // steam API 调用地址 + StatusURL = "ISteamUser/GetPlayerSummaries/v2/?key=%+v&steamids=%+v" // 根据用户steamID获取用户状态 + steamapikeygid = 3 +) + +var apiKey string + +func init() { + engine.OnRegex(`^steam绑定\s*api\s*key\s*(.*)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) { + apiKey = ctx.State["regex_matched"].([]string)[1] + m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + _ = m.Manager.Response(steamapikeygid) + err := m.Manager.SetExtra(steamapikeygid, apiKey) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: 保存apikey失败!")) + return + } + ctx.SendChain(message.Text("保存apikey成功!")) + }) + engine.OnFullMatch("查看apikey", zero.OnlyPrivate, zero.SuperUserPermission, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + ctx.SendChain(message.Text("apikey为: ", apiKey)) + }) + engine.OnFullMatch("拉取steam订阅", getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + su := zero.BotConfig.SuperUsers[0] + // 获取所有处于监听状态的用户信息 + infos, err := database.findAll() + if err != nil { + // 挂了就给管理员发消息 + ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err)) + return + } + if len(infos) == 0 { + return + } + // 收集这波用户的streamId,然后查当前的状态,并建立信息映射表 + streamIds := make([]string, len(infos)) + localPlayerMap := make(map[int64]*player) + for i, info := range infos { + streamIds[i] = strconv.FormatInt(info.SteamID, 10) + localPlayerMap[info.SteamID] = info + } + // 将所有用户状态查一遍 + playerStatus, err := getPlayerStatus(streamIds...) + if err != nil { + // 出错就发消息 + ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err)) + return + } + // 遍历返回的信息做对比,假如信息有变化则发消息 + now := time.Now() + msg := make(message.Message, 0, len(playerStatus)) + for _, playerInfo := range playerStatus { + msg = msg[:0] + localInfo := localPlayerMap[playerInfo.SteamID] + // 排除不需要处理的情况 + if localInfo.GameID == 0 && playerInfo.GameID == 0 { + continue + } + // 打开游戏 + if localInfo.GameID == 0 && playerInfo.GameID != 0 { + msg = append(msg, message.Text(playerInfo.PersonaName, "正在玩", playerInfo.GameExtraInfo)) + localInfo.LastUpdate = now.Unix() + } + // 更换游戏 + if localInfo.GameID != 0 && playerInfo.GameID != localInfo.GameID && playerInfo.GameID != 0 { + msg = append(msg, message.Text(playerInfo.PersonaName, "玩了", (now.Unix()-localInfo.LastUpdate)/60, "分钟后, 丢下了", localInfo.GameExtraInfo, ", 转头去玩", playerInfo.GameExtraInfo)) + localInfo.LastUpdate = now.Unix() + } + // 关闭游戏 + if playerInfo.GameID != localInfo.GameID && playerInfo.GameID == 0 { + msg = append(msg, message.Text(playerInfo.PersonaName, "玩了", (now.Unix()-localInfo.LastUpdate)/60, "分钟后, 关掉了", localInfo.GameExtraInfo)) + localInfo.LastUpdate = 0 + } + if len(msg) != 0 { + groups := strings.Split(localInfo.Target, ",") + for _, groupString := range groups { + group, err := strconv.ParseInt(groupString, 10, 64) + if err != nil { + ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err, "\nOTHER: SteamID ", localInfo.SteamID)) + continue + } + ctx.SendGroupMessage(group, msg) + } + } + // 更新数据 + localInfo.GameID = playerInfo.GameID + localInfo.GameExtraInfo = playerInfo.GameExtraInfo + if err = database.update(localInfo); err != nil { + ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err, "\nEXP: 更新数据失败\nOTHER: SteamID ", localInfo.SteamID)) + } + } + }) +} + +// getPlayerStatus 获取用户状态 +func getPlayerStatus(streamIds ...string) ([]*player, error) { + players := make([]*player, 0) + // 拼接请求地址 + url := fmt.Sprintf(URL+StatusURL, apiKey, strings.Join(streamIds, ",")) + // 拉取并解析数据 + data, err := web.GetData(url) + if err != nil { + return players, err + } + dataStr := binary.BytesToString(data) + index := gjson.Get(dataStr, "response.players.#").Uint() + for i := uint64(0); i < index; i++ { + players = append(players, &player{ + SteamID: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.steamid", i)).Int(), + PersonaName: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.personaname", i)).String(), + GameID: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.gameid", i)).Int(), + GameExtraInfo: gjson.Get(dataStr, fmt.Sprintf("response.players.%d.gameextrainfo", i)).String(), + }) + } + return players, nil +} diff --git a/plugin/steam/steam.go b/plugin/steam/steam.go index ac9f3f116c..925dc90a99 100644 --- a/plugin/steam/steam.go +++ b/plugin/steam/steam.go @@ -1,158 +1,158 @@ -// Package steam 获取steam用户状态 -package steam - -import ( - "strconv" - "strings" - "time" - - "github.com/FloatTech/floatbox/binary" - "github.com/FloatTech/floatbox/math" - ctrl "github.com/FloatTech/zbpctrl" - "github.com/FloatTech/zbputils/control" - "github.com/FloatTech/zbputils/ctxext" - "github.com/FloatTech/zbputils/img/text" - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" -) - -var ( - engine = control.Register("steam", &ctrl.Options[*zero.Ctx]{ - DisableOnDefault: false, - Brief: "steam相关插件", - Help: "- steam添加订阅 xxxxxxx (可输入需要绑定的 steamid)\n" + - "- steam删除订阅 xxxxxxx (删除你创建的对于 steamid 的绑定)\n" + - "- steam查询订阅 (查询本群内所有的绑定对象)\n" + - "-----------------------\n" + - "- steam绑定 api key xxxxxxx (密钥在steam网站申请, 申请地址: https://steamcommunity.com/dev/registerkey)\n" + - "- 查看apikey (查询已经绑定的密钥)\n" + - "- 拉取steam订阅 (使用插件定时任务开始)\n" + - "-----------------------\n" + - "Tips: steamID在用户资料页的链接上面, 形如7656119820673xxxx\n" + - "需要先私聊绑定apikey, 订阅用户之后使用job插件设置定时, 例: \n" + - "记录在\"@every 1m\"触发的指令\n" + - "拉取steam订阅", - PrivateDataFolder: "steam", - }).ApplySingle(ctxext.DefaultSingle) -) - -func init() { - // 创建绑定流程 - engine.OnRegex(`^steam添加订阅\s*(\d+)$`, zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { - steamidstr := ctx.State["regex_matched"].([]string)[1] - steamID := math.Str2Int64(steamidstr) - // 获取用户状态 - playerStatus, err := getPlayerStatus(steamidstr) - if err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 添加失败, 获取用户信息错误")) - return - } - if len(playerStatus) == 0 { - ctx.SendChain(message.Text("[steam] ERROR: 需要添加的用户不存在, 请检查id或url")) - return - } - playerData := playerStatus[0] - // 判断用户是否已经初始化:若未初始化,通过用户的steamID获取当前状态并初始化;若已经初始化则更新用户信息 - info, err := database.find(steamID) - if err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 添加失败,数据库错误")) - return - } - // 处理数据 - groupID := strconv.FormatInt(ctx.Event.GroupID, 10) - if info.Target == "" { - info = player{ - SteamID: steamID, - PersonaName: playerData.PersonaName, - Target: groupID, - GameID: playerData.GameID, - GameExtraInfo: playerData.GameExtraInfo, - LastUpdate: time.Now().Unix(), - } - } else if !strings.Contains(info.Target, groupID) { - info.Target = strings.Join([]string{info.Target, groupID}, ",") - } - // 更新数据库 - if err = database.update(&info); err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 更新数据库失败")) - return - } - ctx.SendChain(message.Text("添加成功")) - }) - // 删除绑定流程 - engine.OnRegex(`^steam删除订阅\s*(\d+)$`, zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { - steamID := math.Str2Int64(ctx.State["regex_matched"].([]string)[1]) - groupID := strconv.FormatInt(ctx.Event.GroupID, 10) - // 判断是否已经绑定该steamID,若已绑定就将群列表从推送群列表钟去除 - info, err := database.findWithGroupID(steamID, groupID) - if err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) - return - } - if info.SteamID == 0 { - ctx.SendChain(message.Text("[steam] ERROR: 所需要删除的用户不存在。")) - return - } - // 从绑定列表中剔除需要删除的对象 - targets := strings.Split(info.Target, ",") - newTargets := make([]string, 0) - for _, target := range targets { - if target == groupID { - continue - } - newTargets = append(newTargets, target) - } - if len(newTargets) == 0 { - if err = database.del(steamID); err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) - return - } - } else { - info.Target = strings.Join(newTargets, ",") - if err = database.update(&info); err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) - return - } - } - ctx.SendChain(message.Text("删除成功")) - }) - // 查询当前群绑定信息 - engine.OnFullMatch("steam查询订阅", zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { - // 获取群信息 - groupID := strconv.FormatInt(ctx.Event.GroupID, 10) - // 获取所有绑定信息 - infos, err := database.findAll() - if err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 查询订阅失败, 数据库错误")) - return - } - if len(infos) == 0 { - ctx.SendChain(message.Text("[steam] ERROR: 还未订阅过用户关系!")) - return - } - // 遍历所有信息,如果包含该群就收集对应的steamID - var sb strings.Builder - head := " 查询steam订阅成功, 该群订阅的用户有: \n" - sb.WriteString(head) - for _, info := range infos { - if strings.Contains(info.Target, groupID) { - sb.WriteString(" ") - sb.WriteString(info.PersonaName) - sb.WriteString(":") - sb.WriteString(strconv.FormatInt(info.SteamID, 10)) - sb.WriteString("\n") - } - } - if sb.String() == head { - ctx.SendChain(message.Text("查询成功,该群暂时还没有被绑定的用户!")) - return - } - // 组装并返回结果 - data, err := text.RenderToBase64(sb.String(), text.FontFile, 400, 18) - if err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err)) - return - } - ctx.SendChain(message.Image("base64://" + binary.BytesToString(data))) - }) -} +// Package steam 获取steam用户状态 +package steam + +import ( + "strconv" + "strings" + "time" + + "github.com/FloatTech/floatbox/binary" + "github.com/FloatTech/floatbox/math" + ctrl "github.com/FloatTech/zbpctrl" + "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/ctxext" + "github.com/FloatTech/zbputils/img/text" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +var ( + engine = control.Register("steam", &ctrl.Options[*zero.Ctx]{ + DisableOnDefault: false, + Brief: "steam相关插件", + Help: "- steam添加订阅 xxxxxxx (可输入需要绑定的 steamid)\n" + + "- steam删除订阅 xxxxxxx (删除你创建的对于 steamid 的绑定)\n" + + "- steam查询订阅 (查询本群内所有的绑定对象)\n" + + "-----------------------\n" + + "- steam绑定 api key xxxxxxx (密钥在steam网站申请, 申请地址: https://steamcommunity.com/dev/registerkey)\n" + + "- 查看apikey (查询已经绑定的密钥)\n" + + "- 拉取steam订阅 (使用插件定时任务开始)\n" + + "-----------------------\n" + + "Tips: steamID在用户资料页的链接上面, 形如7656119820673xxxx\n" + + "需要先私聊绑定apikey, 订阅用户之后使用job插件设置定时, 例: \n" + + "记录在\"@every 1m\"触发的指令\n" + + "拉取steam订阅", + PrivateDataFolder: "steam", + }).ApplySingle(ctxext.DefaultSingle) +) + +func init() { + // 创建绑定流程 + engine.OnRegex(`^steam添加订阅\s*(\d+)$`, zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + steamidstr := ctx.State["regex_matched"].([]string)[1] + steamID := math.Str2Int64(steamidstr) + // 获取用户状态 + playerStatus, err := getPlayerStatus(steamidstr) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 添加失败, 获取用户信息错误")) + return + } + if len(playerStatus) == 0 { + ctx.SendChain(message.Text("[steam] ERROR: 需要添加的用户不存在, 请检查id或url")) + return + } + playerData := playerStatus[0] + // 判断用户是否已经初始化:若未初始化,通过用户的steamID获取当前状态并初始化;若已经初始化则更新用户信息 + info, err := database.find(steamID) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 添加失败,数据库错误")) + return + } + // 处理数据 + groupID := strconv.FormatInt(ctx.Event.GroupID, 10) + if info.Target == "" { + info = player{ + SteamID: steamID, + PersonaName: playerData.PersonaName, + Target: groupID, + GameID: playerData.GameID, + GameExtraInfo: playerData.GameExtraInfo, + LastUpdate: time.Now().Unix(), + } + } else if !strings.Contains(info.Target, groupID) { + info.Target = strings.Join([]string{info.Target, groupID}, ",") + } + // 更新数据库 + if err = database.update(&info); err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 更新数据库失败")) + return + } + ctx.SendChain(message.Text("添加成功")) + }) + // 删除绑定流程 + engine.OnRegex(`^steam删除订阅\s*(\d+)$`, zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + steamID := math.Str2Int64(ctx.State["regex_matched"].([]string)[1]) + groupID := strconv.FormatInt(ctx.Event.GroupID, 10) + // 判断是否已经绑定该steamID,若已绑定就将群列表从推送群列表钟去除 + info, err := database.findWithGroupID(steamID, groupID) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) + return + } + if info.SteamID == 0 { + ctx.SendChain(message.Text("[steam] ERROR: 所需要删除的用户不存在。")) + return + } + // 从绑定列表中剔除需要删除的对象 + targets := strings.Split(info.Target, ",") + newTargets := make([]string, 0) + for _, target := range targets { + if target == groupID { + continue + } + newTargets = append(newTargets, target) + } + if len(newTargets) == 0 { + if err = database.del(steamID); err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) + return + } + } else { + info.Target = strings.Join(newTargets, ",") + if err = database.update(&info); err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 删除失败,数据库错误")) + return + } + } + ctx.SendChain(message.Text("删除成功")) + }) + // 查询当前群绑定信息 + engine.OnFullMatch("steam查询订阅", zero.OnlyGroup, getDB).SetBlock(true).Handle(func(ctx *zero.Ctx) { + // 获取群信息 + groupID := strconv.FormatInt(ctx.Event.GroupID, 10) + // 获取所有绑定信息 + infos, err := database.findAll() + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err, "\nEXP: 查询订阅失败, 数据库错误")) + return + } + if len(infos) == 0 { + ctx.SendChain(message.Text("[steam] ERROR: 还未订阅过用户关系!")) + return + } + // 遍历所有信息,如果包含该群就收集对应的steamID + var sb strings.Builder + head := " 查询steam订阅成功, 该群订阅的用户有: \n" + sb.WriteString(head) + for _, info := range infos { + if strings.Contains(info.Target, groupID) { + sb.WriteString(" ") + sb.WriteString(info.PersonaName) + sb.WriteString(":") + sb.WriteString(strconv.FormatInt(info.SteamID, 10)) + sb.WriteString("\n") + } + } + if sb.String() == head { + ctx.SendChain(message.Text("查询成功,该群暂时还没有被绑定的用户!")) + return + } + // 组装并返回结果 + data, err := text.RenderToBase64(sb.String(), text.FontFile, 400, 18) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err)) + return + } + ctx.SendChain(message.Image("base64://" + binary.BytesToString(data))) + }) +} diff --git a/plugin/steam/store.go b/plugin/steam/store.go index b175fb2164..16c934447e 100644 --- a/plugin/steam/store.go +++ b/plugin/steam/store.go @@ -1,117 +1,117 @@ -package steam - -import ( - "strconv" - "sync" - "time" - - fcext "github.com/FloatTech/floatbox/ctxext" - sql "github.com/FloatTech/sqlite" - ctrl "github.com/FloatTech/zbpctrl" - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" -) - -var ( - database streamDB - // 开启并检查数据库链接 - getDB = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { - database.db.DBPath = engine.DataFolder() + "steam.db" - err := database.db.Open(time.Hour * 24) - if err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err)) - return false - } - if err = database.db.Create(TableListenPlayer, &player{}); err != nil { - ctx.SendChain(message.Text("[steam] ERROR: ", err)) - return false - } - // 校验密钥是否初始化 - m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) - _ = m.Manager.Response(steamapikeygid) - _ = m.Manager.GetExtra(steamapikeygid, &apiKey) - if apiKey == "" { - ctx.SendChain(message.Text("ERROR: 未设置steam apikey")) - return false - } - return true - }) -) - -// streamDB 继承方法的存储结构 -type streamDB struct { - sync.RWMutex - db sql.Sqlite -} - -const ( - // TableListenPlayer 存储查询用户信息 - TableListenPlayer = "listen_player" -) - -// player 用户状态存储结构体 -type player struct { - SteamID int64 `json:"steam_id"` // 绑定用户标识ID - PersonaName string `json:"persona_name"` // 用户昵称 - Target string `json:"target"` // 信息推送群组 - GameID int64 `json:"game_id"` // 游戏ID - GameExtraInfo string `json:"game_extra_info"` // 游戏信息 - LastUpdate int64 `json:"last_update"` // 更新时间 -} - -// update 如果主键不存在则插入一条新的数据,如果主键存在直接复写 -func (sql *streamDB) update(dbInfo *player) error { - sql.Lock() - defer sql.Unlock() - return sql.db.Insert(TableListenPlayer, dbInfo) -} - -// find 根据主键查信息 -func (sql *streamDB) find(steamID int64) (dbInfo player, err error) { - sql.Lock() - defer sql.Unlock() - condition := "where steam_id = " + strconv.FormatInt(steamID, 10) - if !sql.db.CanFind(TableListenPlayer, condition) { - return player{}, nil // 规避没有该用户数据的报错 - } - err = sql.db.Find(TableListenPlayer, &dbInfo, condition) - return -} - -// findWithGroupID 根据用户steamID和groupID查询信息 -func (sql *streamDB) findWithGroupID(steamID int64, groupID string) (dbInfo player, err error) { - sql.Lock() - defer sql.Unlock() - condition := "where steam_id = " + strconv.FormatInt(steamID, 10) + " AND target LIKE '%" + groupID + "%'" - if !sql.db.CanFind(TableListenPlayer, condition) { - return player{}, nil // 规避没有该用户数据的报错 - } - err = sql.db.Find(TableListenPlayer, &dbInfo, condition) - return -} - -// findAll 查询所有库信息 -func (sql *streamDB) findAll() (dbInfos []*player, err error) { - sql.Lock() - defer sql.Unlock() - var info player - num, err := sql.db.Count(TableListenPlayer) - if err != nil || num == 0 { - return - } - dbInfos = make([]*player, 0, num) - err = sql.db.FindFor(TableListenPlayer, &info, "", func() error { - if info.SteamID != 0 { - dbInfos = append(dbInfos, &info) - } - return nil - }) - return -} - -// del 删除指定数据 -func (sql *streamDB) del(steamID int64) error { - sql.Lock() - defer sql.Unlock() - return sql.db.Del(TableListenPlayer, "where steam_id = "+strconv.FormatInt(steamID, 10)) -} +package steam + +import ( + "strconv" + "sync" + "time" + + fcext "github.com/FloatTech/floatbox/ctxext" + sql "github.com/FloatTech/sqlite" + ctrl "github.com/FloatTech/zbpctrl" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +var ( + database streamDB + // 开启并检查数据库链接 + getDB = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { + database.db.DBPath = engine.DataFolder() + "steam.db" + err := database.db.Open(time.Hour * 24) + if err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err)) + return false + } + if err = database.db.Create(TableListenPlayer, &player{}); err != nil { + ctx.SendChain(message.Text("[steam] ERROR: ", err)) + return false + } + // 校验密钥是否初始化 + m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx]) + _ = m.Manager.Response(steamapikeygid) + _ = m.Manager.GetExtra(steamapikeygid, &apiKey) + if apiKey == "" { + ctx.SendChain(message.Text("ERROR: 未设置steam apikey")) + return false + } + return true + }) +) + +// streamDB 继承方法的存储结构 +type streamDB struct { + sync.RWMutex + db sql.Sqlite +} + +const ( + // TableListenPlayer 存储查询用户信息 + TableListenPlayer = "listen_player" +) + +// player 用户状态存储结构体 +type player struct { + SteamID int64 `json:"steam_id"` // 绑定用户标识ID + PersonaName string `json:"persona_name"` // 用户昵称 + Target string `json:"target"` // 信息推送群组 + GameID int64 `json:"game_id"` // 游戏ID + GameExtraInfo string `json:"game_extra_info"` // 游戏信息 + LastUpdate int64 `json:"last_update"` // 更新时间 +} + +// update 如果主键不存在则插入一条新的数据,如果主键存在直接复写 +func (sql *streamDB) update(dbInfo *player) error { + sql.Lock() + defer sql.Unlock() + return sql.db.Insert(TableListenPlayer, dbInfo) +} + +// find 根据主键查信息 +func (sql *streamDB) find(steamID int64) (dbInfo player, err error) { + sql.Lock() + defer sql.Unlock() + condition := "where steam_id = " + strconv.FormatInt(steamID, 10) + if !sql.db.CanFind(TableListenPlayer, condition) { + return player{}, nil // 规避没有该用户数据的报错 + } + err = sql.db.Find(TableListenPlayer, &dbInfo, condition) + return +} + +// findWithGroupID 根据用户steamID和groupID查询信息 +func (sql *streamDB) findWithGroupID(steamID int64, groupID string) (dbInfo player, err error) { + sql.Lock() + defer sql.Unlock() + condition := "where steam_id = " + strconv.FormatInt(steamID, 10) + " AND target LIKE '%" + groupID + "%'" + if !sql.db.CanFind(TableListenPlayer, condition) { + return player{}, nil // 规避没有该用户数据的报错 + } + err = sql.db.Find(TableListenPlayer, &dbInfo, condition) + return +} + +// findAll 查询所有库信息 +func (sql *streamDB) findAll() (dbInfos []*player, err error) { + sql.Lock() + defer sql.Unlock() + var info player + num, err := sql.db.Count(TableListenPlayer) + if err != nil || num == 0 { + return + } + dbInfos = make([]*player, 0, num) + err = sql.db.FindFor(TableListenPlayer, &info, "", func() error { + if info.SteamID != 0 { + dbInfos = append(dbInfos, &info) + } + return nil + }) + return +} + +// del 删除指定数据 +func (sql *streamDB) del(steamID int64) error { + sql.Lock() + defer sql.Unlock() + return sql.db.Del(TableListenPlayer, "where steam_id = "+strconv.FormatInt(steamID, 10)) +} From 6474b36ccdb049bc877bb18e71d7384f8e622c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?= <101934327+fangliuyu@users.noreply.github.com> Date: Sat, 18 Mar 2023 12:07:13 +0800 Subject: [PATCH 04/11] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BA=95=E9=83=A8?= =?UTF-8?q?=E5=87=BA=E7=8E=B0=E9=BB=91=E6=9D=A1=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=20(#626)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/drawlots/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/drawlots/main.go b/plugin/drawlots/main.go index 5097ffbc2f..096dcff875 100644 --- a/plugin/drawlots/main.go +++ b/plugin/drawlots/main.go @@ -244,10 +244,10 @@ func randGif(gifName string) (image.Image, error) { return nil, err } v := im.Image[rand.Intn(len(im.Image))] - return imgfactory.Size(firstImg, firstImg.Bounds().Max.X, firstImg.Bounds().Max.Y).InsertUpC(v, 0, 0, firstImg.Bounds().Max.X/2, firstImg.Bounds().Max.Y/2).Clone().Image(),err + return imgfactory.Size(firstImg, firstImg.Bounds().Dx(), firstImg.Bounds().Dy()).InsertUpC(v, 0, 0, firstImg.Bounds().Dx()/2, firstImg.Bounds().Dy()/2).Clone().Image(),err /*/ // 如果gif图片出现信息缺失请使用上面注释掉的代码,把下面注释了(上面代码部分图存在bug) v := im.Image[rand.Intn(len(im.Image))] - return imgfactory.NewFactoryBG(v.Rect.Max.X, v.Rect.Max.Y, color.NRGBA{0, 0, 0, 255}).InsertUp(v, 0, 0, 0, 0).Clone().Image(), err + return imgfactory.NewFactoryBG(v.Rect.Dx(), v.Rect.Dy(), color.NRGBA{0, 0, 0, 255}).InsertUp(v, 0, 0, 0, 0).Clone().Image(), err // */ } From e9eb4c5602079699b850736d3029c7b16145c858 Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Mon, 20 Mar 2023 11:57:46 +0800 Subject: [PATCH 05/11] Fix steam & lint (#630) * fix * make lint happy --- main.go | 13 +++++----- plugin/atri/atri.go | 2 +- plugin/saucenao/searcher.go | 38 ++++++++++++++--------------- plugin/setutime/setu_geter.go | 5 +--- plugin/sleep_manage/sleep_manage.go | 4 +-- plugin/steam/listenter.go | 6 ++--- plugin/steam/store.go | 6 ++--- 7 files changed, 35 insertions(+), 39 deletions(-) diff --git a/main.go b/main.go index b6edd3cd20..3126843741 100644 --- a/main.go +++ b/main.go @@ -234,13 +234,12 @@ func init() { fmt.Println("Usage:") flag.PrintDefaults() os.Exit(0) - } else { - if *d && !*w { - logrus.SetLevel(logrus.DebugLevel) - } - if *w { - logrus.SetLevel(logrus.WarnLevel) - } + } + if *d && !*w { + logrus.SetLevel(logrus.DebugLevel) + } + if *w { + logrus.SetLevel(logrus.WarnLevel) } for _, s := range flag.Args() { diff --git a/plugin/atri/atri.go b/plugin/atri/atri.go index e2385f71ed..0b5331130f 100644 --- a/plugin/atri/atri.go +++ b/plugin/atri/atri.go @@ -40,7 +40,7 @@ func randText(text ...string) message.MessageSegment { } // isAtriSleeping 凌晨0点到6点,ATRI 在睡觉,不回应任何请求 -func isAtriSleeping(ctx *zero.Ctx) bool { +func isAtriSleeping(*zero.Ctx) bool { if now := time.Now().Hour(); now >= 1 && now < 6 { return false } diff --git a/plugin/saucenao/searcher.go b/plugin/saucenao/searcher.go index 10107efd75..e51b692d2b 100644 --- a/plugin/saucenao/searcher.go +++ b/plugin/saucenao/searcher.go @@ -162,27 +162,27 @@ func init() { // 插件主体 ctx.SendChain(message.Text("请私聊发送 设置 saucenao api key [apikey] 以启用 saucenao 搜图 (方括号不需要输入), key 请前往 https://saucenao.com/user.php?page=search-api 获取")) } // ascii2d 搜索 - if result, err := ascii2d.ASCII2d(pic); err != nil { + result, err := ascii2d.ASCII2d(pic) + if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) continue - } else { - msg := message.Message{ctxext.FakeSenderForwardNode(ctx, message.Text("ascii2d搜图结果"))} - for i := 0; i < len(result) && i < 5; i++ { - msg = append(msg, ctxext.FakeSenderForwardNode(ctx, - message.Image(result[i].Thumb), - message.Text(fmt.Sprintf( - "标题: %s\n图源: %s\n画师: %s\n画师链接: %s\n图片链接: %s", - result[i].Name, - result[i].Type, - result[i].AuthNm, - result[i].Author, - result[i].Link, - ))), - ) - } - if id := ctx.Send(msg).ID(); id == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } + } + msg := message.Message{ctxext.FakeSenderForwardNode(ctx, message.Text("ascii2d搜图结果"))} + for i := 0; i < len(result) && i < 5; i++ { + msg = append(msg, ctxext.FakeSenderForwardNode(ctx, + message.Image(result[i].Thumb), + message.Text(fmt.Sprintf( + "标题: %s\n图源: %s\n画师: %s\n画师链接: %s\n图片链接: %s", + result[i].Name, + result[i].Type, + result[i].AuthNm, + result[i].Author, + result[i].Link, + ))), + ) + } + if id := ctx.Send(msg).ID(); id == 0 { + ctx.SendChain(message.Text("ERROR: 可能被风控了")) } } }) diff --git a/plugin/setutime/setu_geter.go b/plugin/setutime/setu_geter.go index b01370e0ff..b03c3328f9 100644 --- a/plugin/setutime/setu_geter.go +++ b/plugin/setutime/setu_geter.go @@ -236,10 +236,7 @@ func (p *imgpool) add(ctx *zero.Ctx, imgtype string, id int64) error { return err } // 添加插画到对应的数据库table - if err := p.db.Insert(imgtype, illust); err != nil { - return err - } - return nil + return p.db.Insert(imgtype, illust) } func (p *imgpool) remove(imgtype string, id int64) error { diff --git a/plugin/sleep_manage/sleep_manage.go b/plugin/sleep_manage/sleep_manage.go index 0b346e2f5d..d7d5b2becc 100644 --- a/plugin/sleep_manage/sleep_manage.go +++ b/plugin/sleep_manage/sleep_manage.go @@ -55,13 +55,13 @@ func timeDuration(time time.Duration) (hour, minute, second int64) { } // 只统计6点到12点的早安 -func isMorning(ctx *zero.Ctx) bool { +func isMorning(*zero.Ctx) bool { now := time.Now().Hour() return now >= 6 && now <= 12 } // 只统计21点到凌晨3点的晚安 -func isEvening(ctx *zero.Ctx) bool { +func isEvening(*zero.Ctx) bool { now := time.Now().Hour() return now >= 21 || now <= 3 } diff --git a/plugin/steam/listenter.go b/plugin/steam/listenter.go index 9cf2ca3431..976826558e 100644 --- a/plugin/steam/listenter.go +++ b/plugin/steam/listenter.go @@ -53,9 +53,9 @@ func init() { // 收集这波用户的streamId,然后查当前的状态,并建立信息映射表 streamIds := make([]string, len(infos)) localPlayerMap := make(map[int64]*player) - for i, info := range infos { - streamIds[i] = strconv.FormatInt(info.SteamID, 10) - localPlayerMap[info.SteamID] = info + for i := 0; i < len(infos); i++ { + streamIds[i] = strconv.FormatInt(infos[i].SteamID, 10) + localPlayerMap[infos[i].SteamID] = &infos[i] } // 将所有用户状态查一遍 playerStatus, err := getPlayerStatus(streamIds...) diff --git a/plugin/steam/store.go b/plugin/steam/store.go index 16c934447e..171a60f7d6 100644 --- a/plugin/steam/store.go +++ b/plugin/steam/store.go @@ -91,7 +91,7 @@ func (sql *streamDB) findWithGroupID(steamID int64, groupID string) (dbInfo play } // findAll 查询所有库信息 -func (sql *streamDB) findAll() (dbInfos []*player, err error) { +func (sql *streamDB) findAll() (dbInfos []player, err error) { sql.Lock() defer sql.Unlock() var info player @@ -99,10 +99,10 @@ func (sql *streamDB) findAll() (dbInfos []*player, err error) { if err != nil || num == 0 { return } - dbInfos = make([]*player, 0, num) + dbInfos = make([]player, 0, num) err = sql.db.FindFor(TableListenPlayer, &info, "", func() error { if info.SteamID != 0 { - dbInfos = append(dbInfos, &info) + dbInfos = append(dbInfos, info) } return nil }) From 86b87c2b4e4863f2e68e8c6f69feed8006fb7cd1 Mon Sep 17 00:00:00 2001 From: DreamZero <79574799+Jiang-Red@users.noreply.github.com> Date: Mon, 20 Mar 2023 11:59:03 +0800 Subject: [PATCH 06/11] fix slow aifalse (#631) --- plugin/ai_false/ai_false.go | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/plugin/ai_false/ai_false.go b/plugin/ai_false/ai_false.go index c3f48aa1e6..230ebfae35 100644 --- a/plugin/ai_false/ai_false.go +++ b/plugin/ai_false/ai_false.go @@ -187,7 +187,13 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg back = imgfactory.Size(back, int(bw*cw/bw), int(bh*cw/bw)).Image() canvas.DrawImage(back, 0, 0) } - + var blurback image.Image + bwg := &sync.WaitGroup{} + bwg.Add(1) + go func() { + defer bwg.Done() + blurback = imaging.Blur(canvas.Image(), 8) + }() wg := &sync.WaitGroup{} wg.Add(5) @@ -200,8 +206,8 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg go func() { defer wg.Done() titlecard := gg.NewContext(cardw, titlecardh) - - titlecard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70) + bwg.Wait() + titlecard.DrawImage(blurback, -70, -70) titlecard.DrawRoundedRectangle(1, 1, float64(titlecard.W()-1*2), float64(titlecardh-1*2), 16) titlecard.SetLineWidth(3) @@ -253,8 +259,8 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg go func() { defer wg.Done() basiccard := gg.NewContext(cardw, basiccardh) - - basiccard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40) + bwg.Wait() + basiccard.DrawImage(blurback, -70, -70-titlecardh-40) basiccard.DrawRoundedRectangle(1, 1, float64(basiccard.W()-1*2), float64(basiccardh-1*2), 16) basiccard.SetLineWidth(3) @@ -317,7 +323,8 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg go func() { defer wg.Done() diskcard := gg.NewContext(cardw, diskcardh) - diskcard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40-basiccardh-40) + bwg.Wait() + diskcard.DrawImage(blurback, -70, -70-titlecardh-40-basiccardh-40) diskcard.DrawRoundedRectangle(1, 1, float64(diskcard.W()-1*2), float64(diskcardh-1*2), 16) diskcard.SetLineWidth(3) @@ -335,6 +342,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg if dslen == 1 { diskcard.SetRGBA255(192, 192, 192, 255) diskcard.DrawRoundedRectangle(40, 40, float64(diskcard.W())-40-100, 50, 12) + diskcard.ClipPreserve() diskcard.Fill() switch { @@ -348,7 +356,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg diskcard.DrawRoundedRectangle(40, 40, (float64(diskcard.W())-40-100)*diskstate[0].precent*0.01, 50, 12) diskcard.Fill() - + diskcard.ResetClip() diskcard.SetRGBA255(30, 30, 30, 255) fw, _ := diskcard.MeasureString(diskstate[0].name) @@ -392,8 +400,8 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg go func() { defer wg.Done() moreinfocard := gg.NewContext(cardw, moreinfocardh) - - moreinfocard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40-basiccardh-40-diskcardh-40) + bwg.Wait() + moreinfocard.DrawImage(blurback, -70, -70-titlecardh-40-basiccardh-40-diskcardh-40) moreinfocard.DrawRoundedRectangle(1, 1, float64(moreinfocard.W()-1*2), float64(moreinfocard.H()-1*2), 16) moreinfocard.SetLineWidth(3) @@ -430,7 +438,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg shadow.Stroke() shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40), float64(cardw), float64(basiccardh), 16) shadow.Stroke() - shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40+basiccardh+40), float64(cardw), float64(basiccardh), 16) + shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40+basiccardh+40), float64(cardw), float64(diskcardh), 16) shadow.Stroke() shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40+basiccardh+40+diskcardh+40), float64(cardw), float64(moreinfocardh), 16) shadow.Stroke() From 1734f1f7d43a52ca4f0155b631859c2fcdb29712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=B2=E5=AE=9D=E5=9D=8F=E5=9D=8F=E5=9D=8F?= <2758988938@qq.com> Date: Mon, 20 Mar 2023 12:23:52 +0800 Subject: [PATCH 07/11] =?UTF-8?q?=E6=9B=B4=E6=8D=A2=E7=99=BE=E5=BA=A6?= =?UTF-8?q?=E4=B8=80=E4=B8=8B=E4=B8=BA=E7=99=BE=E5=BA=A6=E7=99=BE=E7=A7=91?= =?UTF-8?q?=20(#627)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +-- plugin/baidu/search.go | 56 ++++++++++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index b1a594aeca..c7e7cbe5eb 100644 --- a/README.md +++ b/README.md @@ -436,11 +436,11 @@ print("run[CQ:image,file="+j["img"]+"]")
- 百度一下 + 百度百科 `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/baidu"` - - [x] 百度下[xxx] + - [x] 百度/百科[xxx]
diff --git a/plugin/baidu/search.go b/plugin/baidu/search.go index 642804d458..853ab76725 100644 --- a/plugin/baidu/search.go +++ b/plugin/baidu/search.go @@ -1,27 +1,51 @@ -// Package baidu 百度一下 +// Package baidu 百度百科 package baidu import ( - "net/url" + "encoding/json" + "fmt" + "github.com/FloatTech/floatbox/web" + ctrl "github.com/FloatTech/zbpctrl" + "github.com/FloatTech/zbputils/control" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" +) - ctrl "github.com/FloatTech/zbpctrl" - "github.com/FloatTech/zbputils/control" - "github.com/FloatTech/zbputils/ctxext" +const ( + api = "https://api.a20safe.com/api.php?api=21&key=7d06a110e9e20a684e02934549db1d3d&text=%s" // api地址 ) -func init() { - control.Register("baidu", &ctrl.Options[*zero.Ctx]{ +type result struct { + Code int `json:"code"` + Msg string `json:"msg"` + Data []struct { + Content string `json:"content"` + } `json:"data"` +} + +func init() { // 主函数 + en := control.Register("baidu", &ctrl.Options[*zero.Ctx]{ DisableOnDefault: false, - Brief: "不会百度吗", - Help: "- 百度下[xxx]", - }).OnPrefix("百度下").SetBlock(true).Limit(ctxext.LimitByGroup). - Handle(func(ctx *zero.Ctx) { - txt := ctx.State["args"].(string) - if txt != "" { - ctx.SendChain(message.Text("https://buhuibaidu.me/?s=" + url.QueryEscape(txt))) - } - }) + Help: "百度百科\n" + + "- 百度/百科[关键字]", + }) + en.OnRegex(`^[百度|百科]\s*(.+)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) { + es, err := web.GetData(fmt.Sprintf(api, ctx.State["regex_matched"].([]string)[1])) // 将网站返回结果赋值 + if err != nil { + ctx.SendChain(message.Text("出现错误捏:", err)) + return + } + var r result // r数组 + err = json.Unmarshal(es, &r) // 填api返回结果,struct地址 + if err != nil { + ctx.SendChain(message.Text("出现错误捏:", err)) + return + } + if r.Code == 0 && len(r.Data) > 0 { + ctx.SendChain(message.Text(r.Data[0].Content)) // 输出提取后的结果 + } else { + ctx.SendChain(message.Text("API访问错误")) + } + }) } From 68386910c4a12f33008b19e4a4a19324453ed0bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Mon, 20 Mar 2023 12:28:19 +0800 Subject: [PATCH 08/11] =?UTF-8?q?=F0=9F=94=96=20v1.7.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kanban/banner/banner.go | 4 ++-- winres/winres.json | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/kanban/banner/banner.go b/kanban/banner/banner.go index 3f8313e161..b372b83865 100644 --- a/kanban/banner/banner.go +++ b/kanban/banner/banner.go @@ -3,13 +3,13 @@ package banner // Version ... -var Version = "v1.7.0-beta5" +var Version = "v1.7.0" // Copyright ... var Copyright = "© 2020 - 2023 FloatTech" // Banner ... var Banner = "* OneBot + ZeroBot + Golang\n" + - "* Version " + Version + " - 2023-03-16 19:22:03 +0800 CST\n" + + "* Version " + Version + " - 2023-03-20 12:27:42 +0800 CST\n" + "* Copyright " + Copyright + ". All Rights Reserved.\n" + "* Project: https://github.com/FloatTech/ZeroBot-Plugin" diff --git a/winres/winres.json b/winres/winres.json index b81b3d5516..48c0ede1d5 100644 --- a/winres/winres.json +++ b/winres/winres.json @@ -12,7 +12,7 @@ "0409": { "identity": { "name": "ZeroBot-Plugin", - "version": "1.7.0.1749" + "version": "1.7.0.1760" }, "description": "", "minimum-os": "vista", @@ -36,23 +36,23 @@ "#1": { "0000": { "fixed": { - "file_version": "1.7.0.1749", - "product_version": "v1.7.0-beta5", - "timestamp": "2023-03-16T19:22:18+08:00" + "file_version": "1.7.0.1760", + "product_version": "v1.7.0", + "timestamp": "2023-03-20T12:28:01+08:00" }, "info": { "0409": { "Comments": "OneBot plugins based on ZeroBot", "CompanyName": "FloatTech", "FileDescription": "https://github.com/FloatTech/ZeroBot-Plugin", - "FileVersion": "1.7.0.1749", + "FileVersion": "1.7.0.1760", "InternalName": "", "LegalCopyright": "© 2020 - 2023 FloatTech. All Rights Reserved.", "LegalTrademarks": "", "OriginalFilename": "ZBP.EXE", "PrivateBuild": "", "ProductName": "ZeroBot-Plugin", - "ProductVersion": "v1.7.0-beta5", + "ProductVersion": "v1.7.0", "SpecialBuild": "" } } From 1376803b076357cdb385326f0a082d6ea660681c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8E=AB=E6=80=9D=E6=BD=8B?= <55676105+shudorcl@users.noreply.github.com> Date: Wed, 22 Mar 2023 20:17:15 +0800 Subject: [PATCH 09/11] fix: always (#633) * update deps * update always * fix: always: broken images and fonts --- go.mod | 2 +- go.sum | 2 ++ plugin/gif/gif.go | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5d506aea45..46a0a90d71 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/FloatTech/AnimeAPI v1.6.1-0.20230316111643-46d40c9d80e3 github.com/FloatTech/floatbox v0.0.0-20230316111222-7ffde57284cc github.com/FloatTech/gg v1.1.2 - github.com/FloatTech/imgfactory v0.2.2-0.20230315152233-49741fc994f9 + github.com/FloatTech/imgfactory v0.2.2-0.20230322091809-b0ddbe44b94b github.com/FloatTech/rendercard v0.0.10-0.20230223064326-45d29fa4ede9 github.com/FloatTech/sqlite v1.5.7 github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b diff --git a/go.sum b/go.sum index 201fa93ee7..0d1dd29eee 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/FloatTech/gg v1.1.2 h1:YolgOYg3uDHc1+g0bLtt6QuRA/pvLn+b9IBCIhOOX88= github.com/FloatTech/gg v1.1.2/go.mod h1:uzPzAeT35egARdRuu+1oyjU3CmTwCceoq3Vvje7LpcI= github.com/FloatTech/imgfactory v0.2.2-0.20230315152233-49741fc994f9 h1:IzZLuM/fgKclyMaU/Qb1qlLdGrs2FTietkqOWhh07Gw= github.com/FloatTech/imgfactory v0.2.2-0.20230315152233-49741fc994f9/go.mod h1:el5hGpj1C1bDRxcTXYRwEivDCr40zZeJpcrLrB1fajs= +github.com/FloatTech/imgfactory v0.2.2-0.20230322091809-b0ddbe44b94b h1:VMNci4SWBySdw/6poqF9Dn9zlT5ntTFSJOEEBjRnJ/4= +github.com/FloatTech/imgfactory v0.2.2-0.20230322091809-b0ddbe44b94b/go.mod h1:el5hGpj1C1bDRxcTXYRwEivDCr40zZeJpcrLrB1fajs= github.com/FloatTech/rendercard v0.0.10-0.20230223064326-45d29fa4ede9 h1:hffajvmQFfP68U6wUwHemPuuwCUoss+SEFfoLYwbGwE= github.com/FloatTech/rendercard v0.0.10-0.20230223064326-45d29fa4ede9/go.mod h1:NBFPhWae4hqVMeG8ELBBnUQkKce3nDjkljVn6PdiUNs= github.com/FloatTech/sqlite v1.5.7 h1:Bvo4LSojcZ6dVtbHrkqvt6z4v8e+sj0G5PSUIvdawsk= diff --git a/plugin/gif/gif.go b/plugin/gif/gif.go index 0b8d57274f..1174f2f5a3 100644 --- a/plugin/gif/gif.go +++ b/plugin/gif/gif.go @@ -1404,7 +1404,7 @@ func alwaysDoGif(cc *context, value ...string) (string, error) { var err error var face []*imgfactory.Factory name := cc.usrdir + "AlwaysDo.gif" - face, err = imgfactory.LoadAllFrames(cc.headimgsdir[0], 500, 500) + face, err = imgfactory.LoadAllTrueFrames(cc.headimgsdir[0], 500, 500) if err != nil { // 载入失败尝试载入第一帧 face = nil @@ -1438,7 +1438,7 @@ func alwaysDoGif(cc *context, value ...string) (string, error) { canvas := gg.NewContext(500, 600) canvas.DrawImage(f.Image(), 0, 0) canvas.SetColor(color.Black) - // _ = canvas.ParseFontFace(data, 40) + _ = canvas.ParseFontFace(data, 40) canvas.DrawString(arg, 280-l, 560) canvas.DrawImage(imgfactory.Size(f.Image(), 90, 90).Image(), 280, 505) canvas.DrawString("吗", 370, 560) From 500dcaa9ed389acff57e1851f0fff234ef7ba091 Mon Sep 17 00:00:00 2001 From: anyanfei <87066062@qq.com> Date: Fri, 24 Mar 2023 14:03:18 +0800 Subject: [PATCH 10/11] =?UTF-8?q?fix:=20baidu=20=E6=AD=A3=E5=88=99?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=20(#636)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/baidu/search.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/baidu/search.go b/plugin/baidu/search.go index 853ab76725..887bdeac1f 100644 --- a/plugin/baidu/search.go +++ b/plugin/baidu/search.go @@ -30,7 +30,7 @@ func init() { // 主函数 Help: "百度百科\n" + "- 百度/百科[关键字]", }) - en.OnRegex(`^[百度|百科]\s*(.+)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) { + en.OnRegex(`^百[度科]\s*(.+)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) { es, err := web.GetData(fmt.Sprintf(api, ctx.State["regex_matched"].([]string)[1])) // 将网站返回结果赋值 if err != nil { ctx.SendChain(message.Text("出现错误捏:", err)) From d693f988bb0ba42fe16b4e641e99efa4c0d7b639 Mon Sep 17 00:00:00 2001 From: Sora39 <36908878+Sora39831@users.noreply.github.com> Date: Fri, 24 Mar 2023 17:25:04 +0800 Subject: [PATCH 11/11] =?UTF-8?q?fix:=20steam=20=E3=83=98=E3=83=AB?= =?UTF-8?q?=E3=83=97=E3=81=AB=E3=81=82=E3=82=8B=20api=20=E3=81=AE=E7=94=B3?= =?UTF-8?q?=E8=AF=B7=E5=9C=B0=E5=9D=80=20(#637)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/steam/steam.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/steam/steam.go b/plugin/steam/steam.go index 925dc90a99..db51b2b5f0 100644 --- a/plugin/steam/steam.go +++ b/plugin/steam/steam.go @@ -24,7 +24,7 @@ var ( "- steam删除订阅 xxxxxxx (删除你创建的对于 steamid 的绑定)\n" + "- steam查询订阅 (查询本群内所有的绑定对象)\n" + "-----------------------\n" + - "- steam绑定 api key xxxxxxx (密钥在steam网站申请, 申请地址: https://steamcommunity.com/dev/registerkey)\n" + + "- steam绑定 api key xxxxxxx (密钥在steam网站申请, 申请地址: https://steamcommunity.com/dev/apikey)\n" + "- 查看apikey (查询已经绑定的密钥)\n" + "- 拉取steam订阅 (使用插件定时任务开始)\n" + "-----------------------\n" +