diff --git a/README.md b/README.md index 336281875a..9dcef358bd 100644 --- a/README.md +++ b/README.md @@ -1135,6 +1135,14 @@ print("run[CQ:image,file="+j["img"]+"]") - 注:本插件来源于[tgbot](https://github.com/YukariChiba/tgbot/blob/main/modules/Reborn.py) + +
+ 打劫 + +`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/robbery"` + +- [x] 打劫[对方Q号|@对方QQ] +
在线代码运行 diff --git a/main.go b/main.go index 5ce6e6acf5..e1881754d4 100644 --- a/main.go +++ b/main.go @@ -119,6 +119,7 @@ import ( _ "github.com/FloatTech/ZeroBot-Plugin/plugin/qzone" // qq空间表白墙 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/realcugan" // realcugan清晰术 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/reborn" // 投胎 + _ "github.com/FloatTech/ZeroBot-Plugin/plugin/robbery" // 打劫群友的ATRI币 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/runcode" // 在线运行代码 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/saucenao" // 以图搜图 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/score" // 分数 diff --git a/plugin/robbery/robbery.go b/plugin/robbery/robbery.go new file mode 100644 index 0000000000..a4d3ec8c25 --- /dev/null +++ b/plugin/robbery/robbery.go @@ -0,0 +1,173 @@ +// Package robbery 打劫群友 基于“qqwife”插件魔改 +package robbery + +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/wdvxdr1123/ZeroBot/extension/single" + + "github.com/FloatTech/AnimeAPI/wallet" + "github.com/FloatTech/floatbox/math" + "github.com/FloatTech/zbputils/ctxext" + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" +) + +type robberyRepo struct { + db *sql.Sqlite + sync.RWMutex +} + +type robberyRecord struct { + UserID int64 `db:"user_id"` // 劫匪 + VictimID int64 `db:"victim_id"` // 受害者 + Time string `db:"time"` // 时间 +} + +func init() { + police := &robberyRepo{ + db: &sql.Sqlite{}, + } + engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{ + DisableOnDefault: false, + Brief: "打劫别人的ATRI币", + Help: "- 打劫[对方Q号|@对方QQ]\n" + + "1. 受害者钱包少于1000不能被打劫\n" + + "2. 打劫成功率 40%\n" + + "4. 打劫失败罚款1000(钱不够不罚钱)\n" + + "5. 保险赔付0-80%\n" + + "6. 打劫成功获得对方0-5%+500的财产(最高1W)\n" + + "7. 每日可打劫或被打劫一次\n" + + "8. 打劫失败不计入次数\n", + PrivateDataFolder: "robbery", + }).ApplySingle(single.New( + single.WithKeyFn(func(ctx *zero.Ctx) int64 { return ctx.Event.GroupID }), + single.WithPostFn[int64](func(ctx *zero.Ctx) { + ctx.Send( + message.ReplyWithMessage(ctx.Event.MessageID, + message.Text("别着急,警察局门口排长队了!"), + ), + ) + }), + )) + getdb := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { + police.db.DBPath = engine.DataFolder() + "robbery.db" + err := police.db.Open(time.Hour) + if err == nil { + // 创建CD表 + err = police.db.Create("criminal_record", &robberyRecord{}) + if err != nil { + ctx.SendChain(message.Text("[ERROR]:", err)) + return false + } + return true + } + ctx.SendChain(message.Text("[ERROR]:", err)) + return false + }) + + // 打劫功能 + engine.OnRegex(`^打劫\s?(\[CQ:at,qq=(\d+)\]|(\d+))`, getdb).SetBlock(true).Limit(ctxext.LimitByUser). + Handle(func(ctx *zero.Ctx) { + uid := ctx.Event.UserID + fiancee := ctx.State["regex_matched"].([]string) + victimID, _ := strconv.ParseInt(fiancee[2]+fiancee[3], 10, 64) + if victimID == uid { + ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.At(uid), message.Text("不能打劫自己"))) + return + } + + // 查询记录 + ok, err := police.getRecord(victimID, uid) + if err != nil { + ctx.SendChain(message.Text("[ERROR]:", err)) + return + } + if !ok { + ctx.SendChain(message.Text("你已经打劫过了/对方已经被打劫过了")) + return + } + + // 穷人保护 + victimWallet := wallet.GetWalletOf(victimID) + if victimWallet < 1000 { + ctx.SendChain(message.Text("对方太穷了!打劫失败")) + return + } + + // 判断打劫是否成功 + if rand.Intn(100) > 60 { + ctx.SendChain(message.Text("打劫失败,罚款1000")) + err := wallet.InsertWalletOf(uid, -1000) + if err != nil { + ctx.SendChain(message.Text("[ERROR]:罚款失败,钱包坏掉力:\n", err)) + return + } + return + } + userIncrMonry := math.Min(rand.Intn(victimWallet/20)+500, 10000) + victimDecrMonry := userIncrMonry / (rand.Intn(4) + 1) + + // 记录结果 + err = wallet.InsertWalletOf(victimID, -victimDecrMonry) + if err != nil { + ctx.SendChain(message.Text("[ERROR]:钱包坏掉力:\n", err)) + return + } + err = wallet.InsertWalletOf(uid, +userIncrMonry) + if err != nil { + ctx.SendChain(message.Text("[ERROR]:打劫失败,脏款掉入虚无\n", err)) + return + } + + // 写入记录 + err = police.insertRecord(victimID, uid) + if err != nil { + ctx.SendChain(message.At(uid), message.Text("[ERROR]:犯罪记录写入失败\n", err)) + } + + ctx.SendChain(message.At(uid), message.Text("打劫成功,钱包增加:", userIncrMonry, "ATRI币")) + ctx.SendChain(message.At(victimID), message.Text("保险公司对您进行了赔付,您实际损失:", victimDecrMonry, "ATRI币")) + }) +} + +func (sql *robberyRepo) getRecord(victimID, uid int64) (ok bool, err error) { + sql.Lock() + defer sql.Unlock() + // 创建群表格 + err = sql.db.Create("criminal_record", &robberyRecord{}) + if err != nil { + return false, err + } + limitID := "where victim_id is " + strconv.FormatInt(victimID, 10) + + " or user_id is " + strconv.FormatInt(uid, 10) + if !sql.db.CanFind("criminal_record", limitID) { + // 没有记录即不用比较 + return true, nil + } + cdinfo := robberyRecord{} + _ = sql.db.Find("criminal_record", &cdinfo, limitID) + if time.Now().Format("2006/01/02") != cdinfo.Time { + // // 如果跨天了就删除 + err = sql.db.Del("criminal_record", limitID) + return true, err + } + return false, nil +} + +func (sql *robberyRepo) insertRecord(vid int64, uid int64) error { + sql.Lock() + defer sql.Unlock() + return sql.db.Insert("criminal_record", &robberyRecord{ + UserID: uid, + VictimID: vid, + Time: time.Now().Format("2006/01/02"), + }) +}