Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update: 重写[mcfish]交易检测逻辑 #1070

Merged
merged 1 commit into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 23 additions & 47 deletions plugin/mcfish/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"math/rand"
"os"
"strconv"
"strings"
"sync"
"time"

Expand All @@ -28,7 +29,7 @@ type fishdb struct {
const FishLimit = 50

// version 规则版本号
const version = "5.5.8"
const version = "5.5.9"

// 各物品信息
type jsonInfo struct {
Expand Down Expand Up @@ -147,7 +148,7 @@ var (
"8.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率90%(包括梭哈),合成鱼竿的附魔等级=(附魔等级合/合成鱼竿数量)\n" +
"9.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为60%(理论值!!!)\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿,修复时可直接满耐久\n" +
"-> 鱼竿数量大于50的不能买东西;\n 鱼竿数量大于30的不能钓鱼;\n 每购/售10次鱼竿获得1层宝藏诅咒;\n 每购买20次物品将获得3次价格减半福利;\n 每钓鱼75次获得1本净化书;\n" +
" 每天最多只可出售5个鱼竿和购买15次物品;鱼类交易每天最多100条.",
" 每天可交易鱼竿10个,物品200件.",
PublicDataFolder: "McFish",
}).ApplySingle(ctxext.DefaultSingle)
getdb = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
Expand Down Expand Up @@ -344,7 +345,7 @@ func (sql *fishdb) setEquipFor(uid int64) (err error) {
if err != nil {
return err
}
_ = sql.db.Find("fishState", &userInfo, "WHERE ID = ?", uid)
err = sql.db.Find("fishState", &userInfo, "WHERE ID = ?", uid)
if err != nil {
return err
}
Expand Down Expand Up @@ -608,7 +609,7 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
}
}
thing := store{}
oldThing := []store{}
var oldThing []store
_ = sql.db.FindFor("stroeDiscount", &thing, "WHERE type = 'pole'", func() error {
if time.Since(time.Unix(thing.Duration, 0)) > 24 {
oldThing = append(oldThing, thing)
Expand All @@ -628,7 +629,7 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
Price: priceList[fish] * discountList[fish] / 100,
}
_ = sql.db.Find("store", &thingInfo, "WHERE Name = ?", fish)
thingInfo.Number += (100 - discountList[fish])
thingInfo.Number += 100 - discountList[fish]
if thingInfo.Number < 1 {
thingInfo.Number = 100
}
Expand Down Expand Up @@ -774,15 +775,14 @@ func (sql *fishdb) useCouponAt(uid int64, times int) (int, error) {
return useTimes, sql.db.Insert("buff", &userInfo)
}

// 检测卖鱼竿上限
func (sql *fishdb) checkCanSalesFor(uid int64, sales bool) (int, error) {
residue := 0
// 买卖上限检测
func (sql *fishdb) checkCanSalesFor(uid int64, saleType string, salesNum int) (int, error) {
sql.Lock()
defer sql.Unlock()
userInfo := buffInfo{ID: uid}
err := sql.db.Create("buff", &userInfo)
if err != nil {
return residue, err
return salesNum, err
}
_ = sql.db.Find("buff", &userInfo, "WHERE ID = ?", uid)
if time.Now().Day() != time.Unix(userInfo.Duration, 0).Day() {
Expand All @@ -791,14 +791,22 @@ func (sql *fishdb) checkCanSalesFor(uid int64, sales bool) (int, error) {
userInfo.BuyTing = 0
userInfo.SalesFish = 0
}
if sales && userInfo.SalesPole < 5 {
residue = 5 - userInfo.SalesPole
if strings.Contains(saleType, "竿") {
if userInfo.SalesPole >= 10 {
salesNum = -1
}
userInfo.SalesPole++
} else if userInfo.BuyTing < 15 {
residue = 15 - userInfo.BuyTing
userInfo.BuyTing++
} else {
maxSales := 200 - userInfo.SalesFish
if maxSales < 0 {
salesNum = 0
}
if salesNum > maxSales {
salesNum = maxSales
}
}
return residue, sql.db.Insert("buff", &userInfo)

return salesNum, sql.db.Insert("buff", &userInfo)
}

// 检测物品是否是鱼
Expand All @@ -811,38 +819,6 @@ func checkIsFish(thing string) bool {
return false
}

// 查询能交易鱼类的数量
func (sql *fishdb) selectCanSalesFishFor(uid int64, sales int) int {
residue := 0
sql.Lock()
defer sql.Unlock()
userInfo := buffInfo{ID: uid}
err := sql.db.Create("buff", &userInfo)
if err != nil {
return residue
}
_ = sql.db.Find("buff", &userInfo, "WHERE ID = ?", uid)
if time.Now().Day() != time.Unix(userInfo.Duration, 0).Day() {
userInfo.Duration = time.Now().Unix()
// 在 checkCanSalesFor 也有更新buff时间,TODO:重构 *CanSalesFishFor 俩个函数
userInfo.SalesPole = 0
userInfo.BuyTing = 0
userInfo.SalesFish = 0
err := sql.db.Insert("buff", &userInfo)
if err != nil {
return residue
}
}
maxSales := 100 - userInfo.SalesFish
if maxSales < 0 {
maxSales = 0
}
if sales > maxSales {
sales = maxSales
}
return sales
}

// 更新买卖鱼上限,假定sales变量已经在 selectCanSalesFishFor 进行了防护
func (sql *fishdb) updateCanSalesFishFor(uid int64, sales int) error {
sql.Lock()
Expand Down
67 changes: 34 additions & 33 deletions plugin/mcfish/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,29 +70,28 @@ func init() {
engine.OnRegex(`^出售(`+strings.Join(thingList, "|")+`)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(limitSet).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
thingName := ctx.State["regex_matched"].([]string)[1]
if strings.Contains(thingName, "竿") {
times, err := dbdata.checkCanSalesFor(uid, true)
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.75]:", err))
return
}
if times <= 0 {
ctx.SendChain(message.Text("出售次数已达到上限,明天再来售卖吧"))
return
}
}
number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[2])
if number == 0 || strings.Contains(thingName, "竿") {
number = 1
}
if checkIsFish(thingName) {
residue := dbdata.selectCanSalesFishFor(uid, number)
if residue <= 0 {
ctx.SendChain(message.Text("一天只能交易100条鱼,明天再来卖鱼吧"))
return

// 检测物品交易次数
number, err := dbdata.checkCanSalesFor(uid, thingName, number)
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.75]:", err))
return
}
if number <= 0 {
var msg string
if strings.Contains(thingName, "竿") {
msg = "一天只能交易10把鱼竿,明天再来售卖吧"
} else {
msg = "一天只能交易200次物品,明天再来吧~"
}
number = residue
ctx.SendChain(message.Text(msg))
return
}

articles, err := dbdata.getUserThingInfo(uid, thingName)
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.5]:", err))
Expand Down Expand Up @@ -402,6 +401,12 @@ func init() {
})
engine.OnRegex(`^购买(`+strings.Join(thingList, "|")+`)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(limitSet).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
thingName := ctx.State["regex_matched"].([]string)[1]
number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[2])
if number == 0 || strings.Contains(thingName, "竿") {
number = 1
}

numberOfPole, err := dbdata.getNumberFor(uid, "竿")
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.9.3]:", err))
Expand All @@ -411,28 +416,24 @@ func init() {
ctx.SendChain(message.Text("你有", numberOfPole, "支鱼竿,大于50支的玩家不允许购买东西"))
return
}
buytimes, err := dbdata.checkCanSalesFor(uid, false)

// 检测物品交易次数
number, err = dbdata.checkCanSalesFor(uid, thingName, number)
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.75]:", err))
return
}
if buytimes <= 0 {
ctx.SendChain(message.Text("购买次数已达到上限,明天再来购买吧"))
return
}
thingName := ctx.State["regex_matched"].([]string)[1]
number, _ := strconv.Atoi(ctx.State["regex_matched"].([]string)[2])
if number == 0 {
number = 1
}
if checkIsFish(thingName) {
residue := dbdata.selectCanSalesFishFor(uid, number)
if residue <= 0 {
ctx.SendChain(message.Text("一天只能交易100条鱼,明天再来买鱼吧"))
return
if number <= 0 {
var msg string
if strings.Contains(thingName, "竿") {
msg = "一天只能交易10把鱼竿,明天再来售卖吧"
} else {
msg = "一天只能交易200次物品,明天再来吧~"
}
number = residue
ctx.SendChain(message.Text(msg))
return
}

thingInfos, err := dbdata.getStoreThingInfo(thingName)
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.11]:", err))
Expand Down
Loading