diff --git a/plugin/mai/alias.go b/plugin/mai/alias.go new file mode 100644 index 0000000..2508d98 --- /dev/null +++ b/plugin/mai/alias.go @@ -0,0 +1,43 @@ +package mai + +import ( + "encoding/json" + "github.com/FloatTech/floatbox/web" + "net/http" + "os" +) + +type LxnsAliases struct { + Aliases []struct { + SongId int `json:"song_id"` + Aliases []string `json:"aliases"` + } `json:"aliases"` +} + +// only support LXNS because => DivingFish need Token. + +// RequestAliasFromLxns Get Alias From LXNS Network. +func RequestAliasFromLxns() LxnsAliases { + getData, err := web.RequestDataWithHeaders(web.NewDefaultClient(), "https://maimai.lxns.net/api/v0/maimai/alias/list", "GET", func(request *http.Request) error { + request.Header.Add("Authorization", os.Getenv("lxnskey")) + return nil + }, nil) + if err != nil { + return LxnsAliases{} + } + var handlerData LxnsAliases + json.Unmarshal(getData, &handlerData) + return handlerData +} + +// QueryReferSong CASE: In DivingFish Mode this SongID will be added "00" AHEAD IF SONGID IS LOWER THAN 1000 (if lower than 100 then it will be added "000" ) , Otherwise it will be added "1" AHEAD. || LXNS don't need to do anything. (DEFAULT RETURN LXNS SONGDATA) +func (requester *LxnsAliases) QueryReferSong(songAlias string) (status bool, songID int64) { + for i, dataInnner := range requester.Aliases { + for _, v := range dataInnner.Aliases { + if songAlias == v { + return true, int64(requester.Aliases[i].SongId) + } + } + } + return false, 0 +} diff --git a/plugin/mai/lxnsHandler.go b/plugin/mai/lxnsHandler.go index 921d0de..3070c89 100644 --- a/plugin/mai/lxnsHandler.go +++ b/plugin/mai/lxnsHandler.go @@ -14,10 +14,10 @@ import ( "time" "unicode/utf8" - "github.com/MoYoez/Lucy_reibot/utils/toolchain" "github.com/FloatTech/floatbox/web" "github.com/FloatTech/gg" "github.com/FloatTech/imgfactory" + "github.com/MoYoez/Lucy_reibot/utils/toolchain" rei "github.com/fumiama/ReiBot" "golang.org/x/text/width" ) @@ -104,6 +104,44 @@ type LxnsMaimaiRequestDataPiece struct { UploadTime time.Time `json:"upload_time"` } +type LxnsMaimaiRequestUserReferBestSong struct { + Success bool `json:"success"` + Code int `json:"code"` + Data []struct { + Id int `json:"id"` + SongName string `json:"song_name"` + Level string `json:"level"` + LevelIndex int `json:"level_index"` + Achievements float64 `json:"achievements"` + Fc *string `json:"fc"` + Fs *string `json:"fs"` + DxScore int `json:"dx_score"` + DxRating float64 `json:"dx_rating"` + Rate string `json:"rate"` + Type string `json:"type"` + UploadTime time.Time `json:"upload_time"` + } `json:"data"` +} + +type LxnsMaimaiRequestUserReferBestSongIndex struct { + Success bool `json:"success"` + Code int `json:"code"` + Data struct { + Id int `json:"id"` + SongName string `json:"song_name"` + Level string `json:"level"` + LevelIndex int `json:"level_index"` + Achievements float64 `json:"achievements"` + Fc *string `json:"fc"` + Fs *string `json:"fs"` + DxScore int `json:"dx_score"` + DxRating float64 `json:"dx_rating"` + Rate string `json:"rate"` + Type string `json:"type"` + UploadTime time.Time `json:"upload_time"` + } `json:"data"` +} + // on tg, user use friendCode to bind info. // RequestBasicDataFromLxns @@ -164,7 +202,46 @@ func RequestB50DataByFriendCode(friendCode int64) LxnsMaimaiRequestB50 { return handlerData } -func ReCardRenderBase(data LxnsMaimaiRequestDataPiece, getNum int) image.Image { +func RequestReferSong(friendID int64, songID int64, isSD bool) LxnsMaimaiRequestUserReferBestSong { + var getReferType string + if isSD { + getReferType = "standard" + } else { + getReferType = "dx" + } + getData, err := web.RequestDataWithHeaders(web.NewDefaultClient(), "https://maimai.lxns.net/api/v0/maimai/player/"+strconv.FormatInt(friendID, 10)+"/bests?song_id="+strconv.FormatInt(songID, 10)+"&song_type="+getReferType, "GET", func(request *http.Request) error { + request.Header.Add("Authorization", os.Getenv("lxnskey")) + return nil + }, nil) + if err != nil { + return LxnsMaimaiRequestUserReferBestSong{Success: false} + } + var handlerData LxnsMaimaiRequestUserReferBestSong + json.Unmarshal(getData, &handlerData) + return handlerData +} + +func RequestReferSongIndex(friendID int64, songID int64, diff int64, isSD bool) LxnsMaimaiRequestUserReferBestSongIndex { + var getReferType string + if isSD { + getReferType = "standard" + } else { + getReferType = "dx" + } + getData, err := web.RequestDataWithHeaders(web.NewDefaultClient(), "https://maimai.lxns.net/api/v0/maimai/player/"+strconv.FormatInt(friendID, 10)+"/bests?song_id="+strconv.FormatInt(songID, 10)+"&song_type="+getReferType+"&level_index="+strconv.FormatInt(diff, 10), "GET", func(request *http.Request) error { + request.Header.Add("Authorization", os.Getenv("lxnskey")) + return nil + }, nil) + if err != nil { + return LxnsMaimaiRequestUserReferBestSongIndex{Success: false} + } + var handlerData LxnsMaimaiRequestUserReferBestSongIndex + json.Unmarshal(getData, &handlerData) + return handlerData +} + +// ReCardRenderBase This Function is same as cardRender, but it convert for LXNS Network Maimai. +func ReCardRenderBase(data LxnsMaimaiRequestDataPiece, getNum int, isSimpleRender bool) image.Image { getType := data.Type var CardBackGround string var multiTypeRender sync.WaitGroup @@ -231,7 +308,9 @@ func ReCardRenderBase(data LxnsMaimaiRequestDataPiece, getNum int) image.Image { drawBackGround.Fill() drawBackGround.SetFontFace(rankFont) drawBackGround.SetColor(diffColor[data.LevelIndex]) - drawBackGround.DrawString("#"+strconv.Itoa(getNum), 130, 111) + if !isSimpleRender { + drawBackGround.DrawString("#"+strconv.Itoa(getNum), 130, 111) + } drawBackGround.FillPreserve() // draw rest of card. drawBackGround.SetFontFace(levelFont) @@ -399,7 +478,7 @@ func ReFullPageRender(data LxnsMaimaiRequestB50, userData LxnsMaimaiRequestFromF getInitY := 285 var i int for i = 0; i < getSDLength; i++ { - b50Render.DrawImage(ReCardRenderBase(DataPiecesRepacked(data, true, i), i+1), getInitX, getInitY) + b50Render.DrawImage(ReCardRenderBase(DataPiecesRepacked(data, true, i), i+1, false), getInitX, getInitY) getInitX += 400 if getInitX == 2045 { getInitX = 45 @@ -408,7 +487,7 @@ func ReFullPageRender(data LxnsMaimaiRequestB50, userData LxnsMaimaiRequestFromF } for dx := 0; dx < getDXLength; dx++ { - b50Render.DrawImage(ReCardRenderBase(DataPiecesRepacked(data, false, dx), dx+1), getDXinitX, getDXinitY) + b50Render.DrawImage(ReCardRenderBase(DataPiecesRepacked(data, false, dx), dx+1, false), getDXinitX, getDXinitY) getDXinitX += 400 if getDXinitX == 2045 { getDXinitX = 45 diff --git a/plugin/mai/main.go b/plugin/mai/main.go index ac795ed..54665ee 100644 --- a/plugin/mai/main.go +++ b/plugin/mai/main.go @@ -3,21 +3,21 @@ package mai import ( "bytes" "encoding/json" - "image" - "math" - "net/http" - "os" - "strconv" - "strings" - - "github.com/MoYoez/Lucy_reibot/utils/toolchain" + "fmt" "github.com/FloatTech/floatbox/web" "github.com/FloatTech/gg" ctrl "github.com/FloatTech/zbpctrl" + "github.com/MoYoez/Lucy_reibot/utils/toolchain" rei "github.com/fumiama/ReiBot" tgba "github.com/go-telegram-bot-api/telegram-bot-api/v5" "github.com/tidwall/gjson" "github.com/wdvxdr1123/ZeroBot/utils/helper" + "image" + "math" + "net/http" + "os" + "strconv" + "strings" ) var engine = rei.Register("mai", &ctrl.Options[*rei.Ctx]{ @@ -215,6 +215,258 @@ func init() { ctx.SendPlainMessage(true, getCode) case getSplitStringList[1] == "raw" || getSplitStringList[1] == "file": MaimaiRenderBase(ctx, true) + case getSplitStringList[1] == "query": + if getSplitLength < 3 { + ctx.SendPlainMessage(true, "参数提供不足, /mai query [绿黄红紫白][dx|标] ") + return + } + // CASE: if User Trigger This command, check other settings. + // getQuery: + // level_index | song_type + getLength, getSplitInfo := toolchain.SplitCommandTo(getSplitStringList[2], 2) + userSettingInterface := map[string]string{} + var settedSongAlias string + + if getLength > 1 { // prefix judge. + settedSongAlias = getSplitInfo[1] + for i, returnLevelValue := range []string{"绿", "黄", "红", "紫", "白"} { + if strings.Contains(getSplitInfo[0], returnLevelValue) { + userSettingInterface["level_index"] = strconv.Itoa(i) + break + } + } + switch { + case strings.Contains(getSplitInfo[0], "dx"): + userSettingInterface["song_type"] = "dx" + case strings.Contains(getSplitInfo[0], "标"): + userSettingInterface["song_type"] = "standard" + } + } else { + // no other infos. || default setting ==> dx Master | std Master | dx expert | std expert (as the highest score) + settedSongAlias = getSplitInfo[0] + } + getSongs := RequestAliasFromLxns() + queryStatus, songID := getSongs.QueryReferSong(settedSongAlias) + if queryStatus == false { + ctx.SendPlainMessage(true, "未找到对应歌曲,可能是数据库未收录(") + return + } + // get SongID, render. + getUserID, _ := toolchain.GetChatUserInfoID(ctx) + // check the user is Lxns Service | DivingFish Service. + getBool := GetUserSwitcherInfoFromDatabase(getUserID) + // first read the config. + getLevelIndex := userSettingInterface["level_index"] + getSongType := userSettingInterface["song_type"] + var getReferIndexIsOn bool + if getLevelIndex != "" { // use custom diff + getReferIndexIsOn = true + } + + if getBool { // lxns service. + getFriendID := GetUserMaiFriendID(getUserID) + if getFriendID.MaimaiID == 0 { + ctx.SendPlainMessage(true, "没有绑定哦~ 使用/mai lxbind 以绑定") + return + } + if !getReferIndexIsOn { // no refer then return the last one. + var getReport LxnsMaimaiRequestUserReferBestSong + switch { + case getSongType == "standard": + getReport = RequestReferSong(getFriendID.MaimaiID, songID, true) + if getReport.Code == 404 { + ctx.SendPlainMessage(true, "没有发现 SD 谱面~ 如不确定可以忽略请求参数, Lucy会自动识别") + return + } + case getSongType == "dx": + getReport = RequestReferSong(getFriendID.MaimaiID, songID, false) + if getReport.Code != 404 { + ctx.SendPlainMessage(true, "没有发现 DX 谱面~ 如不确定可以忽略请求参数, Lucy会自动识别") + return + } + default: + getReport = RequestReferSong(getFriendID.MaimaiID, songID, false) + if getReport.Code != 200 { + getReport = RequestReferSong(getFriendID.MaimaiID, songID, true) + } + } + + getReturnTypeLength := len(getReport.Data) + if getReturnTypeLength == 0 { + ctx.SendPlainMessage(true, "Lucy 似乎没有查询到你的游玩数据呢(") + return + } + // DataGet, convert To MaiPlayData Render. + maiRenderPieces := LxnsMaimaiRequestDataPiece{ + Id: getReport.Data[len(getReport.Data)-1].Id, + SongName: getReport.Data[len(getReport.Data)-1].SongName, + Level: getReport.Data[len(getReport.Data)-1].Level, + LevelIndex: getReport.Data[len(getReport.Data)-1].LevelIndex, + Achievements: getReport.Data[len(getReport.Data)-1].Achievements, + Fc: getReport.Data[len(getReport.Data)-1].Fc, + Fs: getReport.Data[len(getReport.Data)-1].Fs, + DxScore: getReport.Data[len(getReport.Data)-1].DxScore, + DxRating: getReport.Data[len(getReport.Data)-1].DxRating, + Rate: getReport.Data[len(getReport.Data)-1].Rate, + Type: getReport.Data[len(getReport.Data)-1].Type, + UploadTime: getReport.Data[len(getReport.Data)-1].UploadTime, + } + getFinalPic := ReCardRenderBase(maiRenderPieces, 0, true) + _ = gg.NewContextForImage(getFinalPic).SavePNG(engine.DataFolder() + "save/" + "LXNS_PIC_" + strconv.Itoa(int(songID)) + "_" + strconv.Itoa(int(getUserID)) + ".png") + ctx.SendPhoto(tgba.FilePath(engine.DataFolder()+"save/"+"LXNS_PIC_"+strconv.Itoa(int(songID))+"_"+strconv.Itoa(int(getUserID))+".png"), true, "") + } else { + var getReport LxnsMaimaiRequestUserReferBestSongIndex + getLevelIndexToint, _ := strconv.ParseInt(getLevelIndex, 10, 64) + switch { + case getSongType == "standard": + getReport = RequestReferSongIndex(getFriendID.MaimaiID, songID, getLevelIndexToint, true) + if getReport.Code == 404 { + ctx.SendPlainMessage(true, "没有发现 SD 谱面~ 如不确定可以忽略请求参数, Lucy会自动识别") + return + } + case getSongType == "dx": + getReport = RequestReferSongIndex(getFriendID.MaimaiID, songID, getLevelIndexToint, false) + if getReport.Code != 404 { + ctx.SendPlainMessage(true, "没有发现 DX 谱面~ 如不确定可以忽略请求参数, Lucy会自动识别") + return + } + default: + getReport = RequestReferSongIndex(getFriendID.MaimaiID, songID, getLevelIndexToint, false) + if getReport.Code != 200 { + getReport = RequestReferSongIndex(getFriendID.MaimaiID, songID, getLevelIndexToint, true) + } + } + if getReport.Data.SongName == "" { // nil pointer. + ctx.SendPlainMessage(true, "Lucy 似乎没有查询到你的游玩数据呢(") + return + } + maiRenderPieces := LxnsMaimaiRequestDataPiece{ + Id: getReport.Data.Id, + SongName: getReport.Data.SongName, + Level: getReport.Data.Level, + LevelIndex: getReport.Data.LevelIndex, + Achievements: getReport.Data.Achievements, + Fc: getReport.Data.Fc, + Fs: getReport.Data.Fs, + DxScore: getReport.Data.DxScore, + DxRating: getReport.Data.DxRating, + Rate: getReport.Data.Rate, + Type: getReport.Data.Type, + UploadTime: getReport.Data.UploadTime, + } + getFinalPic := ReCardRenderBase(maiRenderPieces, 0, true) + _ = gg.NewContextForImage(getFinalPic).SavePNG(engine.DataFolder() + "save/" + "LXNS_PIC_" + strconv.Itoa(int(songID)) + "_" + strconv.Itoa(int(getUserID)) + ".png") + ctx.SendPhoto(tgba.FilePath(engine.DataFolder()+"save/"+"LXNS_PIC_"+strconv.Itoa(int(songID))+"_"+strconv.Itoa(int(getUserID))+".png"), true, "") + } + } else { + // diving fish checker: + getUsername := GetUserInfoNameFromDatabase(getUserID) + if getUsername == "" { + ctx.SendPlainMessage(true, "你还没有绑定呢!使用/mai bind 以绑定") + return + } + fullDevData := QueryDevDataFromDivingFish(getUsername) + // default setting ==> dx Master | std Master | dx expert | std expert (as the highest score) + var ReferSongTypeList []int + switch { + case getSongType == "standard": + for numPosition, index := range fullDevData.Records { + if index.Type == "SD" && index.SongId == int(songID) { + ReferSongTypeList = append(ReferSongTypeList, numPosition) + } + } + if len(ReferSongTypeList) == 0 { + ctx.SendPlainMessage(true, "没有发现游玩过的 SD 谱面~ 如不确定可以忽略请求参数, Lucy会自动识别") + return + } + case getSongType == "dx": + for numPosition, index := range fullDevData.Records { + var songIDStr string + switch { + case songID < 1000: + songIDStr = fmt.Sprintf("10%d", songID) + case songID > 1000: + songIDStr = fmt.Sprintf("1%d", songID) + } + + songIDs, _ := strconv.ParseInt(songIDStr, 10, 64) + if index.Type == "DX" && index.SongId == int(songIDs) { + ReferSongTypeList = append(ReferSongTypeList, numPosition) + } + } + if len(ReferSongTypeList) == 0 { + ctx.SendPlainMessage(true, "没有发现游玩过的 DX 谱面~ 如不确定可以忽略请求参数, Lucy会自动识别") + return + } + default: // no settings. + for numPosition, index := range fullDevData.Records { + if index.Type == "SD" && index.SongId == int(songID) { + ReferSongTypeList = append(ReferSongTypeList, numPosition) + } + } + + if len(ReferSongTypeList) == 0 { + var songIDStr string + switch { + case songID < 1000: + songIDStr = fmt.Sprintf("10%d", songID) + case songID > 1000: + songIDStr = fmt.Sprintf("1%d", songID) + } + + songIDs, _ := strconv.ParseInt(songIDStr, 10, 64) + + for numPosition, index := range fullDevData.Records { + if index.Type == "DX" && index.SongId == int(songIDs) { + ReferSongTypeList = append(ReferSongTypeList, numPosition) + // number, listPostion + } + } + } + if len(ReferSongTypeList) == 0 { + ctx.SendPlainMessage(true, "貌似没有发现你玩过这首歌曲呢(") + return + } + } + + if !getReferIndexIsOn { + // index a map == level_index = "record_diff" + levelIndexMap := map[int]string{} + for _, dataPack := range ReferSongTypeList { + levelIndexMap[fullDevData.Records[dataPack].LevelIndex] = strconv.Itoa(dataPack) + } + + var trulyReturnedData string + for i := 4; i >= 0; i-- { + if levelIndexMap[i] != "" { + trulyReturnedData = levelIndexMap[i] + break + } + } + + getNum, _ := strconv.Atoi(trulyReturnedData) + // getNum ==> 0 + returnPackage := fullDevData.Records[getNum] + _ = gg.NewContextForImage(RenderCard(returnPackage, 0, true)).SavePNG(engine.DataFolder() + "save/" + strconv.Itoa(int(songID)) + "_" + strconv.Itoa(int(getUserID)) + ".png") + ctx.SendPhoto(tgba.FilePath(engine.DataFolder()+"save/"+strconv.Itoa(int(songID))+"_"+strconv.Itoa(int(getUserID))+".png"), true, "") + } else { + levelIndexMap := map[int]string{} + for _, dataPack := range ReferSongTypeList { + levelIndexMap[fullDevData.Records[dataPack].LevelIndex] = strconv.Itoa(dataPack) + } + getDiff, _ := strconv.Atoi(userSettingInterface["level_index"]) + + if levelIndexMap[getDiff] != "" { + getNum, _ := strconv.Atoi(levelIndexMap[getDiff]) + returnPackage := fullDevData.Records[getNum] + _ = gg.NewContextForImage(RenderCard(returnPackage, 0, true)).SavePNG(engine.DataFolder() + "save/" + strconv.Itoa(int(songID)) + "_" + strconv.Itoa(int(getUserID)) + ".png") + ctx.SendPhoto(tgba.FilePath(engine.DataFolder()+"save/"+strconv.Itoa(int(songID))+"_"+strconv.Itoa(int(getUserID))+".png"), true, "") + } else { + ctx.SendPlainMessage(true, "貌似你没有玩过这个难度的曲子哦~") + } + } + } + default: ctx.SendPlainMessage(true, "未知的指令或者指令出现错误~") } @@ -338,7 +590,19 @@ func MaimaiRenderBase(ctx *rei.Ctx, israw bool) { } getImager, _ := ReFullPageRender(getGameUserData, getUserData, ctx) _ = gg.NewContextForImage(getImager).SavePNG(engine.DataFolder() + "save/" + "LXNS_" + strconv.Itoa(int(getUserID)) + ".png") - ctx.SendPhoto(tgba.FilePath(engine.DataFolder()+"save/"+"LXNS_"+strconv.Itoa(int(getUserID))+".png"), true, "") + if israw { + getDocumentType := &tgba.DocumentConfig{ + BaseFile: tgba.BaseFile{BaseChat: tgba.BaseChat{ + ChatID: ctx.Message.Chat.ID, + }, + File: tgba.FilePath(engine.DataFolder() + "save/" + "LXNS_" + strconv.Itoa(int(getUserID)) + ".png")}, + Caption: "", + CaptionEntities: nil, + } + ctx.Send(true, getDocumentType) + } else { + ctx.SendPhoto(tgba.FilePath(engine.DataFolder()+"save/"+"LXNS_"+strconv.Itoa(int(getUserID))+".png"), true, "") + } } else { // diving fish checker: getUsername := GetUserInfoNameFromDatabase(getUserID) @@ -382,7 +646,6 @@ func MaimaiSwitcherService(ctx *rei.Ctx) { } var getEventText string // due to it changed, so reverse. - // due to it changed, so reverse. if getBool == false { getEventText = "Lxns查分" } else { diff --git a/plugin/mai/req.go b/plugin/mai/req.go index 14a47a6..70a4b16 100644 --- a/plugin/mai/req.go +++ b/plugin/mai/req.go @@ -4,8 +4,10 @@ import ( "bytes" "encoding/json" "errors" + "github.com/FloatTech/floatbox/web" "io" "net/http" + "os" ) type DivingFishB50UserName struct { @@ -13,6 +15,29 @@ type DivingFishB50UserName struct { B50 bool `json:"b50"` } +type DivingFishDevFullDataRecords struct { + AdditionalRating int `json:"additional_rating"` + Nickname string `json:"nickname"` + Plate string `json:"plate"` + Rating int `json:"rating"` + Records []struct { + Achievements float64 `json:"achievements"` + Ds float64 `json:"ds"` + DxScore int `json:"dxScore"` + Fc string `json:"fc"` + Fs string `json:"fs"` + Level string `json:"level"` + LevelIndex int `json:"level_index"` + LevelLabel string `json:"level_label"` + Ra int `json:"ra"` + Rate string `json:"rate"` + SongId int `json:"song_id"` + Title string `json:"title"` + Type string `json:"type"` + } `json:"records"` + Username string `json:"username"` +} + func QueryMaiBotDataFromUserName(username string) (playerdata []byte, err error) { // packed json and sent. jsonStruct := DivingFishB50UserName{Username: username, B50: true} @@ -40,3 +65,16 @@ func QueryMaiBotDataFromUserName(username string) (playerdata []byte, err error) playerDataByte, err := io.ReadAll(resp.Body) return playerDataByte, err } + +func QueryDevDataFromDivingFish(username string) DivingFishDevFullDataRecords { + getData, err := web.RequestDataWithHeaders(web.NewDefaultClient(), "https://www.diving-fish.com/api/maimaidxprober/dev/player/records?username="+username, "GET", func(request *http.Request) error { + request.Header.Add("Developer-Token", os.Getenv("dvkey")) + return nil + }, nil) + if err != nil { + return DivingFishDevFullDataRecords{} + } + var handlerData DivingFishDevFullDataRecords + json.Unmarshal(getData, &handlerData) + return handlerData +} diff --git a/plugin/mai/struct.go b/plugin/mai/struct.go index 7c09bc5..61b8b91 100644 --- a/plugin/mai/struct.go +++ b/plugin/mai/struct.go @@ -15,10 +15,10 @@ import ( "sync" "unicode/utf8" - "github.com/MoYoez/Lucy_reibot/utils/toolchain" - "github.com/MoYoez/Lucy_reibot/utils/transform" "github.com/FloatTech/gg" "github.com/FloatTech/imgfactory" + "github.com/MoYoez/Lucy_reibot/utils/toolchain" + "github.com/MoYoez/Lucy_reibot/utils/transform" rei "github.com/fumiama/ReiBot" "golang.org/x/image/font" "golang.org/x/image/font/opentype" @@ -272,7 +272,7 @@ func FullPageRender(data player, ctx *rei.Ctx) (raw image.Image) { getInitY := 285 var i int for i = 0; i < getSDLength; i++ { - b50Render.DrawImage(RenderCard(data.Charts.Sd[i], i+1), getInitX, getInitY) + b50Render.DrawImage(RenderCard(data.Charts.Sd[i], i+1, false), getInitX, getInitY) getInitX += 400 if getInitX == 2045 { getInitX = 45 @@ -281,7 +281,7 @@ func FullPageRender(data player, ctx *rei.Ctx) (raw image.Image) { } for dx := 0; dx < getDXLength; dx++ { - b50Render.DrawImage(RenderCard(data.Charts.Dx[dx], dx+1), getDXinitX, getDXinitY) + b50Render.DrawImage(RenderCard(data.Charts.Dx[dx], dx+1, false), getDXinitX, getDXinitY) getDXinitX += 400 if getDXinitX == 2045 { getDXinitX = 45 @@ -291,8 +291,8 @@ func FullPageRender(data player, ctx *rei.Ctx) (raw image.Image) { return b50Render.Image() } -// RenderCard Main Lucy Render Page -func RenderCard(data playerData, num int) image.Image { +// RenderCard Main Lucy Render Page , if isSimpleRender == true, then render count will not show here. +func RenderCard(data playerData, num int, isSimpleRender bool) image.Image { getType := data.Type var CardBackGround string var multiTypeRender sync.WaitGroup @@ -367,7 +367,9 @@ func RenderCard(data playerData, num int) image.Image { drawBackGround.Fill() drawBackGround.SetFontFace(rankFont) drawBackGround.SetColor(diffColor[data.LevelIndex]) - drawBackGround.DrawString("#"+strconv.Itoa(num), 130, 111) + if isSimpleRender { + drawBackGround.DrawString("#"+strconv.Itoa(num), 130, 111) + } drawBackGround.FillPreserve() // draw rest of card. drawBackGround.SetFontFace(levelFont) diff --git a/qodana.yaml b/qodana.yaml new file mode 100644 index 0000000..215d808 --- /dev/null +++ b/qodana.yaml @@ -0,0 +1,29 @@ +#-------------------------------------------------------------------------------# +# Qodana analysis is configured by qodana.yaml file # +# https://www.jetbrains.com/help/qodana/qodana-yaml.html # +#-------------------------------------------------------------------------------# +version: "1.0" + +#Specify inspection profile for code analysis +profile: + name: qodana.starter + +#Enable inspections +#include: +# - name: + +#Disable inspections +#exclude: +# - name: +# paths: +# - + +#Execute shell command before Qodana execution (Applied in CI/CD pipeline) +#bootstrap: sh ./prepare-qodana.sh + +#Install IDE plugins before Qodana execution (Applied in CI/CD pipeline) +#plugins: +# - id: #(plugin id can be found at https://plugins.jetbrains.com) + +#Specify Qodana linter for analysis (Applied in CI/CD pipeline) +linter: jetbrains/qodana-go:latest