Skip to content

Commit ac18d3d

Browse files
authored
新增一些游戏王相关的插件 (#507)
1 parent daff47d commit ac18d3d

File tree

4 files changed

+357
-1
lines changed

4 files changed

+357
-1
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@ print("run[CQ:image,file="+j["img"]+"]")
752752

753753
------插 件 扩 展------
754754

755-
NeteaseCloudMusicApi项目地址:https://binaryify.github.io/NeteaseCloudMusicApi/#/
755+
- 本插件内置了[NeteaseCloudMusicApi](https://binaryify.github.io/NeteaseCloudMusicApi/#/)框架的一些功能
756756
- [x] 设置猜歌API帮助
757757
- [x] 设置猜歌API [API首页网址]
758758
- [x] 猜歌[开启/关闭][歌单/歌词]自动下载
@@ -1351,6 +1351,29 @@ NeteaseCloudMusicApi项目地址:https://binaryify.github.io/NeteaseCloudMusicAp
13511351

13521352
- [x] 团队七阶猜单词
13531353

1354+
</details>
1355+
<details>
1356+
<summary>一些游戏王插件</summary>
1357+
1358+
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo"`
1359+
1360+
##### 白鸽API卡查
1361+
1362+
###### `"github.com/FloatTech/ZeroBot-Plugin/plugin/ygo/ygocdb.go"`
1363+
- [x] /ydp [xxx]
1364+
- [x] /yds [xxx]
1365+
- [x] /ydb [xxx]
1366+
- 注:[xxx]为搜索内容;p:返回一张图片;s:返回一张效果描述;b:高级搜索
1367+
1368+
##### 集换社卡价查询
1369+
1370+
###### `"github.com/FloatTech/ZeroBot-Plugin/plugin/ygo/ygotrade.go"`
1371+
- [x] 查卡价 [卡名]
1372+
- [x] 查卡价 [卡名] [稀有度 稀有度 ...]
1373+
- [x] 查卡店 [卡名]
1374+
- [x] 查卡店 [卡名] [稀有度]
1375+
- 注:卡店只支持单个稀有度查询
1376+
13541377
</details>
13551378
<details>
13561379
<summary>鬼东西</summary>

main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ import (
136136
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenxinAI" // 百度文心AI画图
137137
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词
138138
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词
139+
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo" // 游戏王相关插件
139140
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame
140141

141142
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西

plugin/ygo/ygocdb.go

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
// Package ygo 一些关于ygo的插件
2+
package ygo
3+
4+
import (
5+
"net/url"
6+
"strconv"
7+
"strings"
8+
"time"
9+
10+
"encoding/json"
11+
12+
"github.com/FloatTech/floatbox/web"
13+
ctrl "github.com/FloatTech/zbpctrl"
14+
control "github.com/FloatTech/zbputils/control"
15+
zero "github.com/wdvxdr1123/ZeroBot"
16+
"github.com/wdvxdr1123/ZeroBot/message"
17+
)
18+
19+
const (
20+
serviceErr = "[ygocdb]error:"
21+
api = "https://ygocdb.com/api/v0/?search="
22+
picherf = "https://cdn.233.momobako.com/ygopro/pics/"
23+
)
24+
25+
type searchResult struct {
26+
Result []struct {
27+
Cid int `json:"cid"`
28+
ID int `json:"id"`
29+
CnName string `json:"cn_name"`
30+
// CnocgN string `json:"cnocg_n"` // 简中卡名
31+
JpName string `json:"jp_name"`
32+
EnName string `json:"en_name"`
33+
Text struct {
34+
Types string `json:"types"`
35+
Pdesc string `json:"pdesc"`
36+
Desc string `json:"desc"`
37+
} `json:"text"`
38+
} `json:"result"`
39+
}
40+
41+
func init() {
42+
en := control.Register("ygocdb", &ctrl.Options[*zero.Ctx]{
43+
DisableOnDefault: false,
44+
Brief: "游戏王百鸽API",// 本插件基于游戏王百鸽API"https://www.ygo-sem.cn/"
45+
Help: "- /ydp [xxx]\n" +
46+
"- /yds [xxx]\n" +
47+
"- /ydb [xxx]\n" +
48+
"[xxx]为搜索内容\np:返回一张图片\ns:返回一张效果描述\nb:全显示",
49+
})
50+
51+
en.OnRegex(`^/yd(p|s|b)\s?(.*)`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
52+
function := ctx.State["regex_matched"].([]string)[1]
53+
ctxtext := ctx.State["regex_matched"].([]string)[2]
54+
if ctxtext == "" {
55+
ctx.SendChain(message.Text("你是想查询「空手假象」吗?"))
56+
return
57+
}
58+
data, err := web.GetData(api + url.QueryEscape(ctxtext))
59+
if err != nil {
60+
ctx.SendChain(message.Text(serviceErr, err))
61+
return
62+
}
63+
var result searchResult
64+
err = json.Unmarshal(data, &result)
65+
if err != nil {
66+
ctx.SendChain(message.Text(serviceErr, err))
67+
return
68+
}
69+
maxpage := len(result.Result)
70+
switch {
71+
case maxpage == 0:
72+
ctx.SendChain(message.Text("没有找到相关的卡片额"))
73+
return
74+
case function == "p":
75+
ctx.SendChain(message.Image(picherf + strconv.Itoa(result.Result[0].ID) + ".jpg"))
76+
return
77+
case function == "s":
78+
cardtextout := cardtext(result, 0)
79+
ctx.SendChain(message.Text(cardtextout))
80+
return
81+
case function == "d" && maxpage == 1:
82+
cardtextout := cardtext(result, 0)
83+
ctx.SendChain(message.Image(picherf+strconv.Itoa(result.Result[0].ID)+".jpg"), message.Text(cardtextout))
84+
return
85+
}
86+
var listName []string
87+
var listid []int
88+
for _, v := range result.Result {
89+
listName = append(listName, strconv.Itoa(len(listName))+"."+v.CnName)
90+
listid = append(listid, v.ID)
91+
}
92+
var (
93+
currentPage = 10
94+
nextpage = 0
95+
)
96+
if maxpage < 10 {
97+
currentPage = maxpage
98+
}
99+
ctx.SendChain(message.Text("找到", strconv.Itoa(maxpage), "张相关卡片,当前显示以下卡名:\n",
100+
strings.Join(listName[:currentPage], "\n"),
101+
"\n————————————\n输入对应数字获取卡片信息,",
102+
"\n或回复“取消”、“下一页”指令"))
103+
recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`(取消)|(下一页)|\d+`), zero.OnlyGroup, zero.CheckUser(ctx.Event.UserID)).Repeat()
104+
after := time.NewTimer(20 * time.Second)
105+
for {
106+
select {
107+
case <-after.C:
108+
cancel()
109+
ctx.Send(
110+
message.ReplyWithMessage(ctx.Event.MessageID,
111+
message.Text("等待超时,搜索结束"),
112+
),
113+
)
114+
return
115+
case e := <-recv:
116+
nextcmd := e.Event.Message.String()
117+
switch nextcmd {
118+
case "取消":
119+
cancel()
120+
after.Stop()
121+
ctx.Send(
122+
message.ReplyWithMessage(ctx.Event.MessageID,
123+
message.Text("用户取消,搜索结束"),
124+
),
125+
)
126+
return
127+
case "下一页":
128+
after.Reset(20 * time.Second)
129+
if maxpage < 11 {
130+
continue
131+
}
132+
nextpage++
133+
if nextpage*10 >= maxpage {
134+
nextpage = 0
135+
currentPage = 10
136+
ctx.SendChain(message.Text("已是最后一页,返回到第一页"))
137+
} else if nextpage == maxpage/10 {
138+
currentPage = maxpage % 10
139+
}
140+
ctx.SendChain(message.Text("找到", strconv.Itoa(maxpage), "张相关卡片,当前显示以下卡名:\n",
141+
strings.Join(listName[nextpage*10:nextpage*10+currentPage], "\n"),
142+
"\n————————————————\n输入对应数字获取卡片信息,",
143+
"\n或回复“取消”、“下一页”指令"))
144+
default:
145+
cardint, err := strconv.Atoi(nextcmd)
146+
switch {
147+
case err != nil:
148+
after.Reset(20 * time.Second)
149+
ctx.SendChain(message.At(ctx.Event.UserID), message.Text("请输入正确的序号"))
150+
default:
151+
if cardint < nextpage*10+currentPage {
152+
cancel()
153+
after.Stop()
154+
cardtextout := cardtext(result, cardint)
155+
ctx.SendChain(message.Image(picherf+strconv.Itoa(listid[cardint])+".jpg"), message.Text(cardtextout))
156+
return
157+
}
158+
after.Reset(20 * time.Second)
159+
ctx.SendChain(message.At(ctx.Event.UserID), message.Text("请输入正确的序号"))
160+
}
161+
}
162+
}
163+
}
164+
})
165+
}
166+
167+
func cardtext(list searchResult, cardid int) string {
168+
var cardtext []string
169+
cardtext = append(cardtext, "中文卡名:\n "+list.Result[cardid].CnName)
170+
if list.Result[cardid].JpName == "" {
171+
cardtext = append(cardtext, "英文卡名:\n "+list.Result[cardid].EnName)
172+
} else {
173+
cardtext = append(cardtext, "日文卡名:\n "+list.Result[cardid].JpName)
174+
}
175+
cardtext = append(cardtext, "卡片密码:"+strconv.Itoa(list.Result[cardid].ID))
176+
cardtext = append(cardtext, list.Result[cardid].Text.Types)
177+
if list.Result[cardid].Text.Pdesc != "" {
178+
cardtext = append(cardtext, "[灵摆效果]\n"+list.Result[cardid].Text.Pdesc)
179+
if strings.Contains(list.Result[cardid].Text.Types, "效果") {
180+
cardtext = append(cardtext, "[怪兽效果]")
181+
} else {
182+
cardtext = append(cardtext, "[怪兽描述]")
183+
}
184+
}
185+
cardtext = append(cardtext, list.Result[cardid].Text.Desc)
186+
return strings.Join(cardtext, "\n")
187+
}

plugin/ygo/ygotrade.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Package ygo 一些关于ygo的插件
2+
package ygo
3+
4+
5+
import (
6+
"encoding/json"
7+
"errors"
8+
"net/url"
9+
"strconv"
10+
"strings"
11+
12+
"github.com/FloatTech/floatbox/web"
13+
ctrl "github.com/FloatTech/zbpctrl"
14+
"github.com/FloatTech/zbputils/control"
15+
"github.com/FloatTech/zbputils/ctxext"
16+
zero "github.com/wdvxdr1123/ZeroBot"
17+
"github.com/wdvxdr1123/ZeroBot/message"
18+
)
19+
20+
const (
21+
rarityTrade = "https://api.jihuanshe.com/api/market/search/match-product?game_key=ygo&game_sub_key=ocg&page=1&keyword="
22+
storeTrade = "https://api.jihuanshe.com/api/market/card-versions/products?game_key=ygo&game_sub_key=ocg&page=1&condition=1&card_version_id="
23+
)
24+
25+
type apiInfo struct {
26+
Data []tradeInfo `json:"data"`
27+
}
28+
29+
type tradeInfo struct {
30+
// 卡片信息
31+
ID int `json:"id"`
32+
NameCn string `json:"name_cn"`
33+
CardID int `json:"card_id"`
34+
Number string `json:"number"`
35+
Rarity string `json:"rarity"`
36+
ImageURL string `json:"image_url"`
37+
MinPrice string `json:"min_price"`
38+
// 卡店信息
39+
SellerUserID int `json:"seller_user_id"`
40+
SellerUsername string `json:"seller_username"`
41+
SellerUserAvatar string `json:"seller_user_avatar"`
42+
SellerProvince string `json:"seller_province"`
43+
SellerCity string `json:"seller_city"`
44+
SellerCreditRank string `json:"seller_credit_rank"`
45+
Quantity string `json:"quantity"`
46+
CardVersionImage string `json:"card_version_image"`
47+
}
48+
49+
func init() {
50+
engine := control.Register("ygotrade", &ctrl.Options[*zero.Ctx]{
51+
DisableOnDefault: false,
52+
Brief: "游戏王卡价查询",// 本插件基于集换社API
53+
Help: "- 查卡价 [卡名]\n- 查卡价 [卡名] [稀有度 稀有度 ...]\n- 查卡店 [卡名]\n- 查卡店 [卡名] [稀有度]",
54+
}).ApplySingle(ctxext.DefaultSingle)
55+
engine.OnPrefix("查卡价", func(ctx *zero.Ctx) bool {
56+
ctx.State["args"] = strings.TrimSpace(ctx.State["args"].(string))
57+
return ctx.State["args"].(string) != ""
58+
}).SetBlock(true).Handle(func(ctx *zero.Ctx) {
59+
cardName, rarity, _ := strings.Cut(ctx.State["args"].(string), " ")
60+
listOfTrace, err := getRarityTrade(cardName, rarity)
61+
if err != nil {
62+
ctx.SendChain(message.Text("ERROR: ", err))
63+
return
64+
}
65+
msg := make(message.Message, len(listOfTrace))
66+
for i := 0; i < len(listOfTrace); i++ {
67+
msg[i] = ctxext.FakeSenderForwardNode(ctx, message.Text(
68+
"卡名:", listOfTrace[i].NameCn,
69+
"\nID:", listOfTrace[i].ID,
70+
"\n卡序:", listOfTrace[i].Number,
71+
"\n罕贵度:", listOfTrace[i].Rarity,
72+
"\n当前最低价:", listOfTrace[i].MinPrice),
73+
message.Image(listOfTrace[i].ImageURL))
74+
}
75+
if id := ctx.Send(msg); id.ID() == 0 {
76+
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
77+
}
78+
})
79+
engine.OnPrefix("查卡店", func(ctx *zero.Ctx) bool {
80+
ctx.State["args"] = strings.TrimSpace(ctx.State["args"].(string))
81+
return ctx.State["args"].(string) != ""
82+
}).SetBlock(true).Handle(func(ctx *zero.Ctx) {
83+
cardName, rarity, _ := strings.Cut(ctx.State["args"].(string), " ")
84+
if strings.Count(rarity, " ") > 0 {
85+
ctx.SendChain(message.Text("ERROR: ", "卡店查询不支持查找多个罕贵度"))
86+
return
87+
}
88+
listOfTrace, err := getRarityTrade(cardName, rarity)
89+
if err != nil {
90+
ctx.SendChain(message.Text("ERROR: ", err))
91+
return
92+
}
93+
listStroe, err := getStoreTrade(listOfTrace[0].ID)
94+
if err != nil {
95+
ctx.SendChain(message.Text("ERROR: ", err))
96+
return
97+
}
98+
msg := make(message.Message, len(listStroe))
99+
for i := 0; i < len(listStroe); i++ {
100+
msg[i] = ctxext.FakeSenderForwardNode(ctx, message.Text(
101+
"卖家名:", listStroe[i].SellerUsername,
102+
"\nID:", listStroe[i].SellerUserID,
103+
"\n地区:", listStroe[i].SellerCity,
104+
"\n信誉度:", listStroe[i].SellerCreditRank,
105+
"\n数量:", listStroe[i].Quantity,
106+
"\n当前最低价:", listStroe[i].MinPrice),
107+
message.Image(listStroe[i].CardVersionImage))
108+
}
109+
if id := ctx.Send(msg); id.ID() == 0 {
110+
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
111+
}
112+
})
113+
}
114+
115+
// 获取卡名该罕贵度卡片数据
116+
func getRarityTrade(key, rarity string) (tradeInfo []tradeInfo, err error) {
117+
listOfTrace, err := web.GetData(rarityTrade + url.QueryEscape(key) + "&rarity=" + url.QueryEscape(rarity))
118+
if err != nil {
119+
return
120+
}
121+
var apiInfo apiInfo
122+
err = json.Unmarshal(listOfTrace, &apiInfo)
123+
if len(apiInfo.Data) == 0 {
124+
err = errors.New("没有找到相关卡片或输入参数错误")
125+
return
126+
}
127+
tradeInfo = apiInfo.Data
128+
return
129+
}
130+
131+
// 获取卡店卡片数据
132+
func getStoreTrade(cardID int) (stroeInfo []tradeInfo, err error) {
133+
listOfTrace, err := web.GetData(storeTrade + url.QueryEscape(strconv.Itoa(cardID)))
134+
if err != nil {
135+
return
136+
}
137+
var apiInfo apiInfo
138+
err = json.Unmarshal(listOfTrace, &apiInfo)
139+
if len(apiInfo.Data) == 0 {
140+
err = errors.New("没有找到相关卡片或输入参数错误")
141+
return
142+
}
143+
stroeInfo = apiInfo.Data
144+
return
145+
}

0 commit comments

Comments
 (0)