From 34dfe3b8a078cf5db24ed54034d8209ce85966c3 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:39:40 +0800 Subject: [PATCH 01/17] Use local probabilities to avoid global state issues Refactor to use local variables for probabilities in fishing logic to prevent global state issues in multiplayer scenarios. --- plugin/mcfish/fish.go | 72 +++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/plugin/mcfish/fish.go b/plugin/mcfish/fish.go index 29cf4cf605..c67fa5d652 100644 --- a/plugin/mcfish/fish.go +++ b/plugin/mcfish/fish.go @@ -171,45 +171,54 @@ func init() { ctx.SendChain(message.Text("[ERROR at fish.go.5.1]:", err)) return } + + // ================= [修复部分:创建局部概率副本] ================= + // 原代码直接操作全局 probabilities,导致多人游戏时概率永久偏移。 + localProbabilities := make(map[string]probabilityLimit, len(probabilities)) + for k, v := range probabilities { + localProbabilities[k] = v + } + // ============================================================= + if number > 100 || equipInfo.Equip == "美西螈" { // 放大概率 - probabilities["treasure"] = probabilityLimit{ + localProbabilities["treasure"] = probabilityLimit{ Min: 0, Max: 2, } - probabilities["pole"] = probabilityLimit{ + localProbabilities["pole"] = probabilityLimit{ Min: 2, Max: 10, } - probabilities["fish"] = probabilityLimit{ + localProbabilities["fish"] = probabilityLimit{ Min: 10, Max: 45, } - probabilities["waste"] = probabilityLimit{ + localProbabilities["waste"] = probabilityLimit{ Min: 45, Max: 90, } } if number2 != 0 { - info := probabilities["waste"] + info := localProbabilities["waste"] info.Max = 100 - probabilities["waste"] = info + localProbabilities["waste"] = info } - for name, info := range probabilities { + for name, info := range localProbabilities { switch name { case "treasure": info.Max += equipInfo.Favor - probabilities[name] = info + localProbabilities[name] = info case "pole": info.Min += equipInfo.Favor info.Max += equipInfo.Favor * 2 - probabilities[name] = info + localProbabilities[name] = info case "fish": info.Min += equipInfo.Favor * 2 info.Max += equipInfo.Favor * 3 - probabilities[name] = info + localProbabilities[name] = info case "waste": info.Min += equipInfo.Favor * 3 - probabilities[name] = info + localProbabilities[name] = info } } // 钓鱼结算 @@ -221,34 +230,35 @@ func init() { number := 1 dice := rand.Intn(100) switch { - case dice >= probabilities["waste"].Min && dice < probabilities["waste"].Max: // 垃圾 + // ================= [修复部分:所有结算均引用局部变量 localProbabilities] ================= + case dice >= localProbabilities["waste"].Min && dice < localProbabilities["waste"].Max: // 垃圾 typeOfThing = "waste" thingName = wasteList[rand.Intn(len(wasteList))] picName = thingName - case dice >= probabilities["treasure"].Min && dice < probabilities["treasure"].Max: // 宝藏 + case dice >= localProbabilities["treasure"].Min && dice < localProbabilities["treasure"].Max: // 宝藏 dice = rand.Intn(100) switch { - case dice >= probabilities["美西螈"].Min && dice < probabilities["美西螈"].Max: + case dice >= localProbabilities["美西螈"].Min && dice < localProbabilities["美西螈"].Max: typeOfThing = "pole" picName = "美西螈" thingName = "美西螈" - case dice >= probabilities["唱片"].Min && dice < probabilities["唱片"].Max: + case dice >= localProbabilities["唱片"].Min && dice < localProbabilities["唱片"].Max: typeOfThing = "article" picName = "唱片" thingName = "唱片" - case dice >= probabilities["海之眷顾"].Min && dice < probabilities["海之眷顾"].Max: + case dice >= localProbabilities["海之眷顾"].Min && dice < localProbabilities["海之眷顾"].Max: typeOfThing = "article" picName = "book" thingName = "海之眷顾" - case dice >= probabilities["净化书"].Min && dice < probabilities["净化书"].Max: + case dice >= localProbabilities["净化书"].Min && dice < localProbabilities["净化书"].Max: typeOfThing = "article" picName = "book" thingName = "净化书" - case dice >= probabilities["宝藏诅咒"].Min && dice < probabilities["宝藏诅咒"].Max: + case dice >= localProbabilities["宝藏诅咒"].Min && dice < localProbabilities["宝藏诅咒"].Max: typeOfThing = "article" picName = "book" thingName = "宝藏诅咒" - case dice >= probabilities["海豚"].Min && dice < probabilities["海豚"].Max: + case dice >= localProbabilities["海豚"].Min && dice < localProbabilities["海豚"].Max: typeOfThing = "fish" picName = "海豚" thingName = "海豚" @@ -257,35 +267,35 @@ func init() { picName = "book" thingName = "诱钓" } - case dice >= probabilities["pole"].Min && dice < probabilities["pole"].Max: // 宝藏 + case dice >= localProbabilities["pole"].Min && dice < localProbabilities["pole"].Max: // 鱼竿 typeOfThing = "pole" dice := rand.Intn(100) switch { - case dice >= probabilities["铁竿"].Min && dice < probabilities["铁竿"].Max: + case dice >= localProbabilities["铁竿"].Min && dice < localProbabilities["铁竿"].Max: thingName = "铁竿" - case dice >= probabilities["金竿"].Min && dice < probabilities["金竿"].Max: + case dice >= localProbabilities["金竿"].Min && dice < localProbabilities["金竿"].Max: thingName = "金竿" - case dice >= probabilities["钻石竿"].Min && dice < probabilities["钻石竿"].Max: + case dice >= localProbabilities["钻石竿"].Min && dice < localProbabilities["钻石竿"].Max: thingName = "钻石竿" - case dice >= probabilities["下界合金竿"].Min && dice < probabilities["下界合金竿"].Max: + case dice >= localProbabilities["下界合金竿"].Min && dice < localProbabilities["下界合金竿"].Max: thingName = "下界合金竿" default: thingName = "木竿" } picName = thingName - case dice >= probabilities["fish"].Min && dice < probabilities["fish"].Max: + case dice >= localProbabilities["fish"].Min && dice < localProbabilities["fish"].Max: // 鱼类 typeOfThing = "fish" dice = rand.Intn(100) switch { - case dice >= probabilities["墨鱼"].Min && dice < probabilities["墨鱼"].Max: + case dice >= localProbabilities["墨鱼"].Min && dice < localProbabilities["墨鱼"].Max: thingName = "墨鱼" - case dice >= probabilities["鳕鱼"].Min && dice < probabilities["鳕鱼"].Max: + case dice >= localProbabilities["鳕鱼"].Min && dice < localProbabilities["鳕鱼"].Max: thingName = "鳕鱼" - case dice >= probabilities["鲑鱼"].Min && dice < probabilities["鲑鱼"].Max: + case dice >= localProbabilities["鲑鱼"].Min && dice < localProbabilities["鲑鱼"].Max: thingName = "鲑鱼" - case dice >= probabilities["热带鱼"].Min && dice < probabilities["热带鱼"].Max: + case dice >= localProbabilities["热带鱼"].Min && dice < localProbabilities["热带鱼"].Max: thingName = "热带鱼" - case dice >= probabilities["河豚"].Min && dice < probabilities["河豚"].Max: + case dice >= localProbabilities["河豚"].Min && dice < localProbabilities["河豚"].Max: thingName = "河豚" default: thingName = "鹦鹉螺" @@ -294,6 +304,8 @@ func init() { default: thingNameList["赛博空气"]++ } + // ====================================================================================== + if thingName != "" { newThing := article{} if strings.Contains(thingName, "竿") { From 71e92dec705c54a669189eccaaea49e0928454e3 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:40:43 +0800 Subject: [PATCH 02/17] Refactor synthesis process for grouped materials Refactor synthesis logic to group materials and determine success rate individually. Update database and construct result message based on synthesis outcomes. --- plugin/mcfish/pole.go | 139 ++++++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 46 deletions(-) diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go index cad6938975..3341adad79 100644 --- a/plugin/mcfish/pole.go +++ b/plugin/mcfish/pole.go @@ -458,50 +458,97 @@ func init() { } } } - upgradeNum := len(list) - 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(100) >= 90 { - ctx.Send( - message.ReplyWithMessage(ctx.Event.MessageID, - message.Text("合成失败,材料已销毁"), - ), - ) - return - } - attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel/upgradeNum) + "/" + strconv.Itoa(favorLevel/upgradeNum) - newthing := article{ - Duration: time.Now().Unix(), - Type: "pole", - Name: thingName, - Number: 1, - Other: attribute, - } - // 代码未对article.Number>1的情况做处理,直接生成多个Number=1的鱼竿 - for i := 0; i < upgradeNum/3; i++ { - // 使用时间戳作为主键,增加固定值避免主键冲突 - newthing.Duration += int64(i * 10) - 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("成功合成:", upgradeNum/3, "个", thingName, "\n属性: ", attribute), - ), - ) - }) + // --- 修改开始:分组独立判定合成成功率 --- + groupCount := len(list) / 3 + successCount := 0 + failCount := 0 + successAttributes := []string{} // 存储成功鱼竿的属性描述 + + for g := 0; g < groupCount; g++ { + idx1 := list[g*3] + idx2 := list[g*3+1] + idx3 := list[g*3+2] + + // 取出三个材料 + thingInfo1 := articles[idx1] + thingInfo2 := articles[idx2] + thingInfo3 := articles[idx3] + + // 删除材料(假设每个数量为1) + thingInfo1.Number = 0 + thingInfo2.Number = 0 + thingInfo3.Number = 0 + + // 更新数据库,删除这三个材料 + err = dbdata.updateUserThingInfo(uid, thingInfo1) + if err != nil { + ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) + return + } + err = dbdata.updateUserThingInfo(uid, thingInfo2) + if err != nil { + ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) + return + } + err = dbdata.updateUserThingInfo(uid, thingInfo3) + if err != nil { + ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) + return + } + + // 随机判定,成功率90% + if rand.Intn(100) >= 90 { + failCount++ + continue + } + + // 计算平均附魔等级 + favorLevel := (poles[idx1].Favor + poles[idx2].Favor + poles[idx3].Favor) / 3 + induceLevel := (poles[idx1].Induce + poles[idx2].Induce + poles[idx3].Induce) / 3 + attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel) + "/" + strconv.Itoa(favorLevel) + + // 生成合成后的鱼竿 + newthing := article{ + Duration: time.Now().Unix() + int64(g*10), // 加偏移避免主键冲突 + 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 + } + successCount++ + successAttributes = append(successAttributes, attribute) + } + + // 构造结果消息 + resultMsg := "" + if successCount > 0 { + resultMsg += "成功合成 " + strconv.Itoa(successCount) + " 个" + thingName + "\n" + // 显示属性,如果太多则只显示前几个 + if len(successAttributes) <= 5 { + for _, attr := range successAttributes { + resultMsg += "属性: " + attr + "\n" + } + } else { + resultMsg += "属性示例: " + successAttributes[0] + " 等\n" + } + } + if failCount > 0 { + resultMsg += "失败 " + strconv.Itoa(failCount) + " 次,材料已销毁。" + } + if resultMsg == "" { + resultMsg = "没有进行任何合成?" + } + + ctx.Send( + message.ReplyWithMessage(ctx.Event.MessageID, + message.Text(resultMsg), + ), + ) + // --- 修改结束 --- +}) } From b4a965f3cae12c6f806227c18ec0e501b9437664 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:42:40 +0800 Subject: [PATCH 03/17] Update function.go --- plugin/qqwife/function.go | 1 - 1 file changed, 1 deletion(-) diff --git a/plugin/qqwife/function.go b/plugin/qqwife/function.go index dd9a339288..a9fd834002 100644 --- a/plugin/qqwife/function.go +++ b/plugin/qqwife/function.go @@ -162,7 +162,6 @@ func init() { message.Text( "\n", "[", ctx.CardOrNickName(fiancee), "]", - "(", fiancee, ")哒", "(", fiancee, ")哒\n当前你们好感度为", favor, ), ) From b05358d52056741f091508565a0caf04d0564a22 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:53:03 +0800 Subject: [PATCH 04/17] Improve error handling and logging for wife data --- plugin/wife/main.go | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/plugin/wife/main.go b/plugin/wife/main.go index dd60d86382..621ac9b448 100644 --- a/plugin/wife/main.go +++ b/plugin/wife/main.go @@ -25,19 +25,28 @@ var ( Brief: "从老婆库抽每日老婆", PublicDataFolder: "Wife", }).ApplySingle(ctxext.DefaultSingle) + getJSON = fcext.DoOnceOnSuccess( func(ctx *zero.Ctx) bool { + // 1. 优先尝试从镜像站更新同步 data, err := engine.GetLazyData("wife.json", true) if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return false + // 2. 如果下载失败(如 MD5 不匹配),尝试直接读取本地已有文件 + logrus.Warnf("[wife] 远程同步 wife.json 失败: %v,正在尝试读取本地缓存...", err) + data, err = engine.GetLazyData("wife.json", false) + if err != nil { + // 3. 本地也没有或读取失败才彻底报错 + ctx.SendChain(message.Text("ERROR: 无法获取老婆库数据(同步及本地读取均失败): ", err)) + return false + } } + err = json.Unmarshal(data, &cards) if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) + ctx.SendChain(message.Text("ERROR: 老婆库格式解析失败: ", err)) return false } - logrus.Infof("[wife]加载%d个老婆", len(cards)) + logrus.Infof("[wife] 已成功加载 %d 个老婆", len(cards)) return true }, ) @@ -56,6 +65,7 @@ func init() { engine.OnFullMatch("抽老婆", getJSON).SetBlock(true). Handle(func(ctx *zero.Ctx) { card := cards[fcext.RandSenderPerDayN(ctx.Event.UserID, len(cards))] + // 图片获取同样可以考虑增加非强制下载逻辑,但通常图片 MD5 报错较少 data, err := engine.GetLazyData("wives/"+card, true) var msgText string work, name := card2name(card) From b5fc36cb285f90f1bc4d8d2942110faa9b64041e Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Tue, 3 Mar 2026 12:53:24 +0800 Subject: [PATCH 05/17] Implement fallback for image loading in wifegame Added a fallback mechanism for loading images in the guessing game, attempting local file retrieval if remote download fails. --- plugin/wife/wifegame.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/plugin/wife/wifegame.go b/plugin/wife/wifegame.go index a31e2ac573..fd2d877309 100644 --- a/plugin/wife/wifegame.go +++ b/plugin/wife/wifegame.go @@ -15,6 +15,7 @@ import ( "github.com/wdvxdr1123/ZeroBot/message" "github.com/FloatTech/imgfactory" + "github.com/sirupsen/logrus" ) var ( @@ -31,16 +32,24 @@ func init() { class := 3 card := cards[rand.Intn(len(cards))] + + // --- 修改部分:增加图片加载的回退机制 --- pic, err := engine.GetLazyData("wives/"+card, true) if err != nil { - ctx.SendChain(message.Text("[猜老婆]error:\n", err)) - return + logrus.Warnf("[wife] 猜老婆图片同步失败: %v,尝试读取本地文件...", err) + pic, err = engine.GetLazyData("wives/"+card, false) + if err != nil { + ctx.SendChain(message.Text("[猜老婆] 远程下载及本地读取图片均失败:\n", err)) + return + } } + // ------------------------------------ + work, name := card2name(card) name = strings.ToLower(name) img, _, err := image.Decode(bytes.NewReader(pic)) if err != nil { - ctx.SendChain(message.Text("[猜老婆]error:\n", err)) + ctx.SendChain(message.Text("[猜老婆] 图片解码失败:\n", err)) return } dst := imgfactory.Size(img, img.Bounds().Dx(), img.Bounds().Dy()) @@ -48,7 +57,7 @@ func init() { if err != nil { ctx.SendChain( message.Reply(ctx.Event.MessageID), - message.Text("[猜老婆]图片生成失败:\n", err), + message.Text("[猜老婆] 磨砂图片生成失败:\n", err), ) return } @@ -80,8 +89,6 @@ func init() { ) return case c := <-recv: - // tick.Reset(105 * time.Second) - // after.Reset(120 * time.Second) msg := strings.ReplaceAll(c.Event.Message.String(), "酱", "") if msg == "" { continue From 6a8b6fcb29f3ed4c0b74a9df1880bd874a2d4145 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Tue, 3 Mar 2026 15:57:21 +0800 Subject: [PATCH 06/17] Fix error message for image generation failure --- plugin/wife/wifegame.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/wife/wifegame.go b/plugin/wife/wifegame.go index fd2d877309..3e6617b4e0 100644 --- a/plugin/wife/wifegame.go +++ b/plugin/wife/wifegame.go @@ -57,7 +57,7 @@ func init() { if err != nil { ctx.SendChain( message.Reply(ctx.Event.MessageID), - message.Text("[猜老婆] 磨砂图片生成失败:\n", err), + message.Text("[猜老婆] 图片生成失败:\n", err), ) return } From 3b3d756dbb795f8a00c8af8c71fe76f9f5db71b7 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:48:55 +0800 Subject: [PATCH 07/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20fish.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/mcfish/fish.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugin/mcfish/fish.go b/plugin/mcfish/fish.go index c67fa5d652..9c7f35fe83 100644 --- a/plugin/mcfish/fish.go +++ b/plugin/mcfish/fish.go @@ -172,13 +172,10 @@ func init() { return } - // ================= [修复部分:创建局部概率副本] ================= - // 原代码直接操作全局 probabilities,导致多人游戏时概率永久偏移。 localProbabilities := make(map[string]probabilityLimit, len(probabilities)) for k, v := range probabilities { localProbabilities[k] = v } - // ============================================================= if number > 100 || equipInfo.Equip == "美西螈" { // 放大概率 localProbabilities["treasure"] = probabilityLimit{ @@ -230,7 +227,6 @@ func init() { number := 1 dice := rand.Intn(100) switch { - // ================= [修复部分:所有结算均引用局部变量 localProbabilities] ================= case dice >= localProbabilities["waste"].Min && dice < localProbabilities["waste"].Max: // 垃圾 typeOfThing = "waste" thingName = wasteList[rand.Intn(len(wasteList))] @@ -304,7 +300,6 @@ func init() { default: thingNameList["赛博空气"]++ } - // ====================================================================================== if thingName != "" { newThing := article{} From fe84435684a2f30b4ccd5dbec1c39c0e82eb525b Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:51:31 +0800 Subject: [PATCH 08/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20wifegame.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/wife/wifegame.go | 1 - 1 file changed, 1 deletion(-) diff --git a/plugin/wife/wifegame.go b/plugin/wife/wifegame.go index 3e6617b4e0..523ef201dd 100644 --- a/plugin/wife/wifegame.go +++ b/plugin/wife/wifegame.go @@ -33,7 +33,6 @@ func init() { card := cards[rand.Intn(len(cards))] - // --- 修改部分:增加图片加载的回退机制 --- pic, err := engine.GetLazyData("wives/"+card, true) if err != nil { logrus.Warnf("[wife] 猜老婆图片同步失败: %v,尝试读取本地文件...", err) From 3cdaff56fd15c912f7cddb358098113031a29f8c Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:52:32 +0800 Subject: [PATCH 09/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20main.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/wife/main.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/plugin/wife/main.go b/plugin/wife/main.go index 621ac9b448..a229bc43b5 100644 --- a/plugin/wife/main.go +++ b/plugin/wife/main.go @@ -28,14 +28,11 @@ var ( getJSON = fcext.DoOnceOnSuccess( func(ctx *zero.Ctx) bool { - // 1. 优先尝试从镜像站更新同步 data, err := engine.GetLazyData("wife.json", true) if err != nil { - // 2. 如果下载失败(如 MD5 不匹配),尝试直接读取本地已有文件 logrus.Warnf("[wife] 远程同步 wife.json 失败: %v,正在尝试读取本地缓存...", err) data, err = engine.GetLazyData("wife.json", false) if err != nil { - // 3. 本地也没有或读取失败才彻底报错 ctx.SendChain(message.Text("ERROR: 无法获取老婆库数据(同步及本地读取均失败): ", err)) return false } @@ -65,7 +62,6 @@ func init() { engine.OnFullMatch("抽老婆", getJSON).SetBlock(true). Handle(func(ctx *zero.Ctx) { card := cards[fcext.RandSenderPerDayN(ctx.Event.UserID, len(cards))] - // 图片获取同样可以考虑增加非强制下载逻辑,但通常图片 MD5 报错较少 data, err := engine.GetLazyData("wives/"+card, true) var msgText string work, name := card2name(card) From 9c05dcacff6265131e082e9c468ad706215a3720 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:54:17 +0800 Subject: [PATCH 10/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20pole.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/mcfish/pole.go | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go index 3341adad79..805a6f1c8d 100644 --- a/plugin/mcfish/pole.go +++ b/plugin/mcfish/pole.go @@ -458,28 +458,24 @@ func init() { } } } - // --- 修改开始:分组独立判定合成成功率 --- groupCount := len(list) / 3 successCount := 0 failCount := 0 - successAttributes := []string{} // 存储成功鱼竿的属性描述 + successAttributes := []string{} for g := 0; g < groupCount; g++ { idx1 := list[g*3] idx2 := list[g*3+1] idx3 := list[g*3+2] - // 取出三个材料 thingInfo1 := articles[idx1] thingInfo2 := articles[idx2] thingInfo3 := articles[idx3] - // 删除材料(假设每个数量为1) thingInfo1.Number = 0 thingInfo2.Number = 0 thingInfo3.Number = 0 - // 更新数据库,删除这三个材料 err = dbdata.updateUserThingInfo(uid, thingInfo1) if err != nil { ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) @@ -496,18 +492,15 @@ func init() { return } - // 随机判定,成功率90% if rand.Intn(100) >= 90 { failCount++ continue } - // 计算平均附魔等级 favorLevel := (poles[idx1].Favor + poles[idx2].Favor + poles[idx3].Favor) / 3 induceLevel := (poles[idx1].Induce + poles[idx2].Induce + poles[idx3].Induce) / 3 attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel) + "/" + strconv.Itoa(favorLevel) - // 生成合成后的鱼竿 newthing := article{ Duration: time.Now().Unix() + int64(g*10), // 加偏移避免主键冲突 Type: "pole", @@ -524,11 +517,9 @@ func init() { successAttributes = append(successAttributes, attribute) } - // 构造结果消息 resultMsg := "" if successCount > 0 { resultMsg += "成功合成 " + strconv.Itoa(successCount) + " 个" + thingName + "\n" - // 显示属性,如果太多则只显示前几个 if len(successAttributes) <= 5 { for _, attr := range successAttributes { resultMsg += "属性: " + attr + "\n" @@ -549,6 +540,5 @@ func init() { message.Text(resultMsg), ), ) - // --- 修改结束 --- }) } From 3cd397ab08918decdb7190fcaeb4b47d14feed36 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Fri, 6 Mar 2026 11:56:53 +0800 Subject: [PATCH 11/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20pole.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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 805a6f1c8d..749d4f1600 100644 --- a/plugin/mcfish/pole.go +++ b/plugin/mcfish/pole.go @@ -502,7 +502,7 @@ func init() { attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel) + "/" + strconv.Itoa(favorLevel) newthing := article{ - Duration: time.Now().Unix() + int64(g*10), // 加偏移避免主键冲突 + Duration: time.Now().Unix() + int64(g*10), Type: "pole", Name: thingName, Number: 1, From ac981053e10e2a425bedc339d463ce06e3e5d589 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Fri, 6 Mar 2026 12:00:17 +0800 Subject: [PATCH 12/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20fish.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/mcfish/fish.go | 1 - 1 file changed, 1 deletion(-) diff --git a/plugin/mcfish/fish.go b/plugin/mcfish/fish.go index 9c7f35fe83..72b5b477cf 100644 --- a/plugin/mcfish/fish.go +++ b/plugin/mcfish/fish.go @@ -300,7 +300,6 @@ func init() { default: thingNameList["赛博空气"]++ } - if thingName != "" { newThing := article{} if strings.Contains(thingName, "竿") { From a37cf1b12c9b55176bce2a1a3c82af27d7f9661c Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Fri, 6 Mar 2026 12:03:26 +0800 Subject: [PATCH 13/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20main.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/wife/main.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugin/wife/main.go b/plugin/wife/main.go index a229bc43b5..8cf8178832 100644 --- a/plugin/wife/main.go +++ b/plugin/wife/main.go @@ -25,7 +25,6 @@ var ( Brief: "从老婆库抽每日老婆", PublicDataFolder: "Wife", }).ApplySingle(ctxext.DefaultSingle) - getJSON = fcext.DoOnceOnSuccess( func(ctx *zero.Ctx) bool { data, err := engine.GetLazyData("wife.json", true) @@ -37,7 +36,6 @@ var ( return false } } - err = json.Unmarshal(data, &cards) if err != nil { ctx.SendChain(message.Text("ERROR: 老婆库格式解析失败: ", err)) From 319c69007d4eca2f1b33f9e7e4b5f734e94d2ce9 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Fri, 6 Mar 2026 12:04:51 +0800 Subject: [PATCH 14/17] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20wifegame.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/wife/wifegame.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugin/wife/wifegame.go b/plugin/wife/wifegame.go index 523ef201dd..b1b5b4bc5f 100644 --- a/plugin/wife/wifegame.go +++ b/plugin/wife/wifegame.go @@ -32,7 +32,6 @@ func init() { class := 3 card := cards[rand.Intn(len(cards))] - pic, err := engine.GetLazyData("wives/"+card, true) if err != nil { logrus.Warnf("[wife] 猜老婆图片同步失败: %v,尝试读取本地文件...", err) @@ -42,8 +41,6 @@ func init() { return } } - // ------------------------------------ - work, name := card2name(card) name = strings.ToLower(name) img, _, err := image.Decode(bytes.NewReader(pic)) From d77b8cf3d03741ea4b267e5afd37e9ed62b11296 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Sat, 7 Mar 2026 13:17:52 +0800 Subject: [PATCH 15/17] Refactor upgrade logic and improve reporting --- plugin/mcfish/pole.go | 132 +++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 74 deletions(-) diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go index 749d4f1600..1f3c3956ed 100644 --- a/plugin/mcfish/pole.go +++ b/plugin/mcfish/pole.go @@ -458,87 +458,71 @@ func init() { } } } - groupCount := len(list) / 3 - successCount := 0 - failCount := 0 - successAttributes := []string{} + upgradeNum := len(list) + if upgradeNum == 0 || upgradeNum%3 != 0 { + ctx.SendChain(message.At(uid), message.Text("❌ 合成失败:材料数量必须是 3 的倍数(当前选择了 ", upgradeNum, " 个)")) + return + } - for g := 0; g < groupCount; g++ { - idx1 := list[g*3] - idx2 := list[g*3+1] - idx3 := list[g*3+2] + groupCount := upgradeNum / 3 + var successCount, failCount int + var reportDetails []string - thingInfo1 := articles[idx1] - thingInfo2 := articles[idx2] - thingInfo3 := articles[idx3] + baseTime := time.Now().Unix() - thingInfo1.Number = 0 - thingInfo2.Number = 0 - thingInfo3.Number = 0 + for g := 0; g < groupCount; g++ { + var groupInduce, groupFavor int - err = dbdata.updateUserThingInfo(uid, thingInfo1) - if err != nil { - ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) - return - } - err = dbdata.updateUserThingInfo(uid, thingInfo2) - if err != nil { - ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) - return - } - err = dbdata.updateUserThingInfo(uid, thingInfo3) - if err != nil { - ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) - return - } + for i := 0; i < 3; i++ { + idx := list[g*3+i] + thingInfo := articles[idx] + thingInfo.Number = 0 + _ = dbdata.updateUserThingInfo(uid, thingInfo) + + groupInduce += poles[idx].Induce + groupFavor += poles[idx].Favor + } - if rand.Intn(100) >= 90 { - failCount++ - continue - } + if rand.Intn(100) >= 90 { + failCount++ + continue + } - favorLevel := (poles[idx1].Favor + poles[idx2].Favor + poles[idx3].Favor) / 3 - induceLevel := (poles[idx1].Induce + poles[idx2].Induce + poles[idx3].Induce) / 3 - attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel) + "/" + strconv.Itoa(favorLevel) + successCount++ + avgInduce := groupInduce / 3 + avgFavor := groupFavor / 3 + attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(avgInduce) + "/" + strconv.Itoa(avgFavor) + + newthing := article{ + Duration: baseTime + int64(g*10) + int64(rand.Intn(100)), + Type: "pole", + Name: thingName, + Number: 1, + Other: attribute, + } + + err = dbdata.updateUserThingInfo(uid, newthing) + if err != nil { + failCount++ + continue + } - newthing := article{ - Duration: time.Now().Unix() + int64(g*10), - 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 - } - successCount++ - successAttributes = append(successAttributes, attribute) - } + if successCount <= 5 { + reportDetails = append(reportDetails, "✨ 第 "+strconv.Itoa(successCount)+" 支: [诱钓"+strconv.Itoa(avgInduce)+" 海眷"+strconv.Itoa(avgFavor)+"]") + } + } - resultMsg := "" - if successCount > 0 { - resultMsg += "成功合成 " + strconv.Itoa(successCount) + " 个" + thingName + "\n" - if len(successAttributes) <= 5 { - for _, attr := range successAttributes { - resultMsg += "属性: " + attr + "\n" - } - } else { - resultMsg += "属性示例: " + successAttributes[0] + " 等\n" - } - } - if failCount > 0 { - resultMsg += "失败 " + strconv.Itoa(failCount) + " 次,材料已销毁。" - } - if resultMsg == "" { - resultMsg = "没有进行任何合成?" - } +finalReport := " 合成报告 \n" + finalReport += "消耗材料: " + strconv.Itoa(upgradeNum) + " 个\n" + finalReport += "成功产出: " + strconv.Itoa(successCount) + " 支 | 失败: " + strconv.Itoa(failCount) + " 组\n" + + if successCount > 0 { + finalReport += "----\n" + strings.Join(reportDetails, "\n") + if successCount > 5 { + finalReport += "\n...以及其余 " + strconv.Itoa(successCount-5) + " 支属性已略过" + } + } - ctx.Send( - message.ReplyWithMessage(ctx.Event.MessageID, - message.Text(resultMsg), - ), - ) -}) + ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text(strings.TrimSpace(finalReport)))) + }) } From f6d75332a5aa72260bfff900c393c4761c2a5517 Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Sun, 8 Mar 2026 16:57:39 +0800 Subject: [PATCH 16/17] Refactor synthesis handling for fishing rods --- plugin/mcfish/pole.go | 235 ++++++++++++++++++------------------------ 1 file changed, 101 insertions(+), 134 deletions(-) diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go index 1f3c3956ed..7e2d56e573 100644 --- a/plugin/mcfish/pole.go +++ b/plugin/mcfish/pole.go @@ -342,137 +342,112 @@ func init() { } 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 - } - maxCount := len(articles) - if maxCount < 3 { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你的合成材料不足")) - return - } - poles := make([]equip, 0, maxCount) - 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")) - msg = append(msg, message.Text("- 输入3个序号进行合成(用空格分割)\n")) - msg = append(msg, message.Text("- 输入“取消”,终止本次合成\n")) - msg = append(msg, message.Text("- 输入“梭哈“,合成所有鱼竿")) - 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 - } - if nextcmd == "梭哈" { - // len(list)取3的倍数,表示能够用于合成鱼竿的最大数量,note:此处未对article.Number>1的情况做处理 - for i := 3; i < (len(articles)/3)*3; i++ { - list = append(list, i) - } - check = true - break - } - chooseList := strings.Split(nextcmd, " ") - 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 - } - list = []int{first, second, third} - if first == second || first == third || second == third { - ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[0]请输入正确的序号\n", list)) - continue - } - if first >= maxCount || second >= maxCount || third >= maxCount { - ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[", maxCount, "]请输入正确的序号\n", list)) - continue - } - check = true - } - if check { - break - } - } - } - upgradeNum := len(list) - if upgradeNum == 0 || upgradeNum%3 != 0 { - ctx.SendChain(message.At(uid), message.Text("❌ 合成失败:材料数量必须是 3 的倍数(当前选择了 ", upgradeNum, " 个)")) - return - } +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 + } + maxCount := len(articles) + if maxCount < 3 { + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你的合成材料不足")) + return + } + poles := make([]equip, 0, maxCount) + 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, + }) + } + var list []int + check := false + msg := make(message.Message, 0, 3+len(articles)) + msg = append(msg, message.Text("找到以下材料 ("+thingList[indexOfMaterial]+"):\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")) + msg = append(msg, message.Text("- 输入3个序号进行合成(用空格分割)\n")) + msg = append(msg, message.Text("- 输入“取消”,终止本次合成\n")) + msg = append(msg, message.Text("- 输入“梭哈“,合成所有鱼竿")) + ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, msg...)) + recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(梭哈|取消|(?:\d+\s*)+)$`), 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 := strings.TrimSpace(e.Event.Message.String()) + if nextcmd == "取消" { + ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("已取消合成"))) + return + } + if nextcmd == "梭哈" { + for i := 0; i < (len(articles)/3)*3; i++ { + list = append(list, i) + } + check = true + } else { + parts := strings.Fields(nextcmd) + if len(parts)%3 != 0 { + ctx.SendChain(message.At(ctx.Event.UserID), message.Text("\n合成失败:材料数量必须是 3 的倍数(当前输入了 ", len(parts), " 个)")) + continue + } + tempList := []int{} + valid := true + for _, p := range parts { + idx, err := strconv.Atoi(p) + if err != nil || idx < 0 || idx >= maxCount { + ctx.SendChain(message.At(ctx.Event.UserID), message.Text("\n序号 [", p, "] 超出范围,请重新输入")) + valid = false + break + } + tempList = append(tempList, idx) + } + if valid { + list = tempList + check = true + } + } + } + if check { + break + } + } + upgradeNum := len(list) groupCount := upgradeNum / 3 var successCount, failCount int var reportDetails []string - baseTime := time.Now().Unix() - for g := 0; g < groupCount; g++ { var groupInduce, groupFavor int - for i := 0; i < 3; i++ { idx := list[g*3+i] thingInfo := articles[idx] @@ -482,17 +457,14 @@ func init() { groupInduce += poles[idx].Induce groupFavor += poles[idx].Favor } - if rand.Intn(100) >= 90 { failCount++ continue } - successCount++ avgInduce := groupInduce / 3 avgFavor := groupFavor / 3 attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(avgInduce) + "/" + strconv.Itoa(avgFavor) - newthing := article{ Duration: baseTime + int64(g*10) + int64(rand.Intn(100)), Type: "pole", @@ -500,29 +472,24 @@ func init() { Number: 1, Other: attribute, } - err = dbdata.updateUserThingInfo(uid, newthing) if err != nil { failCount++ continue } - if successCount <= 5 { - reportDetails = append(reportDetails, "✨ 第 "+strconv.Itoa(successCount)+" 支: [诱钓"+strconv.Itoa(avgInduce)+" 海眷"+strconv.Itoa(avgFavor)+"]") + reportDetails = append(reportDetails, "第 "+strconv.Itoa(successCount)+" 支: [诱钓"+strconv.Itoa(avgInduce)+" 海眷"+strconv.Itoa(avgFavor)+"]") } } - -finalReport := " 合成报告 \n" +finalReport := "合成报告\n" finalReport += "消耗材料: " + strconv.Itoa(upgradeNum) + " 个\n" finalReport += "成功产出: " + strconv.Itoa(successCount) + " 支 | 失败: " + strconv.Itoa(failCount) + " 组\n" - if successCount > 0 { finalReport += "----\n" + strings.Join(reportDetails, "\n") if successCount > 5 { finalReport += "\n...以及其余 " + strconv.Itoa(successCount-5) + " 支属性已略过" } } - ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text(strings.TrimSpace(finalReport)))) }) } From 43dba36cd913022267b373586609415927d8c5fc Mon Sep 17 00:00:00 2001 From: fengling <92540917+FengLing11@users.noreply.github.com> Date: Sun, 8 Mar 2026 17:39:09 +0800 Subject: [PATCH 17/17] =?UTF-8?q?=E5=BE=85=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin/mcfish/pole.go | 341 +++++++++++++++++++++++++----------------- 1 file changed, 200 insertions(+), 141 deletions(-) diff --git a/plugin/mcfish/pole.go b/plugin/mcfish/pole.go index 7e2d56e573..228f15baea 100644 --- a/plugin/mcfish/pole.go +++ b/plugin/mcfish/pole.go @@ -342,154 +342,213 @@ func init() { } 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 - } - maxCount := len(articles) - if maxCount < 3 { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你的合成材料不足")) - return - } - - poles := make([]equip, 0, maxCount) - 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, - }) - } - var list []int - check := false - msg := make(message.Message, 0, 3+len(articles)) - msg = append(msg, message.Text("找到以下材料 ("+thingList[indexOfMaterial]+"):\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")) - msg = append(msg, message.Text("- 输入3个序号进行合成(用空格分割)\n")) - msg = append(msg, message.Text("- 输入“取消”,终止本次合成\n")) - msg = append(msg, message.Text("- 输入“梭哈“,合成所有鱼竿")) - ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, msg...)) - recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(梭哈|取消|(?:\d+\s*)+)$`), 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 := strings.TrimSpace(e.Event.Message.String()) - if nextcmd == "取消" { - ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("已取消合成"))) - return - } - if nextcmd == "梭哈" { - for i := 0; i < (len(articles)/3)*3; i++ { - list = append(list, i) - } - check = true - } else { - parts := strings.Fields(nextcmd) - if len(parts)%3 != 0 { - ctx.SendChain(message.At(ctx.Event.UserID), message.Text("\n合成失败:材料数量必须是 3 的倍数(当前输入了 ", len(parts), " 个)")) - continue - } - tempList := []int{} - valid := true - for _, p := range parts { - idx, err := strconv.Atoi(p) - if err != nil || idx < 0 || idx >= maxCount { - ctx.SendChain(message.At(ctx.Event.UserID), message.Text("\n序号 [", p, "] 超出范围,请重新输入")) - valid = false - break - } - tempList = append(tempList, idx) - } - if valid { - list = tempList - check = true - } - } - } - if check { - break - } - } - upgradeNum := len(list) - groupCount := upgradeNum / 3 - var successCount, failCount int - var reportDetails []string - baseTime := time.Now().Unix() - for g := 0; g < groupCount; g++ { - var groupInduce, groupFavor int - for i := 0; i < 3; i++ { - idx := list[g*3+i] - thingInfo := articles[idx] - thingInfo.Number = 0 - _ = dbdata.updateUserThingInfo(uid, thingInfo) - - groupInduce += poles[idx].Induce - groupFavor += poles[idx].Favor + 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 rand.Intn(100) >= 90 { - failCount++ - continue + } + 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 + } + maxCount := len(articles) + if maxCount < 3 { + ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你的合成材料不足")) + return + } + poles := make([]equip, 0, maxCount) + 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")) } - successCount++ - avgInduce := groupInduce / 3 - avgFavor := groupFavor / 3 - attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(avgInduce) + "/" + strconv.Itoa(avgFavor) - newthing := article{ - Duration: baseTime + int64(g*10) + int64(rand.Intn(100)), - Type: "pole", - Name: thingName, - Number: 1, - Other: attribute, + msg = append(msg, message.Text("————————\n")) + msg = append(msg, message.Text("- 输入3个序号进行合成(用空格分割)\n")) + msg = append(msg, message.Text("- 输入“取消”,终止本次合成\n")) + msg = append(msg, message.Text("- 输入“梭哈“,合成所有鱼竿")) + 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 + } + if nextcmd == "梭哈" { + totalBatches := maxCount / 3 + success := 0 + fail := 0 + for batch := 0; batch < totalBatches; batch++ { + base := batch * 3 + indices := []int{base, base + 1, base + 2} + sumInduce := 0 + sumFavor := 0 + for _, idx := range indices { + sumInduce += poles[idx].Induce + sumFavor += poles[idx].Favor + } + avgInduce := sumInduce / 3 + avgFavor := sumFavor / 3 + for _, idx := range indices { + thingInfo := articles[idx] + thingInfo.Number = 0 + err = dbdata.updateUserThingInfo(uid, thingInfo) + if err != nil { + ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) + return + } + } + if rand.Intn(100) < 90 { + attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(avgInduce) + "/" + strconv.Itoa(avgFavor) + newthing := article{ + Duration: time.Now().Unix() + int64(batch*10), + 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 + } + success++ + } else { + fail++ + } + } + remaining := maxCount % 3 + msgText := "合成完成,成功:" + strconv.Itoa(success) + " 个,失败:" + strconv.Itoa(fail) + " 个" + if remaining > 0 { + msgText += ",剩余 " + strconv.Itoa(remaining) + " 根材料未参与合成" + } + ctx.Send( + message.ReplyWithMessage(ctx.Event.MessageID, + message.Text(msgText), + ), + ) + return + } + chooseList := strings.Split(nextcmd, " ") + 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 + } + list = []int{first, second, third} + if first == second || first == third || second == third { + ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[0]请输入正确的序号\n", list)) + continue + } + if first >= maxCount || second >= maxCount || third >= maxCount { + ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[", maxCount, "]请输入正确的序号\n", list)) + continue + } + check = true + } + if check { + break + } } - err = dbdata.updateUserThingInfo(uid, newthing) + } + upgradeNum := len(list) + favorLevel := 0 + induceLevel := 0 + for _, index := range list { + thingInfo := articles[index] + thingInfo.Number = 0 + err = dbdata.updateUserThingInfo(uid, thingInfo) if err != nil { - failCount++ - continue - } - if successCount <= 5 { - reportDetails = append(reportDetails, "第 "+strconv.Itoa(successCount)+" 支: [诱钓"+strconv.Itoa(avgInduce)+" 海眷"+strconv.Itoa(avgFavor)+"]") + ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err)) + return } + favorLevel += poles[index].Favor + induceLevel += poles[index].Induce + } + if rand.Intn(100) >= 90 { + ctx.Send( + message.ReplyWithMessage(ctx.Event.MessageID, + message.Text("合成失败,材料已销毁"), + ), + ) + return } -finalReport := "合成报告\n" - finalReport += "消耗材料: " + strconv.Itoa(upgradeNum) + " 个\n" - finalReport += "成功产出: " + strconv.Itoa(successCount) + " 支 | 失败: " + strconv.Itoa(failCount) + " 组\n" - if successCount > 0 { - finalReport += "----\n" + strings.Join(reportDetails, "\n") - if successCount > 5 { - finalReport += "\n...以及其余 " + strconv.Itoa(successCount-5) + " 支属性已略过" + attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel/upgradeNum) + "/" + strconv.Itoa(favorLevel/upgradeNum) + newthing := article{ + Duration: time.Now().Unix(), + Type: "pole", + Name: thingName, + Number: 1, + Other: attribute, + } + // 代码未对article.Number>1的情况做处理,直接生成多个Number=1的鱼竿 + for i := 0; i < upgradeNum/3; i++ { + // 使用时间戳作为主键,增加固定值避免主键冲突 + newthing.Duration += int64(i * 10) + 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(strings.TrimSpace(finalReport)))) + ctx.Send( + message.ReplyWithMessage(ctx.Event.MessageID, + message.Text("成功合成:", upgradeNum/3, "个", thingName, "\n属性: ", attribute), + ), + ) }) }