From 46e73741fab9d1a26b0b788ed3bb31aaf00454ae Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sat, 2 Sep 2023 10:07:06 +0800
Subject: [PATCH 01/12] Add files via upload
---
plugin/mcfish/fish.go | 327 +++++++++++++++++++++++
plugin/mcfish/main.go | 507 +++++++++++++++++++++++++++++++++++
plugin/mcfish/pack.go | 386 +++++++++++++++++++++++++++
plugin/mcfish/pole.go | 478 +++++++++++++++++++++++++++++++++
plugin/mcfish/store.go | 593 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 2291 insertions(+)
create mode 100644 plugin/mcfish/fish.go
create mode 100644 plugin/mcfish/main.go
create mode 100644 plugin/mcfish/pack.go
create mode 100644 plugin/mcfish/pole.go
create mode 100644 plugin/mcfish/store.go
diff --git a/plugin/mcfish/fish.go b/plugin/mcfish/fish.go
new file mode 100644
index 0000000000..5614d20714
--- /dev/null
+++ b/plugin/mcfish/fish.go
@@ -0,0 +1,327 @@
+// Package mcfish 钓鱼模拟器
+package mcfish
+
+import (
+ "math/rand"
+ "strconv"
+ "time"
+
+ "github.com/FloatTech/AnimeAPI/wallet"
+ "github.com/FloatTech/zbputils/ctxext"
+ "github.com/sirupsen/logrus"
+ zero "github.com/wdvxdr1123/ZeroBot"
+ "github.com/wdvxdr1123/ZeroBot/message"
+)
+
+func init() {
+ engine.OnRegex(`^进行(([1-5]\d*)次)?钓鱼$`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ fishNumber := 1
+ info := ctx.State["regex_matched"].([]string)[2]
+ if info != "" {
+ number, err := strconv.Atoi(info)
+ if err != nil || number > 50 {
+ ctx.SendChain(message.Text("请输入正确的次数"))
+ return
+ }
+ fishNumber = number
+ }
+ residue, err := dbdata.updateFishInfo(uid, fishNumber)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.1]:", err))
+ return
+ }
+ if residue == 0 {
+ ctx.SendChain(message.Text("今天你已经进行", fishLimit, "次钓鱼了.\n游戏虽好,但请不要沉迷。"))
+ return
+ }
+ fishNumber = residue
+ equipInfo, err := dbdata.getUserEquip(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.2]:", err))
+ return
+ }
+ if equipInfo == (equip{}) {
+ ok, err := dbdata.checkEquipFor(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.2.1]:", err))
+ return
+ }
+ if !ok {
+ ctx.SendChain(message.At(uid), message.Text("请装备鱼竿后钓鱼", err))
+ return
+ }
+ ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你尚未装备鱼竿,是否花费100购买鱼竿?\n回答\"是\"或\"否\""))
+ // 等待用户下一步选择
+ recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(是|否)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel()
+ buy := false
+ for {
+ select {
+ case <-time.After(time.Second * 120):
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("等待超时,取消钓鱼")))
+ return
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "否" {
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("已取消购买")))
+ return
+ }
+ money := wallet.GetWalletOf(uid)
+ if money < 100 {
+ ctx.SendChain(message.Text("你钱包当前只有", money, "ATRI币,无法完成支付"))
+ return
+ }
+ err = wallet.InsertWalletOf(uid, -100)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.3]:", err))
+ return
+ }
+ equipInfo = equip{
+ ID: uid,
+ Equip: "木竿",
+ Durable: 30,
+ }
+ err = dbdata.updateUserEquip(equipInfo)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.4]:", err))
+ return
+ }
+ err = dbdata.setEquipFor(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.4]:", err))
+ return
+ }
+ buy = true
+ }
+ if buy {
+ break
+ }
+ }
+ } else if equipInfo.Durable < fishNumber {
+ fishNumber = equipInfo.Durable
+ }
+ msg := ""
+ if equipInfo.Equip != "美西螈" {
+ equipInfo.Durable -= fishNumber
+ err = dbdata.updateUserEquip(equipInfo)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.5]:", err))
+ return
+ }
+ if equipInfo.Durable < 10 {
+ msg = "(你的鱼竿耐久仅剩" + strconv.Itoa(equipInfo.Durable) + ")"
+ }
+ } else {
+ fishNmae, err := dbdata.pickFishFor(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.5.1]:", err))
+ return
+ }
+ if fishNmae == "" {
+ equipInfo.Durable = 0
+ err = dbdata.updateUserEquip(equipInfo)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.5]:", err))
+ }
+ ctx.SendChain(message.Text("美西螈因为没吃到鱼,钓鱼时一直没回来,你失去了美西螈"))
+ return
+ }
+ msg = "(美西螈吃掉了一条" + fishNmae + ")"
+ }
+ waitTime := 120 / (equipInfo.Induce + 1)
+ ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你开始去钓鱼了,请耐心等待鱼上钩(预计要", time.Second*time.Duration(waitTime), ")"))
+ timer := time.NewTimer(time.Second * time.Duration(rand.Intn(waitTime)+1))
+ for {
+ <-timer.C
+ timer.Stop()
+ break
+ }
+ // 概率
+ wasteProbability := 41 + equipInfo.Favor*10
+ poleProbability := 11 + equipInfo.Favor*3
+ bookProbability := 1 + equipInfo.Favor*1
+ // 钓到鱼的范围
+ number, err := dbdata.getNumberFor(uid, "鱼")
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.5.1]:", err))
+ return
+ }
+ getFishMaxDy := 9
+ getFishMinDy := 2
+ getFishMaxDx := 9
+ getFishMinDx := 1
+ if number > 100 || equipInfo.Equip == "美西螈" {
+ getFishMaxDy = 10
+ getFishMinDy = 1
+ getFishMaxDx = 10
+ getFishMinDx = 0
+ }
+ // 钓鱼结算
+ thingNameList := make(map[string]int)
+ picName := ""
+ for i := fishNumber; i > 0; i-- {
+ fishDx := rand.Intn(11)
+ fishDy := rand.Intn(11)
+ if fishDx < getFishMinDx || fishDx > getFishMaxDx || fishDy < getFishMinDy || fishDy > getFishMaxDy {
+ if fishNumber == 1 {
+ ctx.SendChain(message.At(uid), message.Text("很遗憾你没有钓到鱼", msg))
+ return
+ }
+ thingNameList["空竿"]++
+ continue
+ }
+ dice := rand.Intn(100)
+ switch {
+ case dice >= wasteProbability: // 垃圾
+ waste := wasteList[rand.Intn(len(wasteList))]
+ money := 10
+ if equipInfo.Equip == "美西螈" {
+ money *= 3
+ }
+ err := wallet.InsertWalletOf(uid, money)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.9]:", err))
+ return
+ }
+ picName = waste
+ thingNameList[waste]++
+ if fishNumber == 1 {
+ msg = "为河流净化做出了贡献,\n给予" + strconv.Itoa(money) + "奖励金\n" + msg
+ }
+ case dice <= bookProbability:
+ picName = "book"
+ thingName := "诱钓"
+ dice := rand.Intn(100)
+ switch {
+ case dice == 0:
+ picName = "美西螈"
+ thingName = "美西螈"
+ case dice == 1:
+ picName = "唱片"
+ thingName = "唱片"
+ case dice < 41 && dice > 1:
+ thingName = "海之眷顾"
+ }
+ books, err := dbdata.getUserThingInfo(uid, thingName)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.6]:", err))
+ return
+ }
+ if len(books) == 0 {
+ books = append(books, article{
+ Duration: time.Now().Unix()*100 + int64(i),
+ Type: "article",
+ Name: thingName,
+ })
+ }
+ if thingName == "美西螈" {
+ books[0].Type = "pole"
+ books[0].Other = "999/0/0/0"
+ }
+ number := 1
+ if equipInfo.Equip == "美西螈" && thingName != "美西螈" {
+ number += 2
+ }
+ books[0].Number += number
+ err = dbdata.updateUserThingInfo(uid, books[0])
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.7]:", err))
+ return
+ }
+ thingNameList[thingName] += number
+ case dice > bookProbability && dice <= poleProbability:
+ poleNmae := "木竿"
+ dice := rand.Intn(100)
+ switch {
+ case dice >= 10 && dice < 30:
+ poleNmae = "铁竿"
+ case dice >= 4 && dice < 10:
+ poleNmae = "金竿"
+ case dice >= 1 && dice < 4:
+ poleNmae = "钻石竿"
+ case dice == 0:
+ poleNmae = "下界合金竿竿竿"
+ }
+ newPole := article{
+ Duration: time.Now().Unix()*100 + int64(i),
+ Type: "pole",
+ Name: poleNmae,
+ Number: 1,
+ Other: strconv.Itoa(rand.Intn(equipAttribute[poleNmae])+1) +
+ "/" + strconv.Itoa(rand.Intn(10)) + "/" +
+ strconv.Itoa(rand.Intn(3)) + "/" + strconv.Itoa(rand.Intn(2)),
+ }
+ err = dbdata.updateUserThingInfo(uid, newPole)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.8]:", err))
+ return
+ }
+ picName = poleNmae
+ thingNameList[poleNmae]++
+ default:
+ fishName := ""
+ dice = rand.Intn(100)
+ switch {
+ case dice == 99:
+ fishName = "墨鱼"
+ case dice >= 30 && dice != 99:
+ fishName = "鳕鱼"
+ case dice >= 10 && dice < 30:
+ fishName = "鲑鱼"
+ case dice >= 4 && dice < 10:
+ fishName = "热带鱼"
+ case dice >= 1 && dice < 4:
+ fishName = "河豚"
+ default:
+ fishName = "鹦鹉螺"
+ }
+ fishes, err := dbdata.getUserThingInfo(uid, fishName)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.10]:", err))
+ return
+ }
+ if len(fishes) == 0 {
+ fishes = append(fishes, article{
+ Duration: time.Now().Unix()*100 + int64(i),
+ Type: "fish",
+ Name: fishName,
+ })
+ }
+ number := 1
+ if equipInfo.Equip == "美西螈" || equipInfo.Equip == "三叉戟" {
+ number += 2
+ }
+ fishes[0].Number += number
+ err = dbdata.updateUserThingInfo(uid, fishes[0])
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.11]:", err))
+ return
+ }
+ picName = fishName
+ thingNameList[fishName] += number
+ }
+ }
+ if len(thingNameList) == 1 {
+ thingName := ""
+ for name := range thingNameList {
+ thingName = name
+ }
+ pic, err := engine.GetLazyData(picName+".png", false)
+ if err != nil {
+ logrus.Warnln("[mcfish]error:", err)
+ ctx.SendChain(message.At(uid), message.Text("恭喜你钓到了", thingName, "\n", msg))
+ return
+ }
+ ctx.SendChain(message.At(uid), message.Text("恭喜你钓到了", thingName, "\n", msg), message.ImageBytes(pic))
+ return
+ }
+ msgInfo := make(message.Message, 0, 3+len(thingNameList))
+ msgInfo = append(msgInfo, message.Reply(ctx.Event.MessageID), message.Text("你进行了", fishNumber, "次钓鱼,结果如下:\n"))
+ for name, number := range thingNameList {
+ msgInfo = append(msgInfo, message.Text(name, " : ", number, "\n"))
+ }
+ msgInfo = append(msgInfo, message.Text(msg))
+ ctx.Send(msgInfo)
+ })
+}
diff --git a/plugin/mcfish/main.go b/plugin/mcfish/main.go
new file mode 100644
index 0000000000..574f0401f0
--- /dev/null
+++ b/plugin/mcfish/main.go
@@ -0,0 +1,507 @@
+// Package mcfish 钓鱼模拟器
+package mcfish
+
+import (
+ "math/rand"
+ "strconv"
+ "sync"
+ "time"
+
+ fcext "github.com/FloatTech/floatbox/ctxext"
+ sql "github.com/FloatTech/sqlite"
+ ctrl "github.com/FloatTech/zbpctrl"
+ "github.com/FloatTech/zbputils/control"
+ "github.com/FloatTech/zbputils/ctxext"
+ zero "github.com/wdvxdr1123/ZeroBot"
+ "github.com/wdvxdr1123/ZeroBot/message"
+)
+
+type fishdb struct {
+ db *sql.Sqlite
+ sync.RWMutex
+}
+
+/*
+type userInfo struct {
+ UserID int64 // QQ
+ Bait int // 鱼饵
+ // 鱼竿 10% 装备/耐久/维修次数/诱钓/眷顾
+ WoodenPole string // 木竿属性 70%
+ IronPole string // 铁竿属性 20%
+ GoldenPole string // 金竿属性 6%
+ DiamondPole string // 钻石竿属性 3%
+ NetherPole string // 下界合金竿属性 1%
+ // 鱼 30%
+ Cod int // 鳕鱼数量 69%
+ Salmon int // 鲑鱼数量 20%
+ Tropical int // 热带鱼 6%
+ Globe int // 河豚 3%
+ Nautilus int // 鹦鹉螺 1%
+ Nautilus int // 墨鱼1%
+ // 宝藏 1%
+ Induce int // 诱钓 59%
+ Favor int // 眷顾 39%
+ Record int // 唱片 1%
+ Record int // 美西螈 1%
+ // 垃圾 59%
+ Leaf int // 荷叶 10%
+ Rod int // 木棍 10%
+ bamboo int // 竹子 10%
+ Shoe int // 鞋子 10%
+ Bottle int // 瓶子 10%
+ Hanger int // 拌线钩 10%
+ Bone int // 骨头 10%
+ Leather int // 皮革 10%
+ Carrion int // 腐肉 10%
+ Bowl int // 碗 10%
+}
+*/
+
+type equip struct {
+ ID int64 // 用户
+ Equip string // 装备名称
+ Durable int // 耐久
+ Maintenance int // 维修次数
+ Induce int // 诱钓等级
+ Favor int // 眷顾等级
+}
+
+type article struct {
+ Duration int64
+ Name string
+ Number int
+ Other string // 耐久/维修次数/诱钓/眷顾
+ Type string
+}
+
+type store struct {
+ Duration int64
+ Name string
+ Number int
+ Price int
+ Other string // 耐久/维修次数/诱钓/眷顾
+ Type string
+}
+
+type fishState struct {
+ ID int64
+ Duration int64
+ Fish int
+ Equip int
+}
+
+type storeDiscount struct {
+ Name string
+ Discount int
+}
+
+var (
+ equipAttribute = map[string]int{
+ "木竿": 30, "铁竿": 50, "金竿": 70, "钻石竿": 100, "下界合金竿": 150, "三叉戟": 300, "美西螈": 999,
+ }
+ thingPice = map[string]int{
+ "鳕鱼": 10, "鲑鱼": 50, "热带鱼": 100, "河豚": 300, "鹦鹉螺": 500, "墨鱼": 500,
+ "木竿": 100, "铁竿": 300, "金竿": 700, "钻石竿": 1500, "下界合金竿": 3100, "三叉戟": 4000,
+ "诱钓": 1000, "海之眷顾": 2500, "唱片": 3000, "美西螈": 3000,
+ }
+ discount = map[string]int{
+ "鳕鱼": 100, "鲑鱼": 100, "热带鱼": 100, "河豚": 100, "鹦鹉螺": 100, "墨鱼": 100,
+ "木竿": 100, "铁竿": 100, "金竿": 100, "钻石竿": 100, "下界合金竿": 100, "三叉戟": 100,
+ "诱钓": 100, "海之眷顾": 100, "唱片": 100, "美西螈": 100,
+ }
+ fishList = []string{"鳕鱼", "鲑鱼", "热带鱼"}
+ wasteList = []string{"海草", "木棍", "帽子", "鞋子", "瓶子", "拌线钩", "骨头", "皮革", "腐肉", "碗"}
+ enchantLevel = []string{"0", "Ⅰ", "Ⅱ", "Ⅲ"}
+ dbdata = &fishdb{
+ db: &sql.Sqlite{},
+ }
+ engine = control.Register("mcfish", &ctrl.Options[*zero.Ctx]{
+ DisableOnDefault: false,
+ Brief: "钓鱼",
+ Help: "一款钓鱼模拟器\n----------指令----------\n" +
+ "- 钓鱼看板/钓鱼商店\n- 购买xxx\n- 购买xxx [数量]\n- 出售xxx\n- 出售xxx [数量]\n" +
+ "- 钓鱼背包\n- 装备[xx竿|三叉戟|美西螈]\n- 附魔[诱钓|海之眷顾]\n- 修复鱼竿\n- 合成[xx竿|三叉戟]\n" +
+ "- 进行钓鱼\n- 进行n次钓鱼\n" +
+ "规则:\n1.每日的商店价格是波动的!!如何最大化收益自己考虑一下喔\n" +
+ "2.装备信息:\n-> 木竿 : 耐久上限:30 均价:100 上钩概率:7%\n-> 铁竿 : 耐久上限:50 均价:300 上钩概率:2%\n-> 金竿 : 耐久上限:70 均价700 上钩概率:0.6%\n" +
+ "-> 钻石竿 : 耐久上限:100 均价1500 上钩概率:0.3%\n-> 下界合金竿 : 耐久上限:150 均价3100 上钩概率:0.1%\n-> 三叉戟 : 可使钓的鱼类物品数量变成3 耐久上限:300 均价4000 只能合成和交易\n" +
+ "3.附魔书信息:\n-> 诱钓 : 减少上钩时间. 均价:1000, 上钩概率:0.59%\n-> 海之眷顾 : 增加宝藏上钩概率. 均价:2500, 上钩概率:0.39%\n" +
+ "4.稀有物品:\n-> 唱片 : 出售物品时使用该物品使价格翻倍. 均价:3000, 上钩概率:0.01%\n-> 美西螈 : 可装备,获得隐形[钓鱼佬]buff,并让钓到除鱼竿和美西螈外的物品数量变成3,无耐久上限.不可修复/附魔,每次钓鱼消耗任意一鱼类物品. 均价:3000, 上钩概率:0.01%\n" +
+ "5.鱼类信息:\n-> 鳕鱼 : 均价:10 上钩概率:20.7%\n-> 鲑鱼 : 均价:50 上钩概率:6%\n-> 热带鱼 : 均价:100 上钩概率:1.8%\n-> 河豚 : 均价:300 上钩概率:0.9%\n-> 鹦鹉螺 : 均价:500 上钩概率:0.3%\n-> 墨鱼 : 均价:500 上钩概率:0.3%\n" +
+ "6.物品BUFF:\n-> 钓鱼佬 : 当背包名字含有'鱼'的物品数量超过100时激活,钓到物品概率提高至90%\n-> 修复大师 : 当背包鱼竿数量超过10时激活,修复物品时耐久百分百继承\n" +
+ "7.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率70%,继承附魔等级合/3的等级\n" +
+ "8.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为56%\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿",
+ PublicDataFolder: "McFish",
+ }).ApplySingle(ctxext.DefaultSingle)
+ getdb = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
+ dbdata.db.DBPath = engine.DataFolder() + "fishdata.db"
+ err := dbdata.db.Open(time.Hour * 24)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at main.go.1]:", err))
+ return false
+ }
+ return true
+ })
+ fishLimit = 50 // 钓鱼次数上限
+)
+
+/*
+func init() {
+ for name := range thingPice {
+ _, _ = engine.GetLazyData(name+".png", false)
+ }
+}
+*/
+// 获取装备信息
+func (sql *fishdb) getUserEquip(uid int64) (userInfo equip, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ err = sql.db.Create("equips", &userInfo)
+ if err != nil {
+ return
+ }
+ if !sql.db.CanFind("equips", "where ID = "+strconv.FormatInt(uid, 10)) {
+ return
+ }
+ err = sql.db.Find("equips", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
+ return
+}
+
+// 更新装备信息
+func (sql *fishdb) updateUserEquip(userInfo equip) (err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ err = sql.db.Create("equips", &userInfo)
+ if err != nil {
+ return
+ }
+ if userInfo.Durable == 0 {
+ return sql.db.Del("equips", "where ID = "+strconv.FormatInt(userInfo.ID, 10))
+ }
+ return sql.db.Insert("equips", &userInfo)
+}
+
+// 获取用户背包信息
+func (sql *fishdb) getUserPack(uid int64) (thingInfos []article, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := article{}
+ err = sql.db.Create(strconv.FormatInt(uid, 10)+"Pack", &userInfo)
+ if err != nil {
+ return
+ }
+ count, err := sql.db.Count(strconv.FormatInt(uid, 10) + "Pack")
+ if err != nil {
+ return
+ }
+ if count == 0 {
+ return
+ }
+ err = sql.db.FindFor(strconv.FormatInt(uid, 10)+"Pack", &userInfo, "ORDER by Type, Name, Other ASC", func() error {
+ thingInfos = append(thingInfos, userInfo)
+ return nil
+ })
+ return
+}
+
+// 获取用户物品信息
+func (sql *fishdb) getUserThingInfo(uid int64, thing string) (thingInfos []article, err error) {
+ name := strconv.FormatInt(uid, 10) + "Pack"
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := article{}
+ err = sql.db.Create(name, &userInfo)
+ if err != nil {
+ return
+ }
+ count, err := sql.db.Count(name)
+ if err != nil {
+ return
+ }
+ if count == 0 {
+ return
+ }
+ if !sql.db.CanFind(name, "where Name = '"+thing+"'") {
+ return
+ }
+ err = sql.db.FindFor(name, &userInfo, "where Name = '"+thing+"'", func() error {
+ thingInfos = append(thingInfos, userInfo)
+ return nil
+ })
+ return
+}
+
+// 更新用户物品信息
+func (sql *fishdb) updateUserThingInfo(uid int64, userInfo article) (err error) {
+ name := strconv.FormatInt(uid, 10) + "Pack"
+ sql.Lock()
+ defer sql.Unlock()
+ err = sql.db.Create(name, &userInfo)
+ if err != nil {
+ return
+ }
+ if userInfo.Number == 0 {
+ return sql.db.Del(name, "where Duration = "+strconv.FormatInt(userInfo.Duration, 10))
+ }
+ return sql.db.Insert(name, &userInfo)
+}
+
+// 获取商店信息
+func (sql *fishdb) getStoreInfo() (thingInfos []store, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ thingInfo := store{}
+ err = sql.db.Create("store", &thingInfo)
+ if err != nil {
+ return
+ }
+ count, err := sql.db.Count("store")
+ if err != nil {
+ return
+ }
+ if count == 0 {
+ return
+ }
+ err = sql.db.FindFor("store", &thingInfo, "ORDER by Type, Name, Price ASC", func() error {
+ thingInfos = append(thingInfos, thingInfo)
+ return nil
+ })
+ return
+}
+
+// 获取商店物品信息
+func (sql *fishdb) getStoreThingInfo(thing string) (thingInfos []store, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ thingInfo := store{}
+ err = sql.db.Create("store", &thingInfo)
+ if err != nil {
+ return
+ }
+ count, err := sql.db.Count("store")
+ if err != nil {
+ return
+ }
+ if count == 0 {
+ return
+ }
+ if !sql.db.CanFind("store", "where Name = '"+thing+"'") {
+ return
+ }
+ err = sql.db.FindFor("store", &thingInfo, "where Name = '"+thing+"'", func() error {
+ thingInfos = append(thingInfos, thingInfo)
+ return nil
+ })
+ return
+}
+
+// 更新商店信息
+func (sql *fishdb) updateStoreInfo(thingInfo store) (err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ err = sql.db.Create("store", &thingInfo)
+ if err != nil {
+ return
+ }
+ if thingInfo.Number == 0 {
+ return sql.db.Del("store", "where Duration = "+strconv.FormatInt(thingInfo.Duration, 10))
+ }
+ return sql.db.Insert("store", &thingInfo)
+}
+
+// 更新上限信息
+func (sql *fishdb) updateFishInfo(uid int64, number int) (residue int, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := fishState{ID: uid}
+ err = sql.db.Create("fishState", &userInfo)
+ if err != nil {
+ return 0, err
+ }
+ _ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
+ if time.Unix(userInfo.Duration, 0).Day() != time.Now().Day() {
+ userInfo.Fish = 0
+ userInfo.Duration = time.Now().Unix()
+ }
+ if userInfo.Fish >= fishLimit {
+ return 0, nil
+ }
+ residue = number
+ if userInfo.Fish+number > fishLimit {
+ residue = fishLimit - userInfo.Fish
+ number = residue
+ }
+ userInfo.Fish += number
+ err = sql.db.Insert("fishState", &userInfo)
+ return
+}
+
+// 更新上限信息
+func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ err = sql.db.Create("stroeDiscount", &storeDiscount{})
+ if err != nil {
+ return false, err
+ }
+ lastTime := storeDiscount{}
+ _ = sql.db.Find("stroeDiscount", &lastTime, "where Name = 'lastTime'")
+ refresh := false
+ timeNow := time.Now().Day()
+ if timeNow != lastTime.Discount {
+ lastTime = storeDiscount{
+ Name: "lastTime",
+ Discount: timeNow,
+ }
+ err = sql.db.Insert("stroeDiscount", &lastTime)
+ if err != nil {
+ return false, err
+ }
+ refresh = true
+ }
+ for name := range thingPice {
+ thing := storeDiscount{}
+ switch refresh {
+ case true:
+ thingDiscount := 50 + rand.Intn(150)
+ thing = storeDiscount{
+ Name: name,
+ Discount: thingDiscount,
+ }
+ err = sql.db.Insert("stroeDiscount", &thing)
+ if err != nil {
+ return
+ }
+ default:
+ err = sql.db.Find("stroeDiscount", &thing, "where Name = '"+name+"'")
+ if err != nil {
+ return
+ }
+ }
+ if thing.Discount != 0 {
+ discount[name] = thing.Discount
+ } else {
+ discount[name] = 100
+ }
+ }
+ if refresh { // 每天调控1种鱼
+ thingInfo := store{}
+ err = sql.db.Create("store", &thingInfo)
+ if err != nil {
+ return
+ }
+ fish := fishList[rand.Intn(len(fishList))]
+ _ = sql.db.Find("store", &thingInfo, "where Name = '"+fish+"'")
+ if thingInfo == (store{}) {
+ thingInfo.Duration = time.Now().Unix()
+ thingInfo.Type = "fish"
+ thingInfo.Name = fish
+ thingInfo.Price = thingPice[fish] * discount[fish] / 100
+ }
+ thingInfo.Number -= (discount[fish] - 100)
+ if thingInfo.Number < 1 {
+ thingInfo.Number = 1
+ }
+ _ = sql.db.Insert("store", &thingInfo)
+ }
+ return true, nil
+}
+
+func (sql *fishdb) getNumberFor(uid int64, thing string) (number int, err error) {
+ name := strconv.FormatInt(uid, 10) + "Pack"
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := article{}
+ err = sql.db.Create(name, &userInfo)
+ if err != nil {
+ return
+ }
+ count, err := sql.db.Count(name)
+ if err != nil {
+ return
+ }
+ if count == 0 {
+ return
+ }
+ if !sql.db.CanFind(name, "where Name glob '*"+thing+"*'") {
+ return
+ }
+ err = sql.db.FindFor(name, &article{}, "where Name glob '*"+thing+"*'", func() error {
+ number++
+ return nil
+ })
+ return
+}
+
+func (sql *fishdb) checkEquipFor(uid int64) (ok bool, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := fishState{ID: uid}
+ err = sql.db.Create("fishState", &userInfo)
+ if err != nil {
+ return false, err
+ }
+ if !sql.db.CanFind("fishState", "where ID = "+strconv.FormatInt(uid, 10)) {
+ return true, nil
+ }
+ err = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
+ if err != nil {
+ return false, err
+ }
+ if userInfo.Equip > 3 {
+ return false, nil
+ }
+ return true, nil
+}
+
+func (sql *fishdb) setEquipFor(uid int64) (err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := fishState{ID: uid}
+ err = sql.db.Create("fishState", &userInfo)
+ if err != nil {
+ return err
+ }
+ _ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
+ if err != nil {
+ return err
+ }
+ userInfo.Equip++
+ return sql.db.Insert("fishState", &userInfo)
+}
+
+func (sql *fishdb) pickFishFor(uid int64) (fishName string, err error) {
+ name := strconv.FormatInt(uid, 10) + "Pack"
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := article{}
+ err = sql.db.Create(name, &userInfo)
+ if err != nil {
+ return
+ }
+ count, err := sql.db.Count(name)
+ if err != nil {
+ return
+ }
+ if count == 0 {
+ return
+ }
+ if !sql.db.CanFind(name, "where Type is 'fish'") {
+ return
+ }
+ fishTypes := make([]article, 0, count)
+ fishInfo := article{}
+ err = sql.db.FindFor(name, &fishInfo, "where Type is 'fish'", func() error {
+ fishTypes = append(fishTypes, fishInfo)
+ return nil
+ })
+ if err != nil {
+ return
+ }
+ if len(fishTypes) == 0 {
+ return
+ }
+ randNumber := rand.Intn(len(fishTypes))
+ fishTypes[randNumber].Number--
+ return fishTypes[randNumber].Name, sql.db.Insert(name, &fishTypes[randNumber])
+}
diff --git a/plugin/mcfish/pack.go b/plugin/mcfish/pack.go
new file mode 100644
index 0000000000..0ec4f5cc53
--- /dev/null
+++ b/plugin/mcfish/pack.go
@@ -0,0 +1,386 @@
+// Package mcfish 钓鱼模拟器
+package mcfish
+
+import (
+ "bytes"
+ "errors"
+ "image"
+ "image/color"
+ "strconv"
+ "strings"
+ "sync"
+
+ "github.com/FloatTech/AnimeAPI/wallet"
+ "github.com/FloatTech/floatbox/file"
+ "github.com/FloatTech/floatbox/math"
+ "github.com/FloatTech/gg"
+ "github.com/FloatTech/imgfactory"
+ "github.com/FloatTech/zbputils/control"
+ "github.com/FloatTech/zbputils/ctxext"
+ "github.com/FloatTech/zbputils/img/text"
+ zero "github.com/wdvxdr1123/ZeroBot"
+ "github.com/wdvxdr1123/ZeroBot/message"
+)
+
+func init() {
+ engine.OnFullMatch("钓鱼背包", getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ equipInfo, err := dbdata.getUserEquip(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pack.go.1]:", err))
+ return
+ }
+ articles, err := dbdata.getUserPack(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pack.go.2]:", err))
+ return
+ }
+ pic, err := drawPackImage(uid, equipInfo, articles)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pack.go.3]:", err))
+ return
+ }
+ ctx.SendChain(message.ImageBytes(pic))
+ })
+}
+
+func drawPackImage(uid int64, equipInfo equip, articles []article) (imagePicByte []byte, err error) {
+ fontdata, err := file.GetLazyData(text.BoldFontFile, control.Md5File, true)
+ if err != nil {
+ return nil, err
+ }
+ var (
+ wg sync.WaitGroup
+ equipBlock image.Image // 装备信息
+ packBlock image.Image // 背包信息
+ )
+ wg.Add(1)
+ // 绘制ID
+ go func() {
+ defer wg.Done()
+ if equipInfo == (equip{}) {
+ equipBlock, err = drawEquipEmptyBlock(fontdata)
+ } else {
+ equipBlock, err = drawEquipInfoBlock(equipInfo, fontdata)
+ }
+ if err != nil {
+ return
+ }
+ }()
+ wg.Add(1)
+ // 绘制基本信息
+ go func() {
+ defer wg.Done()
+ if len(articles) == 0 {
+ packBlock, err = drawArticleEmptyBlock(fontdata)
+ } else {
+ packBlock, err = drawArticleInfoBlock(uid, articles, fontdata)
+ }
+ if err != nil {
+ return
+ }
+ }()
+ wg.Wait()
+ if equipBlock == nil || packBlock == nil {
+ err = errors.New("生成图片失败,数据缺失")
+ return
+ }
+ // 计算图片高度
+ backDX := 1020
+ backDY := 10 + equipBlock.Bounds().Dy() + 10 + packBlock.Bounds().Dy() + 10
+ canvas := gg.NewContext(backDX, backDY)
+
+ // 画底色
+ canvas.DrawRectangle(0, 0, float64(backDX), float64(backDY))
+ canvas.SetRGBA255(150, 150, 150, 255)
+ canvas.Fill()
+ canvas.DrawRectangle(10, 10, float64(backDX-20), float64(backDY-20))
+ canvas.SetRGBA255(255, 255, 255, 255)
+ canvas.Fill()
+
+ canvas.DrawImage(equipBlock, 10, 10)
+ canvas.DrawImage(packBlock, 10, 10+equipBlock.Bounds().Dy()+10)
+
+ return imgfactory.ToBytes(canvas.Image())
+}
+
+// 绘制装备栏区域
+func drawEquipEmptyBlock(fontdata []byte) (image.Image, error) {
+ canvas := gg.NewContext(1000, 300)
+ // 画底色
+ canvas.DrawRectangle(0, 0, 1000, 300)
+ canvas.SetRGBA255(255, 255, 255, 150)
+ canvas.Fill()
+ // 边框框
+ canvas.DrawRectangle(0, 0, 1000, 300)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+
+ canvas.SetColor(color.Black)
+ err := canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ textW, textH := canvas.MeasureString("装备信息")
+ canvas.DrawString("装备信息", 10, 10+textH)
+ canvas.DrawLine(10, textH*1.2, textW, textH*1.2)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+ if err = canvas.ParseFontFace(fontdata, 50); err != nil {
+ return nil, err
+ }
+ canvas.DrawString("没有装备任何鱼竿", 50, 10+textH*2+50)
+ return canvas.Image(), nil
+}
+func drawEquipInfoBlock(equipInfo equip, fontdata []byte) (image.Image, error) {
+ canvas := gg.NewContext(1, 1)
+ err := canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ _, titleH := canvas.MeasureString("装备信息")
+ err = canvas.ParseFontFace(fontdata, 50)
+ if err != nil {
+ return nil, err
+ }
+ _, textH := canvas.MeasureString("装备信息")
+
+ backDY := math.Max(int(10+titleH*2+(textH*2)*4+10), 300)
+
+ canvas = gg.NewContext(1000, backDY)
+ // 画底色
+ canvas.DrawRectangle(0, 0, 1000, float64(backDY))
+ canvas.SetRGBA255(255, 255, 255, 150)
+ canvas.Fill()
+ // 边框框
+ canvas.DrawRectangle(0, 0, 1000, float64(backDY))
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+ getAvatar, err := engine.GetLazyData(equipInfo.Equip+".png", false)
+ if err != nil {
+ return nil, err
+ }
+ equipPic, _, err := image.Decode(bytes.NewReader(getAvatar))
+ if err != nil {
+ return nil, err
+ }
+ picDy := float64(backDY) - 10 - titleH*2
+ equipPic = imgfactory.Size(equipPic, int(picDy)-10, int(picDy)-10).Image()
+ canvas.DrawImage(equipPic, 10, 10+int(titleH)*2)
+
+ // 放字
+ canvas.SetColor(color.Black)
+ if err = canvas.ParseFontFace(fontdata, 100); err != nil {
+ return nil, err
+ }
+ titleW, titleH := canvas.MeasureString("装备信息")
+ canvas.DrawString("装备信息", 10, 10+titleH*1.2)
+ canvas.DrawLine(10, titleH*1.6, titleW, titleH*1.6)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+
+ textDx := picDy + 10
+ textDy := 10 + titleH*2
+ if err = canvas.ParseFontFace(fontdata, 75); err != nil {
+ return nil, err
+ }
+ textW, textH := canvas.MeasureString(equipInfo.Equip)
+ canvas.DrawStringAnchored(equipInfo.Equip, textDx+textW/2, textDy+textH/2, 0.5, 0.5)
+
+ textDy += textH * 1.5
+ if err = canvas.ParseFontFace(fontdata, 50); err != nil {
+ return nil, err
+ }
+ textW, textH = canvas.MeasureString("维修次数")
+ durable := strconv.Itoa(equipInfo.Durable)
+ valueW, _ := canvas.MeasureString("100")
+ barW := 1000 - textDx - textW - 10 - valueW - 10
+
+ canvas.DrawStringAnchored("装备耐久", textDx+textW/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawRectangle(textDx+textW+5, textDy, barW, textH*1.2)
+ canvas.SetRGB255(150, 150, 150)
+ canvas.Fill()
+ canvas.SetRGB255(0, 0, 0)
+ durableW := barW * float64(equipInfo.Durable) / float64(equipAttribute[equipInfo.Equip])
+ canvas.DrawRectangle(textDx+textW+5, textDy, durableW, textH*1.2)
+ canvas.SetRGB255(102, 102, 102)
+ canvas.Fill()
+ canvas.SetColor(color.Black)
+ canvas.DrawStringAnchored(durable, textDx+textW+5+barW+5+valueW/2, textDy+textH/2, 0.5, 0.5)
+
+ textDy += textH * 2
+ maintenance := strconv.Itoa(equipInfo.Maintenance)
+ canvas.DrawStringAnchored("维修次数", textDx+textW/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawRectangle(textDx+textW+5, textDy, barW, textH*1.2)
+ canvas.SetRGB255(150, 150, 150)
+ canvas.Fill()
+ canvas.SetRGB255(0, 0, 0)
+ canvas.DrawRectangle(textDx+textW+5, textDy, barW*float64(equipInfo.Maintenance)/10, textH*1.2)
+ canvas.SetRGB255(102, 102, 102)
+ canvas.Fill()
+ canvas.SetColor(color.Black)
+ canvas.DrawStringAnchored(maintenance, textDx+textW+5+barW+5+valueW/2, textDy+textH/2, 0.5, 0.5)
+
+ textDy += textH * 3
+ canvas.DrawString(" 附魔: 诱钓"+enchantLevel[equipInfo.Induce]+" 海之眷顾"+enchantLevel[equipInfo.Favor], textDx, textDy)
+ return canvas.Image(), nil
+}
+
+// 绘制背包信息区域
+func drawArticleEmptyBlock(fontdata []byte) (image.Image, error) {
+ canvas := gg.NewContext(1000, 300)
+ // 画底色
+ canvas.DrawRectangle(0, 0, 1000, 300)
+ canvas.SetRGBA255(255, 255, 255, 150)
+ canvas.Fill()
+ // 边框框
+ canvas.DrawRectangle(0, 0, 1000, 300)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+
+ canvas.SetColor(color.Black)
+ err := canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ textW, textH := canvas.MeasureString("背包信息")
+ canvas.DrawString("背包信息", 10, 10+textH*1.2)
+ canvas.DrawLine(10, textH*1.6, textW, textH*1.6)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+ if err = canvas.ParseFontFace(fontdata, 50); err != nil {
+ return nil, err
+ }
+ canvas.DrawStringAnchored("背包没有存放任何东西", 500, 10+textH*2+50, 0.5, 0)
+ return canvas.Image(), nil
+}
+func drawArticleInfoBlock(uid int64, articles []article, fontdata []byte) (image.Image, error) {
+ canvas := gg.NewContext(1, 1)
+ err := canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ titleW, titleH := canvas.MeasureString("背包信息")
+ front := 50.0
+ err = canvas.ParseFontFace(fontdata, front)
+ if err != nil {
+ return nil, err
+ }
+ _, textH := canvas.MeasureString("高度")
+
+ nameWOfFiest := 0.0
+ nameWOfSecond := 0.0
+ for i, info := range articles {
+ textW, _ := canvas.MeasureString(info.Name + "(" + info.Other + ")")
+ if i%2 == 0 && textW > nameWOfFiest {
+ nameWOfFiest = textW
+ } else if textW > nameWOfSecond {
+ nameWOfSecond = textW
+ }
+ }
+ valueW, _ := canvas.MeasureString("10000")
+
+ if (10+nameWOfFiest+10+valueW+10)+(10+nameWOfSecond+10+valueW+10) > 980 {
+ front = 32.0
+ err = canvas.ParseFontFace(fontdata, front)
+ if err != nil {
+ return nil, err
+ }
+ _, textH = canvas.MeasureString("高度")
+
+ nameWOfFiest = 0
+ nameWOfSecond = 0
+ for i, info := range articles {
+ textW, _ := canvas.MeasureString(info.Name + "(" + info.Other + ")")
+ if i%2 == 0 && textW > nameWOfFiest {
+ nameWOfFiest = textW
+ } else if textW > nameWOfSecond {
+ nameWOfSecond = textW
+ }
+ }
+ valueW, _ = canvas.MeasureString("10000")
+ }
+ wallW := (980 - (10 + nameWOfFiest + 10 + valueW + 10) - (10 + nameWOfSecond + 10 + valueW + 10)) / 2
+ backY := math.Max(10+int(titleH*1.6)+10+int(textH*2)*(math.Ceil(len(articles), 2)+1), 500)
+ canvas = gg.NewContext(1000, backY)
+ // 画底色
+ canvas.DrawRectangle(0, 0, 1000, float64(backY))
+ canvas.SetRGBA255(255, 255, 255, 150)
+ canvas.Fill()
+ // 边框框
+ canvas.DrawRectangle(0, 0, 1000, float64(backY))
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+
+ // 放字
+ canvas.SetColor(color.Black)
+ err = canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ canvas.DrawString("背包信息", 10, 10+titleH*1.2)
+ canvas.DrawLine(10, titleH*1.6, titleW, titleH*1.6)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+
+ textDy := 10 + titleH*1.7
+ if err = canvas.ParseFontFace(fontdata, front); err != nil {
+ return nil, err
+ }
+ canvas.SetColor(color.Black)
+ numberOfFish := 0
+ numberOfEquip := 0
+ canvas.DrawStringAnchored("名称", wallW+20+nameWOfFiest/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored("数量", wallW+20+nameWOfFiest+10+valueW/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored("名称", wallW+20+nameWOfFiest+10+valueW+10+10+nameWOfSecond/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored("数量", wallW+20+nameWOfFiest+10+valueW+10+10+nameWOfSecond+10+valueW/2, textDy+textH/2, 0.5, 0.5)
+ textDy += textH * 2
+ for i, info := range articles {
+ name := info.Name
+ if info.Other != "" {
+ numberOfEquip++
+ name += "(" + info.Other + ")"
+ } else if strings.Contains(name, "鱼") {
+ numberOfFish += info.Number
+ }
+ valueStr := strconv.Itoa(info.Number)
+ if i%2 == 0 {
+ if i != 0 {
+ textDy += textH * 2
+ }
+ canvas.DrawStringAnchored(name, wallW+20+nameWOfFiest/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored(valueStr, wallW+20+nameWOfFiest+10+valueW/2, textDy+textH/2, 0.5, 0.5)
+ } else {
+ canvas.DrawStringAnchored(name, wallW+20+nameWOfFiest+10+valueW+10+10+nameWOfSecond/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored(valueStr, wallW+20+nameWOfFiest+10+valueW+10+10+nameWOfSecond+10+valueW/2, textDy+textH/2, 0.5, 0.5)
+ }
+ }
+ if err = canvas.ParseFontFace(fontdata, 30); err != nil {
+ return nil, err
+ }
+ textDy = 10
+ text := "钱包余额: " + strconv.Itoa(wallet.GetWalletOf(uid))
+ textW, textH := canvas.MeasureString(text)
+ w, _ := canvas.MeasureString("维修大师[已激活]")
+ if w > textW {
+ textW = w
+ }
+ canvas.DrawStringAnchored(text, 980-textW/2, textDy+textH/2, 0.5, 0.5)
+ textDy += textH * 1.5
+ if numberOfFish > 100 {
+ canvas.DrawStringAnchored("钓鱼佬[已激活]", 980-textW/2, textDy+textH/2, 0.5, 0.5)
+ textDy += textH * 1.5
+ }
+ if numberOfEquip > 10 {
+ canvas.DrawStringAnchored("维修大师[已激活]", 980-textW/2, textDy+textH/2, 0.5, 0.5)
+ }
+ return canvas.Image(), nil
+}
diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go
new file mode 100644
index 0000000000..e4989c742a
--- /dev/null
+++ b/plugin/mcfish/pole.go
@@ -0,0 +1,478 @@
+// Package mcfish 钓鱼模拟器
+package mcfish
+
+import (
+ "math/rand"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/FloatTech/zbputils/ctxext"
+ zero "github.com/wdvxdr1123/ZeroBot"
+ "github.com/wdvxdr1123/ZeroBot/message"
+)
+
+func init() {
+ engine.OnRegex("^装备(.+竿|美西螈|三叉戟)$", getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ equipInfo, err := dbdata.getUserEquip(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.1]:", err))
+ return
+ }
+ thingName := ctx.State["regex_matched"].([]string)[1]
+ articles, err := dbdata.getUserThingInfo(uid, thingName)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.2]:", err))
+ return
+ }
+ if len(articles) == 0 {
+ ctx.SendChain(message.Text("你的背包不存在该物品"))
+ return
+ }
+ poles := make([]equip, 0, len(articles))
+ for _, info := range articles {
+ poleInfo := strings.Split(info.Other, "/")
+ durable, _ := strconv.Atoi(poleInfo[0])
+ maintenance, _ := strconv.Atoi(poleInfo[1])
+ induceLevel, _ := strconv.Atoi(poleInfo[2])
+ favorLevel, _ := strconv.Atoi(poleInfo[3])
+ poles = append(poles, equip{
+ ID: uid,
+ Equip: info.Name,
+ Durable: durable,
+ Maintenance: maintenance,
+ Induce: induceLevel,
+ Favor: favorLevel,
+ })
+ }
+ check := false
+ index := 0
+ if thingName != "美西螈" && len(poles) > 1 {
+ msg := make(message.Message, 0, 3+len(articles))
+ msg = append(msg, message.Reply(ctx.Event.MessageID), message.Text("找到以下鱼竿:\n"))
+ for i, info := range poles {
+ msg = append(msg, message.Text("[", i, "] ", info.Equip, " : 耐", info.Durable, "/修", info.Maintenance,
+ "/诱", enchantLevel[info.Induce], "/眷顾", enchantLevel[info.Favor], "\n"))
+ }
+ msg = append(msg, message.Text("————————\n输入对应序号进行装备,或回复“取消”取消"))
+ ctx.Send(msg)
+ // 等待用户下一步选择
+ recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(取消|\d+)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel()
+ for {
+ select {
+ case <-time.After(time.Second * 120):
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("等待超时,取消装备"),
+ ),
+ )
+ return
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "取消" {
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("已取消装备"),
+ ),
+ )
+ return
+ }
+ index, err = strconv.Atoi(nextcmd)
+ if err != nil || index > len(articles)-1 {
+ ctx.SendChain(message.At(ctx.Event.UserID), message.Text("请输入正确的序号"))
+ continue
+ }
+ check = true
+ }
+ if check {
+ break
+ }
+ }
+ }
+ newEquipInfo := poles[index]
+ packEquip := articles[index]
+ packEquip.Number--
+ err = dbdata.updateUserThingInfo(uid, packEquip)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.3]:", err))
+ return
+ }
+ err = dbdata.updateUserEquip(newEquipInfo)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.3.1]:", err))
+ return
+ }
+ oldthing := article{}
+ if equipInfo != (equip{}) && equipInfo.Equip != "美西螈" {
+ oldthing = article{
+ Duration: time.Now().Unix(),
+ Type: "pole",
+ Name: equipInfo.Equip,
+ Number: 1,
+ Other: strconv.Itoa(equipInfo.Durable) + "/" + strconv.Itoa(equipInfo.Maintenance) + "/" + strconv.Itoa(equipInfo.Induce) + "/" + strconv.Itoa(equipInfo.Favor),
+ }
+ } else if equipInfo.Equip == "美西螈" {
+ articles, err = dbdata.getUserThingInfo(uid, "美西螈")
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.3.2]:", err))
+ return
+ }
+ if len(articles) == 0 {
+ oldthing = article{
+ Duration: time.Now().Unix(),
+ Type: "pole",
+ Name: equipInfo.Equip,
+ Number: 1,
+ Other: strconv.Itoa(equipInfo.Durable) + "/" + strconv.Itoa(equipInfo.Maintenance) + "/" + strconv.Itoa(equipInfo.Induce) + "/" + strconv.Itoa(equipInfo.Favor),
+ }
+ } else {
+ oldthing = articles[0]
+ oldthing.Number++
+ }
+ }
+ err = dbdata.updateUserThingInfo(uid, oldthing)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.4]:", err))
+ return
+ }
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("装备成功"),
+ ),
+ )
+ })
+ engine.OnFullMatchGroup([]string{"修复鱼竿", "维修鱼竿"}, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ equipInfo, err := dbdata.getUserEquip(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.5]:", err))
+ return
+ }
+ if equipInfo.Equip == "" || equipInfo.Equip == "美西螈" || equipInfo.Equip == "三叉戟" {
+ ctx.SendChain(message.Text("仅能修复装备中的鱼竿"))
+ return
+ }
+ if equipInfo.Maintenance >= 10 {
+ ctx.SendChain(message.Text("装备的鱼竿已经达到修复上限"))
+ return
+ }
+ articles, err := dbdata.getUserThingInfo(uid, equipInfo.Equip)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.6]:", err))
+ return
+ }
+ if len(articles) == 0 {
+ ctx.SendChain(message.Text("你的背包不存在相同鱼竿进行修复"))
+ return
+ }
+ poles := make([]equip, 0, len(articles))
+ for _, info := range articles {
+ poleInfo := strings.Split(info.Other, "/")
+ durable, _ := strconv.Atoi(poleInfo[0])
+ maintenance, _ := strconv.Atoi(poleInfo[1])
+ induceLevel, _ := strconv.Atoi(poleInfo[2])
+ favorLevel, _ := strconv.Atoi(poleInfo[3])
+ poles = append(poles, equip{
+ ID: uid,
+ Equip: info.Name,
+ Durable: durable,
+ Maintenance: maintenance,
+ Induce: induceLevel,
+ Favor: favorLevel,
+ })
+ }
+ index := 0
+ check := false
+ if len(articles) > 1 {
+ msg := make(message.Message, 0, 3+len(articles))
+ msg = append(msg, message.Text("找到以下鱼竿:\n"))
+ for i, info := range poles {
+ msg = append(msg, message.Text("[", i, "] ", info.Equip, " : 耐", info.Durable, "/修", info.Maintenance,
+ "/诱", enchantLevel[info.Induce], "/眷顾", enchantLevel[info.Favor], "\n"))
+ }
+ msg = append(msg, message.Text("————————\n输入对应序号进行修复,或回复“取消”取消"))
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, msg...))
+ // 等待用户下一步选择
+ recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(取消|\d+)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel()
+ for {
+ select {
+ case <-time.After(time.Second * 120):
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("等待超时,取消修复"),
+ ),
+ )
+ return
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "取消" {
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("已取消修复"),
+ ),
+ )
+ return
+ }
+ index, err = strconv.Atoi(nextcmd)
+ if err != nil || index > len(articles)-1 {
+ ctx.SendChain(message.At(ctx.Event.UserID), message.Text("请输入正确的序号"))
+ continue
+ }
+ check = true
+ }
+ if check {
+ break
+ }
+ }
+ }
+ newEquipInfo := poles[index]
+ number, err := dbdata.getNumberFor(uid, "竿")
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.5.1]:", err))
+ return
+ }
+ if number <= 10 {
+ number = 8
+ } else {
+ number = 10
+ }
+ equipInfo.Durable += newEquipInfo.Durable * number / 10
+ if equipInfo.Durable > equipAttribute[equipInfo.Equip] {
+ equipInfo.Durable = equipAttribute[equipInfo.Equip]
+ }
+ msg := ""
+ if newEquipInfo.Induce != 0 && rand.Intn(100) < 50 {
+ equipInfo.Induce += newEquipInfo.Induce
+ if equipInfo.Induce > 3 {
+ equipInfo.Induce = 3
+ }
+ msg += ",诱钓等级提升至" + enchantLevel[equipInfo.Induce]
+ }
+ if newEquipInfo.Favor != 0 && rand.Intn(100) < 50 {
+ equipInfo.Favor += newEquipInfo.Favor
+ if equipInfo.Favor > 3 {
+ equipInfo.Favor = 3
+ }
+ msg += ",海之眷顾等级提升至" + enchantLevel[equipInfo.Favor]
+ }
+ thingInfo := articles[index]
+ thingInfo.Number = 0
+ err = dbdata.updateUserThingInfo(uid, thingInfo)
+ if err == nil {
+ equipInfo.Maintenance++
+ err = dbdata.updateUserEquip(equipInfo)
+ }
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.7]:", err))
+ return
+ }
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("鱼竿修复成功,耐久提高至", equipInfo.Durable, msg),
+ ),
+ )
+ })
+ engine.OnPrefix("附魔", getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ equipInfo, err := dbdata.getUserEquip(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.7]:", err))
+ return
+ }
+ if equipInfo.Equip == "" || equipInfo.Equip == "美西螈" {
+ ctx.SendChain(message.Text("仅可对装备中的进行附魔"))
+ return
+ }
+ book := strings.TrimSpace(ctx.State["args"].(string))
+ books, err := dbdata.getUserThingInfo(uid, book)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.8]:", err))
+ return
+ }
+ if len(books) == 0 {
+ ctx.SendChain(message.Text("你的背包不存在", book, "进行附魔"))
+ return
+ }
+ bookInfo := books[0]
+ bookInfo.Number--
+ err = dbdata.updateUserThingInfo(uid, bookInfo)
+ number := 0
+ if err == nil {
+ if rand.Intn(100) > 50 {
+ ctx.SendChain(message.Text("附魔失败了"))
+ return
+ }
+ switch book {
+ case "诱钓":
+ equipInfo.Induce++
+ if equipInfo.Induce > 3 {
+ equipInfo.Induce = 3
+ }
+ number = equipInfo.Induce
+ case "海之眷顾":
+ equipInfo.Favor++
+ if equipInfo.Favor > 3 {
+ equipInfo.Favor = 3
+ }
+ number = equipInfo.Favor
+ default:
+ ctx.SendChain(message.Text("附魔失败了"))
+ return
+ }
+ err = dbdata.updateUserEquip(equipInfo)
+ }
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.9]:", err))
+ return
+ }
+ ctx.SendChain(message.Text("附魔成功,", book, "等级提高至", enchantLevel[number]))
+ })
+ engine.OnRegex(`^合成(.+竿|三叉戟)$`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ thingList := []string{"木竿", "铁竿", "金竿", "钻石竿", "下界合金竿", "三叉戟"}
+ thingName := ctx.State["regex_matched"].([]string)[1]
+ indexOfMaterial := -1
+ for i, name := range thingList {
+ if thingName == name {
+ indexOfMaterial = (i - 1)
+ break
+ }
+ }
+ if indexOfMaterial < 0 {
+ return
+ }
+ articles, err := dbdata.getUserThingInfo(uid, thingList[indexOfMaterial])
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.10]:", err))
+ return
+ }
+ max := len(articles)
+ if max == 0 {
+ ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你的合成材料不足"))
+ return
+ }
+ poles := make([]equip, 0, max)
+ for _, info := range articles {
+ poleInfo := strings.Split(info.Other, "/")
+ durable, _ := strconv.Atoi(poleInfo[0])
+ maintenance, _ := strconv.Atoi(poleInfo[1])
+ induceLevel, _ := strconv.Atoi(poleInfo[2])
+ favorLevel, _ := strconv.Atoi(poleInfo[3])
+ poles = append(poles, equip{
+ ID: uid,
+ Equip: info.Name,
+ Durable: durable,
+ Maintenance: maintenance,
+ Induce: induceLevel,
+ Favor: favorLevel,
+ })
+ }
+ list := []int{0, 1, 2}
+ check := false
+ if len(articles) > 3 {
+ msg := make(message.Message, 0, 3+len(articles))
+ msg = append(msg, message.Text("找到以下鱼竿:\n"))
+ for i, info := range poles {
+ msg = append(msg, message.Text("[", i, "] ", info.Equip, " : 耐", info.Durable, "/修", info.Maintenance,
+ "/诱", enchantLevel[info.Induce], "/眷顾", enchantLevel[info.Favor], "\n"))
+ }
+ msg = append(msg, message.Text("————————\n输入3个序号进行合成(用空格分割),或回复“取消”取消"))
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, msg...))
+ // 等待用户下一步选择
+ recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(取消|\d+ \d+ \d+)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel()
+ for {
+ select {
+ case <-time.After(time.Second * 120):
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("等待超时,取消合成"),
+ ),
+ )
+ return
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "取消" {
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("已取消合成"),
+ ),
+ )
+ return
+ }
+ chooseList := strings.Split(nextcmd, " ")
+ if list[0] == list[1] || list[0] == list[2] || list[1] == list[2] {
+ ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[0]请输入正确的序号\n", list))
+ continue
+ }
+ first, err := strconv.Atoi(chooseList[0])
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.11.1]:", err))
+ return
+ }
+ second, err := strconv.Atoi(chooseList[1])
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.11.2]:", err))
+ return
+ }
+ third, err := strconv.Atoi(chooseList[2])
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.11.3]:", err))
+ return
+ }
+ if first > max || second > max || third > max {
+ ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[", max, "]请输入正确的序号\n", list))
+ continue
+ }
+ list = []int{first, second, third}
+ check = true
+ }
+ if check {
+ break
+ }
+ }
+ }
+ favorLevel := 0
+ induceLevel := 0
+ for _, index := range list {
+ thingInfo := articles[index]
+ thingInfo.Number = 0
+ err = dbdata.updateUserThingInfo(uid, thingInfo)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err))
+ return
+ }
+ favorLevel += poles[index].Favor
+ induceLevel += poles[index].Induce
+ }
+ if rand.Intn(10) > 6 {
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("合成失败,材料已销毁"),
+ ),
+ )
+ return
+ }
+ attribute := strconv.Itoa(equipAttribute[thingName]) + "/0/" + strconv.Itoa(induceLevel/3) + "/" + strconv.Itoa(favorLevel/3)
+ newthing := article{
+ Duration: time.Now().Unix(),
+ Type: "pole",
+ Name: thingName,
+ Number: 1,
+ Other: attribute,
+ }
+ err = dbdata.updateUserThingInfo(uid, newthing)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err))
+ return
+ }
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text(thingName, "合成成功\n属性: ", attribute),
+ ),
+ )
+ })
+}
diff --git a/plugin/mcfish/store.go b/plugin/mcfish/store.go
new file mode 100644
index 0000000000..0591a26fa6
--- /dev/null
+++ b/plugin/mcfish/store.go
@@ -0,0 +1,593 @@
+// Package mcfish 钓鱼模拟器
+package mcfish
+
+import (
+ "image"
+ "image/color"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/FloatTech/AnimeAPI/wallet"
+ "github.com/FloatTech/floatbox/file"
+ "github.com/FloatTech/floatbox/math"
+ "github.com/FloatTech/gg"
+ "github.com/FloatTech/imgfactory"
+ "github.com/FloatTech/zbputils/control"
+ "github.com/FloatTech/zbputils/ctxext"
+ "github.com/FloatTech/zbputils/img/text"
+ zero "github.com/wdvxdr1123/ZeroBot"
+ "github.com/wdvxdr1123/ZeroBot/message"
+)
+
+var (
+ refresh = false
+ timeNow = 0
+ refreshFish = func(ctx *zero.Ctx) bool {
+ if refresh && timeNow == time.Now().Day() {
+ return true
+ }
+ refresh, err := dbdata.refreshStroeInfo()
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.1]:", err))
+ return refresh
+ }
+ timeNow = time.Now().Day()
+ return refresh
+ }
+)
+
+func init() {
+ engine.OnFullMatchGroup([]string{"钓鱼看板", "钓鱼商店"}, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ infos, err := dbdata.getStoreInfo()
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.2]:", err))
+ return
+ }
+ var picImage image.Image
+ if len(infos) == 0 {
+ picImage, err = drawStroeEmptyImage()
+ } else {
+ picImage, err = drawStroeInfoImage(infos)
+ }
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.3]:", err))
+ return
+ }
+ pic, err := imgfactory.ToBytes(picImage)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.4]:", err))
+ return
+ }
+ ctx.SendChain(message.ImageBytes(pic))
+ })
+ engine.OnRegex(`^出售(.+(竿|鱼)|河豚|鹦鹉螺|诱钓|海之眷顾|唱片|美西螈)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ thingName := ctx.State["regex_matched"].([]string)[1]
+ number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[3])
+ if number == 0 {
+ number = 1
+ }
+ articles, err := dbdata.getUserThingInfo(uid, thingName)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.5]:", err))
+ return
+ }
+ if len(articles) == 0 {
+ ctx.SendChain(message.Text("你的背包不存在该物品"))
+ return
+ }
+ index := 0
+ thing := article{}
+ if len(articles) > 1 {
+ msg := make(message.Message, 0, 3+len(articles))
+ msg = append(msg, message.Reply(ctx.Event.MessageID), message.Text("找到以下物品:\n"))
+ for i, info := range articles {
+ if info.Other != "" {
+ msg = append(msg, message.Text("[", i, "] ", info.Name, "(", info.Other, ")\n"))
+ } else {
+ msg = append(msg, message.Text(
+ "[", i, "]", info.Name, " 数量: ", info.Number, "\n"))
+ }
+
+ }
+ msg = append(msg, message.Reply(ctx.Event.MessageID), message.Text("————————\n输入对应序号进行装备,或回复“取消”取消"))
+ ctx.Send(msg)
+ // 等待用户下一步选择
+ sell := false
+ recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(取消|\d+)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel()
+ for {
+ select {
+ case <-time.After(time.Second * 120):
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("等待超时,取消出售"),
+ ),
+ )
+ return
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "取消" {
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("已取消出售"),
+ ),
+ )
+ return
+ }
+ index, err = strconv.Atoi(nextcmd)
+ if err != nil || index > len(articles)-1 {
+ ctx.SendChain(message.At(ctx.Event.UserID), message.Text("请输入正确的序号"))
+ continue
+ }
+ sell = true
+ }
+ if sell {
+ break
+ }
+ }
+ }
+
+ thing = articles[index]
+ if thing.Number < number {
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("背包数量不足")))
+ return
+ }
+
+ var pice int
+ if strings.Contains(thingName, "竿") {
+ poleInfo := strings.Split(articles[index].Other, "/")
+ durable, _ := strconv.Atoi(poleInfo[0])
+ maintenance, _ := strconv.Atoi(poleInfo[1])
+ induceLevel, _ := strconv.Atoi(poleInfo[2])
+ favorLevel, _ := strconv.Atoi(poleInfo[3])
+ pice = (thingPice[thingName] - (equipAttribute[thingName] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discount[thingName] / 100
+ } else {
+ pice = thingPice[thingName] * discount[thingName] / 100
+ }
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("是否接受商店将以", pice*number*8/10, "收购", number, "个", thingName, "?\n回答\"是\"或\"否\"")))
+ // 等待用户下一步选择
+ recv, cancel1 := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(是|否)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel1()
+ buy := false
+ for {
+ select {
+ case <-time.After(time.Second * 60):
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("等待超时,取消钓鱼")))
+ return
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "否" {
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("已取消购买")))
+ return
+ }
+ buy = true
+ }
+ if buy {
+ break
+ }
+ }
+
+ records, err := dbdata.getUserThingInfo(uid, "唱片")
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.9.1]:", err))
+ return
+ }
+ if len(records) != 0 {
+ recordInfo := records[0]
+ numberOfRecord := recordInfo.Number
+ if thingName == "唱片" {
+ numberOfRecord--
+ }
+ if numberOfRecord > 0 {
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("是否使用唱片让价格翻倍?\n回答\"是\"或\"否\"")))
+ // 等待用户下一步选择
+ recv, cancel2 := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(是|否)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel2()
+ use := false
+ checkTime := false
+ for {
+ select {
+ case <-time.After(time.Second * 60):
+ checkTime = true
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "是" {
+ use = true
+ }
+ checkTime = true
+ }
+ if checkTime {
+ break
+ }
+ }
+ if use {
+ pice *= 2
+ recordInfo.Number--
+ err = dbdata.updateUserThingInfo(uid, recordInfo)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.9.2]:", err))
+ return
+ }
+ }
+ }
+ }
+ thing.Number -= number
+ err = dbdata.updateUserThingInfo(uid, thing)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.6]:", err))
+ return
+ }
+ if strings.Contains(thingName, "竿") {
+ if pice >= thingPice[thingName]*3/4 { // 不值钱的删了
+ newCommodity := store{
+ Duration: time.Now().Unix(),
+ Type: "pole",
+ Name: thingName,
+ Number: 1,
+ Price: pice,
+ Other: thing.Other,
+ }
+ err = dbdata.updateStoreInfo(newCommodity)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.7]:", err))
+ return
+ }
+ }
+ } else {
+ things, err1 := dbdata.getStoreThingInfo(thingName)
+ if err1 != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.8]:", err1))
+ return
+ }
+ if len(things) == 0 {
+ things = append(things, store{
+ Duration: time.Now().Unix(),
+ Name: thingName,
+ Number: 0,
+ Price: pice,
+ })
+ if thingName == "海之眷顾" || thingName == "诱钓" || thingName == "唱片" {
+ things[0].Type = "article"
+ } else {
+ things[0].Type = "fish"
+ }
+ }
+ things[0].Number += number
+ err = dbdata.updateStoreInfo(things[0])
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.9]:", err))
+ return
+ }
+ }
+ pice = pice * 8 / 10
+ err = wallet.InsertWalletOf(uid, pice*number)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.10]:", err))
+ return
+ }
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("出售成功,你赚到了", pice*number)))
+ })
+ engine.OnRegex(`^购买(.+(竿|鱼)|河豚|鹦鹉螺|诱钓|海之眷顾|唱片|美西螈)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ thingName := ctx.State["regex_matched"].([]string)[1]
+ number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[3])
+ if number == 0 {
+ number = 1
+ }
+ thingInfos, err := dbdata.getStoreThingInfo(thingName)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.11]:", err))
+ return
+ }
+ if len(thingInfos) == 0 {
+ ctx.SendChain(message.Text("当前商店并没有上架该物品"))
+ return
+ }
+ index := 0
+ pice := make([]int, 0, len(thingInfos))
+ for _, info := range thingInfos {
+ if strings.Contains(thingName, "竿") {
+ poleInfo := strings.Split(info.Other, "/")
+ durable, _ := strconv.Atoi(poleInfo[0])
+ maintenance, _ := strconv.Atoi(poleInfo[1])
+ induceLevel, _ := strconv.Atoi(poleInfo[2])
+ favorLevel, _ := strconv.Atoi(poleInfo[3])
+ thingPice := (thingPice[info.Name] - (equipAttribute[info.Name] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discount[info.Name] / 100
+ pice = append(pice, thingPice)
+ } else {
+ thingPice := thingPice[info.Name] * discount[info.Name] / 100
+ pice = append(pice, thingPice)
+ }
+
+ }
+ if len(thingInfos) > 1 {
+ msg := make(message.Message, 0, 3+len(thingInfos))
+ msg = append(msg, message.Text("找到以下物品:\n"))
+ for i, info := range thingInfos {
+ if strings.Contains(thingName, "竿") {
+ msg = append(msg, message.Text(
+ "[", i, "]", info.Name, "(", info.Other, ") 价格:", pice[i], "\n"))
+ } else {
+ msg = append(msg, message.Text(
+ "[", i, "]", info.Name, " 数量:", info.Number, " 价格:", pice[i], "\n"))
+ }
+
+ }
+ msg = append(msg, message.Text("————————\n输入对应序号进行装备,或回复“取消”取消"))
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, msg...))
+ // 等待用户下一步选择
+ sell := false
+ recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(取消|\d+)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel()
+ for {
+ select {
+ case <-time.After(time.Second * 120):
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("等待超时,取消购买"),
+ ),
+ )
+ return
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "取消" {
+ ctx.Send(
+ message.ReplyWithMessage(ctx.Event.MessageID,
+ message.Text("已取消购买"),
+ ),
+ )
+ return
+ }
+ index, err = strconv.Atoi(nextcmd)
+ if err != nil || index > len(thingInfos)-1 {
+ ctx.SendChain(message.At(ctx.Event.UserID), message.Text("请输入正确的序号"))
+ continue
+ }
+ sell = true
+ }
+ if sell {
+ break
+ }
+ }
+ }
+
+ thing := thingInfos[index]
+ if thing.Number < number {
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("商店数量不足")))
+ return
+ }
+
+ money := wallet.GetWalletOf(uid)
+ if money < pice[index]*number {
+ ctx.SendChain(message.Text("你身上的钱(", money, ")不够支付"))
+ return
+ }
+
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("你确定花费", pice[index]*number, "购买", number, "个", thingName, "?\n回答\"是\"或\"否\"")))
+ // 等待用户下一步选择
+ recv, cancel1 := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(是|否)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
+ defer cancel1()
+ buy := false
+ for {
+ select {
+ case <-time.After(time.Second * 60):
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("等待超时,取消购买")))
+ return
+ case e := <-recv:
+ nextcmd := e.Event.Message.String()
+ if nextcmd == "否" {
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("已取消购买")))
+ return
+ }
+ buy = true
+ }
+ if buy {
+ break
+ }
+ }
+
+ thing.Number -= number
+ err = dbdata.updateStoreInfo(thing)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.12]:", err))
+ return
+ }
+ err = wallet.InsertWalletOf(uid, -pice[index]*number)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.13]:", err))
+ return
+ }
+ if strings.Contains(thingName, "竿") {
+ newCommodity := article{
+ Duration: time.Now().Unix(),
+ Type: "pole",
+ Name: thingName,
+ Number: 1,
+ Other: thing.Other,
+ }
+ err = dbdata.updateUserThingInfo(uid, newCommodity)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.14]:", err))
+ return
+ }
+ } else {
+ things, err1 := dbdata.getUserThingInfo(uid, thingName)
+ if err1 != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.15]:", err1))
+ return
+ }
+ if len(things) == 0 {
+ things = append(things, article{
+ Duration: time.Now().Unix(),
+ Name: thingName,
+ Number: 0,
+ })
+ if thingName == "海之眷顾" || thingName == "诱钓" || thingName == "唱片" {
+ things[0].Type = "article"
+ } else {
+ things[0].Type = "fish"
+ }
+ }
+ things[0].Number += number
+ err = dbdata.updateUserThingInfo(uid, things[0])
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.16]:", err))
+ return
+ }
+ }
+ ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("购买成功")))
+ })
+}
+
+func drawStroeEmptyImage() (picImage image.Image, err error) {
+ fontdata, err := file.GetLazyData(text.BoldFontFile, control.Md5File, true)
+ if err != nil {
+ return nil, err
+ }
+ canvas := gg.NewContext(1000, 300)
+ // 画底色
+ canvas.DrawRectangle(0, 0, 1000, 300)
+ canvas.SetRGBA255(255, 255, 255, 150)
+ canvas.Fill()
+ // 边框框
+ canvas.DrawRectangle(0, 0, 1000, 300)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+
+ canvas.SetColor(color.Black)
+ err = canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ textW, textH := canvas.MeasureString("价格信息")
+ canvas.DrawString("价格信息", 10, 10+textH*1.2)
+ canvas.DrawLine(10, textH*1.6, textW, textH*1.6)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+ if err = canvas.ParseFontFace(fontdata, 50); err != nil {
+ return nil, err
+ }
+ canvas.DrawStringAnchored("当前商店并没有上架任何物品", 500, 10+textH*2+50, 0.5, 0)
+ return canvas.Image(), nil
+}
+
+func drawStroeInfoImage(stroeInfo []store) (picImage image.Image, err error) {
+ fontdata, err := file.GetLazyData(text.BoldFontFile, control.Md5File, true)
+ if err != nil {
+ return nil, err
+ }
+ canvas := gg.NewContext(1, 1)
+ err = canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ titleW, titleH := canvas.MeasureString("价格信息")
+
+ err = canvas.ParseFontFace(fontdata, 50)
+ if err != nil {
+ return nil, err
+ }
+ _, textH := canvas.MeasureString("高度")
+ nameW, _ := canvas.MeasureString("下界合金竿(100/100/0/0)")
+ numberW, _ := canvas.MeasureString("10000")
+ priceW, _ := canvas.MeasureString("10000")
+
+ bolckW := int(10 + nameW + 50 + numberW + 50 + priceW + 10)
+ backY := 10 + int(titleH*2+10)*2 + 10 + (len(stroeInfo)+len(discount)/2+2)*int(textH*2) + 10
+ canvas = gg.NewContext(bolckW, math.Max(backY, 500))
+ // 画底色
+ canvas.DrawRectangle(0, 0, float64(bolckW), float64(backY))
+ canvas.SetRGBA255(150, 150, 150, 255)
+ canvas.Fill()
+
+ // 放字
+ canvas.SetColor(color.Black)
+ err = canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ canvas.DrawString("今日波动", 10, 10+titleH*1.2)
+ canvas.DrawLine(10, titleH*1.6, titleW, titleH*1.6)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+
+ textDy := 10 + titleH*1.7
+ if err = canvas.ParseFontFace(fontdata, 35); err != nil {
+ return nil, err
+ }
+ textDx, textDh := canvas.MeasureString("下界合金竿(均价1000)")
+ valueDx, _ := canvas.MeasureString("+100%")
+ i := 0
+ for name, info := range discount {
+ text := name + "(均价" + strconv.Itoa(thingPice[name]) + ") "
+
+ if i == 2 {
+ i = 0
+ textDy += textDh * 2
+ }
+ canvas.SetColor(color.Black)
+ canvas.DrawStringAnchored(text, 20+(textDx+valueDx+10)*float64(i)+10, textDy+textDh/2, 0, 0.5)
+ if info-100 > 0 {
+ canvas.SetRGBA255(200, 50, 50, 255)
+ text = "+" + strconv.Itoa(info-100) + "%"
+ } else {
+ canvas.SetRGBA255(63, 133, 55, 255)
+ text = strconv.Itoa(info-100) + "%"
+ }
+ canvas.DrawStringAnchored(text, 20+(textDx+valueDx+10)*float64(i)+10+textDx+10, textDy+textDh/2, 0, 0.5)
+ i++
+ }
+ canvas.SetColor(color.Black)
+ textDy += textDh * 2
+ canvas.DrawStringAnchored("注:出售商品将会额外扣除20%的税收,附魔鱼竿请按实际价格", 10, textDy+10+textDh/2, 0, 0.5)
+
+ textDy += textH * 2
+ err = canvas.ParseFontFace(fontdata, 100)
+ if err != nil {
+ return nil, err
+ }
+ canvas.DrawString("上架内容", 10, textDy+titleH*1.2)
+ canvas.DrawLine(10, textDy+titleH*1.6, titleW, textDy+titleH*1.6)
+ canvas.SetLineWidth(3)
+ canvas.SetRGBA255(0, 0, 0, 255)
+ canvas.Stroke()
+
+ textDy += 10 + titleH*1.7
+ if err = canvas.ParseFontFace(fontdata, 50); err != nil {
+ return nil, err
+ }
+
+ canvas.DrawStringAnchored("名称", 10+nameW/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored("数量", 10+nameW+10+numberW/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored("价格", 10+nameW+10+numberW+50+priceW/2, textDy+textH/2, 0.5, 0.5)
+
+ for _, info := range stroeInfo {
+ textDy += textH * 2
+ name := info.Name
+ if info.Other != "" {
+ name += "(" + info.Other + ")"
+ }
+ numberStr := strconv.Itoa(info.Number)
+ pice := 0
+ if strings.Contains(name, "竿") {
+ poleInfo := strings.Split(info.Other, "/")
+ durable, _ := strconv.Atoi(poleInfo[0])
+ maintenance, _ := strconv.Atoi(poleInfo[1])
+ induceLevel, _ := strconv.Atoi(poleInfo[2])
+ favorLevel, _ := strconv.Atoi(poleInfo[3])
+ pice = (thingPice[info.Name] - (equipAttribute[info.Name] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discount[info.Name] / 100
+ } else {
+ pice = thingPice[info.Name] * discount[info.Name] / 100
+ }
+
+ canvas.DrawStringAnchored(name, 10+nameW/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored(numberStr, 10+nameW+10+numberW/2, textDy+textH/2, 0.5, 0.5)
+ canvas.DrawStringAnchored(strconv.Itoa(pice), 10+nameW+10+numberW+50+priceW/2, textDy+textH/2, 0.5, 0.5)
+ }
+ return canvas.Image(), nil
+}
From 6b319921664886d1367429a95dfd714a2d005b28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sat, 2 Sep 2023 10:11:06 +0800
Subject: [PATCH 02/12] Update README.md
---
README.md | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/README.md b/README.md
index 1c788dccb3..f015babcf2 100644
--- a/README.md
+++ b/README.md
@@ -959,6 +959,23 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 吟唱提示[xxxx]
+
+
+ 钓鱼模拟器
+
+ `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/mcfish"`
+
+ - [x] 钓鱼商店
+ - [x] 购买xxx [数量]
+ - [x] 出售xxx [数量]
+ - [x] 钓鱼背包
+ - [x] 装备[xx竿|三叉戟|美西螈]
+ - [x] 附魔[诱钓|海之眷顾]
+ - [x] 修复鱼竿
+ - [x] 合成[xx竿|三叉戟]
+ - [x] 进行钓鱼
+ - [x] 进行n次钓鱼
+
简易midi音乐制作
From b007cef600bfb29f97eba86f7ec457f059070812 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sat, 2 Sep 2023 11:20:54 +0800
Subject: [PATCH 03/12] Add files via upload
---
plugin/mcfish/pack.go | 2 +-
plugin/mcfish/store.go | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/plugin/mcfish/pack.go b/plugin/mcfish/pack.go
index 0ec4f5cc53..2df31eb05d 100644
--- a/plugin/mcfish/pack.go
+++ b/plugin/mcfish/pack.go
@@ -267,7 +267,7 @@ func drawArticleInfoBlock(uid int64, articles []article, fontdata []byte) (image
return nil, err
}
titleW, titleH := canvas.MeasureString("背包信息")
- front := 50.0
+ front := 45.0
err = canvas.ParseFontFace(fontdata, front)
if err != nil {
return nil, err
diff --git a/plugin/mcfish/store.go b/plugin/mcfish/store.go
index 0591a26fa6..8f246ab525 100644
--- a/plugin/mcfish/store.go
+++ b/plugin/mcfish/store.go
@@ -61,7 +61,7 @@ func init() {
}
ctx.SendChain(message.ImageBytes(pic))
})
- engine.OnRegex(`^出售(.+(竿|鱼)|河豚|鹦鹉螺|诱钓|海之眷顾|唱片|美西螈)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ engine.OnRegex(`^出售(.+(竿|鱼)|河豚|鹦鹉螺|诱钓|海之眷顾|唱片|美西螈|三叉戟)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
thingName := ctx.State["regex_matched"].([]string)[1]
number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[3])
@@ -269,7 +269,7 @@ func init() {
}
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("出售成功,你赚到了", pice*number)))
})
- engine.OnRegex(`^购买(.+(竿|鱼)|河豚|鹦鹉螺|诱钓|海之眷顾|唱片|美西螈)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ engine.OnRegex(`^购买(.+(竿|鱼)|河豚|鹦鹉螺|诱钓|海之眷顾|唱片|美西螈|三叉戟)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
thingName := ctx.State["regex_matched"].([]string)[1]
number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[3])
From 18eb9beaf45046b3c5f3c52a6ac2dbba5b2dbf27 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sat, 2 Sep 2023 12:18:38 +0800
Subject: [PATCH 04/12] Add files via upload
---
plugin/mcfish/pack.go | 6 ++--
plugin/mcfish/pole.go | 4 +--
plugin/mcfish/store.go | 72 +++++++++++++++++++++++-------------------
3 files changed, 45 insertions(+), 37 deletions(-)
diff --git a/plugin/mcfish/pack.go b/plugin/mcfish/pack.go
index 2df31eb05d..9304b0c7dc 100644
--- a/plugin/mcfish/pack.go
+++ b/plugin/mcfish/pack.go
@@ -345,8 +345,10 @@ func drawArticleInfoBlock(uid int64, articles []article, fontdata []byte) (image
textDy += textH * 2
for i, info := range articles {
name := info.Name
- if info.Other != "" {
- numberOfEquip++
+ if info.Other != "" && info.Name != "美西螈" {
+ if info.Name != "三叉戟" {
+ numberOfEquip++
+ }
name += "(" + info.Other + ")"
} else if strings.Contains(name, "鱼") {
numberOfFish += info.Number
diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go
index e4989c742a..bd7ac4a054 100644
--- a/plugin/mcfish/pole.go
+++ b/plugin/mcfish/pole.go
@@ -275,7 +275,7 @@ func init() {
),
)
})
- engine.OnPrefix("附魔", getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ engine.OnRegex(`^附魔(诱钓|海之眷顾)$`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
equipInfo, err := dbdata.getUserEquip(uid)
if err != nil {
@@ -286,7 +286,7 @@ func init() {
ctx.SendChain(message.Text("仅可对装备中的进行附魔"))
return
}
- book := strings.TrimSpace(ctx.State["args"].(string))
+ book := ctx.State["regex_matched"].([]string)[1]
books, err := dbdata.getUserThingInfo(uid, book)
if err != nil {
ctx.SendChain(message.Text("[ERROR at pole.go.8]:", err))
diff --git a/plugin/mcfish/store.go b/plugin/mcfish/store.go
index 8f246ab525..a6d0198c57 100644
--- a/plugin/mcfish/store.go
+++ b/plugin/mcfish/store.go
@@ -83,7 +83,7 @@ func init() {
msg := make(message.Message, 0, 3+len(articles))
msg = append(msg, message.Reply(ctx.Event.MessageID), message.Text("找到以下物品:\n"))
for i, info := range articles {
- if info.Other != "" {
+ if info.Other != "" && info.Name != "美西螈" {
msg = append(msg, message.Text("[", i, "] ", info.Name, "(", info.Other, ")\n"))
} else {
msg = append(msg, message.Text(
@@ -136,7 +136,7 @@ func init() {
}
var pice int
- if strings.Contains(thingName, "竿") {
+ if strings.Contains(thingName, "竿") || thingName == "三叉戟" {
poleInfo := strings.Split(articles[index].Other, "/")
durable, _ := strconv.Atoi(poleInfo[0])
maintenance, _ := strconv.Atoi(poleInfo[1])
@@ -219,9 +219,10 @@ func init() {
ctx.SendChain(message.Text("[ERROR at store.go.6]:", err))
return
}
- if strings.Contains(thingName, "竿") {
+ newCommodity := store{}
+ if strings.Contains(thingName, "竿") || thingName == "三叉戟" {
if pice >= thingPice[thingName]*3/4 { // 不值钱的删了
- newCommodity := store{
+ newCommodity = store{
Duration: time.Now().Unix(),
Type: "pole",
Name: thingName,
@@ -229,11 +230,6 @@ func init() {
Price: pice,
Other: thing.Other,
}
- err = dbdata.updateStoreInfo(newCommodity)
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at store.go.7]:", err))
- return
- }
}
} else {
things, err1 := dbdata.getStoreThingInfo(thingName)
@@ -248,18 +244,22 @@ func init() {
Number: 0,
Price: pice,
})
- if thingName == "海之眷顾" || thingName == "诱钓" || thingName == "唱片" {
+ switch {
+ case thingName == "海之眷顾" || thingName == "诱钓" || thingName == "唱片":
things[0].Type = "article"
- } else {
+ case thingName == "美西螈":
+ things[0].Type = "pole"
+ default:
things[0].Type = "fish"
}
}
- things[0].Number += number
- err = dbdata.updateStoreInfo(things[0])
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at store.go.9]:", err))
- return
- }
+ newCommodity = things[0]
+ newCommodity.Number += number
+ }
+ err = dbdata.updateStoreInfo(newCommodity)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.9]:", err))
+ return
}
pice = pice * 8 / 10
err = wallet.InsertWalletOf(uid, pice*number)
@@ -288,7 +288,7 @@ func init() {
index := 0
pice := make([]int, 0, len(thingInfos))
for _, info := range thingInfos {
- if strings.Contains(thingName, "竿") {
+ if strings.Contains(thingName, "竿") || thingName == "三叉戟" {
poleInfo := strings.Split(info.Other, "/")
durable, _ := strconv.Atoi(poleInfo[0])
maintenance, _ := strconv.Atoi(poleInfo[1])
@@ -306,7 +306,7 @@ func init() {
msg := make(message.Message, 0, 3+len(thingInfos))
msg = append(msg, message.Text("找到以下物品:\n"))
for i, info := range thingInfos {
- if strings.Contains(thingName, "竿") {
+ if strings.Contains(thingName, "竿") || thingName == "三叉戟" {
msg = append(msg, message.Text(
"[", i, "]", info.Name, "(", info.Other, ") 价格:", pice[i], "\n"))
} else {
@@ -399,20 +399,25 @@ func init() {
ctx.SendChain(message.Text("[ERROR at store.go.13]:", err))
return
}
- if strings.Contains(thingName, "竿") {
- newCommodity := article{
+ newCommodity := article{}
+ switch {
+ case strings.Contains(thingName, "竿") || thingName == "三叉戟":
+ newCommodity = article{
Duration: time.Now().Unix(),
Type: "pole",
Name: thingName,
Number: 1,
Other: thing.Other,
}
- err = dbdata.updateUserThingInfo(uid, newCommodity)
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at store.go.14]:", err))
- return
+ case thingName == "美西螈":
+ newCommodity = article{
+ Duration: time.Now().Unix(),
+ Type: "pole",
+ Name: thingName,
+ Number: 1,
+ Other: "999/0/0/0",
}
- } else {
+ default:
things, err1 := dbdata.getUserThingInfo(uid, thingName)
if err1 != nil {
ctx.SendChain(message.Text("[ERROR at store.go.15]:", err1))
@@ -430,12 +435,13 @@ func init() {
things[0].Type = "fish"
}
}
- things[0].Number += number
- err = dbdata.updateUserThingInfo(uid, things[0])
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at store.go.16]:", err))
- return
- }
+ newCommodity = things[0]
+ newCommodity.Number += number
+ }
+ err = dbdata.updateUserThingInfo(uid, newCommodity)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at store.go.14]:", err))
+ return
}
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("购买成功")))
})
@@ -569,7 +575,7 @@ func drawStroeInfoImage(stroeInfo []store) (picImage image.Image, err error) {
for _, info := range stroeInfo {
textDy += textH * 2
name := info.Name
- if info.Other != "" {
+ if info.Other != "" && info.Name != "美西螈" {
name += "(" + info.Other + ")"
}
numberStr := strconv.Itoa(info.Number)
From 36a90780549b8a0c6d738c9cceef964ac0caba87 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sat, 2 Sep 2023 12:24:22 +0800
Subject: [PATCH 05/12] Update pole.go
---
plugin/mcfish/pole.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go
index bd7ac4a054..89d2abd8c0 100644
--- a/plugin/mcfish/pole.go
+++ b/plugin/mcfish/pole.go
@@ -350,7 +350,7 @@ func init() {
return
}
max := len(articles)
- if max == 0 {
+ if max < 3 {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你的合成材料不足"))
return
}
From 25edb92d253a4bd961848b6959abb39792ec4fa9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sat, 2 Sep 2023 12:28:27 +0800
Subject: [PATCH 06/12] Update pole.go
---
plugin/mcfish/pole.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go
index 89d2abd8c0..f8ff7e1e91 100644
--- a/plugin/mcfish/pole.go
+++ b/plugin/mcfish/pole.go
@@ -448,7 +448,7 @@ func init() {
favorLevel += poles[index].Favor
induceLevel += poles[index].Induce
}
- if rand.Intn(10) > 6 {
+ if rand.Intn(100) >= 90 {
ctx.Send(
message.ReplyWithMessage(ctx.Event.MessageID,
message.Text("合成失败,材料已销毁"),
From bc23be88840c8511e9ca68cca28a4ceb3ddb03c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sat, 2 Sep 2023 12:28:56 +0800
Subject: [PATCH 07/12] Update main.go
---
plugin/mcfish/main.go | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/plugin/mcfish/main.go b/plugin/mcfish/main.go
index 574f0401f0..8370bf21bd 100644
--- a/plugin/mcfish/main.go
+++ b/plugin/mcfish/main.go
@@ -23,8 +23,6 @@ type fishdb struct {
/*
type userInfo struct {
- UserID int64 // QQ
- Bait int // 鱼饵
// 鱼竿 10% 装备/耐久/维修次数/诱钓/眷顾
WoodenPole string // 木竿属性 70%
IronPole string // 铁竿属性 20%
@@ -129,7 +127,7 @@ var (
"4.稀有物品:\n-> 唱片 : 出售物品时使用该物品使价格翻倍. 均价:3000, 上钩概率:0.01%\n-> 美西螈 : 可装备,获得隐形[钓鱼佬]buff,并让钓到除鱼竿和美西螈外的物品数量变成3,无耐久上限.不可修复/附魔,每次钓鱼消耗任意一鱼类物品. 均价:3000, 上钩概率:0.01%\n" +
"5.鱼类信息:\n-> 鳕鱼 : 均价:10 上钩概率:20.7%\n-> 鲑鱼 : 均价:50 上钩概率:6%\n-> 热带鱼 : 均价:100 上钩概率:1.8%\n-> 河豚 : 均价:300 上钩概率:0.9%\n-> 鹦鹉螺 : 均价:500 上钩概率:0.3%\n-> 墨鱼 : 均价:500 上钩概率:0.3%\n" +
"6.物品BUFF:\n-> 钓鱼佬 : 当背包名字含有'鱼'的物品数量超过100时激活,钓到物品概率提高至90%\n-> 修复大师 : 当背包鱼竿数量超过10时激活,修复物品时耐久百分百继承\n" +
- "7.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率70%,继承附魔等级合/3的等级\n" +
+ "7.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率90%,继承附魔等级合/3的等级\n" +
"8.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为56%\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿",
PublicDataFolder: "McFish",
}).ApplySingle(ctxext.DefaultSingle)
From 8730c7b4525638648001cb4345c5e1b3bbf675f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sat, 2 Sep 2023 13:37:02 +0800
Subject: [PATCH 08/12] Add files via upload
---
plugin/mcfish/fish.go | 12 +++++++++---
plugin/mcfish/main.go | 23 +++++++++++++++++++----
2 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/plugin/mcfish/fish.go b/plugin/mcfish/fish.go
index 5614d20714..858bf27a12 100644
--- a/plugin/mcfish/fish.go
+++ b/plugin/mcfish/fish.go
@@ -113,12 +113,12 @@ func init() {
msg = "(你的鱼竿耐久仅剩" + strconv.Itoa(equipInfo.Durable) + ")"
}
} else {
- fishNmae, err := dbdata.pickFishFor(uid)
+ fishNmaes, err := dbdata.pickFishFor(uid, fishNumber)
if err != nil {
ctx.SendChain(message.Text("[ERROR at fish.go.5.1]:", err))
return
}
- if fishNmae == "" {
+ if len(fishNmaes) == 0 {
equipInfo.Durable = 0
err = dbdata.updateUserEquip(equipInfo)
if err != nil {
@@ -127,7 +127,13 @@ func init() {
ctx.SendChain(message.Text("美西螈因为没吃到鱼,钓鱼时一直没回来,你失去了美西螈"))
return
}
- msg = "(美西螈吃掉了一条" + fishNmae + ")"
+ msg = "(美西螈吃掉了"
+ fishNumber = 0
+ for name, number := range fishNmaes {
+ fishNumber += number
+ msg += strconv.Itoa(number) + name + "、"
+ }
+ msg += ")"
}
waitTime := 120 / (equipInfo.Induce + 1)
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你开始去钓鱼了,请耐心等待鱼上钩(预计要", time.Second*time.Duration(waitTime), ")"))
diff --git a/plugin/mcfish/main.go b/plugin/mcfish/main.go
index 8370bf21bd..5924690705 100644
--- a/plugin/mcfish/main.go
+++ b/plugin/mcfish/main.go
@@ -468,7 +468,8 @@ func (sql *fishdb) setEquipFor(uid int64) (err error) {
return sql.db.Insert("fishState", &userInfo)
}
-func (sql *fishdb) pickFishFor(uid int64) (fishName string, err error) {
+func (sql *fishdb) pickFishFor(uid int64, number int) (fishNames map[string]int, err error) {
+ fishNames = make(map[string]int, 6)
name := strconv.FormatInt(uid, 10) + "Pack"
sql.Lock()
defer sql.Unlock()
@@ -499,7 +500,21 @@ func (sql *fishdb) pickFishFor(uid int64) (fishName string, err error) {
if len(fishTypes) == 0 {
return
}
- randNumber := rand.Intn(len(fishTypes))
- fishTypes[randNumber].Number--
- return fishTypes[randNumber].Name, sql.db.Insert(name, &fishTypes[randNumber])
+ max := 0
+ for _, info := range fishTypes {
+ max += info.Number
+ }
+ if max < number {
+ number = max
+ }
+ for i := number; i > 0; i-- {
+ randNumber := rand.Intn(len(fishTypes))
+ fishTypes[randNumber].Number--
+ err = sql.db.Insert(name, &fishTypes[randNumber])
+ if err != nil {
+ return
+ }
+ fishNames[fishTypes[randNumber].Name]++
+ }
+ return
}
From 80ba593ba6536eccb9b234d4fe7fb5743a94adeb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sun, 3 Sep 2023 09:22:19 +0800
Subject: [PATCH 09/12] Add files via upload
---
plugin/mcfish/fish.go | 273 +++++++++++-----------
plugin/mcfish/main.go | 497 +++++++++++++++++++++++------------------
plugin/mcfish/pack.go | 72 +++++-
plugin/mcfish/pole.go | 43 ++--
plugin/mcfish/store.go | 48 ++--
5 files changed, 529 insertions(+), 404 deletions(-)
diff --git a/plugin/mcfish/fish.go b/plugin/mcfish/fish.go
index 858bf27a12..7b9736e4f8 100644
--- a/plugin/mcfish/fish.go
+++ b/plugin/mcfish/fish.go
@@ -4,6 +4,7 @@ package mcfish
import (
"math/rand"
"strconv"
+ "strings"
"time"
"github.com/FloatTech/AnimeAPI/wallet"
@@ -14,13 +15,13 @@ import (
)
func init() {
- engine.OnRegex(`^进行(([1-5]\d*)次)?钓鱼$`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ engine.OnRegex(`^进行(([1-5]\d|[1-9])次)?钓鱼$`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
fishNumber := 1
info := ctx.State["regex_matched"].([]string)[2]
if info != "" {
number, err := strconv.Atoi(info)
- if err != nil || number > 50 {
+ if err != nil || number > FishLimit {
ctx.SendChain(message.Text("请输入正确的次数"))
return
}
@@ -32,7 +33,7 @@ func init() {
return
}
if residue == 0 {
- ctx.SendChain(message.Text("今天你已经进行", fishLimit, "次钓鱼了.\n游戏虽好,但请不要沉迷。"))
+ ctx.SendChain(message.Text("今天你已经进行", FishLimit, "次钓鱼了.\n游戏虽好,但请不要沉迷。"))
return
}
fishNumber = residue
@@ -143,169 +144,157 @@ func init() {
timer.Stop()
break
}
- // 概率
- wasteProbability := 41 + equipInfo.Favor*10
- poleProbability := 11 + equipInfo.Favor*3
- bookProbability := 1 + equipInfo.Favor*1
// 钓到鱼的范围
number, err := dbdata.getNumberFor(uid, "鱼")
if err != nil {
ctx.SendChain(message.Text("[ERROR at fish.go.5.1]:", err))
return
}
- getFishMaxDy := 9
- getFishMinDy := 2
- getFishMaxDx := 9
- getFishMinDx := 1
- if number > 100 || equipInfo.Equip == "美西螈" {
- getFishMaxDy = 10
- getFishMinDy = 1
- getFishMaxDx = 10
- getFishMinDx = 0
+ if number > 100 || equipInfo.Equip == "美西螈" { //放大概率
+ probabilities["treasure"] = probabilityLimit{
+ Min: 0,
+ Max: 2,
+ }
+ probabilities["pole"] = probabilityLimit{
+ Min: 2,
+ Max: 10,
+ }
+ probabilities["fish"] = probabilityLimit{
+ Min: 10,
+ Max: 45,
+ }
+ probabilities["waste"] = probabilityLimit{
+ Min: 45,
+ Max: 90,
+ }
+ }
+ for name, info := range probabilities {
+ switch name {
+ case "treasure":
+ info.Max += equipInfo.Favor
+ probabilities[name] = info
+ case "pole":
+ info.Min += equipInfo.Favor
+ info.Max += equipInfo.Favor * 2
+ probabilities[name] = info
+ case "fish":
+ info.Min += equipInfo.Favor * 2
+ info.Max += equipInfo.Favor * 3
+ probabilities[name] = info
+ case "waste":
+ info.Min += equipInfo.Favor * 3
+ probabilities[name] = info
+ }
}
// 钓鱼结算
- thingNameList := make(map[string]int)
picName := ""
+ thingNameList := make(map[string]int)
for i := fishNumber; i > 0; i-- {
- fishDx := rand.Intn(11)
- fishDy := rand.Intn(11)
- if fishDx < getFishMinDx || fishDx > getFishMaxDx || fishDy < getFishMinDy || fishDy > getFishMaxDy {
- if fishNumber == 1 {
- ctx.SendChain(message.At(uid), message.Text("很遗憾你没有钓到鱼", msg))
- return
- }
- thingNameList["空竿"]++
- continue
- }
+ thingName := ""
+ typeOfThing := ""
+ number := 1
dice := rand.Intn(100)
switch {
- case dice >= wasteProbability: // 垃圾
- waste := wasteList[rand.Intn(len(wasteList))]
- money := 10
- if equipInfo.Equip == "美西螈" {
- money *= 3
- }
- err := wallet.InsertWalletOf(uid, money)
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at fish.go.9]:", err))
- return
- }
- picName = waste
- thingNameList[waste]++
- if fishNumber == 1 {
- msg = "为河流净化做出了贡献,\n给予" + strconv.Itoa(money) + "奖励金\n" + msg
- }
- case dice <= bookProbability:
- picName = "book"
- thingName := "诱钓"
- dice := rand.Intn(100)
+ case dice <= probabilities["waste"].Min && dice < probabilities["waste"].Max: // 垃圾
+ typeOfThing = "waste"
+ thingName = wasteList[rand.Intn(len(wasteList))]
+ picName = thingName
+ case dice <= probabilities["treasure"].Min && dice < probabilities["treasure"].Max: // 宝藏
+ dice = rand.Intn(100)
switch {
- case dice == 0:
+ case dice <= probabilities["美西螈"].Min && dice < probabilities["美西螈"].Max:
+ typeOfThing = "pole"
picName = "美西螈"
thingName = "美西螈"
- case dice == 1:
+ case dice <= probabilities["唱片"].Min && dice < probabilities["唱片"].Max:
+ typeOfThing = "article"
picName = "唱片"
thingName = "唱片"
- case dice < 41 && dice > 1:
+ case dice <= probabilities["海之眷顾"].Min && dice < probabilities["海之眷顾"].Max:
+ typeOfThing = "article"
+ picName = "book"
thingName = "海之眷顾"
+ default:
+ typeOfThing = "article"
+ picName = "book"
+ thingName = "诱钓"
}
- books, err := dbdata.getUserThingInfo(uid, thingName)
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at fish.go.6]:", err))
- return
- }
- if len(books) == 0 {
- books = append(books, article{
- Duration: time.Now().Unix()*100 + int64(i),
- Type: "article",
- Name: thingName,
- })
- }
- if thingName == "美西螈" {
- books[0].Type = "pole"
- books[0].Other = "999/0/0/0"
- }
- number := 1
- if equipInfo.Equip == "美西螈" && thingName != "美西螈" {
- number += 2
- }
- books[0].Number += number
- err = dbdata.updateUserThingInfo(uid, books[0])
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at fish.go.7]:", err))
- return
- }
- thingNameList[thingName] += number
- case dice > bookProbability && dice <= poleProbability:
- poleNmae := "木竿"
+ case dice <= probabilities["pole"].Min && dice < probabilities["pole"].Max: // 宝藏
+ typeOfThing = "pole"
dice := rand.Intn(100)
switch {
- case dice >= 10 && dice < 30:
- poleNmae = "铁竿"
- case dice >= 4 && dice < 10:
- poleNmae = "金竿"
- case dice >= 1 && dice < 4:
- poleNmae = "钻石竿"
- case dice == 0:
- poleNmae = "下界合金竿竿竿"
- }
- newPole := article{
- Duration: time.Now().Unix()*100 + int64(i),
- Type: "pole",
- Name: poleNmae,
- Number: 1,
- Other: strconv.Itoa(rand.Intn(equipAttribute[poleNmae])+1) +
- "/" + strconv.Itoa(rand.Intn(10)) + "/" +
- strconv.Itoa(rand.Intn(3)) + "/" + strconv.Itoa(rand.Intn(2)),
- }
- err = dbdata.updateUserThingInfo(uid, newPole)
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at fish.go.8]:", err))
- return
+ case dice <= probabilities["铁竿"].Min && dice < probabilities["铁竿"].Max:
+ thingName = "铁竿"
+ case dice <= probabilities["金竿"].Min && dice < probabilities["金竿"].Max:
+ thingName = "金竿"
+ case dice <= probabilities["钻石竿"].Min && dice < probabilities["钻石竿"].Max:
+ thingName = "钻石竿"
+ case dice <= probabilities["下界合金竿竿竿"].Min && dice < probabilities["下界合金竿竿竿"].Max:
+ thingName = "下界合金竿竿竿"
+ default:
+ thingName = "木竿"
}
- picName = poleNmae
- thingNameList[poleNmae]++
- default:
- fishName := ""
+ picName = thingName
+ case dice <= probabilities["fish"].Min && dice < probabilities["fish"].Max:
+ typeOfThing = "fish"
dice = rand.Intn(100)
switch {
- case dice == 99:
- fishName = "墨鱼"
- case dice >= 30 && dice != 99:
- fishName = "鳕鱼"
- case dice >= 10 && dice < 30:
- fishName = "鲑鱼"
- case dice >= 4 && dice < 10:
- fishName = "热带鱼"
- case dice >= 1 && dice < 4:
- fishName = "河豚"
+ case dice <= probabilities["墨鱼"].Min && dice < probabilities["墨鱼"].Max:
+ thingName = "墨鱼"
+ case dice <= probabilities["鳕鱼"].Min && dice < probabilities["鳕鱼"].Max:
+ thingName = "鳕鱼"
+ case dice <= probabilities["鲑鱼"].Min && dice < probabilities["鲑鱼"].Max:
+ thingName = "鲑鱼"
+ case dice <= probabilities["热带鱼"].Min && dice < probabilities["热带鱼"].Max:
+ thingName = "热带鱼"
+ case dice <= probabilities["河豚"].Min && dice < probabilities["河豚"].Max:
+ thingName = "河豚"
default:
- fishName = "鹦鹉螺"
+ thingName = "鹦鹉螺"
}
- fishes, err := dbdata.getUserThingInfo(uid, fishName)
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at fish.go.10]:", err))
- return
- }
- if len(fishes) == 0 {
- fishes = append(fishes, article{
+ picName = thingName
+ default:
+ thingNameList["赛博空气"]++
+ }
+ if thingName != "" {
+ newThing := article{}
+ if strings.Contains(thingName, "竿") {
+ info := strconv.Itoa(rand.Intn(discountList[thingName])+1) +
+ "/" + strconv.Itoa(rand.Intn(10)) + "/" +
+ strconv.Itoa(rand.Intn(3)) + "/" + strconv.Itoa(rand.Intn(2))
+ newThing = article{
Duration: time.Now().Unix()*100 + int64(i),
- Type: "fish",
- Name: fishName,
- })
- }
- number := 1
- if equipInfo.Equip == "美西螈" || equipInfo.Equip == "三叉戟" {
- number += 2
+ Type: typeOfThing,
+ Name: thingName,
+ Number: number,
+ Other: info,
+ }
+ } else {
+ thingInfo, err := dbdata.getUserThingInfo(uid, thingName)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.6]:", err))
+ return
+ }
+ if len(thingInfo) == 0 {
+ newThing = article{
+ Duration: time.Now().Unix()*100 + int64(i),
+ Type: typeOfThing,
+ Name: thingName,
+ }
+ } else {
+ newThing = thingInfo[0]
+ }
+ if equipInfo.Equip == "美西螈" && thingName != "美西螈" {
+ number += 2
+ }
+ newThing.Number += number
}
- fishes[0].Number += number
- err = dbdata.updateUserThingInfo(uid, fishes[0])
+ err = dbdata.updateUserThingInfo(uid, newThing)
if err != nil {
- ctx.SendChain(message.Text("[ERROR at fish.go.11]:", err))
+ ctx.SendChain(message.Text("[ERROR at fish.go.7]:", err))
return
}
- picName = fishName
- thingNameList[fishName] += number
+ thingNameList[thingName] += number
}
}
if len(thingNameList) == 1 {
@@ -313,13 +302,17 @@ func init() {
for name := range thingNameList {
thingName = name
}
- pic, err := engine.GetLazyData(picName+".png", false)
- if err != nil {
- logrus.Warnln("[mcfish]error:", err)
- ctx.SendChain(message.At(uid), message.Text("恭喜你钓到了", thingName, "\n", msg))
+ if picName != "" {
+ pic, err := engine.GetLazyData(picName+".png", false)
+ if err != nil {
+ logrus.Warnln("[mcfish]error:", err)
+ ctx.SendChain(message.At(uid), message.Text("恭喜你钓到了", thingName, "\n", msg))
+ return
+ }
+ ctx.SendChain(message.At(uid), message.Text("恭喜你钓到了", thingName, "\n", msg), message.ImageBytes(pic))
return
}
- ctx.SendChain(message.At(uid), message.Text("恭喜你钓到了", thingName, "\n", msg), message.ImageBytes(pic))
+ ctx.SendChain(message.At(uid), message.Text("恭喜你钓到了", thingName, "\n", msg))
return
}
msgInfo := make(message.Message, 0, 3+len(thingNameList))
diff --git a/plugin/mcfish/main.go b/plugin/mcfish/main.go
index 5924690705..d22aa1b47d 100644
--- a/plugin/mcfish/main.go
+++ b/plugin/mcfish/main.go
@@ -2,7 +2,9 @@
package mcfish
import (
+ "encoding/json"
"math/rand"
+ "os"
"strconv"
"sync"
"time"
@@ -21,39 +23,30 @@ type fishdb struct {
sync.RWMutex
}
-/*
-type userInfo struct {
- // 鱼竿 10% 装备/耐久/维修次数/诱钓/眷顾
- WoodenPole string // 木竿属性 70%
- IronPole string // 铁竿属性 20%
- GoldenPole string // 金竿属性 6%
- DiamondPole string // 钻石竿属性 3%
- NetherPole string // 下界合金竿属性 1%
- // 鱼 30%
- Cod int // 鳕鱼数量 69%
- Salmon int // 鲑鱼数量 20%
- Tropical int // 热带鱼 6%
- Globe int // 河豚 3%
- Nautilus int // 鹦鹉螺 1%
- Nautilus int // 墨鱼1%
- // 宝藏 1%
- Induce int // 诱钓 59%
- Favor int // 眷顾 39%
- Record int // 唱片 1%
- Record int // 美西螈 1%
- // 垃圾 59%
- Leaf int // 荷叶 10%
- Rod int // 木棍 10%
- bamboo int // 竹子 10%
- Shoe int // 鞋子 10%
- Bottle int // 瓶子 10%
- Hanger int // 拌线钩 10%
- Bone int // 骨头 10%
- Leather int // 皮革 10%
- Carrion int // 腐肉 10%
- Bowl int // 碗 10%
+// FishLimit 钓鱼次数上限
+const FishLimit = 50
+
+// 各物品信息
+type jsonInfo struct {
+ ZoneInfo []zoneInfo `json:"分类"` // 区域概率
+ ArticleInfo []articleInfo `json:"物品"` // 物品信息
+}
+type zoneInfo struct {
+ Name string `json:"类型"` //类型
+ Probability int `json:"概率[0-100)"` // 概率
+}
+type articleInfo struct {
+ Name string `json:"名称"` //名称
+ Type string `json:"类型"` // 类型
+ Probability int `json:"概率[0-100),omitempty"` // 概率
+ Durable int `json:"耐久上限,omitempty"` // 耐久
+ Price int `json:"价格"` // 价格
+}
+
+type probabilityLimit struct {
+ Min int
+ Max int
}
-*/
type equip struct {
ID int64 // 用户
@@ -94,25 +87,23 @@ type storeDiscount struct {
}
var (
- equipAttribute = map[string]int{
- "木竿": 30, "铁竿": 50, "金竿": 70, "钻石竿": 100, "下界合金竿": 150, "三叉戟": 300, "美西螈": 999,
- }
- thingPice = map[string]int{
- "鳕鱼": 10, "鲑鱼": 50, "热带鱼": 100, "河豚": 300, "鹦鹉螺": 500, "墨鱼": 500,
- "木竿": 100, "铁竿": 300, "金竿": 700, "钻石竿": 1500, "下界合金竿": 3100, "三叉戟": 4000,
- "诱钓": 1000, "海之眷顾": 2500, "唱片": 3000, "美西螈": 3000,
- }
- discount = map[string]int{
- "鳕鱼": 100, "鲑鱼": 100, "热带鱼": 100, "河豚": 100, "鹦鹉螺": 100, "墨鱼": 100,
- "木竿": 100, "铁竿": 100, "金竿": 100, "钻石竿": 100, "下界合金竿": 100, "三叉戟": 100,
- "诱钓": 100, "海之眷顾": 100, "唱片": 100, "美西螈": 100,
- }
- fishList = []string{"鳕鱼", "鲑鱼", "热带鱼"}
- wasteList = []string{"海草", "木棍", "帽子", "鞋子", "瓶子", "拌线钩", "骨头", "皮革", "腐肉", "碗"}
- enchantLevel = []string{"0", "Ⅰ", "Ⅱ", "Ⅲ"}
- dbdata = &fishdb{
+ articlesInfo = jsonInfo{} // 物品信息
+ thingList = make([]string, 0, 100) // 竿列表
+ poleList = make([]string, 0, 10) // 竿列表
+ fishList = make([]string, 0, 10) // 鱼列表
+ treasureList = make([]string, 0, 10) // 鱼列表
+ wasteList = make([]string, 0, 10) // 垃圾列表
+ probabilities = make(map[string]probabilityLimit, 50) // 概率分布
+ priceList = make(map[string]int, 50) // 价格分布
+ durationList = make(map[string]int, 50) // 装备耐久分布
+ discountList = make(map[string]int, 50) // 价格波动信息
+ enchantLevel = []string{"0", "Ⅰ", "Ⅱ", "Ⅲ"}
+ dbdata = &fishdb{
db: &sql.Sqlite{},
}
+)
+
+var (
engine = control.Register("mcfish", &ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "钓鱼",
@@ -121,14 +112,14 @@ var (
"- 钓鱼背包\n- 装备[xx竿|三叉戟|美西螈]\n- 附魔[诱钓|海之眷顾]\n- 修复鱼竿\n- 合成[xx竿|三叉戟]\n" +
"- 进行钓鱼\n- 进行n次钓鱼\n" +
"规则:\n1.每日的商店价格是波动的!!如何最大化收益自己考虑一下喔\n" +
- "2.装备信息:\n-> 木竿 : 耐久上限:30 均价:100 上钩概率:7%\n-> 铁竿 : 耐久上限:50 均价:300 上钩概率:2%\n-> 金竿 : 耐久上限:70 均价700 上钩概率:0.6%\n" +
- "-> 钻石竿 : 耐久上限:100 均价1500 上钩概率:0.3%\n-> 下界合金竿 : 耐久上限:150 均价3100 上钩概率:0.1%\n-> 三叉戟 : 可使钓的鱼类物品数量变成3 耐久上限:300 均价4000 只能合成和交易\n" +
+ "2.装备信息:\n-> 木竿 : 耐久上限:30 均价:100 上钩概率:0.7%\n-> 铁竿 : 耐久上限:50 均价:300 上钩概率:0.2%\n-> 金竿 : 耐久上限:70 均价700 上钩概率:0.06%\n" +
+ "-> 钻石竿 : 耐久上限:100 均价1500 上钩概率:0..3%\n-> 下界合金竿 : 耐久上限:150 均价3100 上钩概率:0..1%\n-> 三叉戟 : 可使钓的鱼类物品数量变成3 耐久上限:300 均价4000 只能合成和交易\n" +
"3.附魔书信息:\n-> 诱钓 : 减少上钩时间. 均价:1000, 上钩概率:0.59%\n-> 海之眷顾 : 增加宝藏上钩概率. 均价:2500, 上钩概率:0.39%\n" +
"4.稀有物品:\n-> 唱片 : 出售物品时使用该物品使价格翻倍. 均价:3000, 上钩概率:0.01%\n-> 美西螈 : 可装备,获得隐形[钓鱼佬]buff,并让钓到除鱼竿和美西螈外的物品数量变成3,无耐久上限.不可修复/附魔,每次钓鱼消耗任意一鱼类物品. 均价:3000, 上钩概率:0.01%\n" +
- "5.鱼类信息:\n-> 鳕鱼 : 均价:10 上钩概率:20.7%\n-> 鲑鱼 : 均价:50 上钩概率:6%\n-> 热带鱼 : 均价:100 上钩概率:1.8%\n-> 河豚 : 均价:300 上钩概率:0.9%\n-> 鹦鹉螺 : 均价:500 上钩概率:0.3%\n-> 墨鱼 : 均价:500 上钩概率:0.3%\n" +
+ "5.鱼类信息:\n-> 鳕鱼 : 均价:10 上钩概率:0.69%\n-> 鲑鱼 : 均价:50 上钩概率:0.2%\n-> 热带鱼 : 均价:100 上钩概率:0.06%\n-> 河豚 : 均价:300 上钩概率:0.03%\n-> 鹦鹉螺 : 均价:500 上钩概率:0.01%\n-> 墨鱼 : 均价:500 上钩概率:0.01%\n" +
"6.物品BUFF:\n-> 钓鱼佬 : 当背包名字含有'鱼'的物品数量超过100时激活,钓到物品概率提高至90%\n-> 修复大师 : 当背包鱼竿数量超过10时激活,修复物品时耐久百分百继承\n" +
"7.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率90%,继承附魔等级合/3的等级\n" +
- "8.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为56%\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿",
+ "8.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为60%(理论值!!!)\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿",
PublicDataFolder: "McFish",
}).ApplySingle(ctxext.DefaultSingle)
getdb = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
@@ -140,16 +131,147 @@ var (
}
return true
})
- fishLimit = 50 // 钓鱼次数上限
)
-/*
func init() {
- for name := range thingPice {
- _, _ = engine.GetLazyData(name+".png", false)
+ //go func() {
+ _, err := engine.GetLazyData("articlesInfo.json", false)
+ if err != nil {
+ panic(err)
+ }
+ reader, err := os.Open(engine.DataFolder() + "articlesInfo.json")
+ if err == nil {
+ err = json.NewDecoder(reader).Decode(&articlesInfo)
+ }
+ if err == nil {
+ err = reader.Close()
+ }
+ if err != nil {
+ panic(err)
+ }
+ probableList := make([]int, 4)
+ for _, info := range articlesInfo.ZoneInfo {
+ switch info.Name {
+ case "treasure":
+ probableList[0] = info.Probability
+ case "pole":
+ probableList[1] = info.Probability
+ case "fish":
+ probableList[2] = info.Probability
+ case "waste":
+ probableList[3] = info.Probability
+ }
+ }
+ probabilities["treasure"] = probabilityLimit{
+ Min: 0,
+ Max: probableList[0],
+ }
+ probabilities["pole"] = probabilityLimit{
+ Min: probableList[0],
+ Max: probableList[1],
+ }
+ probabilities["fish"] = probabilityLimit{
+ Min: probableList[1],
+ Max: probableList[2],
+ }
+ probabilities["waste"] = probabilityLimit{
+ Min: probableList[2],
+ Max: probableList[3],
+ }
+ min := make(map[string]int, 4)
+ for _, info := range articlesInfo.ArticleInfo {
+ switch {
+ case info.Type == "pole":
+ poleList = append(poleList, info.Name)
+ case info.Type == "fish":
+ fishList = append(fishList, info.Name)
+ case info.Type == "waste":
+ wasteList = append(wasteList, info.Name)
+ case info.Type == "treasure":
+ treasureList = append(treasureList, info.Name)
+ }
+ thingList = append(thingList, info.Name)
+ priceList[info.Name] = info.Price
+ if info.Durable != 0 {
+ durationList[info.Name] = info.Durable
+ }
+ probabilities[info.Name] = probabilityLimit{
+ Min: min[info.Type],
+ Max: min[info.Type] + info.Probability,
+ }
+ min[info.Type] += info.Probability
+ }
+ //}()
+}
+
+// 更新上限信息
+func (sql *fishdb) updateFishInfo(uid int64, number int) (residue int, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := fishState{ID: uid}
+ err = sql.db.Create("fishState", &userInfo)
+ if err != nil {
+ return 0, err
+ }
+ _ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
+ if time.Unix(userInfo.Duration, 0).Day() != time.Now().Day() {
+ userInfo.Fish = 0
+ userInfo.Duration = time.Now().Unix()
+ }
+ if userInfo.Fish >= FishLimit {
+ return 0, nil
+ }
+ residue = number
+ if userInfo.Fish+number > FishLimit {
+ residue = FishLimit - userInfo.Fish
+ number = residue
+ }
+ userInfo.Fish += number
+ err = sql.db.Insert("fishState", &userInfo)
+ return
+}
+
+/*********************************************************/
+/************************装备相关函数***********************/
+/*********************************************************/
+
+func (sql *fishdb) checkEquipFor(uid int64) (ok bool, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := fishState{ID: uid}
+ err = sql.db.Create("fishState", &userInfo)
+ if err != nil {
+ return false, err
+ }
+ if !sql.db.CanFind("fishState", "where ID = "+strconv.FormatInt(uid, 10)) {
+ return true, nil
+ }
+ err = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
+ if err != nil {
+ return false, err
+ }
+ if userInfo.Equip > 3 {
+ return false, nil
+ }
+ return true, nil
+}
+
+func (sql *fishdb) setEquipFor(uid int64) (err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := fishState{ID: uid}
+ err = sql.db.Create("fishState", &userInfo)
+ if err != nil {
+ return err
+ }
+ _ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
+ if err != nil {
+ return err
}
+ userInfo.Equip++
+ return sql.db.Insert("fishState", &userInfo)
}
-*/
+
// 获取装备信息
func (sql *fishdb) getUserEquip(uid int64) (userInfo equip, err error) {
sql.Lock()
@@ -179,6 +301,61 @@ func (sql *fishdb) updateUserEquip(userInfo equip) (err error) {
return sql.db.Insert("equips", &userInfo)
}
+func (sql *fishdb) pickFishFor(uid int64, number int) (fishNames map[string]int, err error) {
+ fishNames = make(map[string]int, 6)
+ name := strconv.FormatInt(uid, 10) + "Pack"
+ sql.Lock()
+ defer sql.Unlock()
+ userInfo := article{}
+ err = sql.db.Create(name, &userInfo)
+ if err != nil {
+ return
+ }
+ count, err := sql.db.Count(name)
+ if err != nil {
+ return
+ }
+ if count == 0 {
+ return
+ }
+ if !sql.db.CanFind(name, "where Type is 'fish'") {
+ return
+ }
+ fishTypes := make([]article, 0, count)
+ fishInfo := article{}
+ err = sql.db.FindFor(name, &fishInfo, "where Type is 'fish'", func() error {
+ fishTypes = append(fishTypes, fishInfo)
+ return nil
+ })
+ if err != nil {
+ return
+ }
+ if len(fishTypes) == 0 {
+ return
+ }
+ max := 0
+ for _, info := range fishTypes {
+ max += info.Number
+ }
+ if max < number {
+ number = max
+ }
+ for i := number; i > 0; i-- {
+ randNumber := rand.Intn(len(fishTypes))
+ fishTypes[randNumber].Number--
+ err = sql.db.Insert(name, &fishTypes[randNumber])
+ if err != nil {
+ return
+ }
+ fishNames[fishTypes[randNumber].Name]++
+ }
+ return
+}
+
+/*********************************************************/
+/************************背包相关函数***********************/
+/*********************************************************/
+
// 获取用户背包信息
func (sql *fishdb) getUserPack(uid int64) (thingInfos []article, err error) {
sql.Lock()
@@ -244,97 +421,39 @@ func (sql *fishdb) updateUserThingInfo(uid int64, userInfo article) (err error)
return sql.db.Insert(name, &userInfo)
}
-// 获取商店信息
-func (sql *fishdb) getStoreInfo() (thingInfos []store, err error) {
- sql.Lock()
- defer sql.Unlock()
- thingInfo := store{}
- err = sql.db.Create("store", &thingInfo)
- if err != nil {
- return
- }
- count, err := sql.db.Count("store")
- if err != nil {
- return
- }
- if count == 0 {
- return
- }
- err = sql.db.FindFor("store", &thingInfo, "ORDER by Type, Name, Price ASC", func() error {
- thingInfos = append(thingInfos, thingInfo)
- return nil
- })
- return
-}
-
-// 获取商店物品信息
-func (sql *fishdb) getStoreThingInfo(thing string) (thingInfos []store, err error) {
+// 获取某关键字的数量
+func (sql *fishdb) getNumberFor(uid int64, thing string) (number int, err error) {
+ name := strconv.FormatInt(uid, 10) + "Pack"
sql.Lock()
defer sql.Unlock()
- thingInfo := store{}
- err = sql.db.Create("store", &thingInfo)
+ userInfo := article{}
+ err = sql.db.Create(name, &userInfo)
if err != nil {
return
}
- count, err := sql.db.Count("store")
+ count, err := sql.db.Count(name)
if err != nil {
return
}
if count == 0 {
return
}
- if !sql.db.CanFind("store", "where Name = '"+thing+"'") {
+ if !sql.db.CanFind(name, "where Name glob '*"+thing+"*'") {
return
}
- err = sql.db.FindFor("store", &thingInfo, "where Name = '"+thing+"'", func() error {
- thingInfos = append(thingInfos, thingInfo)
+ info := article{}
+ err = sql.db.FindFor(name, &info, "where Name glob '*"+thing+"*'", func() error {
+ number += info.Number
return nil
})
return
}
-// 更新商店信息
-func (sql *fishdb) updateStoreInfo(thingInfo store) (err error) {
- sql.Lock()
- defer sql.Unlock()
- err = sql.db.Create("store", &thingInfo)
- if err != nil {
- return
- }
- if thingInfo.Number == 0 {
- return sql.db.Del("store", "where Duration = "+strconv.FormatInt(thingInfo.Duration, 10))
- }
- return sql.db.Insert("store", &thingInfo)
-}
-
-// 更新上限信息
-func (sql *fishdb) updateFishInfo(uid int64, number int) (residue int, err error) {
- sql.Lock()
- defer sql.Unlock()
- userInfo := fishState{ID: uid}
- err = sql.db.Create("fishState", &userInfo)
- if err != nil {
- return 0, err
- }
- _ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
- if time.Unix(userInfo.Duration, 0).Day() != time.Now().Day() {
- userInfo.Fish = 0
- userInfo.Duration = time.Now().Unix()
- }
- if userInfo.Fish >= fishLimit {
- return 0, nil
- }
- residue = number
- if userInfo.Fish+number > fishLimit {
- residue = fishLimit - userInfo.Fish
- number = residue
- }
- userInfo.Fish += number
- err = sql.db.Insert("fishState", &userInfo)
- return
-}
+/*********************************************************/
+/************************商店相关函数***********************/
+/*********************************************************/
-// 更新上限信息
+// 刷新商店信息
func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
sql.Lock()
defer sql.Unlock()
@@ -357,7 +476,7 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
}
refresh = true
}
- for name := range thingPice {
+ for name := range priceList {
thing := storeDiscount{}
switch refresh {
case true:
@@ -371,15 +490,12 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
return
}
default:
- err = sql.db.Find("stroeDiscount", &thing, "where Name = '"+name+"'")
- if err != nil {
- return
- }
+ _ = sql.db.Find("stroeDiscount", &thing, "where Name = '"+name+"'")
}
if thing.Discount != 0 {
- discount[name] = thing.Discount
+ discountList[name] = thing.Discount
} else {
- discount[name] = 100
+ discountList[name] = 100
}
}
if refresh { // 每天调控1种鱼
@@ -394,9 +510,9 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
thingInfo.Duration = time.Now().Unix()
thingInfo.Type = "fish"
thingInfo.Name = fish
- thingInfo.Price = thingPice[fish] * discount[fish] / 100
+ thingInfo.Price = priceList[fish] * discountList[fish] / 100
}
- thingInfo.Number -= (discount[fish] - 100)
+ thingInfo.Number += (100 - discountList[fish])
if thingInfo.Number < 1 {
thingInfo.Number = 1
}
@@ -405,116 +521,65 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
return true, nil
}
-func (sql *fishdb) getNumberFor(uid int64, thing string) (number int, err error) {
- name := strconv.FormatInt(uid, 10) + "Pack"
+// 获取商店信息
+func (sql *fishdb) getStoreInfo() (thingInfos []store, err error) {
sql.Lock()
defer sql.Unlock()
- userInfo := article{}
- err = sql.db.Create(name, &userInfo)
+ thingInfo := store{}
+ err = sql.db.Create("store", &thingInfo)
if err != nil {
return
}
- count, err := sql.db.Count(name)
+ count, err := sql.db.Count("store")
if err != nil {
return
}
if count == 0 {
return
}
- if !sql.db.CanFind(name, "where Name glob '*"+thing+"*'") {
- return
- }
- err = sql.db.FindFor(name, &article{}, "where Name glob '*"+thing+"*'", func() error {
- number++
+ err = sql.db.FindFor("store", &thingInfo, "ORDER by Type, Name, Price ASC", func() error {
+ thingInfos = append(thingInfos, thingInfo)
return nil
})
return
}
-func (sql *fishdb) checkEquipFor(uid int64) (ok bool, err error) {
- sql.Lock()
- defer sql.Unlock()
- userInfo := fishState{ID: uid}
- err = sql.db.Create("fishState", &userInfo)
- if err != nil {
- return false, err
- }
- if !sql.db.CanFind("fishState", "where ID = "+strconv.FormatInt(uid, 10)) {
- return true, nil
- }
- err = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
- if err != nil {
- return false, err
- }
- if userInfo.Equip > 3 {
- return false, nil
- }
- return true, nil
-}
-
-func (sql *fishdb) setEquipFor(uid int64) (err error) {
- sql.Lock()
- defer sql.Unlock()
- userInfo := fishState{ID: uid}
- err = sql.db.Create("fishState", &userInfo)
- if err != nil {
- return err
- }
- _ = sql.db.Find("fishState", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
- if err != nil {
- return err
- }
- userInfo.Equip++
- return sql.db.Insert("fishState", &userInfo)
-}
-
-func (sql *fishdb) pickFishFor(uid int64, number int) (fishNames map[string]int, err error) {
- fishNames = make(map[string]int, 6)
- name := strconv.FormatInt(uid, 10) + "Pack"
+// 获取商店物品信息
+func (sql *fishdb) getStoreThingInfo(thing string) (thingInfos []store, err error) {
sql.Lock()
defer sql.Unlock()
- userInfo := article{}
- err = sql.db.Create(name, &userInfo)
+ thingInfo := store{}
+ err = sql.db.Create("store", &thingInfo)
if err != nil {
return
}
- count, err := sql.db.Count(name)
+ count, err := sql.db.Count("store")
if err != nil {
return
}
if count == 0 {
return
}
- if !sql.db.CanFind(name, "where Type is 'fish'") {
+ if !sql.db.CanFind("store", "where Name = '"+thing+"'") {
return
}
- fishTypes := make([]article, 0, count)
- fishInfo := article{}
- err = sql.db.FindFor(name, &fishInfo, "where Type is 'fish'", func() error {
- fishTypes = append(fishTypes, fishInfo)
+ err = sql.db.FindFor("store", &thingInfo, "where Name = '"+thing+"'", func() error {
+ thingInfos = append(thingInfos, thingInfo)
return nil
})
+ return
+}
+
+// 更新商店信息
+func (sql *fishdb) updateStoreInfo(thingInfo store) (err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ err = sql.db.Create("store", &thingInfo)
if err != nil {
return
}
- if len(fishTypes) == 0 {
- return
- }
- max := 0
- for _, info := range fishTypes {
- max += info.Number
- }
- if max < number {
- number = max
- }
- for i := number; i > 0; i-- {
- randNumber := rand.Intn(len(fishTypes))
- fishTypes[randNumber].Number--
- err = sql.db.Insert(name, &fishTypes[randNumber])
- if err != nil {
- return
- }
- fishNames[fishTypes[randNumber].Name]++
+ if thingInfo.Number == 0 {
+ return sql.db.Del("store", "where Duration = "+strconv.FormatInt(thingInfo.Duration, 10))
}
- return
+ return sql.db.Insert("store", &thingInfo)
}
diff --git a/plugin/mcfish/pack.go b/plugin/mcfish/pack.go
index 9304b0c7dc..f57d6df48f 100644
--- a/plugin/mcfish/pack.go
+++ b/plugin/mcfish/pack.go
@@ -42,6 +42,72 @@ func init() {
}
ctx.SendChain(message.ImageBytes(pic))
})
+ engine.OnFullMatch("当前装备概率明细", getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ uid := ctx.Event.UserID
+ equipInfo, err := dbdata.getUserEquip(uid)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at pack.go.1]:", err))
+ return
+ }
+ number, err := dbdata.getNumberFor(uid, "鱼")
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.5.1]:", err))
+ return
+ }
+ msg := make(message.Message, 0, 20+len(thingList))
+ msg = append(msg, message.At(uid), message.Text("\n大类概率:\n"))
+ probableList := make([]int, 4)
+ for _, info := range articlesInfo.ZoneInfo {
+ switch info.Name {
+ case "treasure":
+ probableList[0] = info.Probability
+ case "pole":
+ probableList[1] = info.Probability
+ case "fish":
+ probableList[2] = info.Probability
+ case "waste":
+ probableList[3] = info.Probability
+ }
+ }
+ if number > 100 || equipInfo.Equip == "美西螈" { //放大概率
+ probableList = []int{2, 8, 35, 45}
+ }
+ if equipInfo.Favor > 0 {
+ probableList[0] += equipInfo.Favor
+ probableList[1] += equipInfo.Favor
+ probableList[2] += equipInfo.Favor
+ probableList[3] -= equipInfo.Favor * 3
+ }
+ probable := probableList[0]
+ msg = append(msg, message.Text("宝藏 : ", probableList[0], "%\n"))
+ probable += probableList[1]
+ msg = append(msg, message.Text("鱼竿 : ", probableList[1], "%\n"))
+ probable += probableList[2]
+ msg = append(msg, message.Text("鱼类 : ", probableList[2], "%\n"))
+ probable += probableList[3]
+ msg = append(msg, message.Text("垃圾 : ", probableList[3], "%\n"))
+ msg = append(msg, message.Text("合计 : ", probable, "%\n"))
+ msg = append(msg, message.Text("-----------\n宝藏概率:\n"))
+ for _, name := range treasureList {
+ msg = append(msg, message.Text(name, " : ",
+ strconv.FormatFloat(float64(probabilities[name].Max-probabilities[name].Min)*float64(probableList[0])/100, 'f', 2, 64),
+ "%\n"))
+ }
+ msg = append(msg, message.Text("-----------\n鱼竿概率:\n"))
+ for _, name := range poleList {
+ msg = append(msg, message.Text(name, " : ",
+ strconv.FormatFloat(float64(probabilities[name].Max-probabilities[name].Min)*float64(probableList[0])/100, 'f', 2, 64),
+ "%\n"))
+ }
+ msg = append(msg, message.Text("-----------\n鱼类概率:\n"))
+ for _, name := range fishList {
+ msg = append(msg, message.Text(name, " : ",
+ strconv.FormatFloat(float64(probabilities[name].Max-probabilities[name].Min)*float64(probableList[0])/100, 'f', 2, 64),
+ "%\n"))
+ }
+ msg = append(msg, message.Text("-----------"))
+ ctx.Send(msg)
+ })
}
func drawPackImage(uid int64, equipInfo equip, articles []article) (imagePicByte []byte, err error) {
@@ -205,7 +271,7 @@ func drawEquipInfoBlock(equipInfo equip, fontdata []byte) (image.Image, error) {
canvas.SetRGB255(150, 150, 150)
canvas.Fill()
canvas.SetRGB255(0, 0, 0)
- durableW := barW * float64(equipInfo.Durable) / float64(equipAttribute[equipInfo.Equip])
+ durableW := barW * float64(equipInfo.Durable) / float64(durationList[equipInfo.Equip])
canvas.DrawRectangle(textDx+textW+5, textDy, durableW, textH*1.2)
canvas.SetRGB255(102, 102, 102)
canvas.Fill()
@@ -345,8 +411,8 @@ func drawArticleInfoBlock(uid int64, articles []article, fontdata []byte) (image
textDy += textH * 2
for i, info := range articles {
name := info.Name
- if info.Other != "" && info.Name != "美西螈" {
- if info.Name != "三叉戟" {
+ if info.Other != "" {
+ if strings.Contains(info.Name, "竿") {
numberOfEquip++
}
name += "(" + info.Other + ")"
diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go
index f8ff7e1e91..3cf1a5fad2 100644
--- a/plugin/mcfish/pole.go
+++ b/plugin/mcfish/pole.go
@@ -13,7 +13,7 @@ import (
)
func init() {
- engine.OnRegex("^装备(.+竿|美西螈|三叉戟)$", getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ engine.OnRegex(`^装备(`+strings.Join(poleList, "|")+`)$`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
equipInfo, err := dbdata.getUserEquip(uid)
if err != nil {
@@ -31,24 +31,32 @@ func init() {
return
}
poles := make([]equip, 0, len(articles))
- for _, info := range articles {
- poleInfo := strings.Split(info.Other, "/")
- durable, _ := strconv.Atoi(poleInfo[0])
- maintenance, _ := strconv.Atoi(poleInfo[1])
- induceLevel, _ := strconv.Atoi(poleInfo[2])
- favorLevel, _ := strconv.Atoi(poleInfo[3])
+ if thingName != "美西螈" {
+ for _, info := range articles {
+ poleInfo := strings.Split(info.Other, "/")
+ durable, _ := strconv.Atoi(poleInfo[0])
+ maintenance, _ := strconv.Atoi(poleInfo[1])
+ induceLevel, _ := strconv.Atoi(poleInfo[2])
+ favorLevel, _ := strconv.Atoi(poleInfo[3])
+ poles = append(poles, equip{
+ ID: uid,
+ Equip: info.Name,
+ Durable: durable,
+ Maintenance: maintenance,
+ Induce: induceLevel,
+ Favor: favorLevel,
+ })
+ }
+ } else {
poles = append(poles, equip{
- ID: uid,
- Equip: info.Name,
- Durable: durable,
- Maintenance: maintenance,
- Induce: induceLevel,
- Favor: favorLevel,
+ ID: uid,
+ Equip: thingName,
+ Durable: 999,
})
}
check := false
index := 0
- if thingName != "美西螈" && len(poles) > 1 {
+ if len(poles) > 1 {
msg := make(message.Message, 0, 3+len(articles))
msg = append(msg, message.Reply(ctx.Event.MessageID), message.Text("找到以下鱼竿:\n"))
for i, info := range poles {
@@ -125,7 +133,6 @@ func init() {
Type: "pole",
Name: equipInfo.Equip,
Number: 1,
- Other: strconv.Itoa(equipInfo.Durable) + "/" + strconv.Itoa(equipInfo.Maintenance) + "/" + strconv.Itoa(equipInfo.Induce) + "/" + strconv.Itoa(equipInfo.Favor),
}
} else {
oldthing = articles[0]
@@ -240,8 +247,8 @@ func init() {
number = 10
}
equipInfo.Durable += newEquipInfo.Durable * number / 10
- if equipInfo.Durable > equipAttribute[equipInfo.Equip] {
- equipInfo.Durable = equipAttribute[equipInfo.Equip]
+ if equipInfo.Durable > durationList[equipInfo.Equip] {
+ equipInfo.Durable = durationList[equipInfo.Equip]
}
msg := ""
if newEquipInfo.Induce != 0 && rand.Intn(100) < 50 {
@@ -456,7 +463,7 @@ func init() {
)
return
}
- attribute := strconv.Itoa(equipAttribute[thingName]) + "/0/" + strconv.Itoa(induceLevel/3) + "/" + strconv.Itoa(favorLevel/3)
+ attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel/3) + "/" + strconv.Itoa(favorLevel/3)
newthing := article{
Duration: time.Now().Unix(),
Type: "pole",
diff --git a/plugin/mcfish/store.go b/plugin/mcfish/store.go
index a6d0198c57..696240e04b 100644
--- a/plugin/mcfish/store.go
+++ b/plugin/mcfish/store.go
@@ -61,10 +61,10 @@ func init() {
}
ctx.SendChain(message.ImageBytes(pic))
})
- engine.OnRegex(`^出售(.+(竿|鱼)|河豚|鹦鹉螺|诱钓|海之眷顾|唱片|美西螈|三叉戟)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ engine.OnRegex(`^出售(`+strings.Join(thingList, "|")+`)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
thingName := ctx.State["regex_matched"].([]string)[1]
- number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[3])
+ number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[2])
if number == 0 {
number = 1
}
@@ -142,9 +142,9 @@ func init() {
maintenance, _ := strconv.Atoi(poleInfo[1])
induceLevel, _ := strconv.Atoi(poleInfo[2])
favorLevel, _ := strconv.Atoi(poleInfo[3])
- pice = (thingPice[thingName] - (equipAttribute[thingName] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discount[thingName] / 100
+ pice = (priceList[thingName] - (durationList[thingName] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discountList[thingName] / 100
} else {
- pice = thingPice[thingName] * discount[thingName] / 100
+ pice = priceList[thingName] * discountList[thingName] / 100
}
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("是否接受商店将以", pice*number*8/10, "收购", number, "个", thingName, "?\n回答\"是\"或\"否\"")))
// 等待用户下一步选择
@@ -221,7 +221,7 @@ func init() {
}
newCommodity := store{}
if strings.Contains(thingName, "竿") || thingName == "三叉戟" {
- if pice >= thingPice[thingName]*3/4 { // 不值钱的删了
+ if pice >= priceList[thingName]*4/5 { // 不值钱的删了
newCommodity = store{
Duration: time.Now().Unix(),
Type: "pole",
@@ -269,10 +269,10 @@ func init() {
}
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("出售成功,你赚到了", pice*number)))
})
- engine.OnRegex(`^购买(.+(竿|鱼)|河豚|鹦鹉螺|诱钓|海之眷顾|唱片|美西螈|三叉戟)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
+ engine.OnRegex(`^购买(`+strings.Join(thingList, "|")+`)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
thingName := ctx.State["regex_matched"].([]string)[1]
- number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[3])
+ number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[2])
if number == 0 {
number = 1
}
@@ -294,10 +294,10 @@ func init() {
maintenance, _ := strconv.Atoi(poleInfo[1])
induceLevel, _ := strconv.Atoi(poleInfo[2])
favorLevel, _ := strconv.Atoi(poleInfo[3])
- thingPice := (thingPice[info.Name] - (equipAttribute[info.Name] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discount[info.Name] / 100
+ thingPice := (priceList[info.Name] - (durationList[info.Name] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discountList[info.Name] / 100
pice = append(pice, thingPice)
} else {
- thingPice := thingPice[info.Name] * discount[info.Name] / 100
+ thingPice := priceList[info.Name] * discountList[info.Name] / 100
pice = append(pice, thingPice)
}
@@ -400,8 +400,7 @@ func init() {
return
}
newCommodity := article{}
- switch {
- case strings.Contains(thingName, "竿") || thingName == "三叉戟":
+ if strings.Contains(thingName, "竿") || thingName == "三叉戟" {
newCommodity = article{
Duration: time.Now().Unix(),
Type: "pole",
@@ -409,15 +408,7 @@ func init() {
Number: 1,
Other: thing.Other,
}
- case thingName == "美西螈":
- newCommodity = article{
- Duration: time.Now().Unix(),
- Type: "pole",
- Name: thingName,
- Number: 1,
- Other: "999/0/0/0",
- }
- default:
+ } else {
things, err1 := dbdata.getUserThingInfo(uid, thingName)
if err1 != nil {
ctx.SendChain(message.Text("[ERROR at store.go.15]:", err1))
@@ -429,9 +420,12 @@ func init() {
Name: thingName,
Number: 0,
})
- if thingName == "海之眷顾" || thingName == "诱钓" || thingName == "唱片" {
+ switch {
+ case thingName == "海之眷顾" || thingName == "诱钓" || thingName == "唱片":
things[0].Type = "article"
- } else {
+ case thingName == "美西螈":
+ things[0].Type = "pole"
+ default:
things[0].Type = "fish"
}
}
@@ -503,7 +497,7 @@ func drawStroeInfoImage(stroeInfo []store) (picImage image.Image, err error) {
priceW, _ := canvas.MeasureString("10000")
bolckW := int(10 + nameW + 50 + numberW + 50 + priceW + 10)
- backY := 10 + int(titleH*2+10)*2 + 10 + (len(stroeInfo)+len(discount)/2+2)*int(textH*2) + 10
+ backY := 10 + int(titleH*2+10)*2 + 10 + (len(stroeInfo)+len(discountList)/2+2)*int(textH*2) + 10
canvas = gg.NewContext(bolckW, math.Max(backY, 500))
// 画底色
canvas.DrawRectangle(0, 0, float64(bolckW), float64(backY))
@@ -529,8 +523,8 @@ func drawStroeInfoImage(stroeInfo []store) (picImage image.Image, err error) {
textDx, textDh := canvas.MeasureString("下界合金竿(均价1000)")
valueDx, _ := canvas.MeasureString("+100%")
i := 0
- for name, info := range discount {
- text := name + "(均价" + strconv.Itoa(thingPice[name]) + ") "
+ for name, info := range discountList {
+ text := name + "(均价" + strconv.Itoa(priceList[name]) + ") "
if i == 2 {
i = 0
@@ -586,9 +580,9 @@ func drawStroeInfoImage(stroeInfo []store) (picImage image.Image, err error) {
maintenance, _ := strconv.Atoi(poleInfo[1])
induceLevel, _ := strconv.Atoi(poleInfo[2])
favorLevel, _ := strconv.Atoi(poleInfo[3])
- pice = (thingPice[info.Name] - (equipAttribute[info.Name] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discount[info.Name] / 100
+ pice = (priceList[info.Name] - (durationList[info.Name] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discountList[info.Name] / 100
} else {
- pice = thingPice[info.Name] * discount[info.Name] / 100
+ pice = priceList[info.Name] * discountList[info.Name] / 100
}
canvas.DrawStringAnchored(name, 10+nameW/2, textDy+textH/2, 0.5, 0.5)
From 9da31034d5e554187b25b85a5bdbddcb2076f7cf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sun, 3 Sep 2023 09:34:49 +0800
Subject: [PATCH 10/12] Update main.go
---
plugin/mcfish/main.go | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/plugin/mcfish/main.go b/plugin/mcfish/main.go
index d22aa1b47d..726d892ecf 100644
--- a/plugin/mcfish/main.go
+++ b/plugin/mcfish/main.go
@@ -113,13 +113,14 @@ var (
"- 进行钓鱼\n- 进行n次钓鱼\n" +
"规则:\n1.每日的商店价格是波动的!!如何最大化收益自己考虑一下喔\n" +
"2.装备信息:\n-> 木竿 : 耐久上限:30 均价:100 上钩概率:0.7%\n-> 铁竿 : 耐久上限:50 均价:300 上钩概率:0.2%\n-> 金竿 : 耐久上限:70 均价700 上钩概率:0.06%\n" +
- "-> 钻石竿 : 耐久上限:100 均价1500 上钩概率:0..3%\n-> 下界合金竿 : 耐久上限:150 均价3100 上钩概率:0..1%\n-> 三叉戟 : 可使钓的鱼类物品数量变成3 耐久上限:300 均价4000 只能合成和交易\n" +
+ "-> 钻石竿 : 耐久上限:100 均价1500 上钩概率:0.03%\n-> 下界合金竿 : 耐久上限:150 均价3100 上钩概率:0.01%\n-> 三叉戟 : 可使钓的鱼类物品数量变成3 耐久上限:300 均价4000 只能合成和交易\n" +
"3.附魔书信息:\n-> 诱钓 : 减少上钩时间. 均价:1000, 上钩概率:0.59%\n-> 海之眷顾 : 增加宝藏上钩概率. 均价:2500, 上钩概率:0.39%\n" +
"4.稀有物品:\n-> 唱片 : 出售物品时使用该物品使价格翻倍. 均价:3000, 上钩概率:0.01%\n-> 美西螈 : 可装备,获得隐形[钓鱼佬]buff,并让钓到除鱼竿和美西螈外的物品数量变成3,无耐久上限.不可修复/附魔,每次钓鱼消耗任意一鱼类物品. 均价:3000, 上钩概率:0.01%\n" +
"5.鱼类信息:\n-> 鳕鱼 : 均价:10 上钩概率:0.69%\n-> 鲑鱼 : 均价:50 上钩概率:0.2%\n-> 热带鱼 : 均价:100 上钩概率:0.06%\n-> 河豚 : 均价:300 上钩概率:0.03%\n-> 鹦鹉螺 : 均价:500 上钩概率:0.01%\n-> 墨鱼 : 均价:500 上钩概率:0.01%\n" +
- "6.物品BUFF:\n-> 钓鱼佬 : 当背包名字含有'鱼'的物品数量超过100时激活,钓到物品概率提高至90%\n-> 修复大师 : 当背包鱼竿数量超过10时激活,修复物品时耐久百分百继承\n" +
- "7.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率90%,继承附魔等级合/3的等级\n" +
- "8.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为60%(理论值!!!)\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿",
+ "6.垃圾:\n-> 均价:10 上钩概率:30%\n" +
+ "7.物品BUFF:\n-> 钓鱼佬 : 当背包名字含有'鱼'的物品数量超过100时激活,钓到物品概率提高至90%\n-> 修复大师 : 当背包鱼竿数量超过10时激活,修复物品时耐久百分百继承\n" +
+ "8.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率90%,继承附魔等级合/3的等级\n" +
+ "9.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为60%(理论值!!!)\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿",
PublicDataFolder: "McFish",
}).ApplySingle(ctxext.DefaultSingle)
getdb = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
From c5f7552ac00ada56708b4c1852fe6b1f0a5ac4d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sun, 3 Sep 2023 09:39:16 +0800
Subject: [PATCH 11/12] Update pack.go
---
plugin/mcfish/pack.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/plugin/mcfish/pack.go b/plugin/mcfish/pack.go
index f57d6df48f..053d9a6dc6 100644
--- a/plugin/mcfish/pack.go
+++ b/plugin/mcfish/pack.go
@@ -96,13 +96,13 @@ func init() {
msg = append(msg, message.Text("-----------\n鱼竿概率:\n"))
for _, name := range poleList {
msg = append(msg, message.Text(name, " : ",
- strconv.FormatFloat(float64(probabilities[name].Max-probabilities[name].Min)*float64(probableList[0])/100, 'f', 2, 64),
+ strconv.FormatFloat(float64(probabilities[name].Max-probabilities[name].Min)*float64(probableList[1])/100, 'f', 2, 64),
"%\n"))
}
msg = append(msg, message.Text("-----------\n鱼类概率:\n"))
for _, name := range fishList {
msg = append(msg, message.Text(name, " : ",
- strconv.FormatFloat(float64(probabilities[name].Max-probabilities[name].Min)*float64(probableList[0])/100, 'f', 2, 64),
+ strconv.FormatFloat(float64(probabilities[name].Max-probabilities[name].Min)*float64(probableList[2])/100, 'f', 2, 64),
"%\n"))
}
msg = append(msg, message.Text("-----------"))
From f15ac7c56093bea95f46befcba4fc55cefd6b706 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Sun, 3 Sep 2023 11:06:05 +0800
Subject: [PATCH 12/12] Add files via upload
---
plugin/mcfish/fish.go | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/plugin/mcfish/fish.go b/plugin/mcfish/fish.go
index 7b9736e4f8..4045b3eea6 100644
--- a/plugin/mcfish/fish.go
+++ b/plugin/mcfish/fish.go
@@ -27,16 +27,6 @@ func init() {
}
fishNumber = number
}
- residue, err := dbdata.updateFishInfo(uid, fishNumber)
- if err != nil {
- ctx.SendChain(message.Text("[ERROR at fish.go.1]:", err))
- return
- }
- if residue == 0 {
- ctx.SendChain(message.Text("今天你已经进行", FishLimit, "次钓鱼了.\n游戏虽好,但请不要沉迷。"))
- return
- }
- fishNumber = residue
equipInfo, err := dbdata.getUserEquip(uid)
if err != nil {
ctx.SendChain(message.Text("[ERROR at fish.go.2]:", err))
@@ -99,9 +89,20 @@ func init() {
break
}
}
- } else if equipInfo.Durable < fishNumber {
+ }
+ if equipInfo.Durable < fishNumber {
fishNumber = equipInfo.Durable
}
+ residue, err := dbdata.updateFishInfo(uid, fishNumber)
+ if err != nil {
+ ctx.SendChain(message.Text("[ERROR at fish.go.1]:", err))
+ return
+ }
+ if residue == 0 {
+ ctx.SendChain(message.Text("今天你已经进行", FishLimit, "次钓鱼了.\n游戏虽好,但请不要沉迷。"))
+ return
+ }
+ fishNumber = residue
msg := ""
if equipInfo.Equip != "美西螈" {
equipInfo.Durable -= fishNumber
@@ -110,8 +111,10 @@ func init() {
ctx.SendChain(message.Text("[ERROR at fish.go.5]:", err))
return
}
- if equipInfo.Durable < 10 {
+ if equipInfo.Durable < 10 || equipInfo.Durable > 0 {
msg = "(你的鱼竿耐久仅剩" + strconv.Itoa(equipInfo.Durable) + ")"
+ } else if equipInfo.Durable <= 0 {
+ msg = "(你的鱼竿耐已销毁)"
}
} else {
fishNmaes, err := dbdata.pickFishFor(uid, fishNumber)