From 4b2fa9e767768afb271c393fee9c6c0c70ed0768 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Fri, 23 Dec 2022 10:15:27 +0800 Subject: [PATCH 01/19] add WarframeAPI --- go.mod | 2 + go.sum | 4 + plugin/warframeapi/gametime.go | 143 ++++++++ plugin/warframeapi/main.go | 643 +++++++++++++++++++++++++++++++++ plugin/warframeapi/wfdata.go | 630 ++++++++++++++++++++++++++++++++ 5 files changed, 1422 insertions(+) create mode 100644 plugin/warframeapi/gametime.go create mode 100644 plugin/warframeapi/main.go create mode 100644 plugin/warframeapi/wfdata.go diff --git a/go.mod b/go.mod index bc8d9613a7..a7e2005d39 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,7 @@ require ( github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5 github.com/antchfx/htmlquery v1.2.5 github.com/corona10/goimagehash v1.1.0 + github.com/davidscholberg/go-durationfmt v0.0.0-20170122144659-64843a2083d3 github.com/fumiama/ahsai v0.1.0 github.com/fumiama/cron v1.3.0 github.com/fumiama/go-base16384 v1.6.1 @@ -25,6 +26,7 @@ require ( github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 github.com/jinzhu/gorm v1.9.16 github.com/jozsefsallai/gophersauce v1.0.1 + github.com/lithammer/fuzzysearch v1.1.5 github.com/lucas-clemente/quic-go v0.31.1 github.com/mroth/weightedrand v1.0.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index ff9b9cd5f7..09df52ae75 100644 --- a/go.sum +++ b/go.sum @@ -38,6 +38,8 @@ github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b/go.mod h1:Oozb github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davidscholberg/go-durationfmt v0.0.0-20170122144659-64843a2083d3 h1:qshMBFxVjYjzI+kwvWvgoByF3uMCvnJiaK8KslWAbr8= +github.com/davidscholberg/go-durationfmt v0.0.0-20170122144659-64843a2083d3/go.mod h1:M9fx6rAdHSYLKxXPgUXGgblb586CA7ceNrpu4DEc2No= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= @@ -126,6 +128,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c= +github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q= github.com/lucas-clemente/quic-go v0.31.1 h1:O8Od7hfioqq0PMYHDyBkxU2aA7iZ2W9pjbrWuja2YR4= github.com/lucas-clemente/quic-go v0.31.1/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g= github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go new file mode 100644 index 0000000000..27b0b4d93b --- /dev/null +++ b/plugin/warframeapi/gametime.go @@ -0,0 +1,143 @@ +package warframeapi + +import ( + "fmt" + "time" + + "github.com/davidscholberg/go-durationfmt" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +var ( + GameTimes []GameTime +) + +func (t GameTime) getStatus() string { + if t.Status { + return t.StatusTrueDes + } else { + return t.StatusTrueDes + } +} +func (t GameTime) getTime() string { + d := time.Until(t.NextTime) + durStr, _ := durationfmt.Format(d, "%m分%s秒后") + return durStr +} + +// 游戏时间模拟初始化 +func gameTimeInit() { + //updateWM() + LoadTime() + go gameRuntime() +} + +func gameRuntime() { + for { + time.Sleep(10 * time.Second) + TimeDet() + } + +} + +func LoadTime() { + //updateWM() + var isfass bool + if wfapi.CambionCycle.Active == "fass" { + isfass = false + } + GameTimes = []GameTime{ + {"地球平原", wfapi.CetusCycle.Expiry.Local(), wfapi.CetusCycle.IsDay, "白天", "夜晚", 100 * 60, 50 * 60}, + {"金星平原", wfapi.VallisCycle.Expiry.Local(), wfapi.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, + {"火卫二平原", wfapi.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, + } + +} + +func TimeDet() { + for i, v := range GameTimes { + if time.Until(v.NextTime).Seconds() < 0 { + if v.Status { + GameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) + } else { + GameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) + } + GameTimes[i].Status = !GameTimes[i].Status + CallUser(i, GameTimes[i].Status, 0) + } else if time.Until(v.NextTime).Seconds() < float64(5)*60 { + CallUser(i, !GameTimes[i].Status, 5) + } else if time.Until(v.NextTime).Seconds() < float64(15)*60 { + if i == 2 && !v.Status { + return + } + CallUser(i, !GameTimes[i].Status, 15) + + } + } +} + +func CallUser(i int, s bool, time int) { + for group, sl := range sublist { + msg := []message.MessageSegment{} + if !sl.Min15Tips && !sl.Min5Tips && time == 15 { + sublist[group].Min15Tips = true + } else if sl.Min15Tips && !sl.Min5Tips && time == 5 { + sublist[group].Min5Tips = true + } else if sl.Min15Tips && sl.Min5Tips && time == 0 { + sublist[group].Min15Tips = false + sublist[group].Min5Tips = false + } else { + return + } + + for qq, st := range sl.SubUser { + if st.SubType[i] != nil { + if *st.SubType[i] == s { + msg = append(msg, message.At(qq)) + } + } + } + if len(msg) == 0 { + continue + } + if time <= 0 { + if s { + msg = append(msg, message.Text(fmt.Sprintf("\n%s白天(%s)到了", GameTimes[i].Name, GameTimes[i].StatusTrueDes))) + } else { + msg = append(msg, message.Text(fmt.Sprintf("\n%s夜晚(%s)到了", GameTimes[i].Name, GameTimes[i].StatusFalseDes))) + } + } else { + if s { + msg = append(msg, message.Text(fmt.Sprintf("\n%s距离白天(%s)还剩下%d分钟", GameTimes[i].Name, GameTimes[i].StatusTrueDes, time))) + } else { + msg = append(msg, message.Text(fmt.Sprintf("\n%s距离夜晚(%s)还剩下%d分钟", GameTimes[i].Name, GameTimes[i].StatusFalseDes, time))) + } + } + + zero.GetBot(2429160662).SendGroupMessage(group, msg) + } + +} + +// 游戏时间模拟 +type GameTime struct { + Name string `json:"name"` //时间名称 + NextTime time.Time `json:"time"` //下次更新时间 + Status bool `json:"status"` //状态 + StatusTrueDes string `json:"true_des"` //状态说明 + StatusFalseDes string `json:"false_des"` //状态说明 + DayTime int `json:"day"` //白天时长 + NightTime int `json:"night"` //夜间时长 +} + +type SubList struct { + SubUser map[int64]SubType `json:"qq_sub"` + Min5Tips bool `json:"min5_tips"` + Min15Tips bool `json:"min15_tips"` +} + +type SubType struct { + SubType map[int]*bool `json:"sub_type"` + SubRaid bool `json:"sub_raid"` +} diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go new file mode 100644 index 0000000000..90172cddeb --- /dev/null +++ b/plugin/warframeapi/main.go @@ -0,0 +1,643 @@ +package warframeapi + +import ( + "bufio" + "encoding/json" + "fmt" + "github.com/FloatTech/floatbox/binary" + "github.com/FloatTech/zbputils/img/text" + "io" + "io/ioutil" + "net/http" + "os" + "sort" + "strconv" + "strings" + "time" + + "github.com/FloatTech/floatbox/web" + ctrl "github.com/FloatTech/zbpctrl" + "github.com/FloatTech/zbputils/control" + "github.com/lithammer/fuzzysearch/fuzzy" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +var ( + wfapi WFAPI + client http.Client + itmeapi WFAPIItem + wmitems map[string]Items + itmeNames []string + fileItemNames map[string]string + itemNamesPath string + sublist map[int64]*SubList + sublistPath string +) + +func init() { + eng := control.Register("warframeapi", &ctrl.Options[*zero.Ctx]{ + DisableOnDefault: false, + Help: "warframeapi\n" + + "- wf数据更新\n" + + "- [金星/地球/火卫二]平原状态\n" + + "- 订阅[金星/地球/火卫二]平原[白天/夜晚]\n" + + "- 取消订阅[金星/地球/火卫二]平原[白天/夜晚]\n" + + "- .wm [物品名称]\n" + + "- 取外号 [原名称] [外号]\n" + + "- [金星/地球/火卫二]平原状态\n" + + "- 仲裁\n" + + "- 警报\n" + + "- 每日特惠", + PrivateDataFolder: "warframeAPI", + }) + + itemNamesPath = eng.DataFolder() + "ItemNames.json" + + if isExist(itemNamesPath) { + data, err := ioutil.ReadFile(itemNamesPath) + if err != nil { + panic(err) + } + err = json.Unmarshal(data, &fileItemNames) + if err != nil { + panic(err) + } + } else { + fileItemNames = map[string]string{} + } + sublistPath = eng.DataFolder() + "Sublist.json" + if isExist(sublistPath) { + data, err := ioutil.ReadFile(sublistPath) + if err != nil { + panic(err) + } + err = json.Unmarshal(data, &sublist) + if err != nil { + panic(err) + } + } else { + sublist = map[int64]*SubList{} + } + updateWM() + loadToFuzzy() + udateWFAPI2() + + eng.OnRegex(`^(.*)平原状态$`).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + args := ctx.State["regex_matched"].([]string) + updateWFAPI(ctx) + + switch args[1] { + case "奥布山谷": + fallthrough + case "金星": + ctx.SendChain( + message.Text( + "平原状态:", GameTimes[1].getStatus(), "\n", + "下次更新:", GameTimes[1].getTime(), + ), + ) + case "夜灵": + fallthrough + case "地球": + ctx.SendChain( + message.Text( + "平原状态:", GameTimes[0].getStatus(), "\n", + "下次更新:", GameTimes[0].getTime(), + ), + ) + case "火卫": + fallthrough + case "火卫二": + fallthrough + case "魔胎之境": + ctx.SendChain( + message.Text( + "平原状态:", GameTimes[2].getStatus(), "\n", + "下次更新:", GameTimes[2].getTime(), + ), + ) + default: + ctx.SendChain(message.Text("Error:平原不存在")) + return + } + }) + + eng.OnRegex(`^警报$`).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + if len(wfapi.Alerts) > 0 { + for _, v := range wfapi.Alerts { + if v.Active { + sendStringArray([]string{ + "节点:" + v.Mission.Node, + "类型:" + v.Mission.Type, + "敌人Lv:" + fmt.Sprint(v.Mission.MinEnemyLevel) + "~" + fmt.Sprint(v.Mission.MaxEnemyLevel), + "奖励:" + v.Mission.Reward.AsString, + "剩余时间:" + v.Eta, + }, ctx) + } + } + } + + }) + eng.OnRegex(`^订阅(.*)平原(.*)$`).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + args := ctx.State["regex_matched"].([]string) + updateWFAPI(ctx) + status := false + switch args[2] { + case "白天": + fallthrough + case "fass": + fallthrough + case "Fass": + fallthrough + case "温暖": + status = true + } + switch args[1] { + case "奥布山谷": + fallthrough + case "金星": + //sublist = append(sublist, SubList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) + addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1, status) + ctx.SendChain( + message.At(ctx.Event.UserID), + message.Text("已成功订阅"), + message.Text(GameTimes[1].Name), + message.Text(status), + ) + case "夜灵": + fallthrough + case "地球": + addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0, status) + ctx.SendChain( + message.At(ctx.Event.UserID), + message.Text("已成功订阅"), + message.Text(GameTimes[0].Name), + message.Text(status), + ) + case "火卫": + fallthrough + case "火卫二": + fallthrough + case "魔胎之境": + addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2, status) + ctx.SendChain( + message.At(ctx.Event.UserID), + message.Text("已成功订阅"), + message.Text(GameTimes[2].Name), + message.Text(status), + ) + default: + ctx.SendChain(message.Text("Error:平原不存在")) + return + } + }) + eng.OnRegex(`^取消订阅(.*)平原(.*)$`).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + args := ctx.State["regex_matched"].([]string) + updateWFAPI(ctx) + status := false + switch args[2] { + case "白天": + fallthrough + case "fass": + fallthrough + case "Fass": + fallthrough + case "温暖": + status = true + } + switch args[1] { + case "奥布山谷": + fallthrough + case "金星": + //sublist = append(sublist, SubList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) + removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1) + ctx.SendChain( + message.At(ctx.Event.UserID), + message.Text("已取消订阅"), + message.Text(GameTimes[1].Name), + message.Text(status), + ) + case "夜灵": + fallthrough + case "地球": + removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0) + ctx.SendChain( + message.At(ctx.Event.UserID), + message.Text("已取消订阅"), + message.Text(GameTimes[0].Name), + message.Text(status), + ) + case "火卫": + fallthrough + case "火卫二": + fallthrough + case "魔胎之境": + removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2) + ctx.SendChain( + message.At(ctx.Event.UserID), + message.Text("已取消订阅"), + message.Text(GameTimes[2].Name), + message.Text(status), + ) + default: + ctx.SendChain(message.Text("Error:平原不存在")) + return + } + }) + eng.OnRegex(`^仲裁$`).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + updateWFAPI(ctx) + sendStringArray([]string{ + "节点:" + wfapi.Arbitration.Node, + "类型:" + wfapi.Arbitration.Type, + "阵营:" + wfapi.Arbitration.Enemy, + "剩余时间:" + fmt.Sprint(int(wfapi.Arbitration.Expiry.Sub(time.Now().UTC()).Minutes())) + "m", + }, ctx) + }) + eng.OnRegex(`^每日特惠$`).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + updateWFAPI(ctx) + for _, dd := range wfapi.DailyDeals { + ctx.SendChain( + message.Text( + "物品:", dd.Item, "\n", + "价格:", dd.OriginalPrice, "→", dd.SalePrice, "\n", + "数量:(", dd.Total, "/", dd.Sold, ")\n", + "时间:", dd.Eta, + ), + ) + } + }) + // eng.OnRegex(`^入侵$`).SetBlock(true). + // Handle(func(ctx *zero.Ctx) { + // updateWFAPI(ctx) + // for _, dd := range wfapi.DailyDeals { + // imagebuild.DrawTextSend([]string{ + // "节点:" + wfapi.Arbitration.Node, + // "类型:" + wfapi.Arbitration.Type, + // "阵营:" + wfapi.Arbitration.Enemy, + // "剩余时间:" + fmt.Sprint(int(wfapi.Arbitration.Expiry.Sub(time.Now().UTC()).Minutes())) + "m", + // }, ctx) + // } + // }) + eng.OnRegex(`^wf数据更新$`).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + updateWFAPI(ctx) + LoadTime() + ctx.SendChain(message.Text("已拉取服务器时间并同步到本地模拟")) + }) + eng.OnRegex(`^.取外号 (.*) (.*)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) { + args := ctx.State["regex_matched"].([]string) + sol := fuzzy.FindNormalizedFold(args[1], itmeNames) + var msg []string + switch len(sol) { + case 0: + ctx.SendChain(message.Text("无法查询到该物品")) + return + case 1: + wmitems[args[2]] = wmitems[sol[0]] + itmeNames = append(itmeNames, args[2]) + fileItemNames[args[2]] = sol[0] + ctx.Send(message.Text("已给[", sol[0], "]新增外号:[", args[2], "]")) + jsonSave(fileItemNames, itemNamesPath) + default: + for i, v := range sol { + msg = append(msg, fmt.Sprintf("[%d] %s", i, v)) + } + msg = append(msg, "包含多个结果,请输入编号来确定具体的物品外号(15s内)") + sendStringArray(msg, ctx) + //msg = []string{} + GETNUM: + next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() + select { + case <-time.After(time.Second * 15): + ctx.SendChain(message.Text("会话已结束!")) + return + case e := <-next: + msg := e.Event.Message.ExtractPlainText() + if msg == "c" { + ctx.SendChain(message.Text("会话已结束!")) + return + } + num, err := strconv.Atoi(msg) + if err != nil { + ctx.SendChain(message.Text("请输入数字!(输入c结束会话)")) + goto GETNUM + } + //name = sol[cc] + //ctx.Send(message.Image("https://warframe.market/static/assets/" + wmitems[sol[cc]].Thumb)) + //msg = append(msg, wmitems[sol[cc]].ItemName) + + wmitems[args[2]] = wmitems[sol[num]] + itmeNames = append(itmeNames, args[2]) + fileItemNames[args[2]] = sol[num] + ctx.Send(message.Text("已给[", sol[num], "]新增外号:[", args[2], "]")) + jsonSave(fileItemNames, itemNamesPath) + } + + } + + }) + eng.OnRegex(`^.wm (.*)$`).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + args := ctx.State["regex_matched"].([]string) + sol := fuzzy.FindNormalizedFold(args[1], itmeNames) + var msg []string + var name string + switch len(sol) { + case 0: + ctx.SendChain(message.Text("无法查询到该物品")) + return + case 1: + name = sol[0] + default: + for i, v := range sol { + msg = append(msg, fmt.Sprintf("[%d] %s", i, v)) + } + msg = append(msg, "包含多个结果,请输入编号查看(15s内),输入c直接结束会话") + sendStringArray(msg, ctx) + msg = []string{} + GETNUM2: + next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() + select { + case <-time.After(time.Second * 15): + ctx.SendChain(message.Text("会话已结束!")) + return + case e := <-next: + msg := e.Event.Message.ExtractPlainText() + if msg == "c" { + ctx.SendChain(message.Text("会话已结束!")) + return + } + num, err := strconv.Atoi(msg) + if err != nil { + ctx.SendChain(message.Text("请输入数字!(输入c结束会话)")) + goto GETNUM2 + } + name = sol[num] + } + } + Mf := false + GETWM: + if Mf { + msg = []string{} + } + sells, itmeinfo, txt, err := getWMItemOrders(wmitems[name].URLName, Mf) + if itmeinfo.ZhHans.WikiLink == "" { + ctx.Send([]message.MessageSegment{ + message.Image("https://warframe.market/static/assets/" + wmitems[name].Thumb), + message.Text(wmitems[name].ItemName, "\n"), + }) + } else { + ctx.Send([]message.MessageSegment{ + message.Image("https://warframe.market/static/assets/" + wmitems[name].Thumb), + message.Text(wmitems[name].ItemName, "\n"), + message.Text("wiki:", itmeinfo.ZhHans.WikiLink), + }) + } + + msg = append(msg, wmitems[name].ItemName) + ismod := false + if err != nil { + ctx.Send(message.Text("Error:", err.Error())) + return + } + if itmeinfo.ModMaxRank != 0 { + ismod = true + } + max := 5 + if sells == nil { + ctx.Send(message.Text("无可购买对象")) + return + } + + if len(sells) <= max { + max = len(sells) + } + + for i := 0; i < max; i++ { + if ismod { + msg = append(msg, fmt.Sprintf("[%d](Rank:%d/%d) %dP - %s\n", i, sells[i].ModRank, itmeinfo.ModMaxRank, sells[i].Platinum, sells[i].User.IngameName)) + } else { + msg = append(msg, fmt.Sprintf("[%d] %dP -%s\n", i, sells[i].Platinum, sells[i].User.IngameName)) + } + } + if ismod && !Mf { + msg = append(msg, "请输入编号选择,或输入r获取满级报价(30s内)\n输入c直接结束会话") + } else { + msg = append(msg, "请输入编号选择(30s内)\n输入c直接结束会话") + } + sendStringArray(msg, ctx) + GETNUM3: + next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() + select { + case <-time.After(time.Second * 30): + ctx.SendChain(message.Text("会话已结束!")) + return + case e := <-next: + msg := e.Event.Message.ExtractPlainText() + if msg == "r" { + Mf = true + goto GETWM + } + if msg == "c" { + ctx.SendChain(message.Text("会话已结束!")) + return + } + i, err := strconv.Atoi(msg) + if err != nil { + ctx.SendChain(message.Text("请输入数字!(输入c结束会话)")) + goto GETNUM3 + } + if err == nil { + if ismod { + ctx.Send(message.Text(fmt.Sprintf("/w %s Hi! I want to buy: %s(Rank:%d) for %d platinum. (warframe.market)", sells[i].User.IngameName, txt, sells[i].ModRank, sells[i].Platinum))) + + } else { + ctx.Send(message.Text(fmt.Sprintf("/w %s Hi! I want to buy: %s for %d platinum. (warframe.market)", sells[i].User.IngameName, txt, sells[i].Platinum))) + } + return + } + + return + } + + }) + +} +func sendStringArray(texts []string, ctx *zero.Ctx) { + b, err := text.RenderToBase64(strings.Join(texts, "\n"), text.FontFile, 800, 20) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + ctx.SendChain(message.Image("base64://" + binary.BytesToString(b))) +} + +func addUseSub(QQ int64, QQGroup int64, stype int, status bool) { + if sb, ok := sublist[QQGroup]; ok { + if st, ok := sb.SubUser[QQ]; ok { + st.SubType[stype] = &status + } else { + sublist[QQGroup].SubUser[QQ] = SubType{map[int]*bool{stype: &status}, false} + } + } else { + sublist[QQGroup] = &SubList{map[int64]SubType{QQ: {map[int]*bool{stype: &status}, false}}, false, false} + } + jsonSave(sublist, sublistPath) +} + +func removeUseSub(QQ int64, QQGroup int64, stype int) { + if sb, ok := sublist[QQGroup]; ok { + if _, ok := sb.SubUser[QQ]; ok { + delete(sublist[QQGroup].SubUser[QQ].SubType, stype) + jsonSave(sublist, sublistPath) + } + } +} + +func updateWFAPI(ctx *zero.Ctx) { + var data []byte + var err error + data, err = web.GetData("https://api.warframestat.us/pc") + if err != nil { + ctx.SendChain(message.Text("Error:", err.Error())) + return + } + err = json.Unmarshal(data, &wfapi) + if err != nil { + ctx.SendChain(message.Text("Error:", err.Error())) + return + } + +} + +func udateWFAPI2() { + var data []byte + var err error + data, err = web.GetData("https://api.warframestat.us/pc") + if err != nil { + return + } + err = json.Unmarshal(data, &wfapi) + if err != nil { + return + } + gameTimeInit() + LoadTime() +} +func updateWM() { + var data []byte + var err error + data, err = getData("https://api.warframe.market/v1/items", []string{"Accept", "Language"}, []string{"application/json", "zh-hans"}) + if err != nil { + panic(err) + + } + err = json.Unmarshal(data, &itmeapi) + if err != nil { + panic(err) + } +} + +func getWMItemOrders(name string, h bool) (Orders, ItemsInSet, string, error) { + var data []byte + var err error + var wfapiio WFAPIItemsOrders + data, err = getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", name), []string{"Accept", "Platform"}, []string{"application/json", "pc"}) + if err != nil { + return nil, ItemsInSet{}, "", err + } + err = json.Unmarshal(data, &wfapiio) + + var sellOrders Orders + for _, v := range wfapiio.Payload.Orders { + if v.OrderType == "sell" && v.User.Status != "offline" { + if h && v.ModRank == wfapiio.Include.Item.ItemsInSet[0].ModMaxRank { + sellOrders = append(sellOrders, v) + } else if !h { + sellOrders = append(sellOrders, v) + } + + } + } + sort.Sort(sellOrders) + + for i, v := range wfapiio.Include.Item.ItemsInSet { + if v.URLName == name { + return sellOrders, wfapiio.Include.Item.ItemsInSet[i], wfapiio.Include.Item.ItemsInSet[i].En.ItemName, err + } + } + return sellOrders, wfapiio.Include.Item.ItemsInSet[0], wfapiio.Include.Item.ItemsInSet[0].En.ItemName, err +} + +func loadToFuzzy() { + wmitems = make(map[string]Items) + itmeNames = []string{} + for _, v := range itmeapi.Payload.Items { + wmitems[v.ItemName] = v + itmeNames = append(itmeNames, v.ItemName) + } + for k, v := range fileItemNames { + wmitems[k] = wmitems[v] + itmeNames = append(itmeNames, k) + } +} + +func getData(url string, head []string, headvalue []string) (data []byte, err error) { + //提交请求 + reqest, err := http.NewRequest("GET", url, nil) + //增加header选项 + for i, v := range head { + reqest.Header.Add(v, headvalue[i]) + } + if err != nil { + return nil, err + } + //处理返回结果 + response, err := client.Do(reqest) + if err != nil { + return nil, err + } + data, err = io.ReadAll(response.Body) + response.Body.Close() + return data, err +} + +func isExist(path string) bool { + _, err := os.Stat(path) + if err != nil { + if os.IsExist(err) { + return true + } + if os.IsNotExist(err) { + return false + } + fmt.Println(err) + return false + } + return true +} +func jsonSave(v interface{}, path string) (bool, error) { + data, err := json.Marshal(v) + if err != nil { + return false, err + } + dataStr := string(data) + + // 将字符串写入指定的文件 + file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + return false, err + } + defer file.Close() // 结束时关闭句柄,释放资源 + writer := bufio.NewWriter(file) + writer.WriteString(dataStr) + writer.Flush() // 缓存数据写入磁盘(持久化) + return true, nil +} diff --git a/plugin/warframeapi/wfdata.go b/plugin/warframeapi/wfdata.go new file mode 100644 index 0000000000..b20d045217 --- /dev/null +++ b/plugin/warframeapi/wfdata.go @@ -0,0 +1,630 @@ +package warframeapi + +import "time" + +type WFAPI struct { + Timestamp time.Time `json:"timestamp"` + News []News `json:"news"` + Events []Events `json:"events"` + Alerts []Alerts `json:"alerts"` + Sortie Sortie `json:"sortie"` + SyndicateMissions []SyndicateMissions `json:"syndicateMissions"` + Fissures []Fissures `json:"fissures"` + GlobalUpgrades []interface{} `json:"globalUpgrades"` + FlashSales []FlashSales `json:"flashSales"` + Invasions []Invasions `json:"invasions"` + DarkSectors []interface{} `json:"darkSectors"` + VoidTrader VoidTrader `json:"voidTrader"` + DailyDeals []DailyDeals `json:"dailyDeals"` + Simaris Simaris `json:"simaris"` + ConclaveChallenges []ConclaveChallenges `json:"conclaveChallenges"` + PersistentEnemies []interface{} `json:"persistentEnemies"` + EarthCycle EarthCycle `json:"earthCycle"` + CetusCycle CetusCycle `json:"cetusCycle"` + CambionCycle CambionCycle `json:"cambionCycle"` + ZarimanCycle ZarimanCycle `json:"zarimanCycle"` + WeeklyChallenges []interface{} `json:"weeklyChallenges"` + ConstructionProgress ConstructionProgress `json:"constructionProgress"` + VallisCycle VallisCycle `json:"vallisCycle"` + Nightwave Nightwave `json:"nightwave"` + Kuva []interface{} `json:"kuva"` + Arbitration Arbitration `json:"arbitration"` + SentientOutposts SentientOutposts `json:"sentientOutposts"` + SteelPath SteelPath `json:"steelPath"` + VaultTrader VaultTrader `json:"vaultTrader"` +} +type Translations struct { + En string `json:"en"` + Fr string `json:"fr"` + It string `json:"it"` + De string `json:"de"` + Es string `json:"es"` + Pt string `json:"pt"` + Ru string `json:"ru"` + Pl string `json:"pl"` + Uk string `json:"uk"` + Tr string `json:"tr"` + Ja string `json:"ja"` + Zh string `json:"zh"` + Ko string `json:"ko"` + Tc string `json:"tc"` +} +type News struct { + ID string `json:"id"` + Message string `json:"message"` + Link string `json:"link"` + ImageLink string `json:"imageLink"` + Priority bool `json:"priority"` + Date time.Time `json:"date"` + Eta string `json:"eta"` + Update bool `json:"update"` + PrimeAccess bool `json:"primeAccess"` + Stream bool `json:"stream"` + Translations Translations `json:"translations"` + AsString string `json:"asString"` +} +type Metadata struct { +} +type NextAlt struct { + Expiry time.Time `json:"expiry"` + Activation time.Time `json:"activation"` +} +type Events struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + MaximumScore int `json:"maximumScore"` + CurrentScore int `json:"currentScore"` + SmallInterval interface{} `json:"smallInterval"` + LargeInterval interface{} `json:"largeInterval"` + Faction string `json:"faction"` + Description string `json:"description"` + Tooltip string `json:"tooltip"` + Node string `json:"node"` + ConcurrentNodes []interface{} `json:"concurrentNodes"` + Rewards []interface{} `json:"rewards"` + Expired bool `json:"expired"` + InterimSteps []interface{} `json:"interimSteps"` + ProgressSteps []interface{} `json:"progressSteps"` + IsPersonal bool `json:"isPersonal"` + RegionDrops []interface{} `json:"regionDrops"` + ArchwingDrops []interface{} `json:"archwingDrops"` + AsString string `json:"asString"` + Metadata Metadata `json:"metadata"` + CompletionBonuses []interface{} `json:"completionBonuses"` + AltExpiry time.Time `json:"altExpiry"` + AltActivation time.Time `json:"altActivation"` + NextAlt NextAlt `json:"nextAlt"` +} +type Variants struct { + MissionType string `json:"missionType"` + Modifier string `json:"modifier"` + ModifierDescription string `json:"modifierDescription"` + Node string `json:"node"` +} +type Sortie struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + RewardPool string `json:"rewardPool"` + Variants []Variants `json:"variants"` + Boss string `json:"boss"` + Faction string `json:"faction"` + Expired bool `json:"expired"` + Eta string `json:"eta"` +} +type Jobs struct { + ID string `json:"id"` + RewardPool []string `json:"rewardPool"` + Type string `json:"type"` + EnemyLevels []int `json:"enemyLevels"` + StandingStages []int `json:"standingStages"` + MinMR int `json:"minMR"` + Expiry time.Time `json:"expiry"` + TimeBound string `json:"timeBound,omitempty"` +} +type SyndicateMissions struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + Syndicate string `json:"syndicate"` + SyndicateKey string `json:"syndicateKey"` + Nodes []interface{} `json:"nodes"` + Jobs []Jobs `json:"jobs"` + Eta string `json:"eta"` +} +type Fissures struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + Node string `json:"node"` + MissionType string `json:"missionType"` + MissionKey string `json:"missionKey"` + Enemy string `json:"enemy"` + EnemyKey string `json:"enemyKey"` + NodeKey string `json:"nodeKey"` + Tier string `json:"tier"` + TierNum int `json:"tierNum"` + Expired bool `json:"expired"` + Eta string `json:"eta"` + IsStorm bool `json:"isStorm"` +} +type FlashSales struct { + Item string `json:"item"` + Expiry time.Time `json:"expiry"` + Activation time.Time `json:"activation"` + Discount int `json:"discount"` + RegularOverride int `json:"regularOverride"` + PremiumOverride int `json:"premiumOverride"` + IsShownInMarket bool `json:"isShownInMarket"` + IsFeatured bool `json:"isFeatured"` + IsPopular bool `json:"isPopular"` + ID string `json:"id"` + Expired bool `json:"expired"` + Eta string `json:"eta"` +} +type CountedItems struct { + Count int `json:"count"` + Type string `json:"type"` + Key string `json:"key"` +} +type AttackerReward struct { + Items []interface{} `json:"items"` + CountedItems []CountedItems `json:"countedItems"` + Credits int `json:"credits"` + AsString string `json:"asString"` + ItemString string `json:"itemString"` + Thumbnail string `json:"thumbnail"` + Color int `json:"color"` +} +type Reward struct { + Items []interface{} `json:"items"` + CountedItems []CountedItems `json:"countedItems"` + Credits int `json:"credits"` + AsString string `json:"asString"` + ItemString string `json:"itemString"` + Thumbnail string `json:"thumbnail"` + Color int `json:"color"` +} +type Attacker struct { + Reward Reward `json:"reward"` + Faction string `json:"faction"` + FactionKey string `json:"factionKey"` +} +type DefenderReward struct { + Items []interface{} `json:"items"` + CountedItems []CountedItems `json:"countedItems"` + Credits int `json:"credits"` + AsString string `json:"asString"` + ItemString string `json:"itemString"` + Thumbnail string `json:"thumbnail"` + Color int `json:"color"` +} +type Defender struct { + Reward Reward `json:"reward"` + Faction string `json:"faction"` + FactionKey string `json:"factionKey"` +} +type Invasions struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Node string `json:"node"` + NodeKey string `json:"nodeKey"` + Desc string `json:"desc"` + AttackerReward AttackerReward `json:"attackerReward"` + AttackingFaction string `json:"attackingFaction"` + Attacker Attacker `json:"attacker"` + DefenderReward DefenderReward `json:"defenderReward"` + DefendingFaction string `json:"defendingFaction"` + Defender Defender `json:"defender"` + VsInfestation bool `json:"vsInfestation"` + Count int `json:"count"` + RequiredRuns int `json:"requiredRuns"` + Completion float64 `json:"completion"` + Completed bool `json:"completed"` + Eta string `json:"eta"` + RewardTypes []string `json:"rewardTypes"` +} +type VoidTrader struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + Character string `json:"character"` + Location string `json:"location"` + Inventory []interface{} `json:"inventory"` + PsID string `json:"psId"` + EndString string `json:"endString"` + InitialStart time.Time `json:"initialStart"` + Schedule []interface{} `json:"schedule"` +} +type DailyDeals struct { + Item string `json:"item"` + Expiry time.Time `json:"expiry"` + Activation time.Time `json:"activation"` + OriginalPrice int `json:"originalPrice"` + SalePrice int `json:"salePrice"` + Total int `json:"total"` + Sold int `json:"sold"` + ID string `json:"id"` + Eta string `json:"eta"` + Discount int `json:"discount"` +} +type Simaris struct { + Target string `json:"target"` + IsTargetActive bool `json:"isTargetActive"` + AsString string `json:"asString"` +} +type ConclaveChallenges struct { + ID string `json:"id"` + Expiry time.Time `json:"expiry"` + Activation time.Time `json:"activation"` + Amount int `json:"amount"` + Mode string `json:"mode"` + Category string `json:"category"` + Eta string `json:"eta"` + Expired bool `json:"expired"` + Daily bool `json:"daily"` + RootChallenge bool `json:"rootChallenge"` + EndString string `json:"endString"` + Description string `json:"description"` + Title string `json:"title"` + Standing int `json:"standing"` + AsString string `json:"asString"` +} +type EarthCycle struct { + ID string `json:"id"` + Expiry time.Time `json:"expiry"` + Activation time.Time `json:"activation"` + IsDay bool `json:"isDay"` + State string `json:"state"` + TimeLeft string `json:"timeLeft"` +} +type CetusCycle struct { + ID string `json:"id"` + Expiry time.Time `json:"expiry"` + Activation time.Time `json:"activation"` + IsDay bool `json:"isDay"` + State string `json:"state"` + TimeLeft string `json:"timeLeft"` + IsCetus bool `json:"isCetus"` + ShortString string `json:"shortString"` +} +type CambionCycle struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + Expiry time.Time `json:"expiry"` + TimeLeft string `json:"timeLeft"` + Active string `json:"active"` +} +type ZarimanCycle struct { + ID string `json:"id"` + BountiesEndDate time.Time `json:"bountiesEndDate"` + Expiry time.Time `json:"expiry"` + Activation time.Time `json:"activation"` + IsCorpus bool `json:"isCorpus"` + State string `json:"state"` + TimeLeft string `json:"timeLeft"` + ShortString string `json:"shortString"` +} +type ConstructionProgress struct { + ID string `json:"id"` + FomorianProgress string `json:"fomorianProgress"` + RazorbackProgress string `json:"razorbackProgress"` + UnknownProgress string `json:"unknownProgress"` +} +type VallisCycle struct { + ID string `json:"id"` + Expiry time.Time `json:"expiry"` + IsWarm bool `json:"isWarm"` + State string `json:"state"` + Activation time.Time `json:"activation"` + TimeLeft string `json:"timeLeft"` + ShortString string `json:"shortString"` +} +type Params struct { +} +type ActiveChallenges struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + IsDaily bool `json:"isDaily,omitempty"` + IsElite bool `json:"isElite"` + Desc string `json:"desc"` + Title string `json:"title"` + Reputation int `json:"reputation"` +} +type Nightwave struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + Season int `json:"season"` + Tag string `json:"tag"` + Phase int `json:"phase"` + Params Params `json:"params"` + PossibleChallenges []interface{} `json:"possibleChallenges"` + ActiveChallenges []ActiveChallenges `json:"activeChallenges"` + RewardTypes []string `json:"rewardTypes"` +} +type Arbitration struct { + Activation time.Time `json:"activation"` + Expiry time.Time `json:"expiry"` + Enemy string `json:"enemy"` + Type string `json:"type"` + Archwing bool `json:"archwing"` + Sharkwing bool `json:"sharkwing"` + Node string `json:"node"` + NodeKey string `json:"nodeKey"` + TypeKey string `json:"typeKey"` + ID string `json:"id"` + Expired bool `json:"expired"` +} +type Mission struct { + Node string `json:"node"` + Faction string `json:"faction"` + Type string `json:"type"` +} +type SentientOutposts struct { + Mission Mission `json:"mission"` + Activation time.Time `json:"activation"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + ID string `json:"id"` +} +type CurrentReward struct { + Name string `json:"name"` + Cost int `json:"cost"` +} +type Rotation struct { + Name string `json:"name"` + Cost int `json:"cost"` +} +type Evergreens struct { + Name string `json:"name"` + Cost int `json:"cost"` +} +type Incursions struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + Expiry time.Time `json:"expiry"` +} +type SteelPath struct { + CurrentReward CurrentReward `json:"currentReward"` + Activation time.Time `json:"activation"` + Expiry time.Time `json:"expiry"` + Remaining string `json:"remaining"` + Rotation []Rotation `json:"rotation"` + Evergreens []Evergreens `json:"evergreens"` + Incursions Incursions `json:"incursions"` +} +type Inventory struct { + Item string `json:"item"` + Ducats int `json:"ducats"` + Credits interface{} `json:"credits"` +} +type Schedule struct { + Expiry time.Time `json:"expiry"` + Item string `json:"item"` +} +type VaultTrader struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + Character string `json:"character"` + Location string `json:"location"` + Inventory []Inventory `json:"inventory"` + PsID string `json:"psId"` + EndString string `json:"endString"` + InitialStart time.Time `json:"initialStart"` + Completed bool `json:"completed"` + Schedule []Schedule `json:"schedule"` +} +type Alerts struct { + ID string `json:"id"` + Activation time.Time `json:"activation"` + StartString string `json:"startString"` + Expiry time.Time `json:"expiry"` + Active bool `json:"active"` + Mission struct { + Description string `json:"description"` + Node string `json:"node"` + NodeKey string `json:"nodeKey"` + Type string `json:"type"` + TypeKey string `json:"typeKey"` + Faction string `json:"faction"` + Reward struct { + Items []interface{} `json:"items"` + CountedItems []struct { + Count int `json:"count"` + Type string `json:"type"` + Key string `json:"key"` + } `json:"countedItems"` + Credits int `json:"credits"` + AsString string `json:"asString"` + ItemString string `json:"itemString"` + Thumbnail string `json:"thumbnail"` + Color int `json:"color"` + } `json:"reward"` + MinEnemyLevel int `json:"minEnemyLevel"` + MaxEnemyLevel int `json:"maxEnemyLevel"` + MaxWaveNum int `json:"maxWaveNum"` + Nightmare bool `json:"nightmare"` + ArchwingRequired bool `json:"archwingRequired"` + IsSharkwing bool `json:"isSharkwing"` + LevelOverride string `json:"levelOverride"` + EnemySpec string `json:"enemySpec"` + AdvancedSpawners []interface{} `json:"advancedSpawners"` + RequiredItems []interface{} `json:"requiredItems"` + LevelAuras []interface{} `json:"levelAuras"` + } `json:"mission"` + Eta string `json:"eta"` + RewardTypes []string `json:"rewardTypes"` + Tag string `json:"tag"` +} +type WFAPIItem struct { + Payload Payload `json:"payload"` +} +type Items struct { + URLName string `json:"url_name"` + Thumb string `json:"thumb"` + ItemName string `json:"item_name"` + ID string `json:"id"` + Vaulted bool `json:"vaulted,omitempty"` +} +type Payload struct { + Items []Items `json:"items"` + Orders Orders `json:"orders"` +} + +type WFAPIItemsOrders struct { + Payload Payload `json:"payload"` + Include Include `json:"include"` +} +type User struct { + IngameName string `json:"ingame_name"` + LastSeen time.Time `json:"last_seen"` + Reputation int `json:"reputation"` + Region string `json:"region"` + ID string `json:"id"` + Avatar interface{} `json:"avatar"` + Status string `json:"status"` +} +type Orders []struct { + OrderType string `json:"order_type"` + LastUpdate time.Time `json:"last_update"` + Region string `json:"region"` + Quantity int `json:"quantity"` + Visible bool `json:"visible"` + CreationDate time.Time `json:"creation_date"` + Platinum int `json:"platinum"` + Platform string `json:"platform"` + User User `json:"user"` + ID string `json:"id"` + ModRank int `json:"mod_rank"` +} + +func (a Orders) Len() int { // 重写 Len() 方法 + return len(a) +} +func (a Orders) Swap(i, j int) { // 重写 Swap() 方法 + a[i], a[j] = a[j], a[i] +} +func (a Orders) Less(i, j int) bool { // 重写 Less() 方法, 从大到小排序 + return a[i].Platinum < a[j].Platinum +} + +type En struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type Ru struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type Ko struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type Fr struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type Sv struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type De struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type ZhHant struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type ZhHans struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type Pt struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type Es struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type Pl struct { + ItemName string `json:"item_name"` + Description string `json:"description"` + WikiLink string `json:"wiki_link"` + Drop []interface{} `json:"drop"` +} +type ItemsInSet struct { + Icon string `json:"icon"` + URLName string `json:"url_name"` + SubIcon string `json:"sub_icon"` + ModMaxRank int `json:"mod_max_rank"` + Thumb string `json:"thumb"` + SetRoot bool `json:"set_root"` + QuantityForSet int `json:"quantity_for_set,omitempty"` + ID string `json:"id"` + TradingTax int `json:"trading_tax"` + Tags []string `json:"tags"` + MasteryLevel int `json:"mastery_level"` + Ducats int `json:"ducats"` + IconFormat string `json:"icon_format"` + En En `json:"en"` + Ru Ru `json:"ru"` + Ko Ko `json:"ko"` + Fr Fr `json:"fr"` + Sv Sv `json:"sv"` + De De `json:"de"` + ZhHant ZhHant `json:"zh-hant"` + ZhHans ZhHans `json:"zh-hans"` + Pt Pt `json:"pt"` + Es Es `json:"es"` + Pl Pl `json:"pl"` +} +type Item struct { + ID string `json:"id"` + ItemsInSet []ItemsInSet `json:"items_in_set"` +} +type Include struct { + Item Item `json:"item"` +} From 83b382561493518429f79e0ef1fa2d8dd4a84a97 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Fri, 23 Dec 2022 11:04:15 +0800 Subject: [PATCH 02/19] WarframeAPI lint fix --- plugin/warframeapi/gametime.go | 60 +++++++++++++++++++------------ plugin/warframeapi/main.go | 64 ++++++++++++++++++---------------- 2 files changed, 70 insertions(+), 54 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index 27b0b4d93b..1a913f0a6b 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -10,17 +10,17 @@ import ( ) var ( - GameTimes []GameTime + GameTimes []gameTime ) -func (t GameTime) getStatus() string { +func (t gameTime) getStatus() string { if t.Status { return t.StatusTrueDes } else { - return t.StatusTrueDes + return t.StatusFalseDes } } -func (t GameTime) getTime() string { +func (t gameTime) getTime() string { d := time.Until(t.NextTime) durStr, _ := durationfmt.Format(d, "%m分%s秒后") return durStr @@ -36,7 +36,7 @@ func gameTimeInit() { func gameRuntime() { for { time.Sleep(10 * time.Second) - TimeDet() + timeDet() } } @@ -47,7 +47,7 @@ func LoadTime() { if wfapi.CambionCycle.Active == "fass" { isfass = false } - GameTimes = []GameTime{ + GameTimes = []gameTime{ {"地球平原", wfapi.CetusCycle.Expiry.Local(), wfapi.CetusCycle.IsDay, "白天", "夜晚", 100 * 60, 50 * 60}, {"金星平原", wfapi.VallisCycle.Expiry.Local(), wfapi.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, {"火卫二平原", wfapi.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, @@ -55,42 +55,56 @@ func LoadTime() { } -func TimeDet() { +func timeDet() { for i, v := range GameTimes { - if time.Until(v.NextTime).Seconds() < 0 { + nt := time.Until(v.NextTime).Seconds() + switch { + case nt < 0: if v.Status { GameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) } else { GameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) } GameTimes[i].Status = !GameTimes[i].Status - CallUser(i, GameTimes[i].Status, 0) - } else if time.Until(v.NextTime).Seconds() < float64(5)*60 { - CallUser(i, !GameTimes[i].Status, 5) - } else if time.Until(v.NextTime).Seconds() < float64(15)*60 { + callUser(i, GameTimes[i].Status, 0) + case nt < float64(5)*60: + callUser(i, !GameTimes[i].Status, 5) + case nt < float64(15)*60: if i == 2 && !v.Status { return } - CallUser(i, !GameTimes[i].Status, 15) - + callUser(i, !GameTimes[i].Status, 15) } } } -func CallUser(i int, s bool, time int) { +func callUser(i int, s bool, time int) { for group, sl := range sublist { msg := []message.MessageSegment{} - if !sl.Min15Tips && !sl.Min5Tips && time == 15 { + + switch { + case !sl.Min15Tips && !sl.Min5Tips && time == 15: sublist[group].Min15Tips = true - } else if sl.Min15Tips && !sl.Min5Tips && time == 5 { + case sl.Min15Tips && !sl.Min5Tips && time == 5: sublist[group].Min5Tips = true - } else if sl.Min15Tips && sl.Min5Tips && time == 0 { + case sl.Min15Tips && sl.Min5Tips && time == 0: sublist[group].Min15Tips = false sublist[group].Min5Tips = false - } else { + default: return } + //if !sl.Min15Tips && !sl.Min5Tips && time == 15 { + // sublist[group].Min15Tips = true + //} else if sl.Min15Tips && !sl.Min5Tips && time == 5 { + // sublist[group].Min5Tips = true + //} else if sl.Min15Tips && sl.Min5Tips && time == 0 { + // sublist[group].Min15Tips = false + // sublist[group].Min5Tips = false + //} else { + // return + //} + for qq, st := range sl.SubUser { if st.SubType[i] != nil { if *st.SubType[i] == s { @@ -121,7 +135,7 @@ func CallUser(i int, s bool, time int) { } // 游戏时间模拟 -type GameTime struct { +type gameTime struct { Name string `json:"name"` //时间名称 NextTime time.Time `json:"time"` //下次更新时间 Status bool `json:"status"` //状态 @@ -131,13 +145,13 @@ type GameTime struct { NightTime int `json:"night"` //夜间时长 } -type SubList struct { - SubUser map[int64]SubType `json:"qq_sub"` +type subList struct { + SubUser map[int64]subType `json:"qq_sub"` Min5Tips bool `json:"min5_tips"` Min15Tips bool `json:"min15_tips"` } -type SubType struct { +type subType struct { SubType map[int]*bool `json:"sub_type"` SubRaid bool `json:"sub_raid"` } diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 90172cddeb..1cb1768072 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -1,3 +1,4 @@ +// Package warframeapi 百度内容审核 package warframeapi import ( @@ -7,7 +8,6 @@ import ( "github.com/FloatTech/floatbox/binary" "github.com/FloatTech/zbputils/img/text" "io" - "io/ioutil" "net/http" "os" "sort" @@ -24,15 +24,15 @@ import ( ) var ( - wfapi WFAPI - client http.Client - itmeapi WFAPIItem - wmitems map[string]Items - itmeNames []string - fileItemNames map[string]string - itemNamesPath string - sublist map[int64]*SubList - sublistPath string + wfapi WFAPI //WarFrameAPI的数据实例 + client http.Client //发起http请求的client实例 + itmeapi WFAPIItem //WarFrame市场的数据实例 + wmitems map[string]Items //WarFrame市场的中文名称对应的物品的字典 + itmeNames []string //物品外号 + fileItemNames map[string]string //物品外号字典 + itemNamesPath string //物品外号存储路径 + sublist map[int64]*subList //订阅列表 + sublistPath string //订阅列表存储路径 ) func init() { @@ -51,11 +51,11 @@ func init() { "- 每日特惠", PrivateDataFolder: "warframeAPI", }) - + //生成物品列表存储路径 itemNamesPath = eng.DataFolder() + "ItemNames.json" - + //检查文件是否存在 if isExist(itemNamesPath) { - data, err := ioutil.ReadFile(itemNamesPath) + data, err := os.ReadFile(itemNamesPath) if err != nil { panic(err) } @@ -68,7 +68,7 @@ func init() { } sublistPath = eng.DataFolder() + "Sublist.json" if isExist(sublistPath) { - data, err := ioutil.ReadFile(sublistPath) + data, err := os.ReadFile(sublistPath) if err != nil { panic(err) } @@ -77,7 +77,7 @@ func init() { panic(err) } } else { - sublist = map[int64]*SubList{} + sublist = map[int64]*subList{} } updateWM() loadToFuzzy() @@ -160,7 +160,7 @@ func init() { case "奥布山谷": fallthrough case "金星": - //sublist = append(sublist, SubList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) + //sublist = append(sublist, subList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1, status) ctx.SendChain( message.At(ctx.Event.UserID), @@ -214,7 +214,7 @@ func init() { case "奥布山谷": fallthrough case "金星": - //sublist = append(sublist, SubList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) + //sublist = append(sublist, subList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1) ctx.SendChain( message.At(ctx.Event.UserID), @@ -479,23 +479,23 @@ func sendStringArray(texts []string, ctx *zero.Ctx) { ctx.SendChain(message.Image("base64://" + binary.BytesToString(b))) } -func addUseSub(QQ int64, QQGroup int64, stype int, status bool) { - if sb, ok := sublist[QQGroup]; ok { - if st, ok := sb.SubUser[QQ]; ok { +func addUseSub(qq int64, qqGroup int64, stype int, status bool) { + if sb, ok := sublist[qqGroup]; ok { + if st, ok := sb.SubUser[qq]; ok { st.SubType[stype] = &status } else { - sublist[QQGroup].SubUser[QQ] = SubType{map[int]*bool{stype: &status}, false} + sublist[qqGroup].SubUser[qq] = subType{map[int]*bool{stype: &status}, false} } } else { - sublist[QQGroup] = &SubList{map[int64]SubType{QQ: {map[int]*bool{stype: &status}, false}}, false, false} + sublist[qqGroup] = &subList{map[int64]subType{qq: {map[int]*bool{stype: &status}, false}}, false, false} } jsonSave(sublist, sublistPath) } -func removeUseSub(QQ int64, QQGroup int64, stype int) { - if sb, ok := sublist[QQGroup]; ok { - if _, ok := sb.SubUser[QQ]; ok { - delete(sublist[QQGroup].SubUser[QQ].SubType, stype) +func removeUseSub(qq int64, qqGroup int64, stype int) { + if sb, ok := sublist[qqGroup]; ok { + if _, ok := sb.SubUser[qq]; ok { + delete(sublist[qqGroup].SubUser[qq].SubType, stype) jsonSave(sublist, sublistPath) } } @@ -623,21 +623,23 @@ func isExist(path string) bool { } return true } -func jsonSave(v interface{}, path string) (bool, error) { +func jsonSave(v interface{}, path string) { data, err := json.Marshal(v) if err != nil { - return false, err + return } dataStr := string(data) // 将字符串写入指定的文件 file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) if err != nil { - return false, err + return } defer file.Close() // 结束时关闭句柄,释放资源 writer := bufio.NewWriter(file) - writer.WriteString(dataStr) + _, err = writer.WriteString(dataStr) + if err != nil { + return + } writer.Flush() // 缓存数据写入磁盘(持久化) - return true, nil } From 68c5aceaaa37f11489a0eacdca31e0493b0466b4 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Fri, 23 Dec 2022 11:17:53 +0800 Subject: [PATCH 03/19] WarframeAPI lint fix --- plugin/warframeapi/gametime.go | 33 ++++++++++++++++----------------- plugin/warframeapi/main.go | 32 ++++++++++++++++---------------- plugin/warframeapi/wfdata.go | 2 +- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index 1a913f0a6b..ca60529b05 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -10,15 +10,14 @@ import ( ) var ( - GameTimes []gameTime + gameTimes []gameTime ) func (t gameTime) getStatus() string { if t.Status { return t.StatusTrueDes - } else { - return t.StatusFalseDes } + return t.StatusFalseDes } func (t gameTime) getTime() string { d := time.Until(t.NextTime) @@ -29,7 +28,7 @@ func (t gameTime) getTime() string { // 游戏时间模拟初始化 func gameTimeInit() { //updateWM() - LoadTime() + loadTime() go gameRuntime() } @@ -41,13 +40,13 @@ func gameRuntime() { } -func LoadTime() { +func loadTime() { //updateWM() var isfass bool if wfapi.CambionCycle.Active == "fass" { isfass = false } - GameTimes = []gameTime{ + gameTimes = []gameTime{ {"地球平原", wfapi.CetusCycle.Expiry.Local(), wfapi.CetusCycle.IsDay, "白天", "夜晚", 100 * 60, 50 * 60}, {"金星平原", wfapi.VallisCycle.Expiry.Local(), wfapi.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, {"火卫二平原", wfapi.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, @@ -56,24 +55,24 @@ func LoadTime() { } func timeDet() { - for i, v := range GameTimes { + for i, v := range gameTimes { nt := time.Until(v.NextTime).Seconds() switch { case nt < 0: if v.Status { - GameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) + gameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) } else { - GameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) + gameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) } - GameTimes[i].Status = !GameTimes[i].Status - callUser(i, GameTimes[i].Status, 0) + gameTimes[i].Status = !gameTimes[i].Status + callUser(i, gameTimes[i].Status, 0) case nt < float64(5)*60: - callUser(i, !GameTimes[i].Status, 5) + callUser(i, !gameTimes[i].Status, 5) case nt < float64(15)*60: if i == 2 && !v.Status { return } - callUser(i, !GameTimes[i].Status, 15) + callUser(i, !gameTimes[i].Status, 15) } } } @@ -117,15 +116,15 @@ func callUser(i int, s bool, time int) { } if time <= 0 { if s { - msg = append(msg, message.Text(fmt.Sprintf("\n%s白天(%s)到了", GameTimes[i].Name, GameTimes[i].StatusTrueDes))) + msg = append(msg, message.Text(fmt.Sprintf("\n%s白天(%s)到了", gameTimes[i].Name, gameTimes[i].StatusTrueDes))) } else { - msg = append(msg, message.Text(fmt.Sprintf("\n%s夜晚(%s)到了", GameTimes[i].Name, GameTimes[i].StatusFalseDes))) + msg = append(msg, message.Text(fmt.Sprintf("\n%s夜晚(%s)到了", gameTimes[i].Name, gameTimes[i].StatusFalseDes))) } } else { if s { - msg = append(msg, message.Text(fmt.Sprintf("\n%s距离白天(%s)还剩下%d分钟", GameTimes[i].Name, GameTimes[i].StatusTrueDes, time))) + msg = append(msg, message.Text(fmt.Sprintf("\n%s距离白天(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusTrueDes, time))) } else { - msg = append(msg, message.Text(fmt.Sprintf("\n%s距离夜晚(%s)还剩下%d分钟", GameTimes[i].Name, GameTimes[i].StatusFalseDes, time))) + msg = append(msg, message.Text(fmt.Sprintf("\n%s距离夜晚(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusFalseDes, time))) } } diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 1cb1768072..173d19d85c 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -24,7 +24,7 @@ import ( ) var ( - wfapi WFAPI //WarFrameAPI的数据实例 + wfapi wfAPI //WarFrameAPI的数据实例 client http.Client //发起http请求的client实例 itmeapi WFAPIItem //WarFrame市场的数据实例 wmitems map[string]Items //WarFrame市场的中文名称对应的物品的字典 @@ -94,8 +94,8 @@ func init() { case "金星": ctx.SendChain( message.Text( - "平原状态:", GameTimes[1].getStatus(), "\n", - "下次更新:", GameTimes[1].getTime(), + "平原状态:", gameTimes[1].getStatus(), "\n", + "下次更新:", gameTimes[1].getTime(), ), ) case "夜灵": @@ -103,8 +103,8 @@ func init() { case "地球": ctx.SendChain( message.Text( - "平原状态:", GameTimes[0].getStatus(), "\n", - "下次更新:", GameTimes[0].getTime(), + "平原状态:", gameTimes[0].getStatus(), "\n", + "下次更新:", gameTimes[0].getTime(), ), ) case "火卫": @@ -114,8 +114,8 @@ func init() { case "魔胎之境": ctx.SendChain( message.Text( - "平原状态:", GameTimes[2].getStatus(), "\n", - "下次更新:", GameTimes[2].getTime(), + "平原状态:", gameTimes[2].getStatus(), "\n", + "下次更新:", gameTimes[2].getTime(), ), ) default: @@ -165,7 +165,7 @@ func init() { ctx.SendChain( message.At(ctx.Event.UserID), message.Text("已成功订阅"), - message.Text(GameTimes[1].Name), + message.Text(gameTimes[1].Name), message.Text(status), ) case "夜灵": @@ -175,7 +175,7 @@ func init() { ctx.SendChain( message.At(ctx.Event.UserID), message.Text("已成功订阅"), - message.Text(GameTimes[0].Name), + message.Text(gameTimes[0].Name), message.Text(status), ) case "火卫": @@ -187,7 +187,7 @@ func init() { ctx.SendChain( message.At(ctx.Event.UserID), message.Text("已成功订阅"), - message.Text(GameTimes[2].Name), + message.Text(gameTimes[2].Name), message.Text(status), ) default: @@ -219,7 +219,7 @@ func init() { ctx.SendChain( message.At(ctx.Event.UserID), message.Text("已取消订阅"), - message.Text(GameTimes[1].Name), + message.Text(gameTimes[1].Name), message.Text(status), ) case "夜灵": @@ -229,7 +229,7 @@ func init() { ctx.SendChain( message.At(ctx.Event.UserID), message.Text("已取消订阅"), - message.Text(GameTimes[0].Name), + message.Text(gameTimes[0].Name), message.Text(status), ) case "火卫": @@ -241,7 +241,7 @@ func init() { ctx.SendChain( message.At(ctx.Event.UserID), message.Text("已取消订阅"), - message.Text(GameTimes[2].Name), + message.Text(gameTimes[2].Name), message.Text(status), ) default: @@ -276,7 +276,7 @@ func init() { // eng.OnRegex(`^入侵$`).SetBlock(true). // Handle(func(ctx *zero.Ctx) { // updateWFAPI(ctx) - // for _, dd := range wfapi.DailyDeals { + // for _, dd := range wfapi.dailyDeals { // imagebuild.DrawTextSend([]string{ // "节点:" + wfapi.Arbitration.Node, // "类型:" + wfapi.Arbitration.Type, @@ -288,7 +288,7 @@ func init() { eng.OnRegex(`^wf数据更新$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { updateWFAPI(ctx) - LoadTime() + loadTime() ctx.SendChain(message.Text("已拉取服务器时间并同步到本地模拟")) }) eng.OnRegex(`^.取外号 (.*) (.*)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) { @@ -529,7 +529,7 @@ func udateWFAPI2() { return } gameTimeInit() - LoadTime() + loadTime() } func updateWM() { var data []byte diff --git a/plugin/warframeapi/wfdata.go b/plugin/warframeapi/wfdata.go index b20d045217..16efe325dc 100644 --- a/plugin/warframeapi/wfdata.go +++ b/plugin/warframeapi/wfdata.go @@ -2,7 +2,7 @@ package warframeapi import "time" -type WFAPI struct { +type wfAPI struct { Timestamp time.Time `json:"timestamp"` News []News `json:"news"` Events []Events `json:"events"` From 5578a2092dacf0eff3e84afe132388c044e2e3b6 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Fri, 23 Dec 2022 11:52:25 +0800 Subject: [PATCH 04/19] WarframeAPI lint fix --- plugin/warframeapi/main.go | 22 +-- plugin/warframeapi/wfdata.go | 264 +++++++++++++++++------------------ 2 files changed, 143 insertions(+), 143 deletions(-) diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 173d19d85c..eff4f60b8f 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -26,8 +26,8 @@ import ( var ( wfapi wfAPI //WarFrameAPI的数据实例 client http.Client //发起http请求的client实例 - itmeapi WFAPIItem //WarFrame市场的数据实例 - wmitems map[string]Items //WarFrame市场的中文名称对应的物品的字典 + itmeapi wfAPIItem //WarFrame市场的数据实例 + wmitems map[string]items //WarFrame市场的中文名称对应的物品的字典 itmeNames []string //物品外号 fileItemNames map[string]string //物品外号字典 itemNamesPath string //物品外号存储路径 @@ -278,10 +278,10 @@ func init() { // updateWFAPI(ctx) // for _, dd := range wfapi.dailyDeals { // imagebuild.DrawTextSend([]string{ - // "节点:" + wfapi.Arbitration.Node, - // "类型:" + wfapi.Arbitration.Type, - // "阵营:" + wfapi.Arbitration.Enemy, - // "剩余时间:" + fmt.Sprint(int(wfapi.Arbitration.Expiry.Sub(time.Now().UTC()).Minutes())) + "m", + // "节点:" + wfapi.arbitration.Node, + // "类型:" + wfapi.arbitration.Type, + // "阵营:" + wfapi.arbitration.Enemy, + // "剩余时间:" + fmt.Sprint(int(wfapi.arbitration.Expiry.Sub(time.Now().UTC()).Minutes())) + "m", // }, ctx) // } // }) @@ -545,17 +545,17 @@ func updateWM() { } } -func getWMItemOrders(name string, h bool) (Orders, ItemsInSet, string, error) { +func getWMItemOrders(name string, h bool) (orders, itemsInSet, string, error) { var data []byte var err error - var wfapiio WFAPIItemsOrders + var wfapiio wfAPIItemsOrders data, err = getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", name), []string{"Accept", "Platform"}, []string{"application/json", "pc"}) if err != nil { - return nil, ItemsInSet{}, "", err + return nil, itemsInSet{}, "", err } err = json.Unmarshal(data, &wfapiio) - var sellOrders Orders + var sellOrders orders for _, v := range wfapiio.Payload.Orders { if v.OrderType == "sell" && v.User.Status != "offline" { if h && v.ModRank == wfapiio.Include.Item.ItemsInSet[0].ModMaxRank { @@ -577,7 +577,7 @@ func getWMItemOrders(name string, h bool) (Orders, ItemsInSet, string, error) { } func loadToFuzzy() { - wmitems = make(map[string]Items) + wmitems = make(map[string]items) itmeNames = []string{} for _, v := range itmeapi.Payload.Items { wmitems[v.ItemName] = v diff --git a/plugin/warframeapi/wfdata.go b/plugin/warframeapi/wfdata.go index 16efe325dc..89c822d5ac 100644 --- a/plugin/warframeapi/wfdata.go +++ b/plugin/warframeapi/wfdata.go @@ -4,36 +4,36 @@ import "time" type wfAPI struct { Timestamp time.Time `json:"timestamp"` - News []News `json:"news"` - Events []Events `json:"events"` - Alerts []Alerts `json:"alerts"` - Sortie Sortie `json:"sortie"` - SyndicateMissions []SyndicateMissions `json:"syndicateMissions"` - Fissures []Fissures `json:"fissures"` + News []news `json:"news"` + Events []events `json:"events"` + Alerts []alerts `json:"alerts"` + Sortie sortie `json:"sortie"` + SyndicateMissions []syndicateMissions `json:"syndicateMissions"` + Fissures []fissures `json:"fissures"` GlobalUpgrades []interface{} `json:"globalUpgrades"` - FlashSales []FlashSales `json:"flashSales"` - Invasions []Invasions `json:"invasions"` + FlashSales []flashSales `json:"flashSales"` + Invasions []invasions `json:"invasions"` DarkSectors []interface{} `json:"darkSectors"` - VoidTrader VoidTrader `json:"voidTrader"` - DailyDeals []DailyDeals `json:"dailyDeals"` - Simaris Simaris `json:"simaris"` - ConclaveChallenges []ConclaveChallenges `json:"conclaveChallenges"` + VoidTrader voidTrader `json:"voidTrader"` + DailyDeals []dailyDeals `json:"dailyDeals"` + Simaris simaris `json:"simaris"` + ConclaveChallenges []conclaveChallenges `json:"conclaveChallenges"` PersistentEnemies []interface{} `json:"persistentEnemies"` - EarthCycle EarthCycle `json:"earthCycle"` - CetusCycle CetusCycle `json:"cetusCycle"` - CambionCycle CambionCycle `json:"cambionCycle"` - ZarimanCycle ZarimanCycle `json:"zarimanCycle"` + EarthCycle earthCycle `json:"earthCycle"` + CetusCycle cetusCycle `json:"cetusCycle"` + CambionCycle cambionCycle `json:"cambionCycle"` + ZarimanCycle zarimanCycle `json:"zarimanCycle"` WeeklyChallenges []interface{} `json:"weeklyChallenges"` - ConstructionProgress ConstructionProgress `json:"constructionProgress"` - VallisCycle VallisCycle `json:"vallisCycle"` - Nightwave Nightwave `json:"nightwave"` + ConstructionProgress constructionProgress `json:"constructionProgress"` + VallisCycle vallisCycle `json:"vallisCycle"` + Nightwave nightwave `json:"nightwave"` Kuva []interface{} `json:"kuva"` - Arbitration Arbitration `json:"arbitration"` - SentientOutposts SentientOutposts `json:"sentientOutposts"` - SteelPath SteelPath `json:"steelPath"` - VaultTrader VaultTrader `json:"vaultTrader"` + Arbitration arbitration `json:"arbitration"` + SentientOutposts sentientOutposts `json:"sentientOutposts"` + SteelPath steelPath `json:"steelPath"` + VaultTrader vaultTrader `json:"vaultTrader"` } -type Translations struct { +type translations struct { En string `json:"en"` Fr string `json:"fr"` It string `json:"it"` @@ -49,7 +49,7 @@ type Translations struct { Ko string `json:"ko"` Tc string `json:"tc"` } -type News struct { +type news struct { ID string `json:"id"` Message string `json:"message"` Link string `json:"link"` @@ -60,16 +60,16 @@ type News struct { Update bool `json:"update"` PrimeAccess bool `json:"primeAccess"` Stream bool `json:"stream"` - Translations Translations `json:"translations"` + Translations translations `json:"translations"` AsString string `json:"asString"` } -type Metadata struct { +type metadata struct { } -type NextAlt struct { +type nextAlt struct { Expiry time.Time `json:"expiry"` Activation time.Time `json:"activation"` } -type Events struct { +type events struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` @@ -92,32 +92,32 @@ type Events struct { RegionDrops []interface{} `json:"regionDrops"` ArchwingDrops []interface{} `json:"archwingDrops"` AsString string `json:"asString"` - Metadata Metadata `json:"metadata"` + Metadata metadata `json:"metadata"` CompletionBonuses []interface{} `json:"completionBonuses"` AltExpiry time.Time `json:"altExpiry"` AltActivation time.Time `json:"altActivation"` - NextAlt NextAlt `json:"nextAlt"` + NextAlt nextAlt `json:"nextAlt"` } -type Variants struct { +type variants struct { MissionType string `json:"missionType"` Modifier string `json:"modifier"` ModifierDescription string `json:"modifierDescription"` Node string `json:"node"` } -type Sortie struct { +type sortie struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` Expiry time.Time `json:"expiry"` Active bool `json:"active"` RewardPool string `json:"rewardPool"` - Variants []Variants `json:"variants"` + Variants []variants `json:"variants"` Boss string `json:"boss"` Faction string `json:"faction"` Expired bool `json:"expired"` Eta string `json:"eta"` } -type Jobs struct { +type jobs struct { ID string `json:"id"` RewardPool []string `json:"rewardPool"` Type string `json:"type"` @@ -127,7 +127,7 @@ type Jobs struct { Expiry time.Time `json:"expiry"` TimeBound string `json:"timeBound,omitempty"` } -type SyndicateMissions struct { +type syndicateMissions struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` @@ -136,10 +136,10 @@ type SyndicateMissions struct { Syndicate string `json:"syndicate"` SyndicateKey string `json:"syndicateKey"` Nodes []interface{} `json:"nodes"` - Jobs []Jobs `json:"jobs"` + Jobs []jobs `json:"jobs"` Eta string `json:"eta"` } -type Fissures struct { +type fissures struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` @@ -157,7 +157,7 @@ type Fissures struct { Eta string `json:"eta"` IsStorm bool `json:"isStorm"` } -type FlashSales struct { +type flashSales struct { Item string `json:"item"` Expiry time.Time `json:"expiry"` Activation time.Time `json:"activation"` @@ -171,61 +171,61 @@ type FlashSales struct { Expired bool `json:"expired"` Eta string `json:"eta"` } -type CountedItems struct { +type countedItems struct { Count int `json:"count"` Type string `json:"type"` Key string `json:"key"` } -type AttackerReward struct { +type attackerReward struct { Items []interface{} `json:"items"` - CountedItems []CountedItems `json:"countedItems"` + CountedItems []countedItems `json:"countedItems"` Credits int `json:"credits"` AsString string `json:"asString"` ItemString string `json:"itemString"` Thumbnail string `json:"thumbnail"` Color int `json:"color"` } -type Reward struct { +type reward struct { Items []interface{} `json:"items"` - CountedItems []CountedItems `json:"countedItems"` + CountedItems []countedItems `json:"countedItems"` Credits int `json:"credits"` AsString string `json:"asString"` ItemString string `json:"itemString"` Thumbnail string `json:"thumbnail"` Color int `json:"color"` } -type Attacker struct { - Reward Reward `json:"reward"` +type attacker struct { + Reward reward `json:"reward"` Faction string `json:"faction"` FactionKey string `json:"factionKey"` } -type DefenderReward struct { +type defenderReward struct { Items []interface{} `json:"items"` - CountedItems []CountedItems `json:"countedItems"` + CountedItems []countedItems `json:"countedItems"` Credits int `json:"credits"` AsString string `json:"asString"` ItemString string `json:"itemString"` Thumbnail string `json:"thumbnail"` Color int `json:"color"` } -type Defender struct { - Reward Reward `json:"reward"` +type defender struct { + Reward reward `json:"reward"` Faction string `json:"faction"` FactionKey string `json:"factionKey"` } -type Invasions struct { +type invasions struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` Node string `json:"node"` NodeKey string `json:"nodeKey"` Desc string `json:"desc"` - AttackerReward AttackerReward `json:"attackerReward"` + AttackerReward attackerReward `json:"attackerReward"` AttackingFaction string `json:"attackingFaction"` - Attacker Attacker `json:"attacker"` - DefenderReward DefenderReward `json:"defenderReward"` + Attacker attacker `json:"attacker"` + DefenderReward defenderReward `json:"defenderReward"` DefendingFaction string `json:"defendingFaction"` - Defender Defender `json:"defender"` + Defender defender `json:"defender"` VsInfestation bool `json:"vsInfestation"` Count int `json:"count"` RequiredRuns int `json:"requiredRuns"` @@ -234,7 +234,7 @@ type Invasions struct { Eta string `json:"eta"` RewardTypes []string `json:"rewardTypes"` } -type VoidTrader struct { +type voidTrader struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` @@ -248,7 +248,7 @@ type VoidTrader struct { InitialStart time.Time `json:"initialStart"` Schedule []interface{} `json:"schedule"` } -type DailyDeals struct { +type dailyDeals struct { Item string `json:"item"` Expiry time.Time `json:"expiry"` Activation time.Time `json:"activation"` @@ -260,12 +260,12 @@ type DailyDeals struct { Eta string `json:"eta"` Discount int `json:"discount"` } -type Simaris struct { +type simaris struct { Target string `json:"target"` IsTargetActive bool `json:"isTargetActive"` AsString string `json:"asString"` } -type ConclaveChallenges struct { +type conclaveChallenges struct { ID string `json:"id"` Expiry time.Time `json:"expiry"` Activation time.Time `json:"activation"` @@ -282,7 +282,7 @@ type ConclaveChallenges struct { Standing int `json:"standing"` AsString string `json:"asString"` } -type EarthCycle struct { +type earthCycle struct { ID string `json:"id"` Expiry time.Time `json:"expiry"` Activation time.Time `json:"activation"` @@ -290,7 +290,7 @@ type EarthCycle struct { State string `json:"state"` TimeLeft string `json:"timeLeft"` } -type CetusCycle struct { +type cetusCycle struct { ID string `json:"id"` Expiry time.Time `json:"expiry"` Activation time.Time `json:"activation"` @@ -300,14 +300,14 @@ type CetusCycle struct { IsCetus bool `json:"isCetus"` ShortString string `json:"shortString"` } -type CambionCycle struct { +type cambionCycle struct { ID string `json:"id"` Activation time.Time `json:"activation"` Expiry time.Time `json:"expiry"` TimeLeft string `json:"timeLeft"` Active string `json:"active"` } -type ZarimanCycle struct { +type zarimanCycle struct { ID string `json:"id"` BountiesEndDate time.Time `json:"bountiesEndDate"` Expiry time.Time `json:"expiry"` @@ -317,13 +317,13 @@ type ZarimanCycle struct { TimeLeft string `json:"timeLeft"` ShortString string `json:"shortString"` } -type ConstructionProgress struct { +type constructionProgress struct { ID string `json:"id"` FomorianProgress string `json:"fomorianProgress"` RazorbackProgress string `json:"razorbackProgress"` UnknownProgress string `json:"unknownProgress"` } -type VallisCycle struct { +type vallisCycle struct { ID string `json:"id"` Expiry time.Time `json:"expiry"` IsWarm bool `json:"isWarm"` @@ -332,9 +332,9 @@ type VallisCycle struct { TimeLeft string `json:"timeLeft"` ShortString string `json:"shortString"` } -type Params struct { +type params struct { } -type ActiveChallenges struct { +type activeChallenges struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` @@ -346,7 +346,7 @@ type ActiveChallenges struct { Title string `json:"title"` Reputation int `json:"reputation"` } -type Nightwave struct { +type nightwave struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` @@ -355,12 +355,12 @@ type Nightwave struct { Season int `json:"season"` Tag string `json:"tag"` Phase int `json:"phase"` - Params Params `json:"params"` + Params params `json:"params"` PossibleChallenges []interface{} `json:"possibleChallenges"` - ActiveChallenges []ActiveChallenges `json:"activeChallenges"` + ActiveChallenges []activeChallenges `json:"activeChallenges"` RewardTypes []string `json:"rewardTypes"` } -type Arbitration struct { +type arbitration struct { Activation time.Time `json:"activation"` Expiry time.Time `json:"expiry"` Enemy string `json:"enemy"` @@ -373,54 +373,54 @@ type Arbitration struct { ID string `json:"id"` Expired bool `json:"expired"` } -type Mission struct { +type mission struct { Node string `json:"node"` Faction string `json:"faction"` Type string `json:"type"` } -type SentientOutposts struct { - Mission Mission `json:"mission"` +type sentientOutposts struct { + Mission mission `json:"mission"` Activation time.Time `json:"activation"` Expiry time.Time `json:"expiry"` Active bool `json:"active"` ID string `json:"id"` } -type CurrentReward struct { +type currentReward struct { Name string `json:"name"` Cost int `json:"cost"` } -type Rotation struct { +type rotation struct { Name string `json:"name"` Cost int `json:"cost"` } -type Evergreens struct { +type evergreens struct { Name string `json:"name"` Cost int `json:"cost"` } -type Incursions struct { +type incursions struct { ID string `json:"id"` Activation time.Time `json:"activation"` Expiry time.Time `json:"expiry"` } -type SteelPath struct { - CurrentReward CurrentReward `json:"currentReward"` +type steelPath struct { + CurrentReward currentReward `json:"currentReward"` Activation time.Time `json:"activation"` Expiry time.Time `json:"expiry"` Remaining string `json:"remaining"` - Rotation []Rotation `json:"rotation"` - Evergreens []Evergreens `json:"evergreens"` - Incursions Incursions `json:"incursions"` + Rotation []rotation `json:"rotation"` + Evergreens []evergreens `json:"evergreens"` + Incursions incursions `json:"incursions"` } -type Inventory struct { +type inventory struct { Item string `json:"item"` Ducats int `json:"ducats"` Credits interface{} `json:"credits"` } -type Schedule struct { +type schedule struct { Expiry time.Time `json:"expiry"` Item string `json:"item"` } -type VaultTrader struct { +type vaultTrader struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` @@ -428,14 +428,14 @@ type VaultTrader struct { Active bool `json:"active"` Character string `json:"character"` Location string `json:"location"` - Inventory []Inventory `json:"inventory"` + Inventory []inventory `json:"inventory"` PsID string `json:"psId"` EndString string `json:"endString"` InitialStart time.Time `json:"initialStart"` Completed bool `json:"completed"` - Schedule []Schedule `json:"schedule"` + Schedule []schedule `json:"schedule"` } -type Alerts struct { +type alerts struct { ID string `json:"id"` Activation time.Time `json:"activation"` StartString string `json:"startString"` @@ -477,26 +477,26 @@ type Alerts struct { RewardTypes []string `json:"rewardTypes"` Tag string `json:"tag"` } -type WFAPIItem struct { - Payload Payload `json:"payload"` +type wfAPIItem struct { + Payload payload `json:"payload"` } -type Items struct { +type items struct { URLName string `json:"url_name"` Thumb string `json:"thumb"` ItemName string `json:"item_name"` ID string `json:"id"` Vaulted bool `json:"vaulted,omitempty"` } -type Payload struct { - Items []Items `json:"items"` - Orders Orders `json:"orders"` +type payload struct { + Items []items `json:"items"` + Orders orders `json:"orders"` } -type WFAPIItemsOrders struct { - Payload Payload `json:"payload"` - Include Include `json:"include"` +type wfAPIItemsOrders struct { + Payload payload `json:"payload"` + Include include `json:"include"` } -type User struct { +type user struct { IngameName string `json:"ingame_name"` LastSeen time.Time `json:"last_seen"` Reputation int `json:"reputation"` @@ -505,7 +505,7 @@ type User struct { Avatar interface{} `json:"avatar"` Status string `json:"status"` } -type Orders []struct { +type orders []struct { OrderType string `json:"order_type"` LastUpdate time.Time `json:"last_update"` Region string `json:"region"` @@ -514,88 +514,88 @@ type Orders []struct { CreationDate time.Time `json:"creation_date"` Platinum int `json:"platinum"` Platform string `json:"platform"` - User User `json:"user"` + User user `json:"user"` ID string `json:"id"` ModRank int `json:"mod_rank"` } -func (a Orders) Len() int { // 重写 Len() 方法 +func (a orders) Len() int { // 重写 Len() 方法 return len(a) } -func (a Orders) Swap(i, j int) { // 重写 Swap() 方法 +func (a orders) Swap(i, j int) { // 重写 Swap() 方法 a[i], a[j] = a[j], a[i] } -func (a Orders) Less(i, j int) bool { // 重写 Less() 方法, 从大到小排序 +func (a orders) Less(i, j int) bool { // 重写 Less() 方法, 从大到小排序 return a[i].Platinum < a[j].Platinum } -type En struct { +type en struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type Ru struct { +type ru struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type Ko struct { +type ko struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type Fr struct { +type fr struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type Sv struct { +type sv struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type De struct { +type de struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type ZhHant struct { +type zhHant struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type ZhHans struct { +type zhHans struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type Pt struct { +type pt struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type Es struct { +type es struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type Pl struct { +type pl struct { ItemName string `json:"item_name"` Description string `json:"description"` WikiLink string `json:"wiki_link"` Drop []interface{} `json:"drop"` } -type ItemsInSet struct { +type itemsInSet struct { Icon string `json:"icon"` URLName string `json:"url_name"` SubIcon string `json:"sub_icon"` @@ -609,22 +609,22 @@ type ItemsInSet struct { MasteryLevel int `json:"mastery_level"` Ducats int `json:"ducats"` IconFormat string `json:"icon_format"` - En En `json:"en"` - Ru Ru `json:"ru"` - Ko Ko `json:"ko"` - Fr Fr `json:"fr"` - Sv Sv `json:"sv"` - De De `json:"de"` - ZhHant ZhHant `json:"zh-hant"` - ZhHans ZhHans `json:"zh-hans"` - Pt Pt `json:"pt"` - Es Es `json:"es"` - Pl Pl `json:"pl"` -} -type Item struct { + En en `json:"en"` + Ru ru `json:"ru"` + Ko ko `json:"ko"` + Fr fr `json:"fr"` + Sv sv `json:"sv"` + De de `json:"de"` + ZhHant zhHant `json:"zh-hant"` + ZhHans zhHans `json:"zh-hans"` + Pt pt `json:"pt"` + Es es `json:"es"` + Pl pl `json:"pl"` +} +type item struct { ID string `json:"id"` - ItemsInSet []ItemsInSet `json:"items_in_set"` + ItemsInSet []itemsInSet `json:"items_in_set"` } -type Include struct { - Item Item `json:"item"` +type include struct { + Item item `json:"item"` } From 6015526129bacf7474d93a99242a3edc6962a8e2 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Fri, 23 Dec 2022 12:06:16 +0800 Subject: [PATCH 05/19] Add WarframeAPI --- README.md | 25 +++++++++++++++++++++++++ main.go | 13 +++++++------ plugin/warframeapi/main.go | 8 ++++---- 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b6d505aa43..6021cfc2b2 100644 --- a/README.md +++ b/README.md @@ -1273,6 +1273,31 @@ print("run[CQ:image,file="+j["img"]+"]") - [x] 来份网易云热评 + +
+ WarframeAPI + + `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi"` + + - [x] wf数据更新 + + - [x] [金星|地球|火卫二]平原状态 + + - [x] 订阅[金星|地球|火卫二]平原[白天|夜晚] + + - [x] 取消订阅[金星|地球|火卫二]平原[白天|夜晚] + + - [x] .wm [物品名称] + + - [x] 取外号 [原名称] [外号] + + - [x] [金星/地球/火卫二]平原状态 + + - [x] 仲裁 + + - [x] 警报 + + - [x] 每日特惠
天气/拼音查询-名言 diff --git a/main.go b/main.go index 866ab7fd0e..805943406b 100644 --- a/main.go +++ b/main.go @@ -134,12 +134,13 @@ import ( _ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtb_quotation" // vtb语录 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wallet" // 钱包 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenben" // 文本指令大全 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenxinAI" // 百度文心AI画图 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo" // 游戏王相关插件 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi" + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenben" // 文本指令大全 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenxinAI" // 百度文心AI画图 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo" // 游戏王相关插件 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame // _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西 diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index eff4f60b8f..b1bac767c9 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -40,12 +40,12 @@ func init() { DisableOnDefault: false, Help: "warframeapi\n" + "- wf数据更新\n" + - "- [金星/地球/火卫二]平原状态\n" + - "- 订阅[金星/地球/火卫二]平原[白天/夜晚]\n" + - "- 取消订阅[金星/地球/火卫二]平原[白天/夜晚]\n" + + "- [金星|地球|火卫二]平原状态\n" + + "- 订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + + "- 取消订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + "- .wm [物品名称]\n" + "- 取外号 [原名称] [外号]\n" + - "- [金星/地球/火卫二]平原状态\n" + + "- [金星|地球|火卫二]平原状态\n" + "- 仲裁\n" + "- 警报\n" + "- 每日特惠", From 34674d23c9ba3a71b8f802e571c487584b133ee1 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Tue, 3 Jan 2023 15:36:30 +0800 Subject: [PATCH 06/19] =?UTF-8?q?wfapi=E9=97=AE=E9=A2=98=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.go | 15 +- plugin/warframeapi/gametime.go | 75 +++++----- plugin/warframeapi/main.go | 263 +++++++++++++-------------------- 3 files changed, 148 insertions(+), 205 deletions(-) diff --git a/main.go b/main.go index 805943406b..d1fbb6cf99 100644 --- a/main.go +++ b/main.go @@ -134,13 +134,13 @@ import ( _ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtb_quotation" // vtb语录 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wallet" // 钱包 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi" - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenben" // 文本指令大全 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenxinAI" // 百度文心AI画图 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo" // 游戏王相关插件 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi" // warframeAPI插件 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenben" // 文本指令大全 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenxinAI" // 百度文心AI画图 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo" // 游戏王相关插件 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame // _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西 @@ -263,7 +263,6 @@ func init() { logrus.Infoln("[main] 从", *runcfg, "读取配置文件") return } - config.W = []*driver.WSClient{driver.NewWebSocketClient(*url, *token)} config.Z = zero.Config{ NickName: append([]string{*adana}, "ATRI", "atri", "亚托莉", "アトリ"), diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index ca60529b05..b797073c86 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -2,87 +2,98 @@ package warframeapi import ( "fmt" + "sync" "time" "github.com/davidscholberg/go-durationfmt" - zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" ) var ( - gameTimes []gameTime + gameTimes [3]*gameTime + rwm sync.RWMutex ) -func (t gameTime) getStatus() string { +func (t *gameTime) getStatus() string { + rwm.RLock() if t.Status { return t.StatusTrueDes } + rwm.RUnlock() return t.StatusFalseDes } -func (t gameTime) getTime() string { +func (t *gameTime) getTime() string { + rwm.RLock() d := time.Until(t.NextTime) + rwm.RUnlock() durStr, _ := durationfmt.Format(d, "%m分%s秒后") return durStr } // 游戏时间模拟初始化 -func gameTimeInit() { - //updateWM() - loadTime() - go gameRuntime() -} +//func gameTimeInit() { +// //updateWM() +// loadTime(wfapi) +// go gameRuntime() +//} func gameRuntime() { - for { - time.Sleep(10 * time.Second) + + for range time.NewTicker(10 * time.Second).C { timeDet() } - + //for { + // time.Sleep(10 * time.Second) + // timeDet() + //} } -func loadTime() { +func loadTime(api wfAPI) { //updateWM() var isfass bool - if wfapi.CambionCycle.Active == "fass" { - isfass = false + if api.CambionCycle.Active == "fass" { + isfass = true } - gameTimes = []gameTime{ - {"地球平原", wfapi.CetusCycle.Expiry.Local(), wfapi.CetusCycle.IsDay, "白天", "夜晚", 100 * 60, 50 * 60}, - {"金星平原", wfapi.VallisCycle.Expiry.Local(), wfapi.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, - {"火卫二平原", wfapi.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, + gameTimes = [3]*gameTime{ + {"地球平原", api.CetusCycle.Expiry.Local(), api.CetusCycle.IsDay, "白天", "夜晚", 100 * 60, 50 * 60}, + {"金星平原", api.VallisCycle.Expiry.Local(), api.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, + {"火卫二平原", api.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, } } func timeDet() { + rwm.Lock() for i, v := range gameTimes { nt := time.Until(v.NextTime).Seconds() switch { case nt < 0: if v.Status { - gameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) + v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) } else { - gameTimes[i].NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) + v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) } - gameTimes[i].Status = !gameTimes[i].Status - callUser(i, gameTimes[i].Status, 0) + v.Status = !v.Status + + callUser(i, v.Status, 0) case nt < float64(5)*60: - callUser(i, !gameTimes[i].Status, 5) + callUser(i, !v.Status, 5) case nt < float64(15)*60: if i == 2 && !v.Status { return } - callUser(i, !gameTimes[i].Status, 15) + callUser(i, !v.Status, 15) } } + rwm.Unlock() } -func callUser(i int, s bool, time int) { +func callUser(i int, s bool, time int) []message.MessageSegment { + msg := []message.MessageSegment{} for group, sl := range sublist { - msg := []message.MessageSegment{} switch { - case !sl.Min15Tips && !sl.Min5Tips && time == 15: + case !sl.Min15Tips && !sl.Min5Tips && time == 15: //是否 sublist[group].Min15Tips = true case sl.Min15Tips && !sl.Min5Tips && time == 5: sublist[group].Min5Tips = true @@ -90,9 +101,8 @@ func callUser(i int, s bool, time int) { sublist[group].Min15Tips = false sublist[group].Min5Tips = false default: - return + return nil } - //if !sl.Min15Tips && !sl.Min5Tips && time == 15 { // sublist[group].Min15Tips = true //} else if sl.Min15Tips && !sl.Min5Tips && time == 5 { @@ -103,7 +113,6 @@ func callUser(i int, s bool, time int) { //} else { // return //} - for qq, st := range sl.SubUser { if st.SubType[i] != nil { if *st.SubType[i] == s { @@ -127,10 +136,8 @@ func callUser(i int, s bool, time int) { msg = append(msg, message.Text(fmt.Sprintf("\n%s距离夜晚(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusFalseDes, time))) } } - - zero.GetBot(2429160662).SendGroupMessage(group, msg) } - + return msg } // 游戏时间模拟 diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index b1bac767c9..3a208ad213 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -2,10 +2,10 @@ package warframeapi import ( - "bufio" "encoding/json" "fmt" "github.com/FloatTech/floatbox/binary" + "github.com/FloatTech/floatbox/file" "github.com/FloatTech/zbputils/img/text" "io" "net/http" @@ -33,6 +33,7 @@ var ( itemNamesPath string //物品外号存储路径 sublist map[int64]*subList //订阅列表 sublistPath string //订阅列表存储路径 + ctx *zero.Ctx //BOT实例 ) func init() { @@ -43,6 +44,7 @@ func init() { "- [金星|地球|火卫二]平原状态\n" + "- 订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + "- 取消订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + + "- wf订阅检测\n" + "- .wm [物品名称]\n" + "- 取外号 [原名称] [外号]\n" + "- [金星|地球|火卫二]平原状态\n" + @@ -51,10 +53,15 @@ func init() { "- 每日特惠", PrivateDataFolder: "warframeAPI", }) + + zero.RangeBot(func(id int64, c *zero.Ctx) bool { + ctx = c + return false + }) //生成物品列表存储路径 itemNamesPath = eng.DataFolder() + "ItemNames.json" //检查文件是否存在 - if isExist(itemNamesPath) { + if file.IsExist(itemNamesPath) { data, err := os.ReadFile(itemNamesPath) if err != nil { panic(err) @@ -66,8 +73,9 @@ func init() { } else { fileItemNames = map[string]string{} } + //订阅名单文件路径 sublistPath = eng.DataFolder() + "Sublist.json" - if isExist(sublistPath) { + if file.IsExist(itemNamesPath) { data, err := os.ReadFile(sublistPath) if err != nil { panic(err) @@ -81,37 +89,29 @@ func init() { } updateWM() loadToFuzzy() - udateWFAPI2() - + updateWFAPI() + //gameTimeInit() eng.OnRegex(`^(.*)平原状态$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { args := ctx.State["regex_matched"].([]string) - updateWFAPI(ctx) + updateWFAPI() switch args[1] { - case "奥布山谷": - fallthrough - case "金星": + case "金星", "奥布山谷": ctx.SendChain( message.Text( "平原状态:", gameTimes[1].getStatus(), "\n", "下次更新:", gameTimes[1].getTime(), ), ) - case "夜灵": - fallthrough - case "地球": + case "地球", "夜灵": ctx.SendChain( message.Text( "平原状态:", gameTimes[0].getStatus(), "\n", "下次更新:", gameTimes[0].getTime(), ), ) - case "火卫": - fallthrough - case "火卫二": - fallthrough - case "魔胎之境": + case "魔胎之境", "火卫二", "火卫": ctx.SendChain( message.Text( "平原状态:", gameTimes[2].getStatus(), "\n", @@ -119,12 +119,12 @@ func init() { ), ) default: - ctx.SendChain(message.Text("Error:平原不存在")) + ctx.SendChain(message.Text("ERROR: 平原不存在")) return } }) - eng.OnRegex(`^警报$`).SetBlock(true). + eng.OnFullMatch(`警报`).SetBlock(true). Handle(func(ctx *zero.Ctx) { if len(wfapi.Alerts) > 0 { for _, v := range wfapi.Alerts { @@ -141,117 +141,94 @@ func init() { } }) - eng.OnRegex(`^订阅(.*)平原(.*)$`).SetBlock(true). + eng.OnRegex(`^(订阅|取消订阅)(.*)平原(.*)$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { args := ctx.State["regex_matched"].([]string) - updateWFAPI(ctx) - status := false - switch args[2] { - case "白天": - fallthrough - case "fass": - fallthrough - case "Fass": - fallthrough - case "温暖": - status = true - } - switch args[1] { - case "奥布山谷": - fallthrough - case "金星": - //sublist = append(sublist, subList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) - addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1, status) - ctx.SendChain( - message.At(ctx.Event.UserID), - message.Text("已成功订阅"), - message.Text(gameTimes[1].Name), - message.Text(status), - ) - case "夜灵": - fallthrough - case "地球": - addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0, status) - ctx.SendChain( - message.At(ctx.Event.UserID), - message.Text("已成功订阅"), - message.Text(gameTimes[0].Name), - message.Text(status), - ) - case "火卫": - fallthrough - case "火卫二": - fallthrough - case "魔胎之境": - addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2, status) - ctx.SendChain( - message.At(ctx.Event.UserID), - message.Text("已成功订阅"), - message.Text(gameTimes[2].Name), - message.Text(status), - ) - default: - ctx.SendChain(message.Text("Error:平原不存在")) - return + var isEnable bool + if args[1] == "订阅" { + isEnable = true } - }) - eng.OnRegex(`^取消订阅(.*)平原(.*)$`).SetBlock(true). - Handle(func(ctx *zero.Ctx) { - args := ctx.State["regex_matched"].([]string) - updateWFAPI(ctx) + updateWFAPI() status := false - switch args[2] { - case "白天": - fallthrough - case "fass": - fallthrough - case "Fass": - fallthrough - case "温暖": + switch args[3] { + case "fass", "白天", "温暖": status = true } - switch args[1] { - case "奥布山谷": - fallthrough - case "金星": + switch args[2] { + case "金星", "奥布山谷": //sublist = append(sublist, subList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) - removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1) + if isEnable { + addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1, status) + } else { + removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1) + } ctx.SendChain( message.At(ctx.Event.UserID), - message.Text("已取消订阅"), + message.Text("已成功", args[1]), message.Text(gameTimes[1].Name), message.Text(status), ) - case "夜灵": - fallthrough - case "地球": - removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0) + case "地球", "夜灵": + if isEnable { + addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0, status) + } else { + removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0) + } ctx.SendChain( message.At(ctx.Event.UserID), - message.Text("已取消订阅"), + message.Text("已成功", args[1]), message.Text(gameTimes[0].Name), message.Text(status), ) - case "火卫": - fallthrough - case "火卫二": - fallthrough - case "魔胎之境": - removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2) + case "魔胎之境", "火卫", "火卫二": + if isEnable { + addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2, status) + } else { + removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2) + } ctx.SendChain( message.At(ctx.Event.UserID), - message.Text("已取消订阅"), + message.Text("已成功", args[1]), message.Text(gameTimes[2].Name), message.Text(status), ) default: - ctx.SendChain(message.Text("Error:平原不存在")) + ctx.SendChain(message.Text("ERROR: 平原不存在")) return } }) - eng.OnRegex(`^仲裁$`).SetBlock(true). + eng.OnFullMatch(`wf订阅检测`).SetBlock(true).Handle(func(ctx *zero.Ctx) { + rwm.Lock() + var msg []message.MessageSegment + for i, v := range gameTimes { + nt := time.Until(v.NextTime).Seconds() + switch { + case nt < 0: + if v.Status { + v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) + } else { + v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) + } + v.Status = !v.Status + + msg = callUser(i, v.Status, 0) + case nt < float64(5)*60: + msg = callUser(i, !v.Status, 5) + case nt < float64(15)*60: + if i == 2 && !v.Status { + return + } + msg = callUser(i, !v.Status, 15) + } + } + rwm.Unlock() + if msg != nil && len(msg) > 0 { + ctx.SendChain(msg...) + } + }) + eng.OnFullMatch(`仲裁`).SetBlock(true). Handle(func(ctx *zero.Ctx) { - updateWFAPI(ctx) + updateWFAPI() sendStringArray([]string{ "节点:" + wfapi.Arbitration.Node, "类型:" + wfapi.Arbitration.Type, @@ -261,7 +238,7 @@ func init() { }) eng.OnRegex(`^每日特惠$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { - updateWFAPI(ctx) + updateWFAPI() for _, dd := range wfapi.DailyDeals { ctx.SendChain( message.Text( @@ -287,8 +264,8 @@ func init() { // }) eng.OnRegex(`^wf数据更新$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { - updateWFAPI(ctx) - loadTime() + updateWFAPI() + loadTime(wfapi) ctx.SendChain(message.Text("已拉取服务器时间并同步到本地模拟")) }) eng.OnRegex(`^.取外号 (.*) (.*)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) { @@ -470,6 +447,8 @@ func init() { }) } + +// 数组文字转图片并发送 func sendStringArray(texts []string, ctx *zero.Ctx) { b, err := text.RenderToBase64(strings.Join(texts, "\n"), text.FontFile, 800, 20) if err != nil { @@ -479,6 +458,7 @@ func sendStringArray(texts []string, ctx *zero.Ctx) { ctx.SendChain(message.Image("base64://" + binary.BytesToString(b))) } +// 添加用户订阅 func addUseSub(qq int64, qqGroup int64, stype int, status bool) { if sb, ok := sublist[qqGroup]; ok { if st, ok := sb.SubUser[qq]; ok { @@ -492,6 +472,7 @@ func addUseSub(qq int64, qqGroup int64, stype int, status bool) { jsonSave(sublist, sublistPath) } +// 移除用户订阅 func removeUseSub(qq int64, qqGroup int64, stype int) { if sb, ok := sublist[qqGroup]; ok { if _, ok := sb.SubUser[qq]; ok { @@ -501,40 +482,26 @@ func removeUseSub(qq int64, qqGroup int64, stype int) { } } -func updateWFAPI(ctx *zero.Ctx) { +// 从WFapi获取数据 +func updateWFAPI() error { var data []byte var err error data, err = web.GetData("https://api.warframestat.us/pc") if err != nil { - ctx.SendChain(message.Text("Error:", err.Error())) - return + return err } err = json.Unmarshal(data, &wfapi) if err != nil { - ctx.SendChain(message.Text("Error:", err.Error())) - return + return err } - + return nil } -func udateWFAPI2() { - var data []byte - var err error - data, err = web.GetData("https://api.warframestat.us/pc") - if err != nil { - return - } - err = json.Unmarshal(data, &wfapi) - if err != nil { - return - } - gameTimeInit() - loadTime() -} +// 从WF市场获取物品数据信息 func updateWM() { var data []byte var err error - data, err = getData("https://api.warframe.market/v1/items", []string{"Accept", "Language"}, []string{"application/json", "zh-hans"}) + data, err = getData("https://api.warframe.market/v1/items", map[string]string{"Accept": "application/json", "Language": "zh-hans"}) if err != nil { panic(err) @@ -549,7 +516,7 @@ func getWMItemOrders(name string, h bool) (orders, itemsInSet, string, error) { var data []byte var err error var wfapiio wfAPIItemsOrders - data, err = getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", name), []string{"Accept", "Platform"}, []string{"application/json", "pc"}) + data, err = getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", name), map[string]string{"Accept": "application/json", "Platform": "pc"}) if err != nil { return nil, itemsInSet{}, "", err } @@ -589,12 +556,12 @@ func loadToFuzzy() { } } -func getData(url string, head []string, headvalue []string) (data []byte, err error) { +func getData(url string, head map[string]string) (data []byte, err error) { //提交请求 reqest, err := http.NewRequest("GET", url, nil) //增加header选项 for i, v := range head { - reqest.Header.Add(v, headvalue[i]) + reqest.Header.Add(i, v) } if err != nil { return nil, err @@ -608,38 +575,8 @@ func getData(url string, head []string, headvalue []string) (data []byte, err er response.Body.Close() return data, err } - -func isExist(path string) bool { - _, err := os.Stat(path) - if err != nil { - if os.IsExist(err) { - return true - } - if os.IsNotExist(err) { - return false - } - fmt.Println(err) - return false - } - return true -} func jsonSave(v interface{}, path string) { - data, err := json.Marshal(v) - if err != nil { - return - } - dataStr := string(data) - - // 将字符串写入指定的文件 - file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) - if err != nil { - return - } - defer file.Close() // 结束时关闭句柄,释放资源 - writer := bufio.NewWriter(file) - _, err = writer.WriteString(dataStr) - if err != nil { - return - } - writer.Flush() // 缓存数据写入磁盘(持久化) + f, _ := os.Create(path) + defer f.Close() + json.NewEncoder(f).Encode(v) } From 777d26f52ca262acaf1d26a5d03ea261d8f23e13 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Thu, 5 Jan 2023 19:47:17 +0800 Subject: [PATCH 07/19] =?UTF-8?q?wfapi=20=E9=83=A8=E5=88=86=E9=94=99?= =?UTF-8?q?=E8=AF=AF=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/gametime.go | 136 ++++++------ plugin/warframeapi/main.go | 387 ++++++++++++++------------------- 2 files changed, 231 insertions(+), 292 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index b797073c86..10697002d9 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -1,12 +1,10 @@ package warframeapi import ( - "fmt" "sync" "time" "github.com/davidscholberg/go-durationfmt" - "github.com/wdvxdr1123/ZeroBot/message" ) var ( @@ -16,10 +14,10 @@ var ( func (t *gameTime) getStatus() string { rwm.RLock() + defer rwm.RUnlock() if t.Status { return t.StatusTrueDes } - rwm.RUnlock() return t.StatusFalseDes } func (t *gameTime) getTime() string { @@ -38,14 +36,9 @@ func (t *gameTime) getTime() string { //} func gameRuntime() { - for range time.NewTicker(10 * time.Second).C { timeDet() } - //for { - // time.Sleep(10 * time.Second) - // timeDet() - //} } func loadTime(api wfAPI) { @@ -64,8 +57,10 @@ func loadTime(api wfAPI) { func timeDet() { rwm.Lock() - for i, v := range gameTimes { + + for _, v := range gameTimes { nt := time.Until(v.NextTime).Seconds() + //暂时只保留时间更新功能 switch { case nt < 0: if v.Status { @@ -74,71 +69,72 @@ func timeDet() { v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) } v.Status = !v.Status - - callUser(i, v.Status, 0) - case nt < float64(5)*60: - callUser(i, !v.Status, 5) - case nt < float64(15)*60: - if i == 2 && !v.Status { - return - } - callUser(i, !v.Status, 15) + // + // callUser(i, v.Status, 0) + //case nt < float64(5)*60: + // callUser(i, !v.Status, 5) + //case nt < float64(15)*60: + // if i == 2 && !v.Status { + // return + // } + // callUser(i, !v.Status, 15) } } - rwm.Unlock() + defer rwm.Unlock() } -func callUser(i int, s bool, time int) []message.MessageSegment { - msg := []message.MessageSegment{} - for group, sl := range sublist { - - switch { - case !sl.Min15Tips && !sl.Min5Tips && time == 15: //是否 - sublist[group].Min15Tips = true - case sl.Min15Tips && !sl.Min5Tips && time == 5: - sublist[group].Min5Tips = true - case sl.Min15Tips && sl.Min5Tips && time == 0: - sublist[group].Min15Tips = false - sublist[group].Min5Tips = false - default: - return nil - } - //if !sl.Min15Tips && !sl.Min5Tips && time == 15 { - // sublist[group].Min15Tips = true - //} else if sl.Min15Tips && !sl.Min5Tips && time == 5 { - // sublist[group].Min5Tips = true - //} else if sl.Min15Tips && sl.Min5Tips && time == 0 { - // sublist[group].Min15Tips = false - // sublist[group].Min5Tips = false - //} else { - // return - //} - for qq, st := range sl.SubUser { - if st.SubType[i] != nil { - if *st.SubType[i] == s { - msg = append(msg, message.At(qq)) - } - } - } - if len(msg) == 0 { - continue - } - if time <= 0 { - if s { - msg = append(msg, message.Text(fmt.Sprintf("\n%s白天(%s)到了", gameTimes[i].Name, gameTimes[i].StatusTrueDes))) - } else { - msg = append(msg, message.Text(fmt.Sprintf("\n%s夜晚(%s)到了", gameTimes[i].Name, gameTimes[i].StatusFalseDes))) - } - } else { - if s { - msg = append(msg, message.Text(fmt.Sprintf("\n%s距离白天(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusTrueDes, time))) - } else { - msg = append(msg, message.Text(fmt.Sprintf("\n%s距离夜晚(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusFalseDes, time))) - } - } - } - return msg -} +//TODO:订阅功能-待重做 +//func callUser(i int, s bool, time int) []message.MessageSegment { +// msg := []message.MessageSegment{} +// for group, sl := range sublist { +// +// switch { +// case !sl.Min15Tips && !sl.Min5Tips && time == 15: //是否 +// sublist[group].Min15Tips = true +// case sl.Min15Tips && !sl.Min5Tips && time == 5: +// sublist[group].Min5Tips = true +// case sl.Min15Tips && sl.Min5Tips && time == 0: +// sublist[group].Min15Tips = false +// sublist[group].Min5Tips = false +// default: +// return nil +// } +// //if !sl.Min15Tips && !sl.Min5Tips && time == 15 { +// // sublist[group].Min15Tips = true +// //} else if sl.Min15Tips && !sl.Min5Tips && time == 5 { +// // sublist[group].Min5Tips = true +// //} else if sl.Min15Tips && sl.Min5Tips && time == 0 { +// // sublist[group].Min15Tips = false +// // sublist[group].Min5Tips = false +// //} else { +// // return +// //} +// for qq, st := range sl.SubUser { +// if st.SubType[i] != nil { +// if *st.SubType[i] == s { +// msg = append(msg, message.At(qq)) +// } +// } +// } +// if len(msg) == 0 { +// continue +// } +// if time <= 0 { +// if s { +// msg = append(msg, message.Text(fmt.Sprintf("\n%s白天(%s)到了", gameTimes[i].Name, gameTimes[i].StatusTrueDes))) +// } else { +// msg = append(msg, message.Text(fmt.Sprintf("\n%s夜晚(%s)到了", gameTimes[i].Name, gameTimes[i].StatusFalseDes))) +// } +// } else { +// if s { +// msg = append(msg, message.Text(fmt.Sprintf("\n%s距离白天(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusTrueDes, time))) +// } else { +// msg = append(msg, message.Text(fmt.Sprintf("\n%s距离夜晚(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusFalseDes, time))) +// } +// } +// } +// return msg +//} // 游戏时间模拟 type gameTime struct { diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 3a208ad213..bcdef42ee6 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "github.com/FloatTech/floatbox/binary" - "github.com/FloatTech/floatbox/file" "github.com/FloatTech/zbputils/img/text" "io" "net/http" @@ -24,16 +23,13 @@ import ( ) var ( - wfapi wfAPI //WarFrameAPI的数据实例 - client http.Client //发起http请求的client实例 - itmeapi wfAPIItem //WarFrame市场的数据实例 - wmitems map[string]items //WarFrame市场的中文名称对应的物品的字典 - itmeNames []string //物品外号 - fileItemNames map[string]string //物品外号字典 - itemNamesPath string //物品外号存储路径 - sublist map[int64]*subList //订阅列表 - sublistPath string //订阅列表存储路径 - ctx *zero.Ctx //BOT实例 + client http.Client //发起http请求的client实例 + itmeapi wfAPIItem //WarFrame市场的数据实例 + wmitems map[string]items //WarFrame市场的中文名称对应的物品的字典 + itmeNames []string //物品名称列表 + //TODO:订阅功能-等待重做 + //sublist map[int64]*subList //订阅列表 + //sublistPath string //订阅列表存储路径 ) func init() { @@ -42,60 +38,40 @@ func init() { Help: "warframeapi\n" + "- wf数据更新\n" + "- [金星|地球|火卫二]平原状态\n" + - "- 订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + - "- 取消订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + - "- wf订阅检测\n" + + //"- 订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + + //"- 取消订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + + //"- wf订阅检测\n" + "- .wm [物品名称]\n" + - "- 取外号 [原名称] [外号]\n" + "- [金星|地球|火卫二]平原状态\n" + "- 仲裁\n" + "- 警报\n" + "- 每日特惠", - PrivateDataFolder: "warframeAPI", + PrivateDataFolder: "warframeapi", }) - - zero.RangeBot(func(id int64, c *zero.Ctx) bool { - ctx = c - return false - }) - //生成物品列表存储路径 - itemNamesPath = eng.DataFolder() + "ItemNames.json" - //检查文件是否存在 - if file.IsExist(itemNamesPath) { - data, err := os.ReadFile(itemNamesPath) - if err != nil { - panic(err) - } - err = json.Unmarshal(data, &fileItemNames) - if err != nil { - panic(err) - } - } else { - fileItemNames = map[string]string{} - } + //TODO:订阅功能-等待重做 //订阅名单文件路径 - sublistPath = eng.DataFolder() + "Sublist.json" - if file.IsExist(itemNamesPath) { - data, err := os.ReadFile(sublistPath) - if err != nil { - panic(err) - } - err = json.Unmarshal(data, &sublist) - if err != nil { - panic(err) - } - } else { - sublist = map[int64]*subList{} - } + //sublistPath = eng.DataFolder() + "Sublist.json" + //if file.IsExist(sublistPath) { + // data, err := os.ReadFile(sublistPath) + // if err != nil { + // panic(err) + // } + // err = json.Unmarshal(data, &sublist) + // if err != nil { + // panic(err) + // } + //} else { + // sublist = map[int64]*subList{} + //} updateWM() loadToFuzzy() - updateWFAPI() - //gameTimeInit() + //尝试初始化游戏时间模拟 + wfapi, _ := getWFAPI() + loadTime(wfapi) + gameRuntime() eng.OnRegex(`^(.*)平原状态$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { args := ctx.State["regex_matched"].([]string) - updateWFAPI() - switch args[1] { case "金星", "奥布山谷": ctx.SendChain( @@ -126,6 +102,11 @@ func init() { eng.OnFullMatch(`警报`).SetBlock(true). Handle(func(ctx *zero.Ctx) { + wfapi, err := getWFAPI() + if err != nil { + ctx.SendChain(message.Text("ERROR:", err.Error())) + return + } if len(wfapi.Alerts) > 0 { for _, v := range wfapi.Alerts { if v.Active { @@ -141,94 +122,100 @@ func init() { } }) - eng.OnRegex(`^(订阅|取消订阅)(.*)平原(.*)$`).SetBlock(true). + //TODO:订阅功能-等待重做 + //eng.OnRegex(`^(订阅|取消订阅)(.*)平原(.*)$`).SetBlock(true). + // Handle(func(ctx *zero.Ctx) { + // args := ctx.State["regex_matched"].([]string) + // var isEnable bool + // if args[1] == "订阅" { + // isEnable = true + // } + // updateWFAPI() + // status := false + // switch args[3] { + // case "fass", "白天", "温暖": + // status = true + // } + // switch args[2] { + // case "金星", "奥布山谷": + // //sublist = append(sublist, subList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) + // if isEnable { + // addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1, status) + // } else { + // removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1) + // } + // ctx.SendChain( + // message.At(ctx.Event.UserID), + // message.Text("已成功", args[1]), + // message.Text(gameTimes[1].Name), + // message.Text(status), + // ) + // case "地球", "夜灵": + // if isEnable { + // addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0, status) + // } else { + // removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0) + // } + // ctx.SendChain( + // message.At(ctx.Event.UserID), + // message.Text("已成功", args[1]), + // message.Text(gameTimes[0].Name), + // message.Text(status), + // ) + // case "魔胎之境", "火卫", "火卫二": + // if isEnable { + // addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2, status) + // } else { + // removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2) + // } + // ctx.SendChain( + // message.At(ctx.Event.UserID), + // message.Text("已成功", args[1]), + // message.Text(gameTimes[2].Name), + // message.Text(status), + // ) + // default: + // ctx.SendChain(message.Text("ERROR: 平原不存在")) + // return + // } + // }) + //eng.OnFullMatch(`wf订阅检测`).SetBlock(true).Handle(func(ctx *zero.Ctx) { + // rwm.Lock() + // var msg []message.MessageSegment + // for i, v := range gameTimes { + // nt := time.Until(v.NextTime).Seconds() + // switch { + // case nt < 0: + // if v.Status { + // v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) + // } else { + // v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) + // } + // v.Status = !v.Status + // + // msg = callUser(i, v.Status, 0) + // case nt < float64(5)*60: + // msg = callUser(i, !v.Status, 5) + // case nt < float64(15)*60: + // if i == 2 && !v.Status { + // return + // } + // msg = callUser(i, !v.Status, 15) + // } + // } + // rwm.Unlock() + // if msg != nil && len(msg) > 0 { + // ctx.SendChain(msg...) + // } + //}) + eng.OnFullMatch(`仲裁`).SetBlock(true). Handle(func(ctx *zero.Ctx) { - args := ctx.State["regex_matched"].([]string) - var isEnable bool - if args[1] == "订阅" { - isEnable = true - } - updateWFAPI() - status := false - switch args[3] { - case "fass", "白天", "温暖": - status = true - } - switch args[2] { - case "金星", "奥布山谷": - //sublist = append(sublist, subList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false}) - if isEnable { - addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1, status) - } else { - removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1) - } - ctx.SendChain( - message.At(ctx.Event.UserID), - message.Text("已成功", args[1]), - message.Text(gameTimes[1].Name), - message.Text(status), - ) - case "地球", "夜灵": - if isEnable { - addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0, status) - } else { - removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0) - } - ctx.SendChain( - message.At(ctx.Event.UserID), - message.Text("已成功", args[1]), - message.Text(gameTimes[0].Name), - message.Text(status), - ) - case "魔胎之境", "火卫", "火卫二": - if isEnable { - addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2, status) - } else { - removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2) - } - ctx.SendChain( - message.At(ctx.Event.UserID), - message.Text("已成功", args[1]), - message.Text(gameTimes[2].Name), - message.Text(status), - ) - default: - ctx.SendChain(message.Text("ERROR: 平原不存在")) - return - } - }) - eng.OnFullMatch(`wf订阅检测`).SetBlock(true).Handle(func(ctx *zero.Ctx) { - rwm.Lock() - var msg []message.MessageSegment - for i, v := range gameTimes { - nt := time.Until(v.NextTime).Seconds() - switch { - case nt < 0: - if v.Status { - v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) - } else { - v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) - } - v.Status = !v.Status + wfapi, err := getWFAPI() - msg = callUser(i, v.Status, 0) - case nt < float64(5)*60: - msg = callUser(i, !v.Status, 5) - case nt < float64(15)*60: - if i == 2 && !v.Status { - return - } - msg = callUser(i, !v.Status, 15) + if err != nil { + ctx.SendChain(message.Text("ERROR:", err.Error())) + return } - } - rwm.Unlock() - if msg != nil && len(msg) > 0 { - ctx.SendChain(msg...) - } - }) - eng.OnFullMatch(`仲裁`).SetBlock(true). - Handle(func(ctx *zero.Ctx) { - updateWFAPI() sendStringArray([]string{ "节点:" + wfapi.Arbitration.Node, "类型:" + wfapi.Arbitration.Type, @@ -238,7 +225,12 @@ func init() { }) eng.OnRegex(`^每日特惠$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { - updateWFAPI() + wfapi, err := getWFAPI() + + if err != nil { + ctx.SendChain(message.Text("ERROR:", err.Error())) + return + } for _, dd := range wfapi.DailyDeals { ctx.SendChain( message.Text( @@ -264,62 +256,15 @@ func init() { // }) eng.OnRegex(`^wf数据更新$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { - updateWFAPI() + wfapi, err := getWFAPI() + + if err != nil { + ctx.SendChain(message.Text("ERROR:", err.Error())) + return + } loadTime(wfapi) ctx.SendChain(message.Text("已拉取服务器时间并同步到本地模拟")) }) - eng.OnRegex(`^.取外号 (.*) (.*)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) { - args := ctx.State["regex_matched"].([]string) - sol := fuzzy.FindNormalizedFold(args[1], itmeNames) - var msg []string - switch len(sol) { - case 0: - ctx.SendChain(message.Text("无法查询到该物品")) - return - case 1: - wmitems[args[2]] = wmitems[sol[0]] - itmeNames = append(itmeNames, args[2]) - fileItemNames[args[2]] = sol[0] - ctx.Send(message.Text("已给[", sol[0], "]新增外号:[", args[2], "]")) - jsonSave(fileItemNames, itemNamesPath) - default: - for i, v := range sol { - msg = append(msg, fmt.Sprintf("[%d] %s", i, v)) - } - msg = append(msg, "包含多个结果,请输入编号来确定具体的物品外号(15s内)") - sendStringArray(msg, ctx) - //msg = []string{} - GETNUM: - next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() - select { - case <-time.After(time.Second * 15): - ctx.SendChain(message.Text("会话已结束!")) - return - case e := <-next: - msg := e.Event.Message.ExtractPlainText() - if msg == "c" { - ctx.SendChain(message.Text("会话已结束!")) - return - } - num, err := strconv.Atoi(msg) - if err != nil { - ctx.SendChain(message.Text("请输入数字!(输入c结束会话)")) - goto GETNUM - } - //name = sol[cc] - //ctx.Send(message.Image("https://warframe.market/static/assets/" + wmitems[sol[cc]].Thumb)) - //msg = append(msg, wmitems[sol[cc]].ItemName) - - wmitems[args[2]] = wmitems[sol[num]] - itmeNames = append(itmeNames, args[2]) - fileItemNames[args[2]] = sol[num] - ctx.Send(message.Text("已给[", sol[num], "]新增外号:[", args[2], "]")) - jsonSave(fileItemNames, itemNamesPath) - } - - } - - }) eng.OnRegex(`^.wm (.*)$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { args := ctx.State["regex_matched"].([]string) @@ -458,43 +403,45 @@ func sendStringArray(texts []string, ctx *zero.Ctx) { ctx.SendChain(message.Image("base64://" + binary.BytesToString(b))) } +//TODO:订阅功能-等待重做 // 添加用户订阅 -func addUseSub(qq int64, qqGroup int64, stype int, status bool) { - if sb, ok := sublist[qqGroup]; ok { - if st, ok := sb.SubUser[qq]; ok { - st.SubType[stype] = &status - } else { - sublist[qqGroup].SubUser[qq] = subType{map[int]*bool{stype: &status}, false} - } - } else { - sublist[qqGroup] = &subList{map[int64]subType{qq: {map[int]*bool{stype: &status}, false}}, false, false} - } - jsonSave(sublist, sublistPath) -} - -// 移除用户订阅 -func removeUseSub(qq int64, qqGroup int64, stype int) { - if sb, ok := sublist[qqGroup]; ok { - if _, ok := sb.SubUser[qq]; ok { - delete(sublist[qqGroup].SubUser[qq].SubType, stype) - jsonSave(sublist, sublistPath) - } - } -} +//func addUseSub(qq int64, qqGroup int64, stype int, status bool) { +// if sb, ok := sublist[qqGroup]; ok { +// if st, ok := sb.SubUser[qq]; ok { +// st.SubType[stype] = &status +// } else { +// sublist[qqGroup].SubUser[qq] = subType{map[int]*bool{stype: &status}, false} +// } +// } else { +// sublist[qqGroup] = &subList{map[int64]subType{qq: {map[int]*bool{stype: &status}, false}}, false, false} +// } +// jsonSave(sublist, sublistPath) +//} +// +//// 移除用户订阅 +//func removeUseSub(qq int64, qqGroup int64, stype int) { +// if sb, ok := sublist[qqGroup]; ok { +// if _, ok := sb.SubUser[qq]; ok { +// delete(sublist[qqGroup].SubUser[qq].SubType, stype) +// jsonSave(sublist, sublistPath) +// } +// } +//} // 从WFapi获取数据 -func updateWFAPI() error { +func getWFAPI() (wfAPI, error) { + var wfapi wfAPI //WarFrameAPI的数据实例 var data []byte var err error data, err = web.GetData("https://api.warframestat.us/pc") if err != nil { - return err + return wfapi, err } err = json.Unmarshal(data, &wfapi) if err != nil { - return err + return wfapi, err } - return nil + return wfapi, nil } // 从WF市场获取物品数据信息 @@ -550,10 +497,6 @@ func loadToFuzzy() { wmitems[v.ItemName] = v itmeNames = append(itmeNames, v.ItemName) } - for k, v := range fileItemNames { - wmitems[k] = wmitems[v] - itmeNames = append(itmeNames, k) - } } func getData(url string, head map[string]string) (data []byte, err error) { From b9b3ed0609b4d683bd395daded7c467e4c32eda6 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Thu, 5 Jan 2023 19:51:53 +0800 Subject: [PATCH 08/19] =?UTF-8?q?wfapi=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/main.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index bcdef42ee6..ec6e3a21f5 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -66,9 +66,9 @@ func init() { updateWM() loadToFuzzy() //尝试初始化游戏时间模拟 - wfapi, _ := getWFAPI() - loadTime(wfapi) - gameRuntime() + //wfapi, _ := getWFAPI() + //loadTime(wfapi) + //gameRuntime() eng.OnRegex(`^(.*)平原状态$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { args := ctx.State["regex_matched"].([]string) @@ -223,7 +223,7 @@ func init() { "剩余时间:" + fmt.Sprint(int(wfapi.Arbitration.Expiry.Sub(time.Now().UTC()).Minutes())) + "m", }, ctx) }) - eng.OnRegex(`^每日特惠$`).SetBlock(true). + eng.OnFullMatch(`每日特惠`).SetBlock(true). Handle(func(ctx *zero.Ctx) { wfapi, err := getWFAPI() @@ -254,7 +254,7 @@ func init() { // }, ctx) // } // }) - eng.OnRegex(`^wf数据更新$`).SetBlock(true). + eng.OnFullMatch(`wf数据更新`).SetBlock(true). Handle(func(ctx *zero.Ctx) { wfapi, err := getWFAPI() From aa5df785ea5c78b38ff83f5a76ef4492b143e0f5 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Thu, 5 Jan 2023 20:03:36 +0800 Subject: [PATCH 09/19] =?UTF-8?q?wfapi=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/gametime.go | 7 ++++++- plugin/warframeapi/main.go | 11 +++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index 10697002d9..7e9c218fbb 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -36,6 +36,11 @@ func (t *gameTime) getTime() string { //} func gameRuntime() { + wfapi, err := getWFAPI() + if err != nil { + println("ERROR:GetWFAPI失败,", err.Error()) + } + loadTime(wfapi) for range time.NewTicker(10 * time.Second).C { timeDet() } @@ -52,7 +57,7 @@ func loadTime(api wfAPI) { {"金星平原", api.VallisCycle.Expiry.Local(), api.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, {"火卫二平原", api.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, } - + println("LoadTime:Success") } func timeDet() { diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index ec6e3a21f5..6d7cf0bebe 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -65,13 +65,13 @@ func init() { //} updateWM() loadToFuzzy() - //尝试初始化游戏时间模拟 - //wfapi, _ := getWFAPI() - //loadTime(wfapi) - //gameRuntime() + //初始化游戏时间模拟 + go gameRuntime() + println("LoadTime:Success") eng.OnRegex(`^(.*)平原状态$`).SetBlock(true). Handle(func(ctx *zero.Ctx) { args := ctx.State["regex_matched"].([]string) + println(args) switch args[1] { case "金星", "奥布山谷": ctx.SendChain( @@ -435,12 +435,15 @@ func getWFAPI() (wfAPI, error) { var err error data, err = web.GetData("https://api.warframestat.us/pc") if err != nil { + println("err:", err.Error()) return wfapi, err } err = json.Unmarshal(data, &wfapi) if err != nil { + println("err:", err.Error()) return wfapi, err } + println("获取成功") return wfapi, nil } From e7d9dfc7bb65110c3950321721d0d8d81bf61df7 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Thu, 5 Jan 2023 20:42:22 +0800 Subject: [PATCH 10/19] =?UTF-8?q?wfapi=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 +---- plugin/warframeapi/gametime.go | 74 +++++++++++++++++++--------------- plugin/warframeapi/main.go | 46 ++++++++++----------- 3 files changed, 63 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 7a13a9714f..bd26e0bd95 100644 --- a/README.md +++ b/README.md @@ -1284,20 +1284,12 @@ print("run[CQ:image,file="+j["img"]+"]") `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi"` - - [x] wf数据更新 + - [x] wf时间同步 - [x] [金星|地球|火卫二]平原状态 - - [x] 订阅[金星|地球|火卫二]平原[白天|夜晚] - - - [x] 取消订阅[金星|地球|火卫二]平原[白天|夜晚] - - [x] .wm [物品名称] - - [x] 取外号 [原名称] [外号] - - - [x] [金星/地球/火卫二]平原状态 - - [x] 仲裁 - [x] 警报 diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index 7e9c218fbb..dd430db37b 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -9,21 +9,20 @@ import ( var ( gameTimes [3]*gameTime - rwm sync.RWMutex ) func (t *gameTime) getStatus() string { - rwm.RLock() - defer rwm.RUnlock() + t.rwm.RLock() + defer t.rwm.RUnlock() if t.Status { return t.StatusTrueDes } return t.StatusFalseDes } func (t *gameTime) getTime() string { - rwm.RLock() + t.rwm.RLock() d := time.Until(t.NextTime) - rwm.RUnlock() + t.rwm.RUnlock() durStr, _ := durationfmt.Format(d, "%m分%s秒后") return durStr } @@ -39,6 +38,7 @@ func gameRuntime() { wfapi, err := getWFAPI() if err != nil { println("ERROR:GetWFAPI失败,", err.Error()) + return } loadTime(wfapi) for range time.NewTicker(10 * time.Second).C { @@ -53,39 +53,46 @@ func loadTime(api wfAPI) { isfass = true } gameTimes = [3]*gameTime{ - {"地球平原", api.CetusCycle.Expiry.Local(), api.CetusCycle.IsDay, "白天", "夜晚", 100 * 60, 50 * 60}, - {"金星平原", api.VallisCycle.Expiry.Local(), api.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, - {"火卫二平原", api.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, + {sync.RWMutex{}, "地球平原", api.CetusCycle.Expiry.Local(), api.CetusCycle.IsDay, "白天", "夜晚", 100 * 60, 50 * 60}, + {sync.RWMutex{}, "金星平原", api.VallisCycle.Expiry.Local(), api.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, + {sync.RWMutex{}, "火卫二平原", api.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, } println("LoadTime:Success") } func timeDet() { - rwm.Lock() - for _, v := range gameTimes { nt := time.Until(v.NextTime).Seconds() - //暂时只保留时间更新功能 - switch { - case nt < 0: + + if nt < 0 { + v.rwm.Lock() if v.Status { v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) } else { v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) } - v.Status = !v.Status - // - // callUser(i, v.Status, 0) - //case nt < float64(5)*60: - // callUser(i, !v.Status, 5) - //case nt < float64(15)*60: - // if i == 2 && !v.Status { - // return - // } - // callUser(i, !v.Status, 15) + v.rwm.Unlock() } + //暂时只保留时间更新功能 + //switch { + //case nt < 0: + // if v.Status { + // v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) + // } else { + // v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) + // } + // v.Status = !v.Status + // + // callUser(i, v.Status, 0) + //case nt < float64(5)*60: + // callUser(i, !v.Status, 5) + //case nt < float64(15)*60: + // if i == 2 && !v.Status { + // return + // } + // callUser(i, !v.Status, 15) + //} } - defer rwm.Unlock() } //TODO:订阅功能-待重做 @@ -143,6 +150,7 @@ func timeDet() { // 游戏时间模拟 type gameTime struct { + rwm sync.RWMutex Name string `json:"name"` //时间名称 NextTime time.Time `json:"time"` //下次更新时间 Status bool `json:"status"` //状态 @@ -152,13 +160,13 @@ type gameTime struct { NightTime int `json:"night"` //夜间时长 } -type subList struct { - SubUser map[int64]subType `json:"qq_sub"` - Min5Tips bool `json:"min5_tips"` - Min15Tips bool `json:"min15_tips"` -} +//type subList struct { +// SubUser map[int64]subType `json:"qq_sub"` +// Min5Tips bool `json:"min5_tips"` +// Min15Tips bool `json:"min15_tips"` +//} -type subType struct { - SubType map[int]*bool `json:"sub_type"` - SubRaid bool `json:"sub_raid"` -} +//type subType struct { +// SubType map[int]*bool `json:"sub_type"` +// SubRaid bool `json:"sub_raid"` +//} diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 6d7cf0bebe..3e94d7c507 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -8,7 +8,6 @@ import ( "github.com/FloatTech/zbputils/img/text" "io" "net/http" - "os" "sort" "strconv" "strings" @@ -36,13 +35,12 @@ func init() { eng := control.Register("warframeapi", &ctrl.Options[*zero.Ctx]{ DisableOnDefault: false, Help: "warframeapi\n" + - "- wf数据更新\n" + - "- [金星|地球|火卫二]平原状态\n" + + "- wf时间同步\n" + + "- [金星|地球|火卫二]平原时间\n" + //"- 订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + //"- 取消订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + //"- wf订阅检测\n" + "- .wm [物品名称]\n" + - "- [金星|地球|火卫二]平原状态\n" + "- 仲裁\n" + "- 警报\n" + "- 每日特惠", @@ -68,29 +66,27 @@ func init() { //初始化游戏时间模拟 go gameRuntime() println("LoadTime:Success") - eng.OnRegex(`^(.*)平原状态$`).SetBlock(true). + eng.OnSuffix("平原时间").SetBlock(true). Handle(func(ctx *zero.Ctx) { - args := ctx.State["regex_matched"].([]string) - println(args) - switch args[1] { + switch ctx.State["args"].(string) { case "金星", "奥布山谷": ctx.SendChain( message.Text( - "平原状态:", gameTimes[1].getStatus(), "\n", + "平原时间:", gameTimes[1].getStatus(), "\n", "下次更新:", gameTimes[1].getTime(), ), ) case "地球", "夜灵": ctx.SendChain( message.Text( - "平原状态:", gameTimes[0].getStatus(), "\n", + "平原时间:", gameTimes[0].getStatus(), "\n", "下次更新:", gameTimes[0].getTime(), ), ) case "魔胎之境", "火卫二", "火卫": ctx.SendChain( message.Text( - "平原状态:", gameTimes[2].getStatus(), "\n", + "平原时间:", gameTimes[2].getStatus(), "\n", "下次更新:", gameTimes[2].getTime(), ), ) @@ -100,7 +96,7 @@ func init() { } }) - eng.OnFullMatch(`警报`).SetBlock(true). + eng.OnFullMatch("警报").SetBlock(true). Handle(func(ctx *zero.Ctx) { wfapi, err := getWFAPI() if err != nil { @@ -208,7 +204,7 @@ func init() { // ctx.SendChain(msg...) // } //}) - eng.OnFullMatch(`仲裁`).SetBlock(true). + eng.OnFullMatch("仲裁").SetBlock(true). Handle(func(ctx *zero.Ctx) { wfapi, err := getWFAPI() @@ -223,7 +219,7 @@ func init() { "剩余时间:" + fmt.Sprint(int(wfapi.Arbitration.Expiry.Sub(time.Now().UTC()).Minutes())) + "m", }, ctx) }) - eng.OnFullMatch(`每日特惠`).SetBlock(true). + eng.OnFullMatch("每日特惠").SetBlock(true). Handle(func(ctx *zero.Ctx) { wfapi, err := getWFAPI() @@ -254,10 +250,9 @@ func init() { // }, ctx) // } // }) - eng.OnFullMatch(`wf数据更新`).SetBlock(true). + eng.OnFullMatch("wf时间同步").SetBlock(true). Handle(func(ctx *zero.Ctx) { wfapi, err := getWFAPI() - if err != nil { ctx.SendChain(message.Text("ERROR:", err.Error())) return @@ -265,10 +260,9 @@ func init() { loadTime(wfapi) ctx.SendChain(message.Text("已拉取服务器时间并同步到本地模拟")) }) - eng.OnRegex(`^.wm (.*)$`).SetBlock(true). + eng.OnPrefix(".wm ").SetBlock(true). Handle(func(ctx *zero.Ctx) { - args := ctx.State["regex_matched"].([]string) - sol := fuzzy.FindNormalizedFold(args[1], itmeNames) + sol := fuzzy.FindNormalizedFold(ctx.State["args"].(string), itmeNames) var msg []string var name string switch len(sol) { @@ -395,7 +389,7 @@ func init() { // 数组文字转图片并发送 func sendStringArray(texts []string, ctx *zero.Ctx) { - b, err := text.RenderToBase64(strings.Join(texts, "\n"), text.FontFile, 800, 20) + b, err := text.RenderToBase64(strings.Join(texts, "\n"), text.FontFile, 400, 20) if err != nil { ctx.SendChain(message.Text("ERROR: ", err)) return @@ -520,9 +514,11 @@ func getData(url string, head map[string]string) (data []byte, err error) { data, err = io.ReadAll(response.Body) response.Body.Close() return data, err -} -func jsonSave(v interface{}, path string) { - f, _ := os.Create(path) - defer f.Close() - json.NewEncoder(f).Encode(v) + + //func jsonSave(v interface{}, path string) { + // f, _ := os.Create(path) + // defer f.Close() + // json.NewEncoder(f).Encode(v) + //} + } From 4f55aab043d8ebdf55e853acf25eeccbb626a9fd Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Thu, 5 Jan 2023 20:56:35 +0800 Subject: [PATCH 11/19] =?UTF-8?q?wfapi=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/gametime.go | 1 + plugin/warframeapi/main.go | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index dd430db37b..65c60f200d 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -34,6 +34,7 @@ func (t *gameTime) getTime() string { // go gameRuntime() //} +// gameRuntime 游戏时间模拟 func gameRuntime() { wfapi, err := getWFAPI() if err != nil { diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 3e94d7c507..4dd0c328df 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -22,8 +22,6 @@ import ( ) var ( - client http.Client //发起http请求的client实例 - itmeapi wfAPIItem //WarFrame市场的数据实例 wmitems map[string]items //WarFrame市场的中文名称对应的物品的字典 itmeNames []string //物品名称列表 //TODO:订阅功能-等待重做 @@ -62,7 +60,7 @@ func init() { // sublist = map[int64]*subList{} //} updateWM() - loadToFuzzy() + //初始化游戏时间模拟 go gameRuntime() println("LoadTime:Success") @@ -443,17 +441,18 @@ func getWFAPI() (wfAPI, error) { // 从WF市场获取物品数据信息 func updateWM() { + var itmeapi wfAPIItem //WarFrame市场的数据实例 var data []byte var err error data, err = getData("https://api.warframe.market/v1/items", map[string]string{"Accept": "application/json", "Language": "zh-hans"}) if err != nil { panic(err) - } err = json.Unmarshal(data, &itmeapi) if err != nil { panic(err) } + loadToFuzzy(itmeapi) } func getWMItemOrders(name string, h bool) (orders, itemsInSet, string, error) { @@ -487,10 +486,10 @@ func getWMItemOrders(name string, h bool) (orders, itemsInSet, string, error) { return sellOrders, wfapiio.Include.Item.ItemsInSet[0], wfapiio.Include.Item.ItemsInSet[0].En.ItemName, err } -func loadToFuzzy() { +func loadToFuzzy(wminfo wfAPIItem) { wmitems = make(map[string]items) itmeNames = []string{} - for _, v := range itmeapi.Payload.Items { + for _, v := range wminfo.Payload.Items { wmitems[v.ItemName] = v itmeNames = append(itmeNames, v.ItemName) } @@ -507,6 +506,8 @@ func getData(url string, head map[string]string) (data []byte, err error) { return nil, err } //处理返回结果 + //发起http请求的client实例 + client := http.Client{} response, err := client.Do(reqest) if err != nil { return nil, err @@ -514,7 +515,6 @@ func getData(url string, head map[string]string) (data []byte, err error) { data, err = io.ReadAll(response.Body) response.Body.Close() return data, err - //func jsonSave(v interface{}, path string) { // f, _ := os.Create(path) // defer f.Close() From aebb2228fee72e78ed837c0da63ed0c69a510256 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Thu, 5 Jan 2023 21:07:51 +0800 Subject: [PATCH 12/19] =?UTF-8?q?wfapi=20=E7=A7=BB=E9=99=A4=E6=97=A5?= =?UTF-8?q?=E5=BF=97=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/gametime.go | 1 - plugin/warframeapi/main.go | 4 ---- 2 files changed, 5 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index 65c60f200d..d3c3f7f737 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -58,7 +58,6 @@ func loadTime(api wfAPI) { {sync.RWMutex{}, "金星平原", api.VallisCycle.Expiry.Local(), api.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, {sync.RWMutex{}, "火卫二平原", api.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, } - println("LoadTime:Success") } func timeDet() { diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 4dd0c328df..5e224344c8 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -63,7 +63,6 @@ func init() { //初始化游戏时间模拟 go gameRuntime() - println("LoadTime:Success") eng.OnSuffix("平原时间").SetBlock(true). Handle(func(ctx *zero.Ctx) { switch ctx.State["args"].(string) { @@ -427,15 +426,12 @@ func getWFAPI() (wfAPI, error) { var err error data, err = web.GetData("https://api.warframestat.us/pc") if err != nil { - println("err:", err.Error()) return wfapi, err } err = json.Unmarshal(data, &wfapi) if err != nil { - println("err:", err.Error()) return wfapi, err } - println("获取成功") return wfapi, nil } From 0a2985dfbf1e592d9b6aa5abc838bdaa3641002c Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Fri, 6 Jan 2023 09:58:55 +0800 Subject: [PATCH 13/19] =?UTF-8?q?wfapi=20=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96=EF=BC=8Cgoto=E6=9B=BF=E6=8D=A2=E4=B8=BA=E9=80=92?= =?UTF-8?q?=E5=BD=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/gametime.go | 20 ++++- plugin/warframeapi/main.go | 138 ++++++++++++++++++++------------- 2 files changed, 105 insertions(+), 53 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index d3c3f7f737..737e45d76a 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -1,6 +1,7 @@ package warframeapi import ( + "github.com/wdvxdr1123/ZeroBot/message" "sync" "time" @@ -11,6 +12,15 @@ var ( gameTimes [3]*gameTime ) +// getTimeString 根据传入的世界编号,获取对应的游戏时间文本 +func getTimeString(wordType int) message.MessageSegment { + return message.Text( + "平原时间:", gameTimes[wordType].getStatus(), "\n", + "下次更新:", gameTimes[wordType].getTime(), + ) +} + +// getStatus 获取当前游戏时间状态(白天/夜晚) func (t *gameTime) getStatus() string { t.rwm.RLock() defer t.rwm.RUnlock() @@ -19,6 +29,8 @@ func (t *gameTime) getStatus() string { } return t.StatusFalseDes } + +// getTime 获取下一次时间状态更新的剩余游戏时间(x分x秒) func (t *gameTime) getTime() string { t.rwm.RLock() d := time.Until(t.NextTime) @@ -47,6 +59,7 @@ func gameRuntime() { } } +// loadTime 根据API返回内容修正游戏时间 func loadTime(api wfAPI) { //updateWM() var isfass bool @@ -60,15 +73,20 @@ func loadTime(api wfAPI) { } } +// timeDet游戏时间更新 func timeDet() { for _, v := range gameTimes { + //当前时间对比下一次游戏状态更新时间,看看还剩多少秒 nt := time.Until(v.NextTime).Seconds() - + //已经过了游戏时间状态更新时间 if nt < 0 { v.rwm.Lock() + //更新游戏状态,如果是白天就切换到晚上,反之亦然 if v.Status { + //计算下次的晚上更新时间 v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) } else { + //计算下次的白天更新时间 v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) } v.rwm.Unlock() diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 5e224344c8..ccecd9160c 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -65,28 +65,14 @@ func init() { go gameRuntime() eng.OnSuffix("平原时间").SetBlock(true). Handle(func(ctx *zero.Ctx) { + //根据具体输入的平原,来显示时间 switch ctx.State["args"].(string) { - case "金星", "奥布山谷": - ctx.SendChain( - message.Text( - "平原时间:", gameTimes[1].getStatus(), "\n", - "下次更新:", gameTimes[1].getTime(), - ), - ) case "地球", "夜灵": - ctx.SendChain( - message.Text( - "平原时间:", gameTimes[0].getStatus(), "\n", - "下次更新:", gameTimes[0].getTime(), - ), - ) + ctx.SendChain(getTimeString(0)) + case "金星", "奥布山谷": + ctx.SendChain(getTimeString(1)) case "魔胎之境", "火卫二", "火卫": - ctx.SendChain( - message.Text( - "平原时间:", gameTimes[2].getStatus(), "\n", - "下次更新:", gameTimes[2].getTime(), - ), - ) + ctx.SendChain(getTimeString(2)) default: ctx.SendChain(message.Text("ERROR: 平原不存在")) return @@ -100,16 +86,20 @@ func init() { ctx.SendChain(message.Text("ERROR:", err.Error())) return } + //如果返回的wfapi中,警报数量>0 if len(wfapi.Alerts) > 0 { + //遍历警报数据,打印警报信息 for _, v := range wfapi.Alerts { + //如果警报处于激活状态 if v.Active { - sendStringArray([]string{ + ctx.SendChain(stringArrayToImage([]string{ "节点:" + v.Mission.Node, "类型:" + v.Mission.Type, "敌人Lv:" + fmt.Sprint(v.Mission.MinEnemyLevel) + "~" + fmt.Sprint(v.Mission.MaxEnemyLevel), "奖励:" + v.Mission.Reward.AsString, "剩余时间:" + v.Eta, - }, ctx) + })) + } } } @@ -203,18 +193,18 @@ func init() { //}) eng.OnFullMatch("仲裁").SetBlock(true). Handle(func(ctx *zero.Ctx) { + //通过wfapi获取仲裁信息 wfapi, err := getWFAPI() - if err != nil { ctx.SendChain(message.Text("ERROR:", err.Error())) return } - sendStringArray([]string{ + ctx.SendChain(stringArrayToImage([]string{ "节点:" + wfapi.Arbitration.Node, "类型:" + wfapi.Arbitration.Type, "阵营:" + wfapi.Arbitration.Enemy, "剩余时间:" + fmt.Sprint(int(wfapi.Arbitration.Expiry.Sub(time.Now().UTC()).Minutes())) + "m", - }, ctx) + })) }) eng.OnFullMatch("每日特惠").SetBlock(true). Handle(func(ctx *zero.Ctx) { @@ -257,43 +247,55 @@ func init() { loadTime(wfapi) ctx.SendChain(message.Text("已拉取服务器时间并同步到本地模拟")) }) + // 根据名称从Warframe市场查询物品售价 eng.OnPrefix(".wm ").SetBlock(true). Handle(func(ctx *zero.Ctx) { + //根据输入的名称,从游戏物品名称列表中进行模糊搜索 sol := fuzzy.FindNormalizedFold(ctx.State["args"].(string), itmeNames) var msg []string + //物品名称 var name string + + //根据搜搜结果,打印找到的物品 switch len(sol) { - case 0: + case 0: //没有搜索到任何东西 ctx.SendChain(message.Text("无法查询到该物品")) return - case 1: + case 1: //如果只搜索到了一个 name = sol[0] - default: + default: //如果搜搜到了多个 + //遍历搜索结果,并打印为图片展出 for i, v := range sol { msg = append(msg, fmt.Sprintf("[%d] %s", i, v)) } msg = append(msg, "包含多个结果,请输入编号查看(15s内),输入c直接结束会话") - sendStringArray(msg, ctx) + ctx.SendChain(stringArrayToImage(msg)) msg = []string{} - GETNUM2: - next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() - select { - case <-time.After(time.Second * 15): - ctx.SendChain(message.Text("会话已结束!")) + + itemIndex := getItemNameFutureEvent(ctx, 2) + if itemIndex == -1 { return - case e := <-next: - msg := e.Event.Message.ExtractPlainText() - if msg == "c" { - ctx.SendChain(message.Text("会话已结束!")) - return - } - num, err := strconv.Atoi(msg) - if err != nil { - ctx.SendChain(message.Text("请输入数字!(输入c结束会话)")) - goto GETNUM2 - } - name = sol[num] } + name = sol[itemIndex] + //GETNUM2: //获取用户具体想查看哪个物品 + //next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() + //select { + //case <-time.After(time.Second * 15): + // ctx.SendChain(message.Text("会话已结束!")) + // return + //case e := <-next: + // msg := e.Event.Message.ExtractPlainText() + // if msg == "c" { + // ctx.SendChain(message.Text("会话已结束!")) + // return + // } + // num, err := strconv.Atoi(msg) + // if err != nil { + // ctx.SendChain(message.Text("请输入数字!(输入c结束会话)")) + // goto GETNUM2 + // } + // name = sol[num] + //} } Mf := false GETWM: @@ -313,7 +315,6 @@ func init() { message.Text("wiki:", itmeinfo.ZhHans.WikiLink), }) } - msg = append(msg, wmitems[name].ItemName) ismod := false if err != nil { @@ -345,7 +346,8 @@ func init() { } else { msg = append(msg, "请输入编号选择(30s内)\n输入c直接结束会话") } - sendStringArray(msg, ctx) + ctx.SendChain(stringArrayToImage(msg)) + GETNUM3: next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() select { @@ -384,14 +386,46 @@ func init() { } -// 数组文字转图片并发送 -func sendStringArray(texts []string, ctx *zero.Ctx) { +// 获取搜索结果中的物品具体名称index的FutureEvent,传入ctx和一个递归次数上限,返回一个int,如果为返回内容为-1,说明会话超时,或主动结束,或超出递归 +func getItemNameFutureEvent(ctx *zero.Ctx, count int) int { + next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() + select { + case <-time.After(time.Second * 15): + //超时15秒处理 + ctx.SendChain(message.Text("会话已超时!")) + return -1 + case e := <-next: + msg := e.Event.Message.ExtractPlainText() + //输入c主动结束的处理 + if msg == "c" { + ctx.SendChain(message.Text("会话已结束!")) + return -1 + } + //尝试对输入进行数字转换 + num, err := strconv.Atoi(msg) + //如果出错,说明输入的并非数字,则重新触发该内容 + if err != nil { + //查看是否超时 + if count == 0 { + ctx.SendChain(message.Text("连续输入错误,会话已结束!")) + return -1 + } else { + ctx.SendChain(message.Text("请输入数字!(输入c结束会话)[", count, "]")) + count-- + return getItemNameFutureEvent(ctx, count) + } + } + return num + } +} + +// 数组字符串转图片 +func stringArrayToImage(texts []string) message.MessageSegment { b, err := text.RenderToBase64(strings.Join(texts, "\n"), text.FontFile, 400, 20) if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return + return message.Text("ERROR: ", err) } - ctx.SendChain(message.Image("base64://" + binary.BytesToString(b))) + return message.Image("base64://" + binary.BytesToString(b)) } //TODO:订阅功能-等待重做 From bf016d0a98836f776d866d0aeea6ea843a74f347 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Fri, 6 Jan 2023 14:50:15 +0800 Subject: [PATCH 14/19] =?UTF-8?q?wfapi=20=E5=A2=9E=E5=8A=A0=E6=B3=A8?= =?UTF-8?q?=E9=87=8A=EF=BC=8C=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/main.go | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index ccecd9160c..8106dd3553 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -409,11 +409,11 @@ func getItemNameFutureEvent(ctx *zero.Ctx, count int) int { if count == 0 { ctx.SendChain(message.Text("连续输入错误,会话已结束!")) return -1 - } else { - ctx.SendChain(message.Text("请输入数字!(输入c结束会话)[", count, "]")) - count-- - return getItemNameFutureEvent(ctx, count) } + ctx.SendChain(message.Text("请输入数字!(输入c结束会话)[", count, "]")) + count-- + return getItemNameFutureEvent(ctx, count) + } return num } @@ -472,9 +472,7 @@ func getWFAPI() (wfAPI, error) { // 从WF市场获取物品数据信息 func updateWM() { var itmeapi wfAPIItem //WarFrame市场的数据实例 - var data []byte - var err error - data, err = getData("https://api.warframe.market/v1/items", map[string]string{"Accept": "application/json", "Language": "zh-hans"}) + data, err := getData("https://api.warframe.market/v1/items", map[string]string{"Accept": "application/json", "Language": "zh-hans"}) if err != nil { panic(err) } @@ -485,31 +483,34 @@ func updateWM() { loadToFuzzy(itmeapi) } -func getWMItemOrders(name string, h bool) (orders, itemsInSet, string, error) { - var data []byte - var err error +// 获取Warframe市场的售价表,并进行排序,cn_name为物品中文名称,onlyMaxRank表示只取最高等级的物品,返回物品售价表,物品信息,物品英文 +func getWMItemOrders(cn_name string, onlyMaxRank bool) (orders, itemsInSet, string, error) { + var wfapiio wfAPIItemsOrders - data, err = getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", name), map[string]string{"Accept": "application/json", "Platform": "pc"}) + data, err := getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", cn_name), map[string]string{"Accept": "application/json", "Platform": "pc"}) if err != nil { return nil, itemsInSet{}, "", err } err = json.Unmarshal(data, &wfapiio) - var sellOrders orders + //遍历市场物品列表 for _, v := range wfapiio.Payload.Orders { + //取其中类型为售卖,且去掉不在线的玩家 if v.OrderType == "sell" && v.User.Status != "offline" { - if h && v.ModRank == wfapiio.Include.Item.ItemsInSet[0].ModMaxRank { + //如果需要满级报价 + if onlyMaxRank && v.ModRank == wfapiio.Include.Item.ItemsInSet[0].ModMaxRank { sellOrders = append(sellOrders, v) - } else if !h { + } else if !onlyMaxRank { sellOrders = append(sellOrders, v) } } } + //对报价表进行排序,由低到高 sort.Sort(sellOrders) - + //获取物品信息 for i, v := range wfapiio.Include.Item.ItemsInSet { - if v.URLName == name { + if v.URLName == cn_name { return sellOrders, wfapiio.Include.Item.ItemsInSet[i], wfapiio.Include.Item.ItemsInSet[i].En.ItemName, err } } From 67552a19dcc07d6fa7db8dd307b446ca14d94958 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Fri, 6 Jan 2023 14:53:28 +0800 Subject: [PATCH 15/19] =?UTF-8?q?wfapi=20lint=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 8106dd3553..7cafc0f969 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -484,10 +484,10 @@ func updateWM() { } // 获取Warframe市场的售价表,并进行排序,cn_name为物品中文名称,onlyMaxRank表示只取最高等级的物品,返回物品售价表,物品信息,物品英文 -func getWMItemOrders(cn_name string, onlyMaxRank bool) (orders, itemsInSet, string, error) { +func getWMItemOrders(cnName string, onlyMaxRank bool) (orders, itemsInSet, string, error) { var wfapiio wfAPIItemsOrders - data, err := getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", cn_name), map[string]string{"Accept": "application/json", "Platform": "pc"}) + data, err := getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", cnName), map[string]string{"Accept": "application/json", "Platform": "pc"}) if err != nil { return nil, itemsInSet{}, "", err } @@ -510,7 +510,7 @@ func getWMItemOrders(cn_name string, onlyMaxRank bool) (orders, itemsInSet, stri sort.Sort(sellOrders) //获取物品信息 for i, v := range wfapiio.Include.Item.ItemsInSet { - if v.URLName == cn_name { + if v.URLName == cnName { return sellOrders, wfapiio.Include.Item.ItemsInSet[i], wfapiio.Include.Item.ItemsInSet[i].En.ItemName, err } } From 05d25b28202e8f904e8d2c7852bc72db98158a04 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Tue, 31 Jan 2023 10:35:45 +0800 Subject: [PATCH 16/19] =?UTF-8?q?wfapi=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/gametime.go | 54 +++++------- plugin/warframeapi/main.go | 154 +++++++++++++++------------------ 2 files changed, 92 insertions(+), 116 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index 737e45d76a..9971ec8c4d 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -1,7 +1,6 @@ package warframeapi import ( - "github.com/wdvxdr1123/ZeroBot/message" "sync" "time" @@ -12,16 +11,14 @@ var ( gameTimes [3]*gameTime ) -// getTimeString 根据传入的世界编号,获取对应的游戏时间文本 -func getTimeString(wordType int) message.MessageSegment { - return message.Text( - "平原时间:", gameTimes[wordType].getStatus(), "\n", - "下次更新:", gameTimes[wordType].getTime(), - ) +// TimeString 根据传入的世界编号,获取对应的游戏时间文本 +func (t *gameTime) String() string { + return "平原时间:" + t.daynight() + "\n" + + "下次更新:" + t.remaintime() } -// getStatus 获取当前游戏时间状态(白天/夜晚) -func (t *gameTime) getStatus() string { +// daynight 获取当前游戏时间状态(白天/夜晚) +func (t *gameTime) daynight() string { t.rwm.RLock() defer t.rwm.RUnlock() if t.Status { @@ -30,8 +27,8 @@ func (t *gameTime) getStatus() string { return t.StatusFalseDes } -// getTime 获取下一次时间状态更新的剩余游戏时间(x分x秒) -func (t *gameTime) getTime() string { +// remaintime 获取下一次时间状态更新的剩余游戏时间(x分x秒) +func (t *gameTime) remaintime() string { t.rwm.RLock() d := time.Until(t.NextTime) t.rwm.RUnlock() @@ -46,30 +43,27 @@ func (t *gameTime) getTime() string { // go gameRuntime() //} -// gameRuntime 游戏时间模拟 -func gameRuntime() { - wfapi, err := getWFAPI() - if err != nil { - println("ERROR:GetWFAPI失败,", err.Error()) - return - } - loadTime(wfapi) - for range time.NewTicker(10 * time.Second).C { - timeDet() - } -} +// 游戏时间模拟 +//func gameRuntime() { +// wfapi, err := getWFAPI() +// if err != nil { +// println("ERROR:GetWFAPI失败,", err.Error()) +// return +// } +// loadTime(wfapi) +// for range time.NewTicker(10 * time.Second).C { +// timeDet() +// } +//} // loadTime 根据API返回内容修正游戏时间 func loadTime(api wfAPI) { //updateWM() - var isfass bool - if api.CambionCycle.Active == "fass" { - isfass = true - } + isfass := api.CambionCycle.Active == "fass" gameTimes = [3]*gameTime{ - {sync.RWMutex{}, "地球平原", api.CetusCycle.Expiry.Local(), api.CetusCycle.IsDay, "白天", "夜晚", 100 * 60, 50 * 60}, - {sync.RWMutex{}, "金星平原", api.VallisCycle.Expiry.Local(), api.VallisCycle.IsWarm, "温暖", "寒冷", 400, 20 * 60}, - {sync.RWMutex{}, "火卫二平原", api.CambionCycle.Expiry.Local(), isfass, "fass", "vome", 100 * 60, 50 * 60}, + {Name: "地球平原", NextTime: api.CetusCycle.Expiry.Local(), Status: api.CetusCycle.IsDay, StatusTrueDes: "白天", StatusFalseDes: "夜晚", DayTime: 100 * 60, NightTime: 50 * 60}, + {Name: "金星平原", NextTime: api.VallisCycle.Expiry.Local(), Status: api.VallisCycle.IsWarm, StatusTrueDes: "温暖", StatusFalseDes: "寒冷", DayTime: 400, NightTime: 20 * 60}, + {Name: "火卫二平原", NextTime: api.CambionCycle.Expiry.Local(), Status: isfass, StatusTrueDes: "fass", StatusFalseDes: "vome", DayTime: 100 * 60, NightTime: 50 * 60}, } } diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 7cafc0f969..7e3ceeb38a 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -4,9 +4,7 @@ package warframeapi import ( "encoding/json" "fmt" - "github.com/FloatTech/floatbox/binary" "github.com/FloatTech/zbputils/img/text" - "io" "net/http" "sort" "strconv" @@ -24,11 +22,16 @@ import ( var ( wmitems map[string]items //WarFrame市场的中文名称对应的物品的字典 itmeNames []string //物品名称列表 + runtime bool //5分钟时间同步标志 //TODO:订阅功能-等待重做 //sublist map[int64]*subList //订阅列表 //sublistPath string //订阅列表存储路径 + ) +const wfapiurl = "https://api.warframestat.us/pc" //星际战甲API +const wfitemurl = "https://api.warframe.market/v1/items" //星际战甲游戏品信息列表URL + func init() { eng := control.Register("warframeapi", &ctrl.Options[*zero.Ctx]{ DisableOnDefault: false, @@ -59,26 +62,42 @@ func init() { //} else { // sublist = map[int64]*subList{} //} + //获取市场物品数据 updateWM() - //初始化游戏时间模拟 - go gameRuntime() + //获取具体的平原时间,在触发后,会启动持续时间按5分钟的时间更新模拟,以此处理短时间内请求时,时间不会变化的问题 eng.OnSuffix("平原时间").SetBlock(true). Handle(func(ctx *zero.Ctx) { - //根据具体输入的平原,来显示时间 + if !runtime { //没有进行同步,就拉取一次服务器状态 + wfapi, err := getWFAPI() + if err != nil { + ctx.SendChain(message.Text("Error:获取服务器时间失败")) + } + loadTime(wfapi) + } switch ctx.State["args"].(string) { case "地球", "夜灵": - ctx.SendChain(getTimeString(0)) + ctx.SendChain(message.Text(gameTimes[0])) case "金星", "奥布山谷": - ctx.SendChain(getTimeString(1)) + ctx.SendChain(message.Text(gameTimes[1])) case "魔胎之境", "火卫二", "火卫": - ctx.SendChain(getTimeString(2)) + ctx.SendChain(message.Text(gameTimes[2])) default: ctx.SendChain(message.Text("ERROR: 平原不存在")) - return + } + // 是否正在进行同步,没有就开启同步,有就不开启 + if !runtime { + // 设置标志位 + runtime = true + //30*10=300=5分钟 + for i := 0; i < 30; i++ { + time.Sleep(10 * time.Second) + timeDet() //5分钟内每隔10秒更新一下时间 + } + //5分钟时间同步结束 + runtime = false } }) - eng.OnFullMatch("警报").SetBlock(true). Handle(func(ctx *zero.Ctx) { wfapi, err := getWFAPI() @@ -277,25 +296,6 @@ func init() { return } name = sol[itemIndex] - //GETNUM2: //获取用户具体想查看哪个物品 - //next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() - //select { - //case <-time.After(time.Second * 15): - // ctx.SendChain(message.Text("会话已结束!")) - // return - //case e := <-next: - // msg := e.Event.Message.ExtractPlainText() - // if msg == "c" { - // ctx.SendChain(message.Text("会话已结束!")) - // return - // } - // num, err := strconv.Atoi(msg) - // if err != nil { - // ctx.SendChain(message.Text("请输入数字!(输入c结束会话)")) - // goto GETNUM2 - // } - // name = sol[num] - //} } Mf := false GETWM: @@ -303,37 +303,41 @@ func init() { msg = []string{} } sells, itmeinfo, txt, err := getWMItemOrders(wmitems[name].URLName, Mf) - if itmeinfo.ZhHans.WikiLink == "" { - ctx.Send([]message.MessageSegment{ - message.Image("https://warframe.market/static/assets/" + wmitems[name].Thumb), - message.Text(wmitems[name].ItemName, "\n"), - }) - } else { - ctx.Send([]message.MessageSegment{ - message.Image("https://warframe.market/static/assets/" + wmitems[name].Thumb), - message.Text(wmitems[name].ItemName, "\n"), - message.Text("wiki:", itmeinfo.ZhHans.WikiLink), - }) + if !Mf { + if itmeinfo.ZhHans.WikiLink == "" { + ctx.Send([]message.MessageSegment{ + message.Image("https://warframe.market/static/assets/" + wmitems[name].Thumb), + message.Text(wmitems[name].ItemName, "\n"), + }) + } else { + ctx.Send([]message.MessageSegment{ + message.Image("https://warframe.market/static/assets/" + wmitems[name].Thumb), + message.Text(wmitems[name].ItemName, "\n"), + message.Text("wiki:", itmeinfo.ZhHans.WikiLink), + }) + } } + msg = append(msg, wmitems[name].ItemName) - ismod := false + if err != nil { ctx.Send(message.Text("Error:", err.Error())) return } - if itmeinfo.ModMaxRank != 0 { - ismod = true - } - max := 5 if sells == nil { ctx.Send(message.Text("无可购买对象")) return } + ismod := false + if itmeinfo.ModMaxRank != 0 { + ismod = true + } + + max := 5 if len(sells) <= max { max = len(sells) } - for i := 0; i < max; i++ { if ismod { msg = append(msg, fmt.Sprintf("[%d](Rank:%d/%d) %dP - %s\n", i, sells[i].ModRank, itmeinfo.ModMaxRank, sells[i].Platinum, sells[i].User.IngameName)) @@ -341,6 +345,7 @@ func init() { msg = append(msg, fmt.Sprintf("[%d] %dP -%s\n", i, sells[i].Platinum, sells[i].User.IngameName)) } } + if ismod && !Mf { msg = append(msg, "请输入编号选择,或输入r获取满级报价(30s内)\n输入c直接结束会话") } else { @@ -356,10 +361,12 @@ func init() { return case e := <-next: msg := e.Event.Message.ExtractPlainText() + // 重新获取报价 if msg == "r" { Mf = true goto GETWM } + // 主动结束会话 if msg == "c" { ctx.SendChain(message.Text("会话已结束!")) return @@ -371,19 +378,13 @@ func init() { } if err == nil { if ismod { - ctx.Send(message.Text(fmt.Sprintf("/w %s Hi! I want to buy: %s(Rank:%d) for %d platinum. (warframe.market)", sells[i].User.IngameName, txt, sells[i].ModRank, sells[i].Platinum))) - + ctx.Send(message.Text("/w ", sells[i].User.IngameName, " Hi! I want to buy: ", txt, "(Rank:", sells[i].ModRank, ") for ", sells[i].Platinum, " platinum. (warframe.market)")) } else { - ctx.Send(message.Text(fmt.Sprintf("/w %s Hi! I want to buy: %s for %d platinum. (warframe.market)", sells[i].User.IngameName, txt, sells[i].Platinum))) + ctx.Send(message.Text("/w ", sells[i].User.IngameName, " Hi! I want to buy: ", txt, " for ", sells[i].Platinum, " platinum. (warframe.market)")) } - return } - - return } - }) - } // 获取搜索结果中的物品具体名称index的FutureEvent,传入ctx和一个递归次数上限,返回一个int,如果为返回内容为-1,说明会话超时,或主动结束,或超出递归 @@ -425,7 +426,7 @@ func stringArrayToImage(texts []string) message.MessageSegment { if err != nil { return message.Text("ERROR: ", err) } - return message.Image("base64://" + binary.BytesToString(b)) + return message.ImageBytes(b) } //TODO:订阅功能-等待重做 @@ -458,7 +459,7 @@ func getWFAPI() (wfAPI, error) { var wfapi wfAPI //WarFrameAPI的数据实例 var data []byte var err error - data, err = web.GetData("https://api.warframestat.us/pc") + data, err = web.GetData(wfapiurl) if err != nil { return wfapi, err } @@ -472,7 +473,12 @@ func getWFAPI() (wfAPI, error) { // 从WF市场获取物品数据信息 func updateWM() { var itmeapi wfAPIItem //WarFrame市场的数据实例 - data, err := getData("https://api.warframe.market/v1/items", map[string]string{"Accept": "application/json", "Language": "zh-hans"}) + + data, err := web.RequestDataWithHeaders(&http.Client{}, wfitemurl, "GET", func(request *http.Request) error { + request.Header.Add("Accept", "application/json") + request.Header.Add("Language", "zh-hans") + return nil + }, nil) if err != nil { panic(err) } @@ -487,7 +493,11 @@ func updateWM() { func getWMItemOrders(cnName string, onlyMaxRank bool) (orders, itemsInSet, string, error) { var wfapiio wfAPIItemsOrders - data, err := getData(fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", cnName), map[string]string{"Accept": "application/json", "Platform": "pc"}) + data, err := web.RequestDataWithHeaders(&http.Client{}, fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", cnName), "GET", func(request *http.Request) error { + request.Header.Add("Accept", "application/json") + request.Header.Add("Platform", "pc") + return nil + }, nil) if err != nil { return nil, itemsInSet{}, "", err } @@ -525,31 +535,3 @@ func loadToFuzzy(wminfo wfAPIItem) { itmeNames = append(itmeNames, v.ItemName) } } - -func getData(url string, head map[string]string) (data []byte, err error) { - //提交请求 - reqest, err := http.NewRequest("GET", url, nil) - //增加header选项 - for i, v := range head { - reqest.Header.Add(i, v) - } - if err != nil { - return nil, err - } - //处理返回结果 - //发起http请求的client实例 - client := http.Client{} - response, err := client.Do(reqest) - if err != nil { - return nil, err - } - data, err = io.ReadAll(response.Body) - response.Body.Close() - return data, err - //func jsonSave(v interface{}, path string) { - // f, _ := os.Create(path) - // defer f.Close() - // json.NewEncoder(f).Encode(v) - //} - -} From 5dc3f92731262f221ba2ce9390fe0f74d522d1f7 Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Tue, 31 Jan 2023 10:42:44 +0800 Subject: [PATCH 17/19] =?UTF-8?q?wfapi=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/main.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 7e3ceeb38a..dc7377574a 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -69,7 +69,7 @@ func init() { eng.OnSuffix("平原时间").SetBlock(true). Handle(func(ctx *zero.Ctx) { if !runtime { //没有进行同步,就拉取一次服务器状态 - wfapi, err := getWFAPI() + wfapi, err := wfapiGetData() if err != nil { ctx.SendChain(message.Text("Error:获取服务器时间失败")) } @@ -100,7 +100,7 @@ func init() { }) eng.OnFullMatch("警报").SetBlock(true). Handle(func(ctx *zero.Ctx) { - wfapi, err := getWFAPI() + wfapi, err := wfapiGetData() if err != nil { ctx.SendChain(message.Text("ERROR:", err.Error())) return @@ -213,7 +213,7 @@ func init() { eng.OnFullMatch("仲裁").SetBlock(true). Handle(func(ctx *zero.Ctx) { //通过wfapi获取仲裁信息 - wfapi, err := getWFAPI() + wfapi, err := wfapiGetData() if err != nil { ctx.SendChain(message.Text("ERROR:", err.Error())) return @@ -227,7 +227,7 @@ func init() { }) eng.OnFullMatch("每日特惠").SetBlock(true). Handle(func(ctx *zero.Ctx) { - wfapi, err := getWFAPI() + wfapi, err := wfapiGetData() if err != nil { ctx.SendChain(message.Text("ERROR:", err.Error())) @@ -258,7 +258,7 @@ func init() { // }) eng.OnFullMatch("wf时间同步").SetBlock(true). Handle(func(ctx *zero.Ctx) { - wfapi, err := getWFAPI() + wfapi, err := wfapiGetData() if err != nil { ctx.SendChain(message.Text("ERROR:", err.Error())) return @@ -291,7 +291,7 @@ func init() { ctx.SendChain(stringArrayToImage(msg)) msg = []string{} - itemIndex := getItemNameFutureEvent(ctx, 2) + itemIndex := itemNameFutureEvent(ctx, 2) if itemIndex == -1 { return } @@ -302,7 +302,7 @@ func init() { if Mf { msg = []string{} } - sells, itmeinfo, txt, err := getWMItemOrders(wmitems[name].URLName, Mf) + sells, itmeinfo, txt, err := wmItemOrders(wmitems[name].URLName, Mf) if !Mf { if itmeinfo.ZhHans.WikiLink == "" { ctx.Send([]message.MessageSegment{ @@ -388,7 +388,7 @@ func init() { } // 获取搜索结果中的物品具体名称index的FutureEvent,传入ctx和一个递归次数上限,返回一个int,如果为返回内容为-1,说明会话超时,或主动结束,或超出递归 -func getItemNameFutureEvent(ctx *zero.Ctx, count int) int { +func itemNameFutureEvent(ctx *zero.Ctx, count int) int { next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next() select { case <-time.After(time.Second * 15): @@ -413,7 +413,7 @@ func getItemNameFutureEvent(ctx *zero.Ctx, count int) int { } ctx.SendChain(message.Text("请输入数字!(输入c结束会话)[", count, "]")) count-- - return getItemNameFutureEvent(ctx, count) + return itemNameFutureEvent(ctx, count) } return num @@ -455,7 +455,7 @@ func stringArrayToImage(texts []string) message.MessageSegment { //} // 从WFapi获取数据 -func getWFAPI() (wfAPI, error) { +func wfapiGetData() (wfAPI, error) { var wfapi wfAPI //WarFrameAPI的数据实例 var data []byte var err error @@ -490,7 +490,7 @@ func updateWM() { } // 获取Warframe市场的售价表,并进行排序,cn_name为物品中文名称,onlyMaxRank表示只取最高等级的物品,返回物品售价表,物品信息,物品英文 -func getWMItemOrders(cnName string, onlyMaxRank bool) (orders, itemsInSet, string, error) { +func wmItemOrders(cnName string, onlyMaxRank bool) (orders, itemsInSet, string, error) { var wfapiio wfAPIItemsOrders data, err := web.RequestDataWithHeaders(&http.Client{}, fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", cnName), "GET", func(request *http.Request) error { From 8a520d76dab2ceb65309cddd9eac5ccf26a230ad Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Tue, 31 Jan 2023 12:34:49 +0800 Subject: [PATCH 18/19] =?UTF-8?q?wfapi=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/gametime.go | 140 ++++----------------------------- plugin/warframeapi/main.go | 91 +++++++-------------- 2 files changed, 45 insertions(+), 186 deletions(-) diff --git a/plugin/warframeapi/gametime.go b/plugin/warframeapi/gametime.go index 9971ec8c4d..c62f0bd190 100644 --- a/plugin/warframeapi/gametime.go +++ b/plugin/warframeapi/gametime.go @@ -1,12 +1,23 @@ package warframeapi import ( + "github.com/davidscholberg/go-durationfmt" "sync" "time" - - "github.com/davidscholberg/go-durationfmt" ) +// 游戏时间模拟 +type gameTime struct { + rwm sync.RWMutex + Name string `json:"name"` //时间名称 + NextTime time.Time `json:"time"` //下次更新时间 + Status bool `json:"status"` //状态 + StatusTrueDes string `json:"true_des"` //状态说明 + StatusFalseDes string `json:"false_des"` //状态说明 + DayTime int `json:"day"` //白天时长 + NightTime int `json:"night"` //夜间时长 +} + var ( gameTimes [3]*gameTime ) @@ -17,7 +28,7 @@ func (t *gameTime) String() string { "下次更新:" + t.remaintime() } -// daynight 获取当前游戏时间状态(白天/夜晚) +// 获取当前游戏时间状态(白天/夜晚) func (t *gameTime) daynight() string { t.rwm.RLock() defer t.rwm.RUnlock() @@ -27,7 +38,7 @@ func (t *gameTime) daynight() string { return t.StatusFalseDes } -// remaintime 获取下一次时间状态更新的剩余游戏时间(x分x秒) +// 获取下一次时间状态更新的剩余游戏时间(x分x秒) func (t *gameTime) remaintime() string { t.rwm.RLock() d := time.Until(t.NextTime) @@ -36,34 +47,12 @@ func (t *gameTime) remaintime() string { return durStr } -// 游戏时间模拟初始化 -//func gameTimeInit() { -// //updateWM() -// loadTime(wfapi) -// go gameRuntime() -//} - -// 游戏时间模拟 -//func gameRuntime() { -// wfapi, err := getWFAPI() -// if err != nil { -// println("ERROR:GetWFAPI失败,", err.Error()) -// return -// } -// loadTime(wfapi) -// for range time.NewTicker(10 * time.Second).C { -// timeDet() -// } -//} - -// loadTime 根据API返回内容修正游戏时间 +// 根据API返回内容修正游戏时间 func loadTime(api wfAPI) { - //updateWM() - isfass := api.CambionCycle.Active == "fass" gameTimes = [3]*gameTime{ {Name: "地球平原", NextTime: api.CetusCycle.Expiry.Local(), Status: api.CetusCycle.IsDay, StatusTrueDes: "白天", StatusFalseDes: "夜晚", DayTime: 100 * 60, NightTime: 50 * 60}, {Name: "金星平原", NextTime: api.VallisCycle.Expiry.Local(), Status: api.VallisCycle.IsWarm, StatusTrueDes: "温暖", StatusFalseDes: "寒冷", DayTime: 400, NightTime: 20 * 60}, - {Name: "火卫二平原", NextTime: api.CambionCycle.Expiry.Local(), Status: isfass, StatusTrueDes: "fass", StatusFalseDes: "vome", DayTime: 100 * 60, NightTime: 50 * 60}, + {Name: "火卫二平原", NextTime: api.CambionCycle.Expiry.Local(), Status: api.CambionCycle.Active == "fass", StatusTrueDes: "fass", StatusFalseDes: "vome", DayTime: 100 * 60, NightTime: 50 * 60}, } } @@ -85,100 +74,5 @@ func timeDet() { } v.rwm.Unlock() } - //暂时只保留时间更新功能 - //switch { - //case nt < 0: - // if v.Status { - // v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second) - // } else { - // v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second) - // } - // v.Status = !v.Status - // - // callUser(i, v.Status, 0) - //case nt < float64(5)*60: - // callUser(i, !v.Status, 5) - //case nt < float64(15)*60: - // if i == 2 && !v.Status { - // return - // } - // callUser(i, !v.Status, 15) - //} } } - -//TODO:订阅功能-待重做 -//func callUser(i int, s bool, time int) []message.MessageSegment { -// msg := []message.MessageSegment{} -// for group, sl := range sublist { -// -// switch { -// case !sl.Min15Tips && !sl.Min5Tips && time == 15: //是否 -// sublist[group].Min15Tips = true -// case sl.Min15Tips && !sl.Min5Tips && time == 5: -// sublist[group].Min5Tips = true -// case sl.Min15Tips && sl.Min5Tips && time == 0: -// sublist[group].Min15Tips = false -// sublist[group].Min5Tips = false -// default: -// return nil -// } -// //if !sl.Min15Tips && !sl.Min5Tips && time == 15 { -// // sublist[group].Min15Tips = true -// //} else if sl.Min15Tips && !sl.Min5Tips && time == 5 { -// // sublist[group].Min5Tips = true -// //} else if sl.Min15Tips && sl.Min5Tips && time == 0 { -// // sublist[group].Min15Tips = false -// // sublist[group].Min5Tips = false -// //} else { -// // return -// //} -// for qq, st := range sl.SubUser { -// if st.SubType[i] != nil { -// if *st.SubType[i] == s { -// msg = append(msg, message.At(qq)) -// } -// } -// } -// if len(msg) == 0 { -// continue -// } -// if time <= 0 { -// if s { -// msg = append(msg, message.Text(fmt.Sprintf("\n%s白天(%s)到了", gameTimes[i].Name, gameTimes[i].StatusTrueDes))) -// } else { -// msg = append(msg, message.Text(fmt.Sprintf("\n%s夜晚(%s)到了", gameTimes[i].Name, gameTimes[i].StatusFalseDes))) -// } -// } else { -// if s { -// msg = append(msg, message.Text(fmt.Sprintf("\n%s距离白天(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusTrueDes, time))) -// } else { -// msg = append(msg, message.Text(fmt.Sprintf("\n%s距离夜晚(%s)还剩下%d分钟", gameTimes[i].Name, gameTimes[i].StatusFalseDes, time))) -// } -// } -// } -// return msg -//} - -// 游戏时间模拟 -type gameTime struct { - rwm sync.RWMutex - Name string `json:"name"` //时间名称 - NextTime time.Time `json:"time"` //下次更新时间 - Status bool `json:"status"` //状态 - StatusTrueDes string `json:"true_des"` //状态说明 - StatusFalseDes string `json:"false_des"` //状态说明 - DayTime int `json:"day"` //白天时长 - NightTime int `json:"night"` //夜间时长 -} - -//type subList struct { -// SubUser map[int64]subType `json:"qq_sub"` -// Min5Tips bool `json:"min5_tips"` -// Min15Tips bool `json:"min15_tips"` -//} - -//type subType struct { -// SubType map[int]*bool `json:"sub_type"` -// SubRaid bool `json:"sub_raid"` -//} diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index dc7377574a..8f331787bc 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -4,31 +4,33 @@ package warframeapi import ( "encoding/json" "fmt" - "github.com/FloatTech/zbputils/img/text" - "net/http" - "sort" - "strconv" - "strings" - "time" - "github.com/FloatTech/floatbox/web" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" + "github.com/FloatTech/zbputils/img/text" "github.com/lithammer/fuzzysearch/fuzzy" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" + "net/http" + "sort" + "strconv" + "strings" + "sync" + "time" ) var ( wmitems map[string]items //WarFrame市场的中文名称对应的物品的字典 itmeNames []string //物品名称列表 - runtime bool //5分钟时间同步标志 - //TODO:订阅功能-等待重做 - //sublist map[int64]*subList //订阅列表 - //sublistPath string //订阅列表存储路径 - + rt runtime ) +// 时间同步状态 +type runtime struct { + rwm sync.RWMutex + enable bool //是否启动 +} + const wfapiurl = "https://api.warframestat.us/pc" //星际战甲API const wfitemurl = "https://api.warframe.market/v1/items" //星际战甲游戏品信息列表URL @@ -38,37 +40,18 @@ func init() { Help: "warframeapi\n" + "- wf时间同步\n" + "- [金星|地球|火卫二]平原时间\n" + - //"- 订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + - //"- 取消订阅[金星|地球|火卫二]平原[白天|夜晚]\n" + - //"- wf订阅检测\n" + "- .wm [物品名称]\n" + "- 仲裁\n" + "- 警报\n" + "- 每日特惠", PrivateDataFolder: "warframeapi", }) - //TODO:订阅功能-等待重做 - //订阅名单文件路径 - //sublistPath = eng.DataFolder() + "Sublist.json" - //if file.IsExist(sublistPath) { - // data, err := os.ReadFile(sublistPath) - // if err != nil { - // panic(err) - // } - // err = json.Unmarshal(data, &sublist) - // if err != nil { - // panic(err) - // } - //} else { - // sublist = map[int64]*subList{} - //} - //获取市场物品数据 updateWM() //获取具体的平原时间,在触发后,会启动持续时间按5分钟的时间更新模拟,以此处理短时间内请求时,时间不会变化的问题 eng.OnSuffix("平原时间").SetBlock(true). Handle(func(ctx *zero.Ctx) { - if !runtime { //没有进行同步,就拉取一次服务器状态 + if !rt.enable { //没有进行同步,就拉取一次服务器状态 wfapi, err := wfapiGetData() if err != nil { ctx.SendChain(message.Text("Error:获取服务器时间失败")) @@ -77,25 +60,32 @@ func init() { } switch ctx.State["args"].(string) { case "地球", "夜灵": - ctx.SendChain(message.Text(gameTimes[0])) + ctx.SendChain(message.Text(gameTimes)) case "金星", "奥布山谷": - ctx.SendChain(message.Text(gameTimes[1])) + ctx.SendChain(message.Text(gameTimes)) case "魔胎之境", "火卫二", "火卫": - ctx.SendChain(message.Text(gameTimes[2])) + ctx.SendChain(message.Text(gameTimes)) default: ctx.SendChain(message.Text("ERROR: 平原不存在")) } // 是否正在进行同步,没有就开启同步,有就不开启 - if !runtime { + if !rt.enable { // 设置标志位 - runtime = true + rt.rwm.Lock() + if rt.enable { + return + } + rt.enable = true + rt.rwm.Unlock() //30*10=300=5分钟 for i := 0; i < 30; i++ { time.Sleep(10 * time.Second) timeDet() //5分钟内每隔10秒更新一下时间 } //5分钟时间同步结束 - runtime = false + rt.rwm.Lock() + rt.enable = false + rt.rwm.Unlock() } }) eng.OnFullMatch("警报").SetBlock(true). @@ -429,31 +419,6 @@ func stringArrayToImage(texts []string) message.MessageSegment { return message.ImageBytes(b) } -//TODO:订阅功能-等待重做 -// 添加用户订阅 -//func addUseSub(qq int64, qqGroup int64, stype int, status bool) { -// if sb, ok := sublist[qqGroup]; ok { -// if st, ok := sb.SubUser[qq]; ok { -// st.SubType[stype] = &status -// } else { -// sublist[qqGroup].SubUser[qq] = subType{map[int]*bool{stype: &status}, false} -// } -// } else { -// sublist[qqGroup] = &subList{map[int64]subType{qq: {map[int]*bool{stype: &status}, false}}, false, false} -// } -// jsonSave(sublist, sublistPath) -//} -// -//// 移除用户订阅 -//func removeUseSub(qq int64, qqGroup int64, stype int) { -// if sb, ok := sublist[qqGroup]; ok { -// if _, ok := sb.SubUser[qq]; ok { -// delete(sublist[qqGroup].SubUser[qq].SubType, stype) -// jsonSave(sublist, sublistPath) -// } -// } -//} - // 从WFapi获取数据 func wfapiGetData() (wfAPI, error) { var wfapi wfAPI //WarFrameAPI的数据实例 From 670c9df30e224584144ef63cce0b8ec2dad335cf Mon Sep 17 00:00:00 2001 From: GenesisAN <501946815@qq.com> Date: Tue, 31 Jan 2023 12:52:34 +0800 Subject: [PATCH 19/19] =?UTF-8?q?wfapi=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/warframeapi/main.go | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/plugin/warframeapi/main.go b/plugin/warframeapi/main.go index 8f331787bc..913cb98806 100644 --- a/plugin/warframeapi/main.go +++ b/plugin/warframeapi/main.go @@ -4,6 +4,7 @@ package warframeapi import ( "encoding/json" "fmt" + "github.com/FloatTech/floatbox/binary" "github.com/FloatTech/floatbox/web" ctrl "github.com/FloatTech/zbpctrl" "github.com/FloatTech/zbputils/control" @@ -60,11 +61,11 @@ func init() { } switch ctx.State["args"].(string) { case "地球", "夜灵": - ctx.SendChain(message.Text(gameTimes)) + ctx.SendChain(message.Text(gameTimes[0])) case "金星", "奥布山谷": - ctx.SendChain(message.Text(gameTimes)) + ctx.SendChain(message.Text(gameTimes[1])) case "魔胎之境", "火卫二", "火卫": - ctx.SendChain(message.Text(gameTimes)) + ctx.SendChain(message.Text(gameTimes[2])) default: ctx.SendChain(message.Text("ERROR: 平原不存在")) } @@ -72,20 +73,24 @@ func init() { if !rt.enable { // 设置标志位 rt.rwm.Lock() - if rt.enable { + if rt.enable { //预检测,防止其他线程同时进来 return } rt.enable = true rt.rwm.Unlock() - //30*10=300=5分钟 - for i := 0; i < 30; i++ { - time.Sleep(10 * time.Second) - timeDet() //5分钟内每隔10秒更新一下时间 - } - //5分钟时间同步结束 - rt.rwm.Lock() - rt.enable = false - rt.rwm.Unlock() + + go func() { + //30*10=300=5分钟 + for i := 0; i < 30; i++ { + time.Sleep(10 * time.Second) + timeDet() //5分钟内每隔10秒更新一下时间 + } + //5分钟时间同步结束 + rt.rwm.Lock() + rt.enable = false + rt.rwm.Unlock() + }() + } }) eng.OnFullMatch("警报").SetBlock(true). @@ -416,7 +421,7 @@ func stringArrayToImage(texts []string) message.MessageSegment { if err != nil { return message.Text("ERROR: ", err) } - return message.ImageBytes(b) + return message.Image("base64://" + binary.BytesToString(b)) } // 从WFapi获取数据