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" +