-
Notifications
You must be signed in to change notification settings - Fork 2k
添加签到,引入分数机制 #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
添加签到,引入分数机制 #101
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
ecd8861
Merge pull request #1 from FloatTech/master
guohuiyuan 7a7094c
feat:添加签到功能,引入分数机制
guohuiyuan 9369a8c
Merge pull request #2 from FloatTech/master
guohuiyuan 79a62db
feat:修lint
guohuiyuan 6f1dbf1
fix:加宽
guohuiyuan f220cb3
fix:修lint和加锁
guohuiyuan e24e467
fix:解决冲突
guohuiyuan f170363
Merge pull request #3 from FloatTech/master
guohuiyuan 98fb1a6
fix:二次判断
guohuiyuan 91d65af
Merge remote-tracking branch 'origin/master'
guohuiyuan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package score | ||
|
||
import ( | ||
"github.com/FloatTech/ZeroBot-Plugin/utils/process" | ||
log "github.com/sirupsen/logrus" | ||
"os" | ||
) | ||
|
||
const ( | ||
cachePath = dbpath + "cache/" | ||
dbpath = "data/Score/" | ||
dbfile = dbpath + "score.db" | ||
) | ||
|
||
// SDB 得分数据库 | ||
var SDB *DB | ||
|
||
// 加载数据库 | ||
func init() { | ||
go func() { | ||
process.SleepAbout1sTo2s() | ||
_ = os.MkdirAll(dbpath, 0755) | ||
os.RemoveAll(cachePath) | ||
_ = os.MkdirAll(cachePath, 0755) | ||
SDB = Initialize(dbfile) | ||
log.Println("[score]加载score数据库") | ||
}() | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
package score | ||
|
||
import ( | ||
"github.com/jinzhu/gorm" | ||
_ "github.com/logoove/sqlite" // import sql | ||
"os" | ||
"time" | ||
) | ||
|
||
// DB 分数数据库 | ||
type DB gorm.DB | ||
|
||
// Score 分数结构体 | ||
type Score struct { | ||
UID int64 `gorm:"column:uid;primary_key"` | ||
Score int `gorm:"column:score;default:0"` | ||
} | ||
|
||
// TableName ... | ||
func (Score) TableName() string { | ||
return "score" | ||
} | ||
|
||
// SignIn 签到结构体 | ||
type SignIn struct { | ||
UID int64 `gorm:"column:uid;primary_key"` | ||
Count int `gorm:"column:count;default:0"` | ||
UpdatedAt time.Time | ||
} | ||
|
||
// TableName ... | ||
func (SignIn) TableName() string { | ||
return "sign_in" | ||
} | ||
|
||
// Initialize 初始化ScoreDB数据库 | ||
func Initialize(dbpath string) *DB { | ||
var err error | ||
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) { | ||
// 生成文件 | ||
f, err := os.Create(dbpath) | ||
if err != nil { | ||
return nil | ||
} | ||
defer f.Close() | ||
} | ||
gdb, err := gorm.Open("sqlite3", dbpath) | ||
if err != nil { | ||
panic(err) | ||
} | ||
gdb.AutoMigrate(&Score{}).AutoMigrate(&SignIn{}) | ||
return (*DB)(gdb) | ||
} | ||
|
||
// Open ... | ||
func Open(dbpath string) (*DB, error) { | ||
db, err := gorm.Open("sqlite3", dbpath) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return (*DB)(db), nil | ||
} | ||
|
||
// Close ... | ||
func (sdb *DB) Close() error { | ||
db := (*gorm.DB)(sdb) | ||
return db.Close() | ||
} | ||
|
||
// GetScoreByUID 取得分数 | ||
func (sdb *DB) GetScoreByUID(uid int64) (s Score) { | ||
db := (*gorm.DB)(sdb) | ||
db.Debug().Model(&Score{}).FirstOrCreate(&s, "uid = ? ", uid) | ||
return s | ||
} | ||
|
||
// InsertOrUpdateScoreByUID 插入或更新分数 | ||
func (sdb *DB) InsertOrUpdateScoreByUID(uid int64, score int) (err error) { | ||
db := (*gorm.DB)(sdb) | ||
s := Score{ | ||
UID: uid, | ||
Score: score, | ||
} | ||
if err = db.Debug().Model(&Score{}).First(&s, "uid = ? ", uid).Error; err != nil { | ||
// error handling... | ||
if gorm.IsRecordNotFoundError(err) { | ||
db.Debug().Model(&Score{}).Create(&s) // newUser not user | ||
} | ||
} else { | ||
err = db.Debug().Model(&Score{}).Where("uid = ? ", uid).Update( | ||
map[string]interface{}{ | ||
"score": score, | ||
}).Error | ||
} | ||
return | ||
} | ||
|
||
// GetSignInByUID 取得签到次数 | ||
func (sdb *DB) GetSignInByUID(uid int64) (si SignIn) { | ||
db := (*gorm.DB)(sdb) | ||
db.Debug().Model(&SignIn{}).FirstOrCreate(&si, "uid = ? ", uid) | ||
return si | ||
} | ||
|
||
// InsertOrUpdateSignInCountByUID 插入或更新签到次数 | ||
func (sdb *DB) InsertOrUpdateSignInCountByUID(uid int64, count int) (err error) { | ||
db := (*gorm.DB)(sdb) | ||
si := SignIn{ | ||
UID: uid, | ||
Count: count, | ||
} | ||
if err = db.Debug().Model(&SignIn{}).First(&si, "uid = ? ", uid).Error; err != nil { | ||
// error handling... | ||
if gorm.IsRecordNotFoundError(err) { | ||
db.Debug().Model(&SignIn{}).Create(&si) // newUser not user | ||
} | ||
} else { | ||
err = db.Debug().Model(&SignIn{}).Where("uid = ? ", uid).Update( | ||
map[string]interface{}{ | ||
"count": count, | ||
}).Error | ||
} | ||
return | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
// Package score 签到,答题得分 | ||
package score | ||
|
||
import ( | ||
"fmt" | ||
"github.com/FloatTech/ZeroBot-Plugin/control" | ||
"github.com/FloatTech/ZeroBot-Plugin/utils/ctxext" | ||
"github.com/FloatTech/ZeroBot-Plugin/utils/file" | ||
"github.com/FloatTech/ZeroBot-Plugin/utils/txt2img" | ||
"github.com/FloatTech/ZeroBot-Plugin/utils/web" | ||
"github.com/fogleman/gg" | ||
log "github.com/sirupsen/logrus" | ||
"github.com/tidwall/gjson" | ||
zero "github.com/wdvxdr1123/ZeroBot" | ||
"github.com/wdvxdr1123/ZeroBot/message" | ||
"github.com/wdvxdr1123/ZeroBot/utils/helper" | ||
"os" | ||
"strconv" | ||
"sync" | ||
"time" | ||
) | ||
|
||
const ( | ||
prio = 5 | ||
backgroundURL = "https://iw233.cn/API/pc.php?type=json" | ||
referer = "https://iw233.cn/main.html" | ||
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36" | ||
signinMax = 1 | ||
// ScoreMax 分数上限定为120 | ||
ScoreMax = 120 | ||
) | ||
|
||
var ( | ||
engine = control.Register("score", &control.Options{ | ||
DisableOnDefault: false, | ||
Help: "签到得分\n- 签到\n- 获得签到背景[@xxx]|获得签到背景", | ||
}) | ||
levelArray = [...]int{0, 1, 2, 5, 10, 20, 35, 55, 75, 100, 120} | ||
// 下载锁 | ||
mu sync.Mutex | ||
) | ||
|
||
func init() { | ||
engine.OnFullMatch("签到").SetBlock(true).SetPriority(prio). | ||
Handle(func(ctx *zero.Ctx) { | ||
uid := ctx.Event.UserID | ||
now := time.Now() | ||
today := now.Format("20060102") | ||
si := SDB.GetSignInByUID(uid) | ||
picFile := cachePath + strconv.FormatInt(uid, 10) + today + ".png" | ||
if file.IsNotExist(picFile) { | ||
fumiama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
mu.Lock() | ||
initPic(picFile) | ||
mu.Unlock() | ||
} | ||
siUpdateTimeStr := si.UpdatedAt.Format("20060102") | ||
if siUpdateTimeStr != today { | ||
if err := SDB.InsertOrUpdateSignInCountByUID(uid, 0); err != nil { | ||
log.Errorln("[score]:", err) | ||
} | ||
} | ||
if si.Count >= signinMax && siUpdateTimeStr == today { | ||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("今天你已经签到过了!")) | ||
return | ||
} | ||
if err := SDB.InsertOrUpdateSignInCountByUID(uid, si.Count+1); err != nil { | ||
log.Errorln("[score]:", err) | ||
} | ||
back, err := gg.LoadImage(picFile) | ||
if err != nil { | ||
log.Errorln("[score]:", err) | ||
} | ||
canvas := gg.NewContext(back.Bounds().Size().X, int(float64(back.Bounds().Size().Y)*1.7)) | ||
canvas.SetRGB(1, 1, 1) | ||
canvas.Clear() | ||
canvas.DrawImage(back, 0, 0) | ||
|
||
monthWord := now.Format("01/02") | ||
hourWord := getHourWord(now) | ||
if err = canvas.LoadFontFace(txt2img.BoldFontFile, float64(back.Bounds().Size().X)*0.1); err != nil { | ||
log.Println("[score]:", err) | ||
} | ||
canvas.SetRGB(0, 0, 0) | ||
canvas.DrawString(hourWord, float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.2) | ||
canvas.DrawString(monthWord, float64(back.Bounds().Size().X)*0.6, float64(back.Bounds().Size().Y)*1.2) | ||
nickName := ctxext.CardOrNickName(ctx, uid) | ||
if err = canvas.LoadFontFace(txt2img.FontFile, float64(back.Bounds().Size().X)*0.04); err != nil { | ||
log.Println("[score]:", err) | ||
} | ||
add := 1 | ||
canvas.DrawString(nickName+fmt.Sprintf(" 小熊饼干+%d", add), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.3) | ||
score := SDB.GetScoreByUID(uid).Score | ||
score += add | ||
if score > ScoreMax { | ||
score = ScoreMax | ||
ctx.SendChain(message.At(uid), message.Text("你获得的小熊饼干已经达到上限")) | ||
} | ||
if err := SDB.InsertOrUpdateScoreByUID(uid, score); err != nil { | ||
log.Println("[score]:", err) | ||
} | ||
level := getLevel(score) | ||
canvas.DrawString("当前小熊饼干:"+strconv.FormatInt(int64(score), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.4) | ||
canvas.DrawString("LEVEL:"+strconv.FormatInt(int64(level), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.5) | ||
canvas.DrawRectangle(float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.55, float64(back.Bounds().Size().X)*0.6, float64(back.Bounds().Size().Y)*0.1) | ||
canvas.SetRGB255(150, 150, 150) | ||
canvas.Fill() | ||
var nextLevelScore int | ||
if level < 10 { | ||
nextLevelScore = levelArray[level+1] | ||
} else { | ||
nextLevelScore = ScoreMax | ||
} | ||
canvas.SetRGB255(0, 0, 0) | ||
canvas.DrawRectangle(float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.55, float64(back.Bounds().Size().X)*0.6*float64(score)/float64(nextLevelScore), float64(back.Bounds().Size().Y)*0.1) | ||
canvas.SetRGB255(102, 102, 102) | ||
canvas.Fill() | ||
canvas.DrawString(fmt.Sprintf("%d/%d", score, nextLevelScore), float64(back.Bounds().Size().X)*0.75, float64(back.Bounds().Size().Y)*1.62) | ||
canvasBase64, err := txt2img.CanvasToBase64(canvas) | ||
if err != nil { | ||
log.Println("[score]:", err) | ||
} | ||
ctx.SendChain(message.Image("base64://" + helper.BytesToString(canvasBase64))) | ||
}) | ||
engine.OnPrefix("获得签到背景", zero.OnlyGroup).SetBlock(true).SetPriority(20). | ||
Handle(func(ctx *zero.Ctx) { | ||
param := ctx.State["args"].(string) | ||
var uidStr string | ||
if len(ctx.Event.Message) > 1 && ctx.Event.Message[1].Type == "at" { | ||
uidStr = ctx.Event.Message[1].Data["qq"] | ||
} else if param == "" { | ||
uidStr = strconv.FormatInt(ctx.Event.UserID, 10) | ||
} | ||
picFile := cachePath + uidStr + time.Now().Format("20060102") + ".png" | ||
if file.IsNotExist(picFile) { | ||
mu.Lock() | ||
fumiama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
initPic(picFile) | ||
mu.Unlock() | ||
} | ||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + picFile)) | ||
}) | ||
} | ||
|
||
func getHourWord(t time.Time) string { | ||
switch { | ||
case 6 <= t.Hour() && t.Hour() < 12: | ||
return "早上好" | ||
case 12 <= t.Hour() && t.Hour() < 14: | ||
return "中午好" | ||
case 14 <= t.Hour() && t.Hour() < 19: | ||
return "下午好" | ||
case 19 <= t.Hour() && t.Hour() < 24: | ||
return "晚上好" | ||
case 0 <= t.Hour() && t.Hour() < 6: | ||
return "凌晨好" | ||
default: | ||
return "" | ||
} | ||
} | ||
|
||
func getLevel(count int) int { | ||
for k, v := range levelArray { | ||
if count == v { | ||
return k | ||
} else if count < v { | ||
return k - 1 | ||
} | ||
} | ||
return -1 | ||
} | ||
|
||
func initPic(picFile string) { | ||
if file.IsNotExist(picFile) { | ||
data, err := web.ReqWith(backgroundURL, "GET", referer, ua) | ||
if err != nil { | ||
log.Errorln("[score]:", err) | ||
} | ||
picURL := gjson.Get(string(data), "pic").String() | ||
data, err = web.ReqWith(picURL, "GET", "", ua) | ||
if err != nil { | ||
log.Errorln("[score]:", err) | ||
} | ||
err = os.WriteFile(picFile, data, 0666) | ||
if err != nil { | ||
log.Errorln("[score]:", err) | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.