From b84c601976feffd5dc6b5249e4e3843d5dea1184 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=96=B9=E6=9F=B3=E7=85=9C?=
<101934327+fangliuyu@users.noreply.github.com>
Date: Fri, 27 Oct 2023 22:36:08 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0qqwife=E6=8F=92=E4=BB=B6=20(#?=
=?UTF-8?q?8)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 添加qqwife插件
* fix
* fix
* update
* update
* fix
---
README.md | 31 ++
main.go | 1 +
plugin/qqwife/dbfile.go | 385 ++++++++++++++++++++++
plugin/qqwife/happyplay.go | 649 +++++++++++++++++++++++++++++++++++++
plugin/qqwife/main.go | 206 ++++++++++++
5 files changed, 1272 insertions(+)
create mode 100644 plugin/qqwife/dbfile.go
create mode 100644 plugin/qqwife/happyplay.go
create mode 100644 plugin/qqwife/main.go
diff --git a/README.md b/README.md
index 3775da1..865a416 100644
--- a/README.md
+++ b/README.md
@@ -182,6 +182,37 @@ nanobot [-Tadhst] ID1 ID2 ...
+
+ 娶群友
+
+ `import _ "github.com/FloatTech/NanoBot-Plugin/plugin/qqwife"`
+
+ - [x] 娶群友
+
+ - [x] 群老婆列表
+
+ - [x] (娶|嫁)@对方QQ
+
+ - [x] 牛@对方QQ
+
+ - [x] 闹离婚
+
+ - [x] 买礼物给@对方QQ
+
+ - [x] 做媒 @攻方QQ @受方QQ
+
+ - [x] 查好感度@对方QQ
+
+ - [x] 好感度列表
+
+ - [x] [允许|禁止]自由恋爱
+
+ - [x] [允许|禁止]牛头人
+
+ - [x] 设置CD为xx小时 →(默认12小时)
+
+
+
在线代码运行
diff --git a/main.go b/main.go
index e36a471..0568d73 100644
--- a/main.go
+++ b/main.go
@@ -24,6 +24,7 @@ import (
_ "github.com/FloatTech/NanoBot-Plugin/plugin/genshin"
_ "github.com/FloatTech/NanoBot-Plugin/plugin/hyaku"
_ "github.com/FloatTech/NanoBot-Plugin/plugin/manager"
+ _ "github.com/FloatTech/NanoBot-Plugin/plugin/qqwife"
_ "github.com/FloatTech/NanoBot-Plugin/plugin/runcode"
_ "github.com/FloatTech/NanoBot-Plugin/plugin/score"
_ "github.com/FloatTech/NanoBot-Plugin/plugin/status"
diff --git a/plugin/qqwife/dbfile.go b/plugin/qqwife/dbfile.go
new file mode 100644
index 0000000..13d4aa6
--- /dev/null
+++ b/plugin/qqwife/dbfile.go
@@ -0,0 +1,385 @@
+// Package qqwife 娶群友
+package qqwife
+
+import (
+ "errors"
+ "path"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "time"
+
+ nano "github.com/fumiama/NanoBot"
+
+ fcext "github.com/FloatTech/floatbox/ctxext"
+ "github.com/FloatTech/gg"
+ sql "github.com/FloatTech/sqlite"
+)
+
+type userInfo struct {
+ ID string
+ Nick string
+ Avatar string
+}
+
+type dbData struct {
+ db *sql.Sqlite
+ sync.RWMutex
+}
+
+// 群设置
+type setting struct {
+ GID string
+ LastTime int
+ CanMatch int // 嫁婚开关
+ CanNtr int // Ntr开关
+ CDtime int64 // CD时间
+}
+
+// 结婚证信息
+type marriage struct {
+ Users string // 双方QQ号
+ Sname string // 户主名称
+ Mname string // 对象名称
+ Updatetime string // 登记时间
+ Spic string
+ Mpic string
+}
+
+// 预留10个为后续扩展
+type cdsheet struct {
+ User string `db:"User"`
+ Mar int64 `db:"CD0"` // 娶
+ Rob int64 `db:"CD1"` // 强
+ Lef int64 `db:"CD2"` // 离
+ Buy int64 `db:"CD3"` // 礼
+ MMk int64 `db:"CD4"` // 做媒
+ CD5 int64 `db:"CD5"`
+ CD6 int64 `db:"CD6"`
+ CD7 int64 `db:"CD7"`
+ CD8 int64 `db:"CD8"`
+ CD9 int64 `db:"CD9"`
+}
+
+// 好感度列表
+type favor struct {
+ Users string // 双方QQ号
+ Favor int // 好感度
+}
+
+var (
+ wifeData = &dbData{
+ db: &sql.Sqlite{},
+ }
+ getdb = fcext.DoOnceOnSuccess(func(ctx *nano.Ctx) bool {
+ wifeData.db.DBPath = engine.DataFolder() + "结婚登记表.db"
+ err := wifeData.db.Open(time.Hour)
+ if err == nil {
+ // 创建群配置表
+ err = wifeData.db.Create("setting", &setting{})
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return false
+ }
+ // 创建CD表
+ err = wifeData.db.Create("cdsheet", &cdsheet{})
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return false
+ }
+ // 创建好感度表
+ err = wifeData.db.Create("favor", &favor{})
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return false
+ }
+ // 刷新列表
+ err = wifeData.refresh(ctx.Message.GuildID)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return false
+ }
+ return true
+ }
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return false
+ })
+)
+
+func getUserInfoIn(ctx *nano.Ctx, gid, uid string) (info userInfo, err error) {
+ uInfo, err := ctx.GetGuildMemberOf(gid, uid)
+ if err != nil {
+ return
+ }
+ nick := uInfo.Nick
+ if nick == "" {
+ nick = uInfo.User.Username
+ }
+ info = userInfo{
+ ID: uInfo.User.ID,
+ Nick: nick,
+ Avatar: uInfo.User.Avatar,
+ }
+ return
+}
+
+func (sql *dbData) getSet(gid string) (dbinfo setting, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ // 创建群表格
+ err = sql.db.Create("setting", &dbinfo)
+ if err != nil {
+ return
+ }
+ if !sql.db.CanFind("setting", "where gid is "+gid) {
+ // 没有记录
+ return setting{
+ GID: gid,
+ CanMatch: 1,
+ CanNtr: 1,
+ CDtime: 12,
+ }, nil
+ }
+ _ = sql.db.Find("setting", &dbinfo, "where gid is "+gid)
+ return
+}
+
+func (sql *dbData) updateSet(dbinfo setting) error {
+ sql.Lock()
+ defer sql.Unlock()
+ return sql.db.Insert("setting", &dbinfo)
+}
+
+func (sql *dbData) refresh(gid string) error {
+ sql.Lock()
+ defer sql.Unlock()
+ // 创建群表格
+ err := sql.db.Create("setting", &setting{})
+ if err != nil {
+ return err
+ }
+ if !sql.db.CanFind("setting", "where gid is "+gid) {
+ return nil
+ }
+ dbinfo := setting{}
+ _ = sql.db.Find("setting", &dbinfo, "where gid is "+gid)
+ if time.Now().Day() != dbinfo.LastTime && time.Now().Hour() >= 4 {
+ _ = sql.db.Drop("group" + gid)
+ // 更新数据时间
+ dbinfo.GID = gid
+ dbinfo.LastTime = time.Now().Day()
+ return sql.db.Insert("setting", &dbinfo)
+ }
+ return nil
+}
+
+func (sql *dbData) checkUser(gid, uid string) (userinfo marriage, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ gidstr := "group" + gid
+ // 创建群表格
+ err = sql.db.Create(gidstr, &userinfo)
+ if err != nil {
+ return
+ }
+ if !sql.db.CanFind(gidstr, "where Users glob '*"+uid+"*'") {
+ return
+ }
+ err = sql.db.Find(gidstr, &userinfo, "where Users glob '*"+uid+"*'")
+ return
+}
+
+// 民政局登记数据
+func (sql *dbData) register(gid string, uid, target userInfo) error {
+ sql.Lock()
+ defer sql.Unlock()
+ gidstr := "group" + gid
+ uidinfo := marriage{
+ Users: uid.ID + " & " + target.ID,
+ Sname: uid.Nick,
+ Spic: uid.Avatar,
+ Mname: target.Nick,
+ Mpic: target.Avatar,
+ Updatetime: time.Now().Format("15:04:05"),
+ }
+ return sql.db.Insert(gidstr, &uidinfo)
+}
+
+// 民政局离婚
+func (sql *dbData) divorce(gid, uid string) error {
+ sql.Lock()
+ defer sql.Unlock()
+ gidstr := "group" + gid
+ // 创建群表格
+ userinfo := marriage{}
+ err := sql.db.Create(gidstr, &userinfo)
+ if err != nil {
+ return err
+ }
+ if !sql.db.CanFind(gidstr, "where Users glob '*"+uid+"*'") {
+ return errors.New("user(" + uid + ") not found")
+ }
+ return sql.db.Del(gidstr, "where Users glob '*"+uid+"*'")
+}
+
+func (sql *dbData) getlist(gid string) (list []marriage, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ gidstr := "group" + gid
+ number, _ := sql.db.Count(gidstr)
+ if number <= 0 {
+ return
+ }
+ var info marriage
+ err = sql.db.FindFor(gidstr, &info, "GROUP BY Users", func() error {
+ users := strings.Split(info.Users, " & ")
+ if users[0] == "" || users[1] == "" {
+ return nil
+ }
+ list = append(list, info)
+ return nil
+ })
+ return
+}
+
+func slicename(name string, canvas *gg.Context) (resultname string) {
+ usermane := []rune(name) // 将每个字符单独放置
+ widthlen := 0
+ numberlen := 0
+ for i, v := range usermane {
+ width, _ := canvas.MeasureString(string(v)) // 获取单个字符的宽度
+ widthlen += int(width)
+ if widthlen > 650 {
+ break // 总宽度不能超过350
+ }
+ numberlen = i
+ }
+ if widthlen > 650 {
+ resultname = string(usermane[:numberlen-1]) + "......" // 名字切片
+ } else {
+ resultname = name
+ }
+ return
+}
+
+func (sql *dbData) favorFor(uid, target string, add int) (favorValue int, err error) {
+ sql.Lock()
+ defer sql.Unlock()
+ // 创建群表格
+ err = sql.db.Create("favor", &favor{})
+ if err != nil {
+ return
+ }
+ key := uid + " & " + target
+ uidInt64, _ := strconv.ParseInt(uid, 10, 64)
+ targetInt64, _ := strconv.ParseInt(target, 10, 64)
+ if uidInt64 < targetInt64 {
+ key = target + " & " + uid
+ }
+ info := favor{}
+ _ = sql.db.Find("favor", &info, "where Users is '"+key+"'")
+ if add > 0 {
+ info.Users = key
+ info.Favor += add
+ err = sql.db.Insert("favor", &info)
+ }
+ return info.Favor, err
+}
+
+func (sql *dbData) getGroupFavorability(uid string) (list []favor, err error) {
+ sql.RLock()
+ defer sql.RUnlock()
+ info := favor{}
+ err = sql.db.FindFor("favor", &info, "where Users glob '*"+uid+"*' AND Favor > 0 ORDER BY DESC", func() error {
+ var target string
+ userList := strings.Split(info.Users, " & ")
+ switch {
+ case len(userList) == 0:
+ return errors.New("好感度系统数据存在错误")
+ case userList[0] == uid:
+ target = userList[1]
+ default:
+ target = userList[0]
+ }
+ list = append(list, favor{
+ Users: target,
+ Favor: info.Favor,
+ })
+ return nil
+ })
+ return
+}
+
+func (sql *dbData) checkCD(gid, uid string, funcType string) (cdTime time.Duration, err error) {
+ setting, err := wifeData.getSet(gid)
+ if err != nil {
+ return
+ }
+ sql.Lock()
+ defer sql.Unlock()
+ // 创建群表格
+ err = sql.db.Create("cdsheet", &cdsheet{})
+ if err != nil {
+ return
+ }
+ number, _ := sql.db.Count("cdsheet")
+ if number <= 0 {
+ return
+ }
+ info := cdsheet{}
+ if !sql.db.CanFind("cdsheet", "where User is '"+uid+"'") {
+ return
+ }
+ err = sql.db.Find("cdsheet", &info, "where User is '"+uid+"'")
+ if err != nil {
+ return
+ }
+ switch funcType {
+ case "娶", "嫁":
+ cdTime = time.Duration(setting.CDtime)*time.Hour - time.Since(time.Unix(info.Mar, 0))
+ case "牛":
+ cdTime = time.Duration(setting.CDtime)*time.Hour - time.Since(time.Unix(info.Rob, 0))
+ case "离":
+ cdTime = time.Duration(setting.CDtime)*time.Hour - time.Since(time.Unix(info.Lef, 0))
+ case "媒":
+ cdTime = time.Duration(setting.CDtime)*time.Hour - time.Since(time.Unix(info.MMk, 0))
+ case "买":
+ cdTime = time.Duration(setting.CDtime)*time.Hour - time.Since(time.Unix(info.Buy, 0))
+ }
+ return
+}
+
+func (sql *dbData) setCD(uid string, funcType string) error {
+ sql.Lock()
+ defer sql.Unlock()
+ // 创建群表格
+ err := sql.db.Create("cdsheet", &cdsheet{})
+ if err != nil {
+ return err
+ }
+ info := cdsheet{}
+ _ = sql.db.Find("cdsheet", &info, "where User is '"+uid+"'")
+ info.User = uid
+ switch funcType {
+ case "娶", "嫁":
+ info.Mar = time.Now().Unix()
+ case "牛":
+ info.Rob = time.Now().Unix()
+ case "离":
+ info.Lef = time.Now().Unix()
+ case "媒":
+ info.MMk = time.Now().Unix()
+ case "买":
+ info.Buy = time.Now().Unix()
+ }
+ return sql.db.Insert("cdsheet", &info)
+}
+
+func getLine() string {
+ _, file, line, ok := runtime.Caller(1)
+ if ok {
+ return path.Base(file) + "." + strconv.Itoa(line)
+ }
+ return ""
+}
diff --git a/plugin/qqwife/happyplay.go b/plugin/qqwife/happyplay.go
new file mode 100644
index 0000000..7d565d5
--- /dev/null
+++ b/plugin/qqwife/happyplay.go
@@ -0,0 +1,649 @@
+package qqwife
+
+import (
+ "math/rand"
+ "strconv"
+ "strings"
+
+ "github.com/FloatTech/AnimeAPI/wallet"
+ "github.com/FloatTech/NanoBot-Plugin/utils/ctxext"
+ "github.com/FloatTech/floatbox/file"
+ "github.com/FloatTech/floatbox/math"
+ "github.com/FloatTech/gg"
+ "github.com/FloatTech/imgfactory"
+ "github.com/FloatTech/zbputils/img/text"
+ nano "github.com/fumiama/NanoBot"
+ log "github.com/sirupsen/logrus"
+)
+
+var sendtext = [...][]string{
+ { // 表白成功
+ "是个勇敢的孩子(*/ω\*) 今天的运气都降临在你的身边~\n\n",
+ "(´・ω・`)对方答应了你 并表示愿意当今天的CP\n\n",
+ },
+ { // 表白失败
+ "今天的运气有一点背哦~明天再试试叭",
+ "_(:з」∠)_下次还有机会 咱抱抱你w",
+ "今天失败了惹. 摸摸头~咱明天还有机会",
+ },
+ { // ntr成功
+ "因为你的个人魅力~~今天他就是你的了w\n\n",
+ },
+ { // 离婚失败
+ "打是情,骂是爱,不打不亲不相爱。答应我不要分手。",
+ "床头打架床尾和,夫妻没有隔夜仇。安啦安啦,不要闹变扭。",
+ },
+ { // 离婚成功
+ "离婚成功力\n话说你不考虑当个1?",
+ "离婚成功力\n天涯何处无芳草,何必单恋一枝花?不如再摘一支(bushi",
+ },
+}
+
+func init() {
+ engine.OnMessageRegex(`^设置CD为(\d+)小时`, nano.OnlyChannel, nano.AdminPermission, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ cdTime, err := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:请设置纯数字\n", err)
+ return
+ }
+ groupInfo, err := wifeData.getSet(ctx.Message.GuildID)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ groupInfo.CDtime = cdTime
+ err = wifeData.updateSet(groupInfo)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]设置CD时长失败\n", err)
+ return
+ }
+ _, _ = ctx.SendPlainMessage(true, "设置成功")
+ })
+ engine.OnMessageRegex(`^(允许|禁止)(自由恋爱|牛头人)$`, nano.OnlyChannel, nano.AdminPermission, getdb).SetBlock(true).Handle(func(ctx *nano.Ctx) {
+ status := ctx.State["regex_matched"].([]string)[1]
+ mode := ctx.State["regex_matched"].([]string)[2]
+ groupInfo, err := wifeData.getSet(ctx.Message.GuildID)
+ switch {
+ case err != nil:
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ case mode == "自由恋爱":
+ if status == "允许" {
+ groupInfo.CanMatch = 1
+ } else {
+ groupInfo.CanMatch = 0
+ }
+ case mode == "牛头人":
+ if status == "允许" {
+ groupInfo.CanNtr = 1
+ } else {
+ groupInfo.CanNtr = 0
+ }
+ }
+ err = wifeData.updateSet(groupInfo)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ _, _ = ctx.SendPlainMessage(true, "设置成功")
+ })
+ // 单身技能
+ engine.OnMessageRegex(`^(娶|嫁)\s*<@!(\d+)>$`, nano.OnlyChannel, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ gid := ctx.Message.GuildID
+ setting, err := wifeData.getSet(gid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if setting.CanMatch == 0 {
+ _, _ = ctx.SendPlainMessage(true, "该频道已发布了禁止自由恋爱,请认真水群")
+ return
+ }
+ uid := ctx.Message.Author.ID
+ choice := ctx.State["regex_matched"].([]string)[1]
+ cdTime, err := wifeData.checkCD(gid, uid, choice)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if cdTime > 0 {
+ _, _ = ctx.SendPlainMessage(true, "你的技能CD还有", cdTime)
+ return
+ }
+ fiance := ctx.State["regex_matched"].([]string)[2]
+ uInfo, err := wifeData.checkUser(gid, uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if uInfo.Users != "" {
+ info := strings.Split(uInfo.Users, " & ")
+ switch {
+ case info[0] == "" || info[1] == "":
+ _, _ = ctx.SendPlainMessage(true, "今天的你是单身贵族噢")
+ return
+ case info[0] == fiance || info[1] == fiance:
+ _, _ = ctx.SendPlainMessage(true, "笨蛋!你们已经在一起了!")
+ return
+ case info[0] == uid: // 如果如为攻
+ _, _ = ctx.SendPlainMessage(true, "笨蛋~你家里还有个吃白饭的w")
+ return
+ case info[1] == uid: // 如果为受
+ _, _ = ctx.SendPlainMessage(true, "该是0就是0,当0有什么不好")
+ return
+ }
+ }
+ fInfo, err := wifeData.checkUser(gid, uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if fInfo.Users != "" {
+ info := strings.Split(fInfo.Users, " & ")
+ switch {
+ case info[0] == "" || info[1] == "":
+ _, _ = ctx.SendPlainMessage(true, "今天的ta是单身贵族噢")
+ return
+ case info[0] == uid: // 如果如为攻
+ _, _ = ctx.SendPlainMessage(true, "他有别的女人了,你该放下了")
+ return
+ case info[1] == uid: // 如果为受
+ _, _ = ctx.SendPlainMessage(true, "ta被别人娶了,你来晚力")
+ return
+ }
+ }
+ // 写入CD
+ err = wifeData.setCD(uid, choice)
+ if err != nil {
+ log.Warnln("[qqwife]你的技能CD记录失败,", err)
+ }
+ uBook, err := getUserInfoIn(ctx, gid, uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if uid == fiance { // 如果是自己
+ switch rand.Intn(3) {
+ case 1:
+ err := wifeData.register(gid, uBook, userInfo{})
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ _, _ = ctx.SendPlainMessage(true, "今日获得成就:单身贵族")
+ default:
+ _, _ = ctx.SendPlainMessage(true, "今日获得成就:自恋狂")
+ }
+ return
+ }
+ fBook, err := getUserInfoIn(ctx, gid, fiance)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ favor, err := wifeData.favorFor(uid, fiance, 0)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if favor < 30 {
+ favor = 30 // 保底30%概率
+ }
+ if rand.Intn(101) >= favor {
+ _, _ = ctx.SendPlainMessage(true, sendtext[1][rand.Intn(len(sendtext[1]))])
+ return
+ }
+ // 去民政局登记
+ var choicetext string
+ switch choice {
+ case "娶":
+ err = wifeData.register(gid, uBook, fBook)
+ choicetext = "\n今天你的群老婆是"
+ default:
+ err = wifeData.register(gid, fBook, uBook)
+ choicetext = "\n今天你的群老公是"
+ }
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ // 请大家吃席
+ _, err = ctx.SendChain(nano.ReplyTo(ctx.Message.ID),
+ nano.Text(sendtext[0][rand.Intn(len(sendtext[0]))], "\n",
+ choicetext, "[", fBook.Nick, "]\n",
+ "当前你们好感度为", favor), nano.Image(fBook.Avatar))
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "", getLine(), " ->ERROR: ", err)
+ }
+ })
+ // NTR技能
+ engine.OnMessageRegex(`^牛\s*<@!(\d+)>$`, nano.OnlyChannel, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ gid := ctx.Message.GuildID
+ setting, err := wifeData.getSet(gid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if setting.CanNtr == 0 {
+ _, _ = ctx.SendPlainMessage(true, "该频道已发布了禁止牛头人,请认真水群")
+ return
+ }
+ uid := ctx.Message.Author.ID
+ cdTime, err := wifeData.checkCD(gid, uid, "牛")
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if cdTime > 0 {
+ _, _ = ctx.SendPlainMessage(true, "你的技能CD还有", cdTime)
+ return
+ }
+ fiance := ctx.State["regex_matched"].([]string)[1]
+ uInfo, err := wifeData.checkUser(gid, uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if uInfo.Users != "" {
+ info := strings.Split(uInfo.Users, " & ")
+ switch {
+ case info[0] == "" || info[1] == "":
+ _, _ = ctx.SendPlainMessage(true, "今天的你是单身贵族噢")
+ return
+ case info[0] == fiance || info[1] == fiance:
+ _, _ = ctx.SendPlainMessage(true, "笨蛋!你们已经在一起了!")
+ return
+ case info[0] == uid: // 如果如为攻
+ _, _ = ctx.SendPlainMessage(true, "笨蛋~你家里还有个吃白饭的w")
+ return
+ case info[1] == uid: // 如果为受
+ _, _ = ctx.SendPlainMessage(true, "该是0就是0,当0有什么不好")
+ return
+ }
+ }
+ fInfo, err := wifeData.checkUser(gid, fiance)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if fInfo.Users == "" {
+ _, _ = ctx.SendPlainMessage(true, "今天的ta是单身噢,快去明媒正娶吧!")
+ return
+ }
+ // 写入CD
+ err = wifeData.setCD(uid, "牛")
+ if err != nil {
+ log.Warnln("[qqwife]你的技能CD记录失败,", err)
+ }
+ if fiance == uid {
+ _, _ = ctx.SendPlainMessage(true, "今日获得成就:自我攻略")
+ return
+ }
+ favor, err := wifeData.favorFor(uid, fiance, 0)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if favor < 30 {
+ favor = 30 // 保底10%概率
+ }
+ if rand.Intn(101) >= favor/3 {
+ _, _ = ctx.SendPlainMessage(true, "失败了!可惜")
+ return
+ }
+ // 判断target是老公还是老婆
+ choicetext := "老公"
+ ntrID := uid
+ targetID := fiance
+ greenID := "" // 被牛的
+
+ err = wifeData.divorce(gid, fiance)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(true, "ta不想和原来的对象分手...\n[error]", err)
+ return
+ }
+ user := strings.Split(fInfo.Users, " & ")
+ switch {
+ case user[0] == fiance: // 是1
+ ntrID = fiance
+ targetID = uid
+ greenID = user[1]
+ case user[1] == fiance: // 是0
+ greenID = user[0]
+ choicetext = "老婆"
+ default:
+ _, _ = ctx.SendPlainMessage(true, "数据库发生问题力")
+ return
+ }
+ userInfo, err := getUserInfoIn(ctx, gid, ntrID)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ fianceInfo, err := getUserInfoIn(ctx, gid, targetID)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ err = wifeData.register(gid, userInfo, fianceInfo)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(true, "[qqwife]复婚登记失败力\n", err)
+ return
+ }
+ favor, err = wifeData.favorFor(uid, fiance, -5)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ }
+ _, err = wifeData.favorFor(uid, greenID, 5)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ }
+ // 输出结果
+ _, err = ctx.SendChain(nano.ReplyTo(ctx.Message.ID),
+ nano.Text(sendtext[2][rand.Intn(len(sendtext[2]))], "\n",
+ choicetext, "[", fianceInfo.Nick, "]\n",
+ "当前你们好感度为", favor), nano.Image(fianceInfo.Avatar))
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ }
+ })
+ // 做媒技能
+ engine.OnMessageRegex(`^做媒\s*<@!(\d+)>\s*<@!(\d+)>`, nano.OnlyChannel, nano.AdminPermission, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ gid := ctx.Message.GuildID
+ uid := ctx.Message.Author.ID
+ cdTime, err := wifeData.checkCD(gid, uid, "媒")
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if cdTime > 0 {
+ _, _ = ctx.SendPlainMessage(true, "你的技能CD还有", cdTime)
+ return
+ }
+ gayOne := ctx.State["regex_matched"].([]string)[1]
+ gaynano := ctx.State["regex_matched"].([]string)[2]
+ uInfo, err := wifeData.checkUser(gid, gayOne)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if uInfo.Users != "" {
+ _, _ = ctx.SendChain(nano.ReplyTo(ctx.Message.ID), nano.At(gayOne), nano.Text("已有家妻"))
+ return
+ }
+ fInfo, err := wifeData.checkUser(gid, gaynano)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if fInfo.Users != "" {
+ _, _ = ctx.SendChain(nano.ReplyTo(ctx.Message.ID), nano.At(gaynano), nano.Text("已有所属"))
+ return
+ }
+ // 写入CD
+ err = wifeData.setCD(uid, "媒")
+ if err != nil {
+ log.Warnln("[qqwife]你的技能CD记录失败,", err)
+ }
+ favor, err := wifeData.favorFor(gayOne, gaynano, 0)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if favor < 30 {
+ favor = 30 // 保底30%概率
+ }
+ if rand.Intn(101) >= favor {
+ _, err = wifeData.favorFor(uid, gayOne, -1)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ }
+ _, err = wifeData.favorFor(uid, gaynano, -1)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ }
+ _, _ = ctx.SendPlainMessage(true, sendtext[1][rand.Intn(len(sendtext[1]))])
+ return
+ }
+ // 去民政局登记
+ userInfo, err := getUserInfoIn(ctx, gid, gayOne)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ fianceInfo, err := getUserInfoIn(ctx, gid, gaynano)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ err = wifeData.register(gid, userInfo, fianceInfo)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ _, err = wifeData.favorFor(uid, gayOne, 1)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ }
+ _, err = wifeData.favorFor(uid, gaynano, 1)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ }
+ _, err = wifeData.favorFor(gayOne, gaynano, 1)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ }
+ // 请大家吃席
+ _, err = ctx.SendChain(nano.ReplyTo(ctx.Message.ID),
+ nano.Text("恭喜你成功撮合了一对CP\n\n"), nano.At(gayOne), nano.Text("今天你的群老婆是[", fianceInfo.Nick, "]"),
+ nano.Image(fianceInfo.Avatar))
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "", getLine(), " ->ERROR: ", err)
+ }
+ })
+ engine.OnMessageFullMatchGroup([]string{"闹离婚", "办离婚"}, nano.OnlyChannel, getdb).Limit(ctxext.LimitByUser).SetBlock(true).Handle(func(ctx *nano.Ctx) {
+ gid := ctx.Message.GuildID
+ uid := ctx.Message.Author.ID
+ cdTime, err := wifeData.checkCD(gid, uid, "离")
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if cdTime > 0 {
+ _, _ = ctx.SendPlainMessage(true, "你的技能CD还有", cdTime)
+ return
+ }
+ uInfo, err := wifeData.checkUser(gid, uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if uInfo.Users == "" {
+ _, _ = ctx.SendPlainMessage(true, "你还是单身噢,快去娶群友吧!")
+ return
+ }
+ // 写入CD
+ err = wifeData.setCD(uid, "离")
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(true, "[qqwife]你的技能CD记录失败\n", err)
+ }
+ user := strings.Split(uInfo.Users, " & ")
+ mun := 0
+ if user[1] == uid {
+ mun = 1
+ }
+ favor, err := wifeData.favorFor(user[0], user[1], 0)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if favor < 30 {
+ favor = 10
+ }
+ if rand.Intn(101) > 110-favor {
+ _, _ = ctx.SendPlainMessage(true, sendtext[3][rand.Intn(len(sendtext[3]))])
+ return
+ }
+ err = wifeData.divorce(gid, uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ /*
+ if rand.Intn(100) > 50 {
+ _, _ = wifeData.favorFor(user[0], user[1], -rand.Intn(favor/2))
+ }
+ */
+ _, _ = ctx.SendPlainMessage(true, sendtext[4][mun])
+ })
+
+ // 好感度系统
+ engine.OnMessageRegex(`^查好感度\s*<@!(\d+)>`, nano.OnlyChannel, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ fiance := ctx.State["regex_matched"].([]string)[1]
+ uid := ctx.Message.Author.ID
+ favor, err := wifeData.favorFor(uid, fiance, 0)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ // 输出结果
+ _, _ = ctx.SendPlainMessage(true, "当前你们好感度为", favor)
+ })
+ // 礼物系统
+ engine.OnMessageRegex(`^买礼物给\s*<@!(\d+)>`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ gid := ctx.Message.GuildID
+ uid := ctx.Message.Author.ID
+ fiance := ctx.State["regex_matched"].([]string)[1]
+ if fiance == uid {
+ _, _ = ctx.SendPlainMessage(true, "你想给自己买什么礼物呢?")
+ return
+ }
+ // 获取CD
+ cdTime, err := wifeData.checkCD(gid, uid, "买")
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if cdTime > 0 {
+ _, _ = ctx.SendPlainMessage(true, "你的技能CD还有", cdTime)
+ return
+ }
+ // 获取好感度
+ favor, err := wifeData.favorFor(uid, fiance, 0)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ // 对接小熊饼干
+ uidint64, _ := strconv.ParseInt(uid, 10, 64)
+ walletinfo := wallet.GetWalletOf(uidint64)
+ if walletinfo < 1 {
+ _, _ = ctx.SendPlainMessage(true, "你钱包没钱啦!")
+ return
+ }
+ moneyToFavor := rand.Intn(math.Min(walletinfo, 100)) + 1
+ // 计算钱对应的好感值
+ newFavor := 1
+ moodMax := 2
+ if favor > 50 {
+ newFavor = moneyToFavor % 10 // 礼物厌倦
+ } else {
+ moodMax = 5
+ newFavor += rand.Intn(moneyToFavor)
+ }
+ // 随机对方心情
+ mood := rand.Intn(moodMax)
+ if mood == 0 {
+ newFavor = -newFavor
+ }
+ // 记录结果
+ err = wallet.InsertWalletOf(uidint64, -moneyToFavor)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ lastfavor, err := wifeData.favorFor(uid, fiance, newFavor)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ // 写入CD
+ err = wifeData.setCD(uid, "买")
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(true, "[qqwife]你的技能CD记录失败\n", err)
+ }
+ // 输出结果
+ if mood == 0 {
+ _, _ = ctx.SendPlainMessage(true, "你花了", moneyToFavor, "ATRI币买了一件女装送给了ta,ta很不喜欢,你们的好感度降低至", lastfavor)
+ } else {
+ _, _ = ctx.SendPlainMessage(true, "你花了", moneyToFavor, "ATRI币买了一件女装送给了ta,ta很喜欢,你们的好感度升至", lastfavor)
+ }
+ })
+ engine.OnMessageFullMatch("好感度列表", nano.OnlyChannel, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ gid := ctx.Message.GuildID
+ uid := ctx.Message.Author.ID
+ fianceeInfo, err := wifeData.getGroupFavorability(uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ /***********设置图片的大小和底色***********/
+ number := len(fianceeInfo)
+ fontSize := 50.0
+ canvas := gg.NewContext(1150, int(170+(50+70)*float64(number)))
+ canvas.SetRGB(1, 1, 1) // 白色
+ canvas.Clear()
+ /***********下载字体***********/
+ data, err := file.GetLazyData(text.BoldFontFile, nano.Md5File, true)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ }
+ /***********设置字体颜色为黑色***********/
+ canvas.SetRGB(0, 0, 0)
+ /***********设置字体大小,并获取字体高度用来定位***********/
+ if err = canvas.ParseFontFace(data, fontSize*2); err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ sl, h := canvas.MeasureString("你的好感度排行列表")
+ /***********绘制标题***********/
+ canvas.DrawString("你的好感度排行列表", (1100-sl)/2, 100) // 放置在中间位置
+ canvas.DrawString("————————————————————", 0, 160)
+ /***********设置字体大小,并获取字体高度用来定位***********/
+ if err = canvas.ParseFontFace(data, fontSize); err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ i := 0
+ for _, info := range fianceeInfo {
+ if info.Favor == 0 {
+ break
+ }
+ if info.Users == "" {
+ continue
+ }
+ user, err := getUserInfoIn(ctx, gid, info.Users)
+ if err != nil {
+ log.Warnln("[", getLine(), " ->ERROR]:", err.Error())
+ continue
+ }
+ canvas.SetRGB255(0, 0, 0)
+ canvas.DrawString(user.Nick+"("+user.ID+")", 10, float64(180+(50+70)*i))
+ canvas.DrawString(strconv.Itoa(info.Favor), 1020, float64(180+60+(50+70)*i))
+ canvas.DrawRectangle(10, float64(180+60+(50+70)*i)-h/2, 1000, 50)
+ canvas.SetRGB255(150, 150, 150)
+ canvas.Fill()
+ canvas.SetRGB255(0, 0, 0)
+ canvas.DrawRectangle(10, float64(180+60+(50+70)*i)-h/2, float64(info.Favor)*10, 50)
+ canvas.SetRGB255(231, 27, 100)
+ canvas.Fill()
+ i++
+ }
+ data, err = imgfactory.ToBytes(canvas.Image())
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ _, _ = ctx.SendImageBytes(data, true)
+ })
+}
diff --git a/plugin/qqwife/main.go b/plugin/qqwife/main.go
new file mode 100644
index 0000000..aa12bf9
--- /dev/null
+++ b/plugin/qqwife/main.go
@@ -0,0 +1,206 @@
+// Package qqwife 娶群友
+package qqwife
+
+import (
+ "math/rand"
+ "strconv"
+ "strings"
+
+ "github.com/FloatTech/NanoBot-Plugin/utils/ctxext"
+ "github.com/FloatTech/imgfactory"
+ ctrl "github.com/FloatTech/zbpctrl"
+ nano "github.com/fumiama/NanoBot"
+
+ "github.com/FloatTech/floatbox/file"
+ "github.com/FloatTech/gg"
+ "github.com/FloatTech/zbputils/img/text"
+)
+
+var (
+ engine = nano.Register("qqwife", &ctrl.Options[*nano.Ctx]{
+ DisableOnDefault: false,
+ Brief: "娶群友",
+ Help: "- 娶群友\n- 群老婆列表\n" +
+ "- [允许|禁止]自由恋爱\n- [允许|禁止]牛头人\n" +
+ "- 设置CD为xx小时 →(默认12小时)\n" +
+ "- 查好感度@对方QQ\n" +
+ "- 好感度列表\n" +
+ "--------------------------------\n以下指令存在CD,频道共用,不跨天刷新,前两个受指令开关\n--------------------------------\n" +
+ "- (娶|嫁)@对方QQ\n (好感度越高成功率越高,保底30%概率)\n" +
+ "- 牛@对方QQ\n (好感度越高成功率越高,保底10%概率)\n" +
+ "- 闹离婚\n (好感度越高成功率越低)\n" +
+ "- 买礼物给@对方QQ\n (使用bot钱包插件的金额获取好感度)\n" +
+ "- 做媒 @攻方QQ @受方QQ\n (攻受双方好感度越高成功率越高,保底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" +
+ "\nTips: 群老婆列表每天4点刷新",
+ PrivateDataFolder: "qqwife",
+ }).ApplySingle(nano.NewSingle(
+ nano.WithKeyFn(func(ctx *nano.Ctx) int64 {
+ gid, _ := strconv.ParseUint(ctx.Message.GuildID, 10, 64)
+ return int64(gid)
+ }),
+ nano.WithPostFn[int64](func(ctx *nano.Ctx) {
+ _, _ = ctx.SendPlainMessage(true, "别着急,民政局门口排长队了!")
+ }),
+ ))
+)
+
+func init() {
+ engine.OnMessageFullMatch("娶群友", nano.OnlyChannel, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ gid := ctx.Message.GuildID
+ uid := ctx.Message.Author.ID
+
+ info, err := wifeData.checkUser(gid, uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ uInfo, err := getUserInfoIn(ctx, gid, uid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if info.Users == "" {
+ menbers, err := ctx.GetGuildMembersIn(gid, "0", 1000)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ list := make(map[int]userInfo, 1000)
+ for i, member := range menbers {
+ nick := member.Nick
+ if nick == "" {
+ nick = member.User.Username
+ }
+ list[i] = userInfo{
+ ID: member.User.ID,
+ Nick: nick,
+ Avatar: member.User.Avatar,
+ }
+ }
+ target := list[rand.Intn(len(list))]
+ if target.ID == uid {
+ err = wifeData.register(gid, uInfo, userInfo{})
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ _, err = ctx.SendChain(nano.At(uid), nano.Text("今日获得成就:单身贵族"))
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ }
+ }
+ info, err = wifeData.checkUser(gid, target.ID)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ if info.Users != "" {
+ _, _ = ctx.SendPlainMessage(true, "呜...没娶到,你可以再尝试一次")
+ return
+ }
+ err = wifeData.register(gid, uInfo, target)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ favor, err := wifeData.favorFor(uid, target.ID, rand.Intn(5)+1)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ _, err = ctx.SendChain(nano.At(uid), nano.Text("\n今天你的群老婆是\n[", target.Nick, "]哒\n当前你们好感度为", favor), nano.Image(target.Avatar))
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ }
+ return
+ }
+ users := strings.Split(info.Users, " & ")
+ switch {
+ case (users[0] == uid && users[1] == "") || (users[1] == uid && users[0] == ""): // 如果是单身贵族
+ _, _ = ctx.SendPlainMessage(true, "今天你是单身贵族噢")
+ return
+ case users[0] == uid: // 娶过别人
+ favor, err := wifeData.favorFor(uid, users[1], 0)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ _, err = ctx.SendChain(nano.At(uid),
+ nano.Text("\n今天你在", info.Updatetime, "娶了群友[", info.Mname, "]\n",
+ "当前你们好感度为", favor), nano.Image(info.Mpic))
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ }
+ return
+ case users[1] == uid: // 嫁给别人
+ favor, err := wifeData.favorFor(users[0], uid, 0)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ _, err = ctx.SendChain(nano.At(uid),
+ nano.Text("\n今天你在", info.Updatetime, "被群友[", info.Sname, "]娶了\n",
+ "当前你们好感度为", favor), nano.Image(info.Spic))
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ }
+ return
+ }
+ })
+ engine.OnMessageFullMatch("群老婆列表", nano.OnlyChannel, getdb).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *nano.Ctx) {
+ gid := ctx.Message.GuildID
+ list, err := wifeData.getlist(gid)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]:", err)
+ return
+ }
+ number := len(list)
+ if number <= 0 {
+ _, _ = ctx.SendPlainMessage(false, "今天没有人结婚哦: ")
+ return
+ }
+ /***********设置图片的大小和底色***********/
+ fontSize := 50.0
+ if number < 10 {
+ number = 10
+ }
+ canvas := gg.NewContext(1500, int(250+fontSize*float64(number)))
+ canvas.SetRGB(1, 1, 1) // 白色
+ canvas.Clear()
+ /***********下载字体,可以注销掉***********/
+ data, err := file.GetLazyData(text.BoldFontFile, nano.Md5File, true)
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ }
+ /***********设置字体颜色为黑色***********/
+ canvas.SetRGB(0, 0, 0)
+ /***********设置字体大小,并获取字体高度用来定位***********/
+ if err = canvas.ParseFontFace(data, fontSize*2); err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ return
+ }
+ sl, h := canvas.MeasureString("群老婆列表")
+ /***********绘制标题***********/
+ canvas.DrawString("群老婆列表", (1500-sl)/2, 160-h) // 放置在中间位置
+ canvas.DrawString("————————————————————", 0, 250-h)
+ /***********设置字体大小,并获取字体高度用来定位***********/
+ if err = canvas.ParseFontFace(data, fontSize); err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ return
+ }
+ _, h = canvas.MeasureString("焯")
+ for i, info := range list {
+ canvas.DrawString(slicename(info.Sname, canvas), 0, float64(260+50*i)-h)
+ canvas.DrawString("←→", 700, float64(260+50*i)-h)
+ canvas.DrawString(slicename(info.Mname, canvas), 800, float64(260+50*i)-h)
+ }
+ data, err = imgfactory.ToBytes(canvas.Image())
+ if err != nil {
+ _, _ = ctx.SendPlainMessage(false, "[", getLine(), " ->ERROR]: ", err)
+ return
+ }
+ _, _ = ctx.SendImageBytes(data, false)
+ })
+}