diff --git a/README.md b/README.md index 76e630c6..add8db9f 100644 --- a/README.md +++ b/README.md @@ -534,14 +534,26 @@ print("run[CQ:image,file="+j["img"]+"]") `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/qqwife"` + - 引入好感度系统,好感度越高,自由恋爱成功率越高 + + - [x] 设置CD为xx小时 + + - [x] 允许/禁止自由恋爱 + + - [x] 允许/禁止牛头人 + - [x] 娶群友 - [x] (娶|嫁)[@对方QQ] - [x] 当[对方Q号|@对方QQ]的小三 + - [x] 做媒 @攻方QQ @受方QQ + - [x] 群老婆列表 + - [x] 重置花名册 +
合成emoji diff --git a/plugin/qqwife/command.go b/plugin/qqwife/command.go index 4935f9d7..2372ab87 100644 --- a/plugin/qqwife/command.go +++ b/plugin/qqwife/command.go @@ -18,8 +18,6 @@ import ( "github.com/wdvxdr1123/ZeroBot/extension/single" // 数据库 sql "github.com/FloatTech/sqlite" - // 定时器 - "github.com/wdvxdr1123/ZeroBot/extension/rate" // 画图 "github.com/Coloured-glaze/gg" fcext "github.com/FloatTech/floatbox/ctxext" @@ -29,12 +27,11 @@ import ( ) // nolint: asciicheck -//nolint: asciicheck +// nolint: asciicheck var ( 民政局 = &婚姻登记{ db: &sql.Sqlite{}, } - skillCD = rate.NewManager[string](time.Hour*12, 1) sendtext = [...][]string{ { // 表白成功 "是个勇敢的孩子(*/ω\*) 今天的运气都降临在你的身边~\n\n", @@ -49,12 +46,12 @@ var ( "因为你的个人魅力~~今天他就是你的了w\n\n", }, { // 离婚失败 - "打是情,骂是爱,,不打不亲不相爱。答应我不要分手。", + "打是情,骂是爱,不打不亲不相爱。答应我不要分手。", "床头打架床尾和,夫妻没有隔夜仇。安啦安啦,不要闹变扭。", }, { // 离婚成功 - "离婚成功力\n天涯何处无芳草,何必单恋一枝花?不如再摘一支(bushi", "离婚成功力\n话说你不考虑当个1?", + "离婚成功力\n天涯何处无芳草,何必单恋一枝花?不如再摘一支(bushi", }, } ) @@ -64,9 +61,14 @@ func init() { DisableOnDefault: false, PrivateDataFolder: "qqwife", Help: "一群一天一夫一妻制群老婆\n(每天凌晨刷新CP)\n" + - "- 娶群友\n- 群老婆列表\n- 我群老婆\n" + - "--------------------------------\n以下技能每个CD12H,不跨天刷新\n--------------------------------\n" + - "- (娶|嫁)@对方QQ\n- 当[对方Q号|@对方QQ]的小三\n- 闹离婚", + "- 娶群友\n- 群老婆列表\n- 允许/禁止自由恋爱\n- 允许/禁止牛头人\n- 设置CD为xx小时 →(默认12小时)\n- 重置花名册\n" + + "--------------------------------\n以下指令存在CD,不跨天刷新,前两个受指令开关\n--------------------------------\n" + + "- (娶|嫁)@对方QQ\n自由选择对象,自由恋爱(好感度越高成功率越高,保底30%概率)\n" + + "- 当[对方Q号|@对方QQ]的小三\n我和你才是真爱,为了你我愿意付出一切(好感度越高成功率越高,保底10%概率)\n" + + "- 闹离婚\n你谁啊,给我滚(好感度越高成功率越低)\n" + + "- 做媒 @攻方QQ @受方QQ\n身为管理,群友的xing福是要搭把手的(攻受双方好感度越高成功率越高,保底30%概率)\n" + + "--------------------------------\n好感度规则\n--------------------------------\n" + + "‘娶群友’指令好感度随机增加1~5。\n‘A牛B的C’会导致C恨A,好感度-5;\nB为了报复A,好感度+5(什么柜子play)\nA为BC做媒,成功B、C对A好感度+1反之-1\n做媒成功BC好感度+1", }).ApplySingle(single.New( single.WithKeyFn(func(ctx *zero.Ctx) int64 { return ctx.Event.GroupID }), single.WithPostFn[int64](func(ctx *zero.Ctx) { @@ -81,24 +83,76 @@ func init() { 民政局.db.DBPath = engine.DataFolder() + "结婚登记表.db" err := 民政局.db.Open(time.Hour * 24) if err != nil { - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) return false } return true }) + // 技能CD设置 + engine.OnRegex(`^设置CD为(\d+)小时`, zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser). + Handle(func(ctx *zero.Ctx) { + cdTime, err := strconv.ParseFloat(ctx.State["regex_matched"].([]string)[1], 64) + if err != nil { + ctx.SendChain(message.Text("[qqwife]请设置纯数字\n", err)) + return + } + gid := ctx.Event.GroupID + err = 民政局.setCDtime(gid, cdTime) + if err != nil { + ctx.SendChain(message.Text("[qqwife]设置CD时长失败\n", err)) + return + } + ctx.SendChain(message.Text("设置成功")) + }) + engine.OnRegex(`^(允许|禁止)(自由恋爱|牛头人)$`, zero.AdminPermission, getdb).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + status := ctx.State["regex_matched"].([]string)[1] + mode := ctx.State["regex_matched"].([]string)[2] + gid := ctx.Event.GroupID + statusBool := 1 + if status == "禁止" { + statusBool = 0 + } + err := 民政局.修改模式(gid, mode, statusBool) + if err != nil { + ctx.SendChain(message.Text("[qqwife]群状态查询失败\n", err)) + return + } + ctx.SendChain(message.Text("设置成功")) + }) + // 好感度系统 + engine.OnRegex(`^查好感度\s?\[CQ:at,qq=(\d+)\]`, zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser). + Handle(func(ctx *zero.Ctx) { + fiancee, err := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64) + if err != nil { + ctx.SendChain(message.Text("[qqwife]你对象好像不存在?\n", err)) + return + } + uid := ctx.Event.UserID + favor, err := 民政局.getFavorability(uid, fiancee) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + return + } + // 输出结果 + ctx.SendChain( + message.At(uid), + message.Text("\n当前你们好感度为", favor), + ) + }) engine.OnFullMatch("娶群友", zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { gid := ctx.Event.GroupID _, err := 民政局.开门时间(gid) if err != nil { - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) return } uid := ctx.Event.UserID targetinfo, status, err := 民政局.查户口(gid, uid) switch { case status == "错": - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) return case (status == "攻" && targetinfo.Target == 0) || (status == "受" && targetinfo.User == 0): // 如果是单身贵族 @@ -139,7 +193,11 @@ func init() { qqgrouplist := make([]int64, 0, len(temp)) for k := 0; k < len(temp); k++ { usr := temp[k].Get("user_id").Int() - _, status, _ := 民政局.查户口(gid, usr) + _, status, err := 民政局.查户口(gid, usr) + if status == "错" { + ctx.SendChain(message.Text("[qqwife]花名册数据读取有误,请重试\n", err)) + return + } if status != "单" { continue } @@ -159,9 +217,13 @@ func init() { // 去民政局办证 err = 民政局.登记(gid, uid, fiancee, ctx.CardOrNickName(uid), ctx.CardOrNickName(fiancee)) if err != nil { - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) return } + favor, err := 民政局.setFavorability(uid, fiancee, 1+rand.Intn(5)) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + } // 请大家吃席 ctx.SendChain( message.At(uid), @@ -170,23 +232,23 @@ func init() { message.Text( "\n", "[", ctx.CardOrNickName(fiancee), "]", - "(", fiancee, ")哒", + "(", fiancee, ")哒\n当前你们好感度为", favor, ), ) }) // 单身技能 - engine.OnRegex(`^(娶|嫁)\[CQ:at,qq=(\d+)\]`, zero.OnlyGroup, getdb, checkdog).SetBlock(true).Limit(cdcheck, iscding). + engine.OnRegex(`^(娶|嫁)\[CQ:at,qq=(\d+)\]`, zero.OnlyGroup, getdb, checkdog).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { + gid := ctx.Event.GroupID + uid := ctx.Event.UserID choice := ctx.State["regex_matched"].([]string)[1] fiancee, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[2], 10, 64) - uid := ctx.Event.UserID - gid := ctx.Event.GroupID if uid == fiancee { // 如果是自己 switch rand.Intn(3) { case 1: err := 民政局.登记(gid, uid, 0, "", "") if err != nil { - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) return } ctx.SendChain(message.Text("今日获得成就:单身贵族")) @@ -195,7 +257,15 @@ func init() { } return } - if rand.Intn(2) == 0 { // 二分之一的概率表白成功 + favor, err := 民政局.getFavorability(uid, fiancee) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + return + } + if favor < 30 { + favor = 30 // 保底30%概率 + } + if rand.Intn(101) >= favor { ctx.SendChain(message.Text(sendtext[1][rand.Intn(len(sendtext[1]))])) return } @@ -205,14 +275,14 @@ func init() { case "娶": err := 民政局.登记(gid, uid, fiancee, ctx.CardOrNickName(uid), ctx.CardOrNickName(fiancee)) if err != nil { - ctx.SendChain(message.Text("结婚登记失败力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]结婚登记失败力\n", err)) return } choicetext = "\n今天你的群老婆是" default: err := 民政局.登记(gid, fiancee, uid, ctx.CardOrNickName(fiancee), ctx.CardOrNickName(uid)) if err != nil { - ctx.SendChain(message.Text("结婚登记失败力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]结婚登记失败力\n", err)) return } choicetext = "\n今天你的群老公是" @@ -231,31 +301,40 @@ func init() { ) }) // NTR技能 - engine.OnRegex(`^当(\[CQ:at,qq=(\d+)\]\s?|(\d+))的小三`, zero.OnlyGroup, getdb, checkcp).SetBlock(true).Limit(cdcheck2, iscding). + engine.OnRegex(`^当(\[CQ:at,qq=(\d+)\]\s?|(\d+))的小三`, zero.OnlyGroup, getdb, checkcp).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { + gid := ctx.Event.GroupID + uid := ctx.Event.UserID fid := ctx.State["regex_matched"].([]string) fiancee, _ := strconv.ParseInt(fid[2]+fid[3], 10, 64) - uid := ctx.Event.UserID if fiancee == uid { ctx.SendChain(message.Text("今日获得成就:自我攻略")) return } - if rand.Intn(10)/4 != 0 { // 十分之三的概率NTR成功 + favor, err := 民政局.getFavorability(uid, fiancee) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + return + } + if favor < 30 { + favor = 30 // 保底10%概率 + } + if rand.Intn(101) >= favor/3 { ctx.SendChain(message.Text("失败了!可惜")) return } - gid := ctx.Event.GroupID // 判断target是老公还是老婆 var choicetext string - userID := uid - targetID := fiancee - fianceeinfo, gender, err := 民政局.查户口(gid, fiancee) + userAID := uid //攻的 + var userBID int64 //被牛的 + userCID := fiancee //受的 + fianceeinfo, gender, err := 民政局.查户口(gid, userCID) switch gender { case "单": ctx.SendChain(message.Text("ta现在还是单身哦,快向ta表白吧!")) return case "错": - ctx.SendChain(message.Text("对象状态查询失败\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]对象状态查询失败\n", err)) return case "攻": err = 民政局.离婚休妻(gid, fianceeinfo.Target) @@ -263,8 +342,9 @@ func init() { ctx.SendChain(message.Text("ta不想和原来的对象分手...\n[error]", err)) return } - userID = fiancee - targetID = uid + userAID = fiancee + userCID = uid + userBID = fianceeinfo.Target choicetext = "老公" case "受": err = 民政局.离婚休夫(gid, fianceeinfo.User) @@ -272,16 +352,25 @@ func init() { ctx.SendChain(message.Text("ta不想和原来的对象分手...\n[error]", err)) return } + userBID = fianceeinfo.User choicetext = "老婆" default: ctx.SendChain(message.Text("数据库发生问题力")) return } - err = 民政局.登记(gid, userID, targetID, ctx.CardOrNickName(userID), ctx.CardOrNickName(targetID)) + err = 民政局.登记(gid, userAID, userCID, ctx.CardOrNickName(userAID), ctx.CardOrNickName(userCID)) if err != nil { - ctx.SendChain(message.Text("复婚登记失败力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]复婚登记失败力\n", err)) return } + favor, err = 民政局.setFavorability(userAID, userCID, -5) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + } + _, err = 民政局.setFavorability(userAID, userBID, 5) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + } // 输出结果 ctx.SendChain( message.Text(sendtext[2][rand.Intn(len(sendtext[2]))]), @@ -291,16 +380,117 @@ func init() { message.Text( "\n", "[", ctx.CardOrNickName(fiancee), "]", - "(", fiancee, ")哒", + "(", fiancee, ")哒\n当前你们好感度为", favor, ), ) }) + // 做媒技能 + engine.OnRegex(`^做媒\s?\[CQ:at,qq=(\d+)\]\s?\[CQ:at,qq=(\d+)\]`, zero.OnlyGroup, zero.AdminPermission, getdb, checkCondition).SetBlock(true).Limit(ctxext.LimitByUser). + Handle(func(ctx *zero.Ctx) { + gid := ctx.Event.GroupID + uid := ctx.Event.UserID + gayOne, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64) + gayZero, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[2], 10, 64) + favor, err := 民政局.getFavorability(gayOne, gayZero) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + return + } + if favor < 30 { + favor = 30 // 保底30%概率 + } + if rand.Intn(101) >= favor { + _, err = 民政局.setFavorability(uid, gayOne, -1) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + } + _, err = 民政局.setFavorability(uid, gayZero, -1) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + } + ctx.SendChain(message.Text(sendtext[1][rand.Intn(len(sendtext[1]))])) + return + } + // 去民政局登记 + err = 民政局.登记(gid, gayOne, gayZero, ctx.CardOrNickName(gayOne), ctx.CardOrNickName(gayZero)) + if err != nil { + ctx.SendChain(message.Text("[qqwife]结婚登记失败力\n", err)) + return + } + _, err = 民政局.setFavorability(uid, gayOne, 1) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + } + _, err = 民政局.setFavorability(uid, gayZero, 1) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + } + _, err = 民政局.setFavorability(gayOne, gayZero, 1) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + } + // 请大家吃席 + ctx.SendChain( + message.At(uid), + message.Text("恭喜你成功撮合了一对CP\n\n"), + message.At(gayOne), + message.Text("今天你的群老婆是"), + message.Image("http://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(gayZero, 10)+"&s=640").Add("cache", 0), + message.Text( + "\n", + "[", ctx.CardOrNickName(gayZero), "]", + "(", gayZero, ")哒", + ), + ) + }) + engine.OnFullMatchGroup([]string{"闹离婚", "办离婚"}, zero.OnlyGroup, getdb, checkdivorce).Limit(ctxext.LimitByUser).SetBlock(true). + Handle(func(ctx *zero.Ctx) { + gid := ctx.Event.GroupID + uid := ctx.Event.UserID + info, uidstatus, err := 民政局.查户口(gid, uid) + mun := 2 + var fiancee int64 + switch uidstatus { + case "错": + ctx.SendChain(message.Text("[qqwife]用户状态查询失败\n", err)) + return + case "攻": + mun = 1 + fiancee = info.Target + case "受": + mun = 0 + fiancee = info.User + } + favor, err := 民政局.getFavorability(uid, fiancee) + if err != nil { + ctx.SendChain(message.Text("[qqwife]好感度库发生问题力\n", err)) + return + } + if rand.Intn(1+favor) > favor/10 { + ctx.SendChain(message.Text(sendtext[3][rand.Intn(len(sendtext[3]))])) + return + } + switch mun { + case 1: + err = 民政局.离婚休妻(gid, fiancee) + case 0: + err = 民政局.离婚休夫(gid, fiancee) + default: + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) + return + } + if err != nil { + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) + return + } + ctx.SendChain(message.Text(sendtext[4][mun])) + }) engine.OnFullMatch("群老婆列表", zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { gid := ctx.Event.GroupID ok, err := 民政局.开门时间(gid) if err != nil { - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) return } if ok { @@ -309,7 +499,7 @@ func init() { } list, number, err := 民政局.花名册(gid) if err != nil { - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) return } if number <= 0 { @@ -327,13 +517,13 @@ func init() { /***********下载字体,可以注销掉***********/ _, err = file.GetLazyData(text.BoldFontFile, true) if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) + ctx.SendChain(message.Text("[qqwife]ERROR: ", err)) } /***********设置字体颜色为黑色***********/ canvas.SetRGB(0, 0, 0) /***********设置字体大小,并获取字体高度用来定位***********/ if err = canvas.LoadFontFace(text.BoldFontFile, fontSize*2); err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) + ctx.SendChain(message.Text("[qqwife]ERROR: ", err)) return } sl, h := canvas.MeasureString("群老婆列表") @@ -342,7 +532,7 @@ func init() { canvas.DrawString("————————————————————", 0, 250-h) /***********设置字体大小,并获取字体高度用来定位***********/ if err = canvas.LoadFontFace(text.BoldFontFile, fontSize); err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) + ctx.SendChain(message.Text("[qqwife]ERROR: ", err)) return } _, h = canvas.MeasureString("焯") @@ -357,53 +547,6 @@ func init() { ctx.SendChain(message.ImageBytes(data)) cl() }) - engine.OnFullMatchGroup([]string{"闹离婚", "办离婚"}, zero.OnlyGroup, getdb, func(ctx *zero.Ctx) bool { - gid := ctx.Event.GroupID - uid := ctx.Event.UserID - _, uidstatus, err := 民政局.查户口(gid, uid) - switch uidstatus { - case "错": - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) - return false - case "单": - ctx.SendChain(message.Text("今天你还没结婚哦")) - return false - } - return true - }).SetBlock(true).Limit(cdcheck3, iscding2). - Handle(func(ctx *zero.Ctx) { - gid := ctx.Event.GroupID - uid := ctx.Event.UserID - info, uidstatus, err := 民政局.查户口(gid, uid) - mun := 2 - switch uidstatus { - case "错": - ctx.SendChain(message.Text("用户状态查询失败\n[error]", err)) - return - case "攻": - mun = 1 - case "受": - mun = 0 - } - if rand.Intn(10) != 1 { // 十分之一的概率成功 - ctx.SendChain(message.Text(sendtext[3][rand.Intn(len(sendtext[3]))])) - return - } - switch mun { - case 1: - err = 民政局.离婚休妻(gid, info.Target) - case 0: - err = 民政局.离婚休妻(gid, info.Target) - default: - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) - return - } - if err != nil { - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) - return - } - ctx.SendChain(message.Text(sendtext[4][mun])) - }) engine.OnRegex(`^重置(所有|本群|/d+)?花名册$`, zero.SuperUserPermission, getdb).SetBlock(true).Limit(ctxext.LimitByUser). Handle(func(ctx *zero.Ctx) { cmd := "0" @@ -427,54 +570,9 @@ func init() { } err := 民政局.清理花名册(cmd) if err != nil { - ctx.SendChain(message.Text("数据库发生问题力\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) return } ctx.SendChain(message.Text("重置成功")) }) - engine.OnFullMatch("我群老婆", zero.OnlyGroup, getdb).SetBlock(true). - Handle(func(ctx *zero.Ctx) { - gid := ctx.Event.GroupID - ok, err := 民政局.开门时间(gid) - if err != nil { - ctx.SendChain(message.Text("群状态查询失败\n[error]", err)) - return - } - if ok { - ctx.SendChain(message.Text("今天你还没结婚哦")) - return - } - uid := ctx.Event.UserID - info, uidstatus, err := 民政局.查户口(gid, uid) - switch uidstatus { - case "错": - ctx.SendChain(message.Text("用户状态查询失败\n[error]", err)) - return - case "单": - ctx.SendChain(message.Text("今天你还没结婚哦")) - return - case "攻": // 娶过别人 - ctx.SendChain( - message.At(uid), - message.Text("\n今天你的群老婆是"), - message.Text( - "\n", - "[", info.Targetname, "]", - "(", info.Target, ")哒", - ), - ) - return - case "受": // 嫁给别人 - ctx.SendChain( - message.At(uid), - message.Text("\n今天你被娶了,群老公是"), - message.Text( - "\n", - "[", info.Username, "]", - "(", info.User, ")哒", - ), - ) - return - } - }) } diff --git a/plugin/qqwife/function.go b/plugin/qqwife/function.go index 3605510c..be5eba37 100644 --- a/plugin/qqwife/function.go +++ b/plugin/qqwife/function.go @@ -1,21 +1,21 @@ package qqwife import ( + "errors" "strconv" "sync" "time" sql "github.com/FloatTech/sqlite" zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/extension/rate" "github.com/wdvxdr1123/ZeroBot/message" // 画图 "github.com/Coloured-glaze/gg" ) -//nolint: asciicheck // nolint: asciicheck +//nolint: asciicheck type 婚姻登记 struct { db *sql.Sqlite dbmu sync.RWMutex @@ -34,8 +34,24 @@ type userinfo struct { // 民政局的当前时间 type updateinfo struct { GID int64 - Updatetime string // 登记时间 + Updatetime string // 登记时间 + CanMatch int // 订婚开关 + CanNtr int // Ntr技能开关 + CDtime float64 // CD时间 +} +// 好感度系统 +type favorability struct { + Userinfo string // 记录用户 + Favor int // 好感度 +} + +// 技能CD记录表 +type cdsheet struct { + Time int64 // 时间 + GroupID int64 // 群号 + UserID int64 // 用户 + ModeID int64 // 技能类型 } func (sql *婚姻登记) 开门时间(gid int64) (ok bool, err error) { @@ -44,7 +60,12 @@ func (sql *婚姻登记) 开门时间(gid int64) (ok bool, err error) { ok = false err = sql.db.Create("updateinfo", &updateinfo{}) if err != nil { - return + if err = sql.db.Drop("updateinfo"); err == nil { + err = sql.db.Create("updateinfo", &updateinfo{}) + } + if err != nil { + return + } } gidstr := strconv.FormatInt(gid, 10) dbinfo := updateinfo{} @@ -55,31 +76,102 @@ func (sql *婚姻登记) 开门时间(gid int64) (ok bool, err error) { err = sql.db.Insert("updateinfo", &updateinfo{ GID: gid, Updatetime: time.Now().Format("2006/01/02"), + CanMatch: 1, + CanNtr: 1, + CDtime: 12, }) if err == nil { ok = true } return } - // 开门了就拿新的花名册 if time.Now().Format("2006/01/02") == dbinfo.Updatetime { return } - err = sql.db.Drop(gidstr) + // 开门了就拿新的花名册 + err = sql.db.Drop("group" + gidstr) if err != nil { + err = sql.db.Create("group"+gidstr, &userinfo{}) return } - updateinfo := updateinfo{ - GID: gid, - Updatetime: time.Now().Format("2006/01/02"), - } - err = sql.db.Insert("updateinfo", &updateinfo) + dbinfo.Updatetime = time.Now().Format("2006/01/02") + err = sql.db.Insert("updateinfo", &dbinfo) if err == nil { ok = true } return } +func (sql *婚姻登记) 营业模式(gid int64) (canMatch, canNtr int, err error) { + sql.dbmu.Lock() + defer sql.dbmu.Unlock() + err = sql.db.Create("updateinfo", &updateinfo{}) + if err != nil { + if err = sql.db.Drop("updateinfo"); err == nil { + err = sql.db.Create("updateinfo", &updateinfo{}) + } + if err != nil { + return + } + } + gidstr := strconv.FormatInt(gid, 10) + dbinfo := updateinfo{} + err = sql.db.Find("updateinfo", &dbinfo, "where gid is "+gidstr) + if err != nil { + canMatch = 1 + canNtr = 1 + err = sql.db.Insert("updateinfo", &updateinfo{ + GID: gid, + CanMatch: canMatch, + CanNtr: canNtr, + CDtime: 12, + }) + return + } + canMatch = dbinfo.CanMatch + canNtr = dbinfo.CanNtr + return +} + +func (sql *婚姻登记) 修改模式(gid int64, mode string, stauts int) (err error) { + sql.dbmu.Lock() + defer sql.dbmu.Unlock() + err = sql.db.Create("updateinfo", &updateinfo{}) + if err != nil { + if err = sql.db.Drop("updateinfo"); err == nil { + err = sql.db.Create("updateinfo", &updateinfo{}) + } + if err != nil { + return + } + } + gidstr := strconv.FormatInt(gid, 10) + dbinfo := updateinfo{} + err = sql.db.Find("updateinfo", &dbinfo, "where gid is "+gidstr) + switch mode { + case "自由恋爱": + dbinfo.CanMatch = stauts + case "牛头人": + dbinfo.CanNtr = stauts + default: + return errors.New("错误:修改内容不匹配!") + } + if err != nil { + dbinfo.GID = gid + switch mode { + case "自由恋爱": + dbinfo.CanNtr = 1 + case "牛头人": + dbinfo.CanMatch = 1 + } + dbinfo.CDtime = 12 + err = sql.db.Insert("updateinfo", &dbinfo) + return + } + err = sql.db.Insert("updateinfo", &dbinfo) + return +} + func (sql *婚姻登记) 清理花名册(gid string) error { sql.dbmu.Lock() defer sql.dbmu.Unlock() @@ -91,7 +183,7 @@ func (sql *婚姻登记) 清理花名册(gid string) error { grouplist = []string{gid} } for _, gid := range grouplist { - err = sql.db.Drop(gid) + err = sql.db.Drop("group" + gid) if err != nil { continue } @@ -108,7 +200,7 @@ func (sql *婚姻登记) 清理花名册(gid string) error { func (sql *婚姻登记) 查户口(gid, uid int64) (info userinfo, status string, err error) { sql.dbmu.Lock() defer sql.dbmu.Unlock() - gidstr := strconv.FormatInt(gid, 10) + gidstr := "group" + strconv.FormatInt(gid, 10) uidstr := strconv.FormatInt(uid, 10) status = "单" err = sql.db.Create(gidstr, &userinfo{}) @@ -131,7 +223,7 @@ func (sql *婚姻登记) 查户口(gid, uid int64) (info userinfo, status string func (sql *婚姻登记) 登记(gid, uid, target int64, username, targetname string) error { sql.dbmu.Lock() defer sql.dbmu.Unlock() - gidstr := strconv.FormatInt(gid, 10) + gidstr := "group" + strconv.FormatInt(gid, 10) err := sql.db.Create(gidstr, &userinfo{}) if err != nil { return err @@ -153,7 +245,7 @@ func (sql *婚姻登记) 登记(gid, uid, target int64, username, targetname str func (sql *婚姻登记) 离婚休妻(gid, wife int64) error { sql.dbmu.Lock() defer sql.dbmu.Unlock() - gidstr := strconv.FormatInt(gid, 10) + gidstr := "group" + strconv.FormatInt(gid, 10) wifestr := strconv.FormatInt(wife, 10) return sql.db.Del(gidstr, "where target = "+wifestr) } @@ -161,7 +253,7 @@ func (sql *婚姻登记) 离婚休妻(gid, wife int64) error { func (sql *婚姻登记) 离婚休夫(gid, husband int64) error { sql.dbmu.Lock() defer sql.dbmu.Unlock() - gidstr := strconv.FormatInt(gid, 10) + gidstr := "group" + strconv.FormatInt(gid, 10) husbandstr := strconv.FormatInt(husband, 10) return sql.db.Del(gidstr, "where user = "+husbandstr) } @@ -169,7 +261,7 @@ func (sql *婚姻登记) 离婚休夫(gid, husband int64) error { func (sql *婚姻登记) 花名册(gid int64) (list [][4]string, number int, err error) { sql.dbmu.Lock() defer sql.dbmu.Unlock() - gidstr := strconv.FormatInt(gid, 10) + gidstr := "group" + strconv.FormatInt(gid, 10) err = sql.db.Create(gidstr, &userinfo{}) if err != nil { return @@ -219,28 +311,210 @@ func slicename(name string, canvas *gg.Context) (resultname string) { return } -// 以群号和昵称为限制 -func cdcheck(ctx *zero.Ctx) *rate.Limiter { - limitID := strconv.FormatInt(ctx.Event.GroupID, 10) + strconv.FormatInt(ctx.Event.UserID, 10) + "1" - return skillCD.Load(limitID) +// 获取好感度 +func (sql *婚姻登记) getFavorability(uid, target int64) (favor int, err error) { + sql.dbmu.Lock() + defer sql.dbmu.Unlock() + err = sql.db.Create("favorability", &favorability{}) + if err != nil { + return + } + info := favorability{} + uidstr := strconv.FormatInt(uid, 10) + targstr := strconv.FormatInt(target, 10) + err = sql.db.Find("favorability", &info, "where Userinfo glob '*"+uidstr+"+"+targstr+"*'") + if err != nil { + err = sql.db.Insert("favorability", &favorability{ + Userinfo: uidstr + "+" + targstr + "+" + uidstr, + Favor: 0, + }) + return + } + favor = info.Favor + return } -func cdcheck2(ctx *zero.Ctx) *rate.Limiter { - limitID := strconv.FormatInt(ctx.Event.GroupID, 10) + strconv.FormatInt(ctx.Event.UserID, 10) + "2" - return skillCD.Load(limitID) + +// 设置好感度 正增负减 +func (sql *婚姻登记) setFavorability(uid, target int64, score int) (favor int, err error) { + sql.dbmu.Lock() + defer sql.dbmu.Unlock() + err = sql.db.Create("favorability", &favorability{}) + if err != nil { + return + } + info := favorability{} + uidstr := strconv.FormatInt(uid, 10) + targstr := strconv.FormatInt(target, 10) + err = sql.db.Find("favorability", &info, "where Userinfo glob '*"+uidstr+"+"+targstr+"*'") + if err != nil { + err = sql.db.Insert("favorability", &favorability{ + Userinfo: uidstr + "+" + targstr + "+" + uidstr, + Favor: score, + }) + return score, err + } + info.Favor += score + if info.Favor > 100 { + info.Favor = 100 + } else if info.Favor < 0 { + info.Favor = 0 + } + err = sql.db.Insert("favorability", &info) + return info.Favor, err } -func cdcheck3(ctx *zero.Ctx) *rate.Limiter { - limitID := strconv.FormatInt(ctx.Event.GroupID, 10) + strconv.FormatInt(ctx.Event.UserID, 10) + "3" - return skillCD.Load(limitID) + +// 获取技能时长 +func (sql *婚姻登记) getCDtime(gid int64) (skillCD float64, err error) { + sql.dbmu.Lock() + defer sql.dbmu.Unlock() + skillCD = 12 + err = sql.db.Create("updateinfo", &updateinfo{}) + if err != nil { + if err = sql.db.Drop("updateinfo"); err == nil { + err = sql.db.Create("updateinfo", &updateinfo{}) + } + if err != nil { + return + } + } + gidstr := strconv.FormatInt(gid, 10) + dbinfo := updateinfo{} + err = sql.db.Find("updateinfo", &dbinfo, "where gid is "+gidstr) + if err != nil { + // 如果没有登记过就记录 + err = sql.db.Insert("updateinfo", &updateinfo{ + GID: gid, + CanMatch: 1, + CanNtr: 1, + CDtime: 12, + }) + return + } + return dbinfo.CDtime, nil } -func iscding(ctx *zero.Ctx) { - ctx.SendChain(message.Text("你的技能现在正在CD中")) + +// 设置技能时长 +func (sql *婚姻登记) setCDtime(gid int64, cdTime float64) (err error) { + sql.dbmu.Lock() + defer sql.dbmu.Unlock() + err = sql.db.Create("updateinfo", &updateinfo{}) + if err != nil { + if err = sql.db.Drop("updateinfo"); err == nil { + err = sql.db.Create("updateinfo", &updateinfo{}) + } + if err != nil { + return + } + } + gidstr := strconv.FormatInt(gid, 10) + dbinfo := updateinfo{} + err = sql.db.Find("updateinfo", &dbinfo, "where gid is "+gidstr) + if err != nil { + // 如果没有登记过就记录 + err = sql.db.Insert("updateinfo", &updateinfo{ + GID: gid, + CanMatch: 1, + CanNtr: 1, + CDtime: cdTime, + }) + return + } + dbinfo.CDtime = cdTime + err = sql.db.Insert("updateinfo", &dbinfo) + return } -func iscding2(ctx *zero.Ctx) { - ctx.SendChain(message.Text("打灭,禁止离婚 (你的技能正在CD中)")) + +// 记录CD +func (sql *婚姻登记) writeCDtime(gid, uid, mun int64) error { + sql.dbmu.Lock() + defer sql.dbmu.Unlock() + err := sql.db.Create("cdsheet", &cdsheet{}) + if err != nil { + if err = sql.db.Drop("cdsheet"); err == nil { + err = sql.db.Create("cdsheet", &cdsheet{}) + } + if err != nil { + return err + } + } + err = sql.db.Insert("cdsheet", &cdsheet{ + Time: time.Now().Unix(), + GroupID: gid, + UserID: uid, + ModeID: mun, + }) + return err +} + +// 判断CD是否过时 +func (sql *婚姻登记) compareCDtime(gid, uid, mun int64, cdtime float64) (ok bool, err error) { + sql.dbmu.Lock() + defer sql.dbmu.Unlock() + ok = false + err = sql.db.Create("cdsheet", &cdsheet{}) + if err != nil { + if err = sql.db.Drop("cdsheet"); err == nil { + err = sql.db.Create("cdsheet", &cdsheet{}) + } + if err != nil { + return + } + } + limitID := "where GroupID is " + strconv.FormatInt(gid, 10) + + " and UserID is " + strconv.FormatInt(uid, 10) + + " and ModeID is " + strconv.FormatInt(mun, 10) + exist := sql.db.CanFind("cdsheet", limitID) + if !exist { + return true, nil + } + cdinfo := cdsheet{} + err = sql.db.Find("cdsheet", &cdinfo, limitID) + if err != nil { + return + } + getTime := time.Unix(cdinfo.Time, 0) + if time.Since(getTime).Hours() > cdtime { + // 如果CD已过就删除 + err = sql.db.Del("cdsheet", limitID) + return true, err + } + return } // 注入判断 是否为单身 func checkdog(ctx *zero.Ctx) bool { + mode := int64(1) // 指代技能1 + gid := ctx.Event.GroupID + uid := ctx.Event.UserID + // 获取CD + cdTime, err := 民政局.getCDtime(gid) + if err != nil { + ctx.SendChain(message.Text("[qqwife]获取该群技能CD错误(将以CD12H计算)\n", err)) + } + ok, err := 民政局.compareCDtime(gid, uid, mode, cdTime) + if err != nil { + ctx.SendChain(message.Text("[qqwife]查询用户CD状态失败,请重试\n", err)) + return false + } + if !ok { + ctx.SendChain(message.Text("你的技能还在CD中...")) + return false + } + // 写入CD + err = 民政局.writeCDtime(gid, uid, mode) + if err != nil { + ctx.SendChain(message.At(uid), message.Text("[qqwife]你的技能CD记录失败\n", err)) + } + // 判断是否符合条件 + stauts, _, err := 民政局.营业模式(gid) + if err != nil { + ctx.SendChain(message.Text("[qqwife]", err)) + return false + } + if stauts == 0 { + ctx.SendChain(message.Text("你群包分配,别在娶妻上面下功夫,好好水群")) + return false + } // 得先判断用户是否存在才行在,再重置 fiancee, err := strconv.ParseInt(ctx.State["regex_matched"].([]string)[2], 10, 64) if err != nil { @@ -248,21 +522,19 @@ func checkdog(ctx *zero.Ctx) bool { return false } // 判断是否需要重置 - gid := ctx.Event.GroupID - ok, err := 民政局.开门时间(gid) + ok, err = 民政局.开门时间(gid) if err != nil { - ctx.SendChain(message.Text("群状态查询失败\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]群状态查询失败\n", err)) return false } if ok { return true // 重置后也全是单身 } // 获取用户信息 - uid := ctx.Event.UserID uidtarget, uidstatus, err := 民政局.查户口(gid, uid) switch { case uidstatus == "错": - ctx.SendChain(message.Text("用户状态查询失败\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]用户状态查询失败\n", err)) return false case uidstatus != "单" && (uidtarget.Target == 0 || uidtarget.User == 0): // 如果是单身贵族 ctx.SendChain(message.Text("今天的你是单身贵族噢")) @@ -281,7 +553,7 @@ func checkdog(ctx *zero.Ctx) bool { fianceeinfo, fianceestatus, err := 民政局.查户口(gid, fiancee) switch { case fianceestatus == "错": - ctx.SendChain(message.Text("对象状态查询失败\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]对象状态查询失败\n", err)) case fianceestatus == "单": // 如果为单身狗 return true case fianceestatus != "单" && (fianceeinfo.Target == 0 || fianceeinfo.User == 0): // 如果是单身贵族 @@ -296,6 +568,38 @@ func checkdog(ctx *zero.Ctx) bool { // 注入判断 是否满足小三要求 func checkcp(ctx *zero.Ctx) bool { + mode := int64(2) // 指代技能2 + gid := ctx.Event.GroupID + uid := ctx.Event.UserID + // 获取CD + cdTime, err := 民政局.getCDtime(gid) + if err != nil { + ctx.SendChain(message.Text("[qqwife]获取该群技能CD错误(将以CD12H计算)\n", err)) + } + ok, err := 民政局.compareCDtime(gid, uid, mode, cdTime) + if err != nil { + ctx.SendChain(message.Text("[qqwife]查询用户CD状态失败,请重试\n", err)) + return false + } + if !ok { + ctx.SendChain(message.Text("你的技能还在CD中...")) + return false + } + // 写入CD + err = 民政局.writeCDtime(gid, uid, mode) + if err != nil { + ctx.SendChain(message.At(uid), message.Text("[qqwife]你的技能CD记录失败\n", err)) + } + // 判断是否符合条件 + _, stauts, err := 民政局.营业模式(gid) + if err != nil { + ctx.SendChain(message.Text("[qqwife]", err)) + return false + } + if stauts == 0 { + ctx.SendChain(message.Text("你群发布了牛头人禁止令,放弃吧")) + return false + } // 得先判断用户是否存在才行在,再重置 fiancee, err := strconv.ParseInt(ctx.State["regex_matched"].([]string)[2], 10, 64) if err != nil { @@ -303,21 +607,19 @@ func checkcp(ctx *zero.Ctx) bool { return false } // 判断是否需要重置 - gid := ctx.Event.GroupID - ok, err := 民政局.开门时间(gid) + ok, err = 民政局.开门时间(gid) if err != nil { - ctx.SendChain(message.Text("群状态查询失败\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]群状态查询失败\n", err)) return false } if ok { ctx.SendChain(message.Text("ta现在还是单身哦,快向ta表白吧!")) return false // 重置后也全是单身 } - uid := ctx.Event.UserID fianceeinfo, fianceestatus, err := 民政局.查户口(gid, fiancee) switch { case fianceestatus == "错": - ctx.SendChain(message.Text("对象状态查询失败\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]对象状态查询失败\n", err)) return false case fianceestatus == "单": // 如果为单身狗 if fiancee == uid { @@ -337,7 +639,7 @@ func checkcp(ctx *zero.Ctx) bool { uidtarget, uidstatus, err := 民政局.查户口(gid, uid) switch { case uidstatus == "错": - ctx.SendChain(message.Text("用户状态查询失败\n[error]", err)) + ctx.SendChain(message.Text("[qqwife]用户状态查询失败\n", err)) case uidstatus == "单": // 如果为单身狗 return true case uidstatus != "单" && (uidtarget.Target == 0 || uidtarget.User == 0): // 如果是单身贵族 @@ -349,3 +651,123 @@ func checkcp(ctx *zero.Ctx) bool { } return false } + +// 注入判断 是否满足离婚要求 +func checkdivorce(ctx *zero.Ctx) bool { + mode := int64(3) // 指代技能3 + gid := ctx.Event.GroupID + uid := ctx.Event.UserID + // 获取CD + cdTime, err := 民政局.getCDtime(gid) + if err != nil { + ctx.SendChain(message.Text("[qqwife]获取该群技能CD错误(将以CD12H计算)\n", err)) + } + ok, err := 民政局.compareCDtime(gid, uid, mode, cdTime) + if err != nil { + ctx.SendChain(message.Text("[qqwife]查询用户CD状态失败,请重试\n", err)) + return false + } + if !ok { + ctx.SendChain(message.Text("你的技能还在CD中...")) + return false + } + // 写入CD + err = 民政局.writeCDtime(gid, uid, mode) + if err != nil { + ctx.SendChain(message.At(uid), message.Text("[qqwife]你的技能CD记录失败\n", err)) + } + // 判断是否符合条件 + _, uidstatus, err := 民政局.查户口(gid, uid) + switch uidstatus { + case "错": + ctx.SendChain(message.Text("[qqwife]数据库发生问题力\n", err)) + return false + case "单": + ctx.SendChain(message.Text("今天你还没结婚哦")) + return false + } + return true +} + +// 注入判断 是否满足做媒要求 +func checkCondition(ctx *zero.Ctx) bool { + mode := int64(4) // 指代技能4 + gid := ctx.Event.GroupID + uid := ctx.Event.UserID + // 获取CD + cdTime, err := 民政局.getCDtime(gid) + if err != nil { + ctx.SendChain(message.Text("[qqwife]获取该群技能CD错误(将以CD12H计算)\n", err)) + } + ok, err := 民政局.compareCDtime(gid, uid, mode, cdTime) + if err != nil { + ctx.SendChain(message.Text("[qqwife]查询用户CD状态失败,请重试\n", err)) + return false + } + if !ok { + ctx.SendChain(message.Text("你的技能还在CD中...")) + return false + } + // 写入CD + err = 民政局.writeCDtime(gid, uid, mode) + if err != nil { + ctx.SendChain(message.At(uid), message.Text("[qqwife]你的技能CD记录失败\n", err)) + } + // 得先判断用户是否存在才行在,再重置 + gayOne, err := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64) + if err != nil { + ctx.SendChain(message.Text("额,攻方好像不存在?")) + return false + } + gayZero, err := strconv.ParseInt(ctx.State["regex_matched"].([]string)[2], 10, 64) + if err != nil { + ctx.SendChain(message.Text("额,受方好像不存在?")) + return false + } + if gayOne == uid || gayZero == uid { + ctx.SendChain(message.Text("禁止自己给自己做媒!")) + return false + } + if gayOne == gayZero { + ctx.SendChain(message.Text("你这个媒人XP很怪咧,不能这样噢")) + return false + } + // 判断是否需要重置 + ok, err = 民政局.开门时间(gid) + if err != nil { + ctx.SendChain(message.Text("[qqwife]群状态查询失败\n", err)) + return false + } + if ok { + return true // 重置后也全是单身 + } + fianceeinfo, fianceestatus, err := 民政局.查户口(gid, gayOne) + switch { + case fianceestatus == "错": + ctx.SendChain(message.Text("[qqwife]对象状态查询失败\n", err)) + return false + case fianceestatus != "单" && (fianceeinfo.Target == 0 || fianceeinfo.User == 0): // 如果是单身贵族 + ctx.SendChain(message.Text("今天的攻方是单身贵族噢")) + return false + case (fianceestatus == "攻" && fianceeinfo.Target == gayZero) || + (fianceestatus == "受" && fianceeinfo.User == gayZero): + ctx.SendChain(message.Text("笨蛋!ta们已经在一起了!")) + return false + case fianceestatus != "单": + ctx.SendChain(message.Text("攻方不是单身,不允许给这种人做媒!")) + return false + } + // 获取用户信息 + uidtarget, uidstatus, err := 民政局.查户口(gid, gayZero) + switch { + case uidstatus == "错": + ctx.SendChain(message.Text("[qqwife]用户状态查询失败\n", err)) + case uidstatus == "单": // 如果为单身狗 + return true + case uidstatus != "单" && (uidtarget.Target == 0 || uidtarget.User == 0): // 如果是单身贵族 + ctx.SendChain(message.Text("今天的你是单身贵族噢")) + case uidstatus != "单": + ctx.SendChain(message.Text("受方不是单身,不允许给这种人做媒!")) + } + return false +}