diff --git a/README.md b/README.md index 240bcc7..81905a9 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ huggingface API 二次元 AI tag 作画 ## nsfw 图片合规性审查 +## niu +niu ## pixiv P站解析与图片下载 ## qzone diff --git a/go.mod b/go.mod index ea30ab2..bc3c995 100644 --- a/go.mod +++ b/go.mod @@ -15,18 +15,22 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/stretchr/testify v1.9.0 github.com/tidwall/gjson v1.18.0 - golang.org/x/image v0.21.0 + golang.org/x/image v0.22.0 ) require ( + github.com/FloatTech/gg v1.1.3 // indirect github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562 // indirect github.com/antchfx/xpath v1.3.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/disintegration/imaging v1.6.2 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/fumiama/cron v1.3.0 // indirect github.com/fumiama/go-registry v0.2.7 // indirect github.com/fumiama/go-simple-protobuf v0.2.0 // indirect github.com/fumiama/gofastTEA v0.0.10 // indirect + github.com/fumiama/imgsz v0.0.2 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/uuid v1.6.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -37,10 +41,9 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect - github.com/wdvxdr1123/ZeroBot v1.8.0 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.26.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/text v0.20.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect modernc.org/libc v1.61.0 // indirect modernc.org/mathutil v1.6.0 // indirect diff --git a/go.sum b/go.sum index 21f5df5..bd1d457 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,9 @@ github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024 h1:mrvWpiwfRklt9AyiQjKgDGJjf4YL6FZ3yC+ydbkuF2o= github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024/go.mod h1:+P3hs+Cvl10/Aj3SNE96TuBvKAXCe+XD1pKphTZyiwk= +github.com/FloatTech/gg v1.1.3 h1:+GlL02lTKsxJQr4WCuNwVxC1/eBZrCvypCIBtxuOFb4= +github.com/FloatTech/gg v1.1.3/go.mod h1:/9oLP54CMfq4r+71XL26uaFTJ1uL1boAyX67680/1HE= +github.com/FloatTech/rendercard v0.2.0 h1:PBTZ2gCEy/dAEGSfWecrGTrWDYpiBJD1dVzNDDaOxh4= +github.com/FloatTech/rendercard v0.2.0/go.mod h1:Sbojcy1t3NfFz7/WicZRmR/uKFxNMYkKF8qHx69dxY0= github.com/FloatTech/sqlite v1.7.0 h1:FGSn4pCR12kESozn7IvNx3U39dwR/AcFM9oPyGACsl0= github.com/FloatTech/sqlite v1.7.0/go.mod h1:/4tzfCGhrZnnjC1U8vcfwGQeF6eR649fhOsS3+Le0+s= github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562 h1:snfw7FNFym1eNnLrQ/VCf80LiQo9C7jHgrunZDwiRcY= @@ -15,6 +19,8 @@ github.com/corona10/goimagehash v1.1.0/go.mod h1:VkvE0mLn84L4aF8vCb6mafVajEb6QYM github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/fumiama/cron v1.3.0 h1:ZWlwuexF+HQHl3cYytEE5HNwD99q+3vNZF1GrEiXCFo= @@ -27,12 +33,16 @@ github.com/fumiama/go-simple-protobuf v0.2.0 h1:ACyN1MAlu7pDR3EszWgzUeNP+IRsSHwH github.com/fumiama/go-simple-protobuf v0.2.0/go.mod h1:5yYNapXq1tQMOZg9bOIVhQlZk9pQqpuFIO4DZLbsdy4= github.com/fumiama/gofastTEA v0.0.10 h1:JJJ+brWD4kie+mmK2TkspDXKzqq0IjXm89aGYfoGhhQ= github.com/fumiama/gofastTEA v0.0.10/go.mod h1:RIdbYZyB4MbH6ZBlPymRaXn3cD6SedlCu5W/HHfMPBk= +github.com/fumiama/imgsz v0.0.2 h1:fAkC0FnIscdKOXwAxlyw3EUba5NzxZdSxGaq3Uyfxak= +github.com/fumiama/imgsz v0.0.2/go.mod h1:dR71mI3I2O5u6+PCpd47M9TZptzP+39tRBcbdIkoqM4= github.com/fumiama/libc v0.0.0-20240530081950-6f6d8586b5c5 h1:jDxsIupsT84A6WHcs6kWbst+KqrRQ8/o0VyoFMnbBOA= github.com/fumiama/libc v0.0.0-20240530081950-6f6d8586b5c5/go.mod h1:15P6ublJ9FJR8YQCGy8DeQ2Uwur7iW9Hserr/T3OFZE= github.com/fumiama/sqlite3 v1.29.10-simp h1:c5y3uKyU0q9t0/SyfynzYyuslQ5zP+5CD8e0yYY554A= github.com/fumiama/sqlite3 v1.29.10-simp/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA= github.com/fumiama/terasu v0.0.0-20241027183601-987ab91031ce h1:T6iDDU16rFyxV/FwfJJR6qcgkIlXJEIFlUTSmTD1h6s= github.com/fumiama/terasu v0.0.0-20241027183601-987ab91031ce/go.mod h1:UVx8YP1jKKL1Cj+uy+OnQRM2Ih6U36Mqy9GSf7jabsI= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -71,8 +81,9 @@ github.com/wdvxdr1123/ZeroBot v1.8.0/go.mod h1:C86nQ0gIdAri4K2vg8IIQIslt08zzrKMc github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/image v0.21.0 h1:c5qV36ajHpdj4Qi0GnE0jUc/yuo33OLFaa0d+crTD5s= -golang.org/x/image v0.21.0/go.mod h1:vUbsLavqK/W303ZroQQVKQ+Af3Yl6Uz1Ppu5J/cLz78= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.22.0 h1:UtK5yLUzilVrkjMAZAZ34DXGpASN8i8pj8g+O+yd10g= +golang.org/x/image v0.22.0/go.mod h1:9hPFhljd4zZ1GNSIZJ49sqbp45GKK9t6w+iXvGqZUz4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -83,7 +94,7 @@ golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -101,8 +112,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= diff --git a/niu/main.go b/niu/main.go new file mode 100644 index 0000000..277f499 --- /dev/null +++ b/niu/main.go @@ -0,0 +1,308 @@ +package niu + +import ( + "errors" + "fmt" + "github.com/FloatTech/AnimeAPI/wallet" + "github.com/FloatTech/floatbox/file" + sql "github.com/FloatTech/sqlite" + "os" + "strconv" + "strings" + "time" +) + +var ( + db = &model{} +) + +func init() { + if file.IsNotExist("data/niuniu") { + err := os.MkdirAll("data/niuniu", 775) + if err != nil { + panic(err) + } + } + db.sql = sql.New("data/niuniu/niuniu.db") + err := db.sql.Open(time.Hour * 24) + if err != nil { + panic(err) + } +} + +// SetWordNiuNiu length > 0 就增加 , length < 0 就减小 +func SetWordNiuNiu(gid, uid int64, length float64) error { + niu, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return err + } + niu.Length += length + return db.setWordNiuNiu(gid, niu) +} + +func GetWordNiuNiu(gid, uid int64) (float64, error) { + niu, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return 0, err + } + return niu.Length, nil +} + +func DeleteWordNiuNiu(gid, uid int64) error { + return db.deleteWordNiuNiu(gid, uid) +} + +func GetRankingInfo(gid int64, t bool) (BaseInfos, error) { + var ( + list users + err error + ) + niuOfGroup, err := db.getAllNiuNiuOfGroup(gid) + if err != nil { + if t { + err = errors.New("暂时没有男孩子哦") + } else { + err = errors.New("暂时没有女孩子哦") + } + return nil, err + } + f := make(BaseInfos, len(niuOfGroup)) + if t { + list = niuOfGroup.positive() + niuOfGroup.sort(t) + } else { + list = niuOfGroup.negative() + niuOfGroup.sort(!t) + } + for i, info := range list { + f[i] = BaseInfo{ + UID: info.UID, + Length: info.Length, + } + } + + return f, nil +} + +// GetRankingOfSpecifiedUser 获取指定用户在群中的排名 +func GetRankingOfSpecifiedUser(gid, uid int64) (int, error) { + niu, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return -1, err + } + group, err := db.getAllNiuNiuOfGroup(gid) + if err != nil { + return -1, err + } + return group.ranking(niu.Length, uid), nil +} + +func View(gid, uid int64, name string) (*strings.Builder, error) { + i, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return nil, errors.New("你还没有牛牛呢不能查看") + } + niuniu := i.Length + var result strings.Builder + sexLong := "长" + sex := "♂️" + if niuniu < 0 { + sexLong = "深" + sex = "♀️" + } + niuniuList, err := db.getAllNiuNiuOfGroup(gid) + if err != nil { + return nil, err + } + result.WriteString(fmt.Sprintf("\n📛%s<%s>的牛牛信息\n⭕性别:%s\n⭕%s度:%.2fcm\n⭕排行:%d\n⭕%s ", + name, strconv.FormatInt(uid, 10), + sex, sexLong, niuniu, niuniuList.ranking(niuniu, uid), generateRandomString(niuniu))) + return &result, nil +} + +func ProcessHitGlue(gid, uid int64, prop string) (string, error) { + niuniu, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return "", errors.New("请先注册牛牛!") + } + + messages, err := niuniu.processNiuNiuAction(prop) + if err != nil { + return "", err + } + if err = db.setWordNiuNiu(gid, niuniu); err != nil { + return "", err + } + return messages, nil +} + +func Register(gid, uid int64) (string, error) { + if _, err := db.getWordNiuNiu(gid, uid); err == nil { + return "", errors.New("你已经注册过了") + } + // 获取初始长度 + length := db.newLength() + u := userInfo{ + UID: uid, + Length: length, + } + if err := db.setWordNiuNiu(gid, &u); err != nil { + return "", err + } + return fmt.Sprintf("注册成功,你的牛牛现在有%.2fcm", u.Length), nil +} + +func JJ(gid, uid, adduser int64, prop string) (message string, adduserLength float64, err error) { + myniuniu, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return "", 0, errors.New("你还没有牛牛快去注册一个吧!") + } + adduserniuniu, err := db.getWordNiuNiu(gid, adduser) + if err != nil { + return "", 0, errors.New("对方还没有牛牛呢,不能🤺") + } + + if uid == adduser { + return "", 0, errors.New("你要和谁🤺?你自己吗?") + } + + message, err = myniuniu.processJJuAction(adduserniuniu, prop) + if err != nil { + return "", 0, err + } + + if err = db.setWordNiuNiu(gid, myniuniu); err != nil { + return "", 0, err + } + + if err = db.setWordNiuNiu(gid, adduserniuniu); err != nil { + return "", 0, err + } + + adduserLength = adduserniuniu.Length + return +} + +func Cancel(gid, uid int64) (string, error) { + _, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return "", errors.New("你还没有牛牛呢,咋的你想凭空造一个啊") + } + err = db.deleteWordNiuNiu(gid, uid) + if err != nil { + err = errors.New("遇到不可抗力因素,注销失败!") + } + return "注销成功,你已经没有牛牛了", err +} + +func Redeem(gid, uid int64, lastLength float64) error { + money := wallet.GetWalletOf(uid) + if money < 150 { + return fmt.Errorf("赎牛牛需要150ATRI币,快去赚钱吧,目前仅有:%d个%s", money, wallet.GetWalletName()) + } + + if err := wallet.InsertWalletOf(uid, -150); err != nil { + return err + } + + niu, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return err + } + + niu.Length = lastLength + + return db.setWordNiuNiu(gid, niu) +} + +func Store(gid, uid int64, n int) error { + info, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return err + } + + money, err := info.purchaseItem(n) + if err != nil { + return err + } + + if wallet.GetWalletOf(uid) < money { + return errors.New("你还没有足够的ATRI币呢,不能购买") + } + + if err = wallet.InsertWalletOf(uid, -money); err != nil { + return err + } + + return db.setWordNiuNiu(uid, info) +} + +func Sell(gid, uid int64) (string, error) { + niu, err := db.getWordNiuNiu(gid, uid) + if err != nil { + return "", errors.New("你没有牛牛怎么卖😰") + } + money, t, message := profit(niu.Length) + if !t { + return message, errors.New(``) + } + err = wallet.InsertWalletOf(uid, money) + if err != nil { + return message, err + } + u := AuctionInfo{ + UID: niu.UID, + Length: niu.Length, + Money: money * 2, + } + err = db.setNiuNiuAuction(gid, &u) + return message, err +} + +func ShowAuction(gid int64) ([]AuctionInfo, error) { + return db.getAllNiuNiuAuction(gid) +} + +func Auction(gid, uid int64, i int) (string, error) { + auction, err := db.getAllNiuNiuAuction(gid) + if err != nil { + return "", errors.New("拍卖行还没有牛牛呢") + } + err = wallet.InsertWalletOf(uid, -auction[i].Money) + if err != nil { + return "", errors.New("你的钱不够快去赚钱吧!") + } + + niu, err := db.getWordNiuNiu(gid, uid) + if err != nil { + niu = &userInfo{ + UID: uid, + } + } + niu.Length = auction[i].Length + + if auction[i].Money > 500 { + niu.WeiGe = 2 + niu.Artifact = 2 + } + + if err = db.setWordNiuNiu(gid, niu); err != nil { + return "", err + } + if auction[i].Money > 500 { + return fmt.Sprintf("恭喜你购买成功,当前长度为%.2fcm,此次购买将赠送你%d个伟哥,%d个媚药", + niu.Length, niu.WeiGe, niu.Artifact), nil + } + + return fmt.Sprintf("恭喜你购买成功,当前长度为%.2fcm", niu.Length), nil +} + +func Bag(gid, uid int64) (string, error) { + niu, err := db.getWordNiuNiu(gid, uid) + message := fmt.Sprintf("当前牛牛背包如下\n伟哥: %v\n媚药: %v\n击剑神器: %v\n击剑神稽: %v", + niu.WeiGe, + niu.Philter, + niu.Artifact, + niu.ShenJi) + return message, err +} diff --git a/niu/models.go b/niu/models.go new file mode 100644 index 0000000..e65739c --- /dev/null +++ b/niu/models.go @@ -0,0 +1,377 @@ +package niu + +import ( + "errors" + "fmt" + sql "github.com/FloatTech/sqlite" + "math" + "math/rand" + "sort" + "strconv" + "sync" +) + +type users []*userInfo + +type model struct { + sql sql.Sqlite + sync.RWMutex +} + +type userInfo struct { + UID int64 + Length float64 + UserCount int + WeiGe int // 伟哥 + Philter int // 媚药 + Artifact int // 击剑神器 + ShenJi int // 击剑神稽 + Buff1 int // 暂定 + Buff2 int // 暂定 + Buff3 int // 暂定 + Buff4 int // 暂定 + Buff5 int // 暂定 +} + +type AuctionInfo struct { + UID int64 + Length float64 + Money int +} + +type BaseInfo struct { + UID int64 + Length float64 +} + +type BaseInfos []BaseInfo + +func (m users) positive() users { + var m1 []*userInfo + for _, i2 := range m { + if i2.Length > 0 { + m1 = append(m1, i2) + } + } + return m1 +} + +func (m users) negative() users { + var m1 []*userInfo + for _, i2 := range m { + if i2.Length <= 0 { + m1 = append(m1, i2) + } + } + return m1 +} + +func (m users) sort(isDesc bool) { + t := func(i, j int) bool { + return m[i].Length < m[j].Length + } + if isDesc { + t = func(i, j int) bool { + return m[i].Length > m[j].Length + } + } + sort.Slice(m, t) +} + +func (m users) ranking(niuniu float64, uid int64) int { + m.sort(niuniu > 0) + for i, user := range m { + if user.UID == uid { + return i + 1 + } + } + return -1 +} + +func (u *userInfo) useWeiGe() (string, float64) { + niuniu := u.Length + reduce := math.Abs(hitGlue(niuniu)) + niuniu += reduce + return randomChoice([]string{ + fmt.Sprintf("哈哈,你这一用道具,牛牛就像是被激发了潜能,增加了%.2fcm!看来今天是个大日子呢!", reduce), + fmt.Sprintf("你这是用了什么神奇的道具?牛牛竟然增加了%.2fcm,简直是牛气冲天!", reduce), + fmt.Sprintf("使用道具后,你的牛牛就像是开启了加速模式,一下增加了%.2fcm,这成长速度让人惊叹!", reduce), + }), niuniu +} + +func (u *userInfo) usePhilter() (string, float64) { + niuniu := u.Length + reduce := math.Abs(hitGlue(niuniu)) + niuniu -= reduce + return randomChoice([]string{ + fmt.Sprintf("你使用媚药,咿呀咿呀一下使当前长度发生了一些变化,当前长度%.2f", niuniu), + fmt.Sprintf("看来你追求的是‘微观之美’,故意使用道具让牛牛凹进去了%.2fcm!", reduce), + fmt.Sprintf("缩小奇迹’在你身上发生了,牛牛凹进去了%.2fcm,你的选择真是独特!", reduce), + }), niuniu +} + +func (u *userInfo) useArtifact(adduserniuniu float64) (string, float64, float64) { + myLength := u.Length + difference := myLength - adduserniuniu + var ( + change float64 + ) + if difference > 0 { + change = hitGlue(myLength + adduserniuniu) + } else { + change = hitGlue((myLength + adduserniuniu) / 2) + } + myLength += change + return randomChoice([]string{ + fmt.Sprintf("凭借神秘道具的力量,你让对方在你的长度面前俯首称臣!你的长度增加了%.2fcm,当前长度达到了%.2fcm", change, myLength), + fmt.Sprintf("神器在手,天下我有!你使用道具后,长度猛增%.2fcm,现在的总长度是%.2fcm,无人能敌!", change, myLength), + fmt.Sprintf("这就是道具的魔力!你轻松增加了%.2fcm,让对手望尘莫及,当前长度为%.2fcm!", change, myLength), + fmt.Sprintf("道具一出,谁与争锋!你的长度因道具而增长%.2fcm,现在的长度是%.2fcm,霸气尽显!", change, myLength), + fmt.Sprintf("使用道具的你,如同获得神助!你的长度增长了%.2fcm,达到%.2fcm的惊人长度,胜利自然到手!", change, myLength), + }), myLength, adduserniuniu - change/1.3 +} + +func (u *userInfo) useShenJi(adduserniuniu float64) (string, float64, float64) { + myLength := u.Length + difference := myLength - adduserniuniu + var ( + change float64 + ) + if difference > 0 { + change = hitGlue(myLength + adduserniuniu) + } else { + change = hitGlue((myLength + adduserniuniu) / 2) + } + myLength -= change + var r string + if myLength > 0 { + r = randomChoice([]string{ + fmt.Sprintf("哦吼!?看来你的牛牛因为使用了神秘道具而缩水了呢🤣🤣🤣!缩小了%.2fcm!", change), + fmt.Sprintf("哈哈,看来这个道具有点儿调皮,让你的长度缩水了%.2fcm!现在你的长度是%.2fcm,下次可得小心使用哦!", change, myLength), + fmt.Sprintf("使用道具后,你的牛牛似乎有点儿害羞,缩水了%.2fcm!现在的长度是%.2fcm,希望下次它能挺直腰板!", change, myLength), + fmt.Sprintf("哎呀,这个道具的效果有点儿意外,你的长度减少了%.2fcm,现在只有%.2fcm了!下次选道具可得睁大眼睛!", change, myLength), + }) + } else { + r = randomChoice([]string{ + fmt.Sprintf("哦哟,小姐姐真是玩得一手好游戏,使用道具后数值又降低了%.2fcm,小巧得更显魅力!", change), + fmt.Sprintf("看来小姐姐喜欢更加精致的风格,使用道具后,数值减少了%.2fcm,更加迷人了!", change), + fmt.Sprintf("小姐姐的每一次变化都让人惊喜,使用道具后,数值减少了%.2fcm,更加优雅动人!", change), + fmt.Sprintf("小姐姐这是在展示什么是真正的精致小巧,使用道具后,数值减少了%.2fcm,美得不可方物!", change), + }) + } + return r, myLength, adduserniuniu + 0.7*change +} + +func (u *userInfo) createUserInfoByProps(props string) error { + var ( + err error + ) + switch props { + case "伟哥": + if u.WeiGe > 0 { + u.WeiGe-- + } else { + err = errors.New("你还没有伟哥呢,不能使用") + } + case "媚药": + if u.Philter > 0 { + u.Philter-- + } else { + err = errors.New("你还没有媚药呢,不能使用") + } + case "击剑神器": + if u.Artifact > 0 { + u.Artifact-- + } else { + err = errors.New("你还没有击剑神器呢,不能使用") + } + case "击剑神稽": + if u.ShenJi > 0 { + u.ShenJi-- + } else { + err = errors.New("你还没有击剑神稽呢,不能使用") + } + default: + err = errors.New("道具不存在") + } + return err +} + +func (u *userInfo) purchaseItem(n int) (int, error) { + var ( + money int + err error + ) + switch n { + case 1: + money = 300 + u.WeiGe += 5 + case 2: + money = 300 + u.Philter += 5 + case 3: + money = 500 + u.Artifact += 2 + case 4: + money = 500 + u.ShenJi += 2 + default: + err = errors.New("无效的选择") + } + return money, err +} + +func (u *userInfo) processNiuNiuAction(props string) (string, error) { + var ( + messages string + info userInfo + err error + f float64 + ) + info = *u + if props != "" { + if props != "伟哥" && props != "媚药" { + err = errors.New("道具不存在") + } + if props == "击剑神器" || props == "击剑神稽" { + err = errors.New("道具不能混着用哦") + } + if err != nil { + return "", err + } + if err = u.createUserInfoByProps(props); err != nil { + return "", err + } + } + switch { + case u.WeiGe-info.WeiGe != 0: + messages, f = u.useWeiGe() + u.Length = f + + case u.Philter-info.Philter != 0: + messages, f = u.usePhilter() + u.Length = f + + default: + messages, f = hitGlueNiuNiu(u.Length) + u.Length = f + } + return messages, err +} + +func (u *userInfo) processJJuAction(adduserniuniu *userInfo, props string) (string, error) { + var ( + fencingResult string + f float64 + f1 float64 + info userInfo + err error + ) + info = *u + if props != "" { + if props != "击剑神器" && props != "击剑神稽" { + err = errors.New("道具不存在") + } + if props == "伟哥" || props == "媚药" { + err = errors.New("道具不能混着用哦") + } + if err != nil { + return "", err + } + if err = u.createUserInfoByProps(props); err != nil { + return "", err + } + } + switch { + + case u.ShenJi-info.ShenJi != 0: + fencingResult, f, f1 = u.useShenJi(adduserniuniu.Length) + u.Length = f + adduserniuniu.Length = f1 + + case u.Artifact-info.Artifact != 0: + fencingResult, f, f1 = u.useArtifact(adduserniuniu.Length) + u.Length = f + adduserniuniu.Length = f1 + + default: + fencingResult, f, f1 = fencing(u.Length, adduserniuniu.Length) + u.Length = f + adduserniuniu.Length = f1 + + } + return fencingResult, err +} + +func (db *model) newLength() float64 { + return float64(rand.Intn(9)+1) + (float64(rand.Intn(100)) / 100) +} + +func (db *model) getWordNiuNiu(gid, uid int64) (*userInfo, error) { + db.RLock() + defer db.RUnlock() + u := userInfo{} + err := db.sql.Find(strconv.FormatInt(gid, 10), &u, "where UID = "+strconv.FormatInt(uid, 10)) + return &u, err +} + +func (db *model) setWordNiuNiu(gid int64, u *userInfo) error { + db.Lock() + defer db.Unlock() + err := db.sql.Insert(strconv.FormatInt(gid, 10), u) + if err != nil { + err = db.sql.Create(strconv.FormatInt(gid, 10), &userInfo{}) + if err != nil { + return err + } + err = db.sql.Insert(strconv.FormatInt(gid, 10), u) + } + return err +} + +func (db *model) deleteWordNiuNiu(gid, uid int64) error { + db.Lock() + defer db.Unlock() + return db.sql.Del(strconv.FormatInt(gid, 10), "where UID = "+strconv.FormatInt(uid, 10)) +} + +func (db *model) getAllNiuNiuOfGroup(gid int64) (users, error) { + db.Lock() + defer db.Unlock() + var user userInfo + var useras users + err := db.sql.FindFor(fmt.Sprintf("%d", gid), &user, "", + func() error { + useras = append(useras, &user) + return nil + }) + return useras, err +} + +func (db *model) setNiuNiuAuction(gid int64, u *AuctionInfo) error { + db.Lock() + defer db.Unlock() + err := db.sql.Insert(fmt.Sprintf("auction_%d", gid), u) + if err != nil { + err = db.sql.Create(strconv.FormatInt(gid, 10), &AuctionInfo{}) + if err != nil { + return err + } + err = db.sql.Insert(strconv.FormatInt(gid, 10), u) + } + return err +} + +func (db *model) getAllNiuNiuAuction(gid int64) ([]AuctionInfo, error) { + db.Lock() + defer db.Unlock() + var user AuctionInfo + var useras []AuctionInfo + err := db.sql.FindFor(fmt.Sprintf("auction_%d", gid), &user, "", + func() error { + useras = append(useras, user) + return nil + }) + + return useras, err +} diff --git a/niu/utils.go b/niu/utils.go new file mode 100644 index 0000000..e52f230 --- /dev/null +++ b/niu/utils.go @@ -0,0 +1,240 @@ +package niu + +import ( + "errors" + "fmt" + "github.com/FloatTech/AnimeAPI/wallet" + "io" + "math" + "math/rand" + "net/http" + "regexp" + "strconv" +) + +func randomChoice(options []string) string { + return options[rand.Intn(len(options))] +} + +func profit(niuniu float64) (money int, t bool, message string) { + switch { + case 0 < niuniu && niuniu <= 15: + message = randomChoice([]string{ + "你的牛牛太小啦", + "这么小的牛牛就要肩负起这么大的责任吗?快去打胶吧!", + }) + case niuniu > 15: + money = int(niuniu * 10) + message = randomChoice([]string{ + fmt.Sprintf("你的牛牛已经离你而去了,你赚取了%d个%s", money, wallet.GetWalletName()), + fmt.Sprintf("啊!你的牛☞已经没啦🤣,为了这点钱就出卖你的牛牛可真不值,你赚取了%d个%s", money, wallet.GetWalletName()), + }) + t = true + case niuniu <= 0 && niuniu >= -15: + message = randomChoice([]string{ + "你的牛牛太小啦", + "这么小的牛牛就要肩负起这么大的责任吗?快去找别人玩吧!", + }) + case niuniu < -15: + money = int(math.Abs(niuniu * 10)) + message = randomChoice([]string{ + fmt.Sprintf("此世做了女孩子来世来当男孩子(bushi),你赚取了%d个%s", money, wallet.GetWalletName()), + fmt.Sprintf("呜呜呜,不哭不哭当女孩子不委屈的,你赚取了%d个%s", money, wallet.GetWalletName()), + }) + t = true + } + return +} + +func hitGlueNiuNiu(niuniu float64) (string, float64) { + probability := rand.Intn(100 + 1) + reduce := math.Abs(hitGlue(niuniu)) + switch { + case probability <= 40: + niuniu += reduce + return randomChoice([]string{ + fmt.Sprintf("你嘿咻嘿咻一下,促进了牛牛发育,牛牛增加%.2fcm了呢!", reduce), + fmt.Sprintf("你打了个舒服痛快的🦶呐,牛牛增加了%.2fcm呢!", reduce), + }), niuniu + case probability <= 60: + return randomChoice([]string{ + "你打了个🦶,但是什么变化也没有,好奇怪捏~", + "你的牛牛刚开始变长了,可过了一会又回来了,什么变化也没有,好奇怪捏~", + }), niuniu + default: + niuniu -= reduce + if niuniu < 0 { + return randomChoice([]string{ + fmt.Sprintf("哦吼!?看来你的牛牛凹进去了%.2fcm呢!", reduce), + fmt.Sprintf("你突发恶疾!你的牛牛凹进去了%.2fcm!", reduce), + fmt.Sprintf("笑死,你因为打🦶过度导致牛牛凹进去了%.2fcm!🤣🤣🤣", reduce), + }), niuniu + } + return randomChoice([]string{ + fmt.Sprintf("阿哦,你过度打🦶,牛牛缩短%.2fcm了呢!", reduce), + fmt.Sprintf("你的牛牛变长了很多,你很激动地继续打🦶,然后牛牛缩短了%.2fcm呢!", reduce), + fmt.Sprintf("小打怡情,大打伤身,强打灰飞烟灭!你过度打🦶,牛牛缩短了%.2fcm捏!", reduce), + }), niuniu + } +} + +func generateRandomString(niuniu float64) string { + switch { + case niuniu <= -100: + return "wtf?你已经进化成魅魔了!魅魔在击剑时有20%的几率消耗自身长度吞噬对方牛牛呢。" + case niuniu <= -50: + return "嗯....好像已经穿过了身体吧..从另一面来看也可以算是凸出来的吧?" + case niuniu <= -25: + return randomChoice([]string{ + "这名女生,你的身体很健康哦!", + "WOW,真的凹进去了好多呢!", + "你已经是我们女孩子的一员啦!", + }) + case niuniu <= -10: + return randomChoice([]string{ + "你已经是一名女生了呢,", + "从女生的角度来说,你发育良好(,", + "你醒啦?你已经是一名女孩子啦!", + "唔...可以放进去一根手指了都...", + }) + case niuniu <= 0: + return randomChoice([]string{ + "安了安了,不要伤心嘛,做女生有什么不好的啊。", + "不哭不哭,摸摸头,虽然很难再长出来,但是请不要伤心啦啊!", + "加油加油!我看好你哦!", + "你醒啦?你现在已经是一名女孩子啦!", + }) + case niuniu <= 10: + return randomChoice([]string{ + "你行不行啊?细狗!", + "虽然短,但是小小的也很可爱呢。", + "像一只蚕宝宝。", + "长大了。", + }) + case niuniu <= 25: + return randomChoice([]string{ + "唔...没话说", + "已经很长了呢!", + }) + case niuniu <= 50: + return randomChoice([]string{ + "话说这种真的有可能吗?", + "厚礼谢!", + }) + case niuniu <= 100: + return randomChoice([]string{ + "已经突破天际了嘛...", + "唔...这玩意应该不会变得比我高吧?", + "你这个长度会死人的...!", + "你马上要进化成牛头人了!!", + "你是什么怪物,不要过来啊!!", + }) + default: + return "惊世骇俗!你已经进化成牛头人了!牛头人在击剑时有20%的几率消耗自身长度吞噬对方牛牛呢。" + } +} + +// fencing 击剑对决逻辑,返回对决结果和myLength的变化值 +func fencing(myLength, oppoLength float64) (string, float64, float64) { + devourLimit := 0.27 + + probability := rand.Intn(100) + 1 + + switch { + case oppoLength <= -100 && myLength > 0 && 10 < probability && probability <= 20: + change := hitGlue(oppoLength) + rand.Float64()*math.Log2(math.Abs(0.5*(myLength+oppoLength))) + myLength += change + return fmt.Sprintf("对方身为魅魔诱惑了你,你同化成魅魔!当前长度%.2fcm!", -myLength), -myLength, oppoLength + + case oppoLength >= 100 && myLength > 0 && 10 < probability && probability <= 20: + change := math.Min(math.Abs(devourLimit*myLength), math.Abs(1.5*myLength)) + myLength += change + return fmt.Sprintf("对方以牛头人的荣誉摧毁了你的牛牛!当前长度%.2fcm!", myLength), myLength, oppoLength + + case myLength <= -100 && oppoLength > 0 && 10 < probability && probability <= 20: + change := hitGlue(myLength+oppoLength) + rand.Float64()*math.Log2(math.Abs(0.5*(myLength+oppoLength))) + oppoLength -= change + myLength -= change + return fmt.Sprintf("你身为魅魔诱惑了对方,吞噬了对方部分长度!当前长度%.2fcm!", myLength), myLength, oppoLength + + case myLength >= 100 && oppoLength > 0 && 10 < probability && probability <= 20: + myLength -= oppoLength + oppoLength = 0.01 + return fmt.Sprintf("你以牛头人的荣誉摧毁了对方的牛牛!当前长度%.2fcm!", myLength), myLength, oppoLength + + default: + return determineResultBySkill(myLength, oppoLength) + } +} + +// determineResultBySkill 根据击剑技巧决定结果 +func determineResultBySkill(myLength, oppoLength float64) (string, float64, float64) { + probability := rand.Intn(100) + 1 + winProbability := calculateWinProbability(myLength, oppoLength) * 100 + return applySkill(myLength, oppoLength, + float64(probability) <= winProbability) +} + +// calculateWinProbability 计算胜率 +func calculateWinProbability(heightA, heightB float64) float64 { + pA := 0.9 + heightRatio := math.Max(heightA, heightB) / math.Min(heightA, heightB) + reductionRate := 0.1 * (heightRatio - 1) + reduction := pA * reductionRate + + adjustedPA := pA - reduction + return math.Max(adjustedPA, 0.01) +} + +// applySkill 应用击剑技巧并生成结果 +func applySkill(myLength, oppoLength float64, increaseLength1 bool) (string, float64, float64) { + reduce := fence(oppoLength) + // 兜底操作 + if reduce == 0 { + reduce = rand.Float64() + float64(rand.Intn(3)) + } + if increaseLength1 { + myLength += reduce + oppoLength -= 0.8 * reduce + if myLength < 0 { + return fmt.Sprintf("哦吼!?你的牛牛在长大欸!长大了%.2fcm!", reduce), myLength, oppoLength + } + return fmt.Sprintf("你以绝对的长度让对方屈服了呢!你的长度增加%.2fcm,当前长度%.2fcm!", reduce, myLength), myLength, oppoLength + } + myLength -= reduce + oppoLength += 0.8 * reduce + if myLength < 0 { + return fmt.Sprintf("哦吼!?看来你的牛牛因为击剑而凹进去了呢🤣🤣🤣!凹进去了%.2fcm!", reduce), myLength, oppoLength + } + return fmt.Sprintf("对方以绝对的长度让你屈服了呢!你的长度减少%.2fcm,当前长度%.2fcm!", reduce, myLength), myLength, oppoLength +} + +// fence 根据长度计算减少的长度 +func fence(rd float64) float64 { + rd = math.Abs(rd) + if rd == 0 { + rd = 1 + } + r := hitGlue(rd)*2 + rand.Float64()*math.Log2(rd) + + return float64(int(r * rand.Float64())) +} + +func hitGlue(l float64) float64 { + if l == 0 { + l = 0.1 + } + l = math.Abs(l) + switch { + case l > 1 && l <= 10: + return rand.Float64() * math.Log2(l*2) + case 10 < l && l <= 100: + return rand.Float64() * math.Log2(l*1.5) + case 100 < l && l <= 1000: + return rand.Float64() * (math.Log10(l*1.5) * 2) + case l > 1000: + return rand.Float64() * (math.Log10(l) * 2) + default: + return rand.Float64() + } +}