def exRecInfo(self, rec): """从rec api中提取信息""" mod = mods.getMod(rec['enabled_mods']) if 'NONE' in mod: mod.remove('NONE') ret = { "mods": ''.join(mod), "acc": mods.get_acc(rec['count300'], rec['count100'], rec['count50'], rec['countmiss']), "cb": rec['maxcombo'], "miss": rec['countmiss'] } return ret
def bbpOutFormat(self, bp5, ousname): """bbp输出格式化 """ s_msg = "%s's bp!!\n" % ousname for i,r in enumerate(bp5[0:5]): msg = 'bp{x},{pp}pp,{acc}%,{rank},+{mod}' c50 = float(r['count50']) c100 = float(r['count100']) c300 = float(r['count300']) cmiss = float(r['countmiss']) acc = round((c50*50+c100*100+c300*300)/(c50+c100+c300+cmiss)/300*100, 2) msg = msg.format( x=i+1, pp=round(float(r['pp'])), acc=acc,rank=r['rank'], mod=','.join(mods.getMod(int(r['enabled_mods']))) ) s_msg = s_msg + msg + '\n' return s_msg[:-1]
def get_rankinfo(uid, groupid, bid, hid=1, mod=-1): logging.info('查询用户[%s]'%uid) ret = score.hid_ranks(bid, groupid, hid, mod) o = osu_user.Osuer() if not ret: return '榜上一个成绩都没有!!! https://osu.ppy.sh/b/%s' % bid ret = ret[0] outstr = '%s(%s)-%s[%s]\n' % (ret['source'], ret['artist'], ret['title'], ret['version']) uids = [] for i,r in enumerate(json.loads(ret['rankjson'])[:10]): for k,v in r.items(): uid = k uids.append(uid) sco = v m = ','.join(mods.getMod(int(sco[5]))) outstr += '#%s {%s} %s分 [%sx] %s%% %s +%s\n' % (i+1, uid, sco[0], sco[1], sco[3], sco[4], m) res = o.get_usernames_by_uid(uids) for r in res: restr = '{%s}' % r['osuid'] outstr = outstr.replace(restr, r['osuname']) return outstr[:-1]
def osuV2stat(self, qq, groupid): rs = "" status, ret = self.getV2osuInfo(qq, groupid) if status < 0: return ret uid = ret["id"] grade_counts = ret['statistics']['grade_counts'] pp = ret['statistics']['pp'] pc = ret['statistics']['play_count'] acc = ret['statistics']['hit_accuracy'] username = ret["username"] join_time = ret['join_date'].split('T')[0] total_hits = ret["statistics"]["total_hits"] tth_pc_incr = int(total_hits / pc) total_hits_str = self.numberFormat2w(total_hits) tth_pc_incr_str = self.numberFormat2w(tth_pc_incr) play_time = ret["statistics"]["play_time"] play_days = play_time / 84600 play_hours = play_time % 84600 / 3600 if not ret['last_visit']: last_visit_str = '?' else: last_visit_f, last_visit_s = ret['last_visit'].split('T') last_visit_utc = '%s %s' % (last_visit_f, last_visit_s.split('+')[0]) last_visit = datetime.strptime( last_visit_utc, '%Y-%m-%d %H:%M:%S') + timedelta(hours=8) last_visit_str = datetime.strftime(last_visit, '%Y-%m-%d %H:%M') follower_count = ret["follower_count"] avatar = ret["avatar_url"] join_days = (datetime.now() - datetime.strptime(join_time, '%Y-%m-%d')).days pp_days_incr = round(float(pp) / join_days, 2) pc_days_incr = round(float(pc) / join_days, 2) # bp botIns = botHandler.botHandler() bpinfo = botIns.getRecBp(uid, "5") bp1 = bpinfo[0] c50, c100, c300, cmiss = int(bp1['count50']), int( bp1['count100']), int(bp1['count300']), int(bp1['countmiss']) bp1_acc = round((c50 * 50 + c100 * 100 + c300 * 300) / (c50 + c100 + c300 + cmiss) / 300 * 100, 2) bp1_mod = ','.join(mods.getMod(int(bp1['enabled_mods']))) bp1_pp = round(float(bp1['pp'])) bp1_rank = bp1['rank'] bp1_data = bp1['date'] bp1_bid = bp1['beatmap_id'] bp1_days = (datetime.now() - datetime.strptime(bp1_data, '%Y-%m-%d %H:%M:%S')).days if bp1_days > 365: bp1_days_str = '%s年前' % int(bp1_days / 365) elif bp1_days > 182: bp1_days_str = '半年前' elif bp1_days > 30: bp1_days_str = '%s个月前' % int(bp1_days / 30) else: bp1_days_str = '%s天前' % bp1_days # map bp1_mapInfo = botIns.getOsuBeatMapInfo(bp1_bid) bp1_stars = bp1_mapInfo["difficultyrating"][:3] rs += '{username}\n'.format(username=username) rs += '[CQ:image,cache=0,file={avatar}]\n'.format(avatar=avatar) rs += '{pp}pp ({pp_days_incr}/day)\n'.format(pp=int(pp), pp_days_incr=pp_days_incr) rs += '{pc}pc ({pc_days_incr}/day)\n'.format(pc=pc, pc_days_incr=pc_days_incr) rs += '{tth}tth ({tth_pc_incr}/pc)\n'.format( tth=total_hits_str, tth_pc_incr=tth_pc_incr_str) rs += '--------------------\n' rs += 'SS+({ssh}) | SS({ss}) | S+({sh}) | S({s}) | A({a})\n'.format( **grade_counts) rs += 'bp1: {pp}pp,{stars}*,{acc}%,+{mod}({d})\n'.format( pp=bp1_pp, acc=bp1_acc, mod=bp1_mod, d=bp1_days_str, stars=bp1_stars) rs += '--------------------\n' rs += '粉丝数: {follower_count}\n'.format(follower_count=follower_count) rs += '爆肝时长: {play_days}天{play_hours}小时\n'.format( play_days=int(play_days), play_hours=int(play_hours)) rs += '最后登录: {last_visit_str}\n'.format(last_visit_str=last_visit_str) rs += '注册时间: {join_time} ({join_days}天)'.format(join_time=join_time, join_days=join_days) return rs
def drawR(mapjson, rankjson, userjson): # skin bg_e = draw_data.check_bg(mapjson['beatmap_id'], mapjson['beatmapset_id']) bg = '%s.jpg' % mapjson['beatmap_id'] if bg_e else 'newgame_background.png' back_icon = 'menu-back-0.png' mod_icon = 'selection-mode.png' mods_icon = 'selection-mods.png' random_icon = 'selection-random.png' options_icon = 'selection-options.png' rank_x = 'ranking-%s-small.png' # ous ui songselecttop = 'songselect-top.png' uptips = 'selection-update.png' osu_icon = 'menu-osu.png' songselect_bottom = 'songselect-bottom.png' level_bar = 'levelbar.png' level_bar_bg = 'levelbar-bg.png' selection_approved = 'selection-approved.png' # 用户信息 uname = userjson.get('username', '') pp = f"{float(userjson.get('pp_raw', 0)):,.0f}" acc = round(float(userjson.get('accuracy', 0)), 2) lv = float(userjson.get('level', 0)) level = int(lv) lv_left = lv - level # 小数位,经验条 rank = userjson.get('pp_rank', 0) umod = 'mode-osu-small.png' #曲子信息 title = mapjson.get('title_unicode', '') source = mapjson.get('source', '') artist = mapjson.get('artist_unicode', '') version = mapjson.get('version', '') creator = mapjson.get('creator', '') bpm = mapjson.get('bpm', '') max_combo = mapjson.get('max_combo', '') difficultyrating = round(float(mapjson.get('difficultyrating', '')), 2) #stars diff_size = mapjson.get('diff_size', '') #CS diff_approach = mapjson.get('diff_approach', '') #AR diff_overall = mapjson.get('diff_overall', '') #OD diff_drain = mapjson.get('diff_drain', '') #HP count_normal = int(mapjson.get('count_normal', 0)) count_slider = int(mapjson.get('count_slider', 0)) count_spinner = int(mapjson.get('count_spinner', 0)) m, s = divmod(int(mapjson.get('total_length')), 60) h, m = divmod(m, 60) if h != 0: hit_length = "%02d:%02d:%02d" % (h, m, s) #sec else: hit_length = "%02d:%02d" % (m, s) #sec # 头像download uids = [list(r.keys())[0] for r in rankjson] check_uids = uids[:12] me = userjson.get('user_id', '') if me not in uids: check_uids.append(me) me_idx = -1 else: me_idx = uids.index(me) draw_data.check_img(check_uids) d = DrawRec() # 第一层bg # d.add_items(isresize=True, path='image/bg/default.jpg') d.add_items(isresize=True, path='image/bg/%s' % bg) # title黑层 d.add_items2(songselecttop) # 更新提示 # d.add_items2(uptips, 20, 200) # 低下大黑条 d.add_items2(songselect_bottom, 0, 648, isresize=True, width=1366, height=120) # 大粉饼 d.add_items2(osu_icon, 1130, 550, isresize=True, width=300, height=300) # 返回 d.add_items(back_icon, 10, 615) # mode d.add_items(mod_icon, 250, 678) # mods选择 d.add_items(mods_icon, 340, 678) # random d.add_items(random_icon, 430, 678) # options d.add_items(options_icon, 520, 678) # 头像 d.add_items(x=690, y=675, path='image/userimg/%s.jpg' % me, isresize=True, width=90, height=90) # 用户信息 d.add_items2(umod, 998, 670, factor=0.5) d.add_text(968, 710, '# %s' % rank, font_size=16, ttype='en') d.add_text(788, 670, uname, font_size=24, ttype='en') d.add_text(788, 700, 'Performance:%spp' % pp, font_size=16, ttype='en') d.add_text(788, 720, 'Accuracy:%s%%' % acc, font_size=16, ttype='en') d.add_text(788, 740, 'Lv:%s' % level, font_size=16, ttype='en') if lv_left > 0.1: d.add_items2(level_bar, 840, 745, isresize=True, width=int(lv_left * 200), height=14) d.add_items2(level_bar_bg, 840, 745) # 曲子信息 bid = mapjson['beatmap_id'] d.add_text(35, 0, '%s (%s) - %s [%s]' % (source, artist, title, version), font_size=25, ttype='cn') d.add_items2(selection_approved, 7, 3) d.add_text(40, 30, '作者: %s [bid: %s]' % (creator, bid), font_size=16, ttype='cn') d.add_text(5, 50, '长度: %s BPM: %s 物件数: %s' % (hit_length, bpm, count_normal + count_slider + count_spinner), font_size=18, ttype='cn') d.add_text(5, 75, '圈数: %s 滑条数: %s 转盘数: %s' % (count_normal, count_slider, count_spinner), font_size=16, ttype='cn') d.add_text( 5, 100, 'CS:%s AR:%s OD:%s HP:%s Star:%s★' % (diff_size, diff_approach, diff_overall, diff_drain, difficultyrating), font_size=16, ttype='en') bid = mapjson['beatmap_id'] d.add_text(1180, 30, f"bid: {bid}", font_size=25, ttype='en') # 榜区域 nums = len(uids) o = botHandler.botHandler() res = o.get_usernames_by_uid(uids) udict = {r['osuid']: r['osuname'] for r in res} if nums > 6: r1 = 6 r2 = nums - 6 else: r1 = nums r2 = 0 offset1 = 65 for i in range(r1): r = rankjson[i] u = uids[i] mds = int(r[u][5]) mds_l = mods.getMod(mds) m = ','.join(mds_l) if mds > 0 else '' rank = 'D' if r[u][4] == 'F' else r[u][4] d.draw_rectangle(x=20, y=160 + i * offset1, width=460, height=60, fill=(0, 0, 0, 50)) d.add_items(x=20, y=160 + i * offset1, path='image/userimg/%s.jpg' % u, isresize=True, width=60, height=60) d.add_items(rank_x % rank, 80, 170 + i * offset1) d.add_text(120, 160 + i * offset1, '%s' % (udict.get(u, 'None')), font_size=25, ttype='en') d.add_text(120, 190 + i * offset1, '得分: %s' % (format(int(r[u][0]), ',')), font_size=20, ttype='cn') d.add_text(300, 190 + i * offset1, '(%sx)' % (format(int(r[u][1]), ',')), font_size=20, ttype='en') d.add_text(450 - 20 * len(mds_l), 165 + i * offset1, '%s' % (m), font_size=20, ttype='en') d.add_text(400, 190 + i * offset1, '%s%%' % (r[u][3]), font_size=18, ttype='en') d.add_text(150, 550, '个人最佳成绩', font_size=24, ttype='cn') d.draw_rectangle(x=20, y=590, width=460, height=60, fill=(0, 0, 0, 50)) if me_idx != -1: r = rankjson[me_idx] u = uids[me_idx] mds = int(r[u][5]) mds_l = mods.getMod(mds) m = ','.join(mds_l) if mds > 0 else '' rank = 'D' if r[u][4] == 'F' else r[u][4] d.add_items(x=20, y=590, path='image/userimg/%s.jpg' % me, isresize=True, width=60, height=60) d.add_items(rank_x % rank, 80, 595) d.add_text(120, 590, '%s' % (udict.get(u, 'None')), font_size=25, ttype='en') d.add_text(120, 620, '得分: %s' % (format(int(r[u][0]), ',')), font_size=20, ttype='cn') d.add_text(300, 620, '(%sx)' % (format(int(r[u][1]), ',')), font_size=20, ttype='en') d.add_text(450 - 20 * len(mds_l), 600, '%s' % (m), font_size=20, ttype='en') d.add_text(410, 620, '%s%%' % (r[u][3]), font_size=18, ttype='en') else: d.add_text(130, 600, '你倒是快刚榜啊', font_size=25, ttype='cn') # copy for i in range(r2): if i == 6: break oi = i + 6 r = rankjson[oi] u = uids[oi] mds = int(r[u][5]) mds_l = mods.getMod(mds) m = ','.join(mds_l) if mds > 0 else '' rank = 'D' if r[u][4] == 'F' else r[u][4] d.draw_rectangle(x=620, y=160 + i * offset1, width=460, height=60, fill=(0, 0, 0, 50)) d.add_items(x=620, y=160 + i * offset1, path='image/userimg/%s.jpg' % u, isresize=True, width=60, height=60) d.add_items(rank_x % rank, 680, 170 + i * offset1) d.add_text(720, 160 + i * offset1, '%s' % (udict.get(u, 'None')), font_size=25, ttype='en') d.add_text(720, 190 + i * offset1, '得分: %s' % (format(int(r[u][0]), ',')), font_size=20, ttype='cn') d.add_text(900, 190 + i * offset1, '(%sx)' % (format(int(r[u][1]), ',')), font_size=20, ttype='en') d.add_text(1050 - 20 * len(mds_l), 165 + i * offset1, '%s' % (m), font_size=20, ttype='en') d.add_text(1010, 190 + i * offset1, '%s%%' % (r[u][3]), font_size=18, ttype='en') n = random.randint(0, 100) p = 'rank%s.png' % n pfs = 'rank%s-fs8.png' % n f = '/static/interbot/image/%s' % p d.save(f) # 压缩 os.system('pngquant -f %s' % f) logging.info('[%s]榜单生成成功!' % pfs) return pfs
def drawRec(mapjson, recinfo, bestinfo, userjson, debug=0, **kw): """ kwargs: pp, fcpp, acpp """ # skin bg_e = draw_data.check_bg(mapjson['beatmap_id'], mapjson['beatmapset_id']) bg = '%s.jpg'%mapjson['beatmap_id'] if bg_e else 'newgame_background.png' back_icon = 'menu-back-0.png' mod_icon = 'selection-mode.png' mods_icon = 'selection-mods.png' random_icon = 'selection-random.png' options_icon = 'selection-options.png' rank_x = 'ranking-%s-small.png' maxcb_icon = 'ranking-maxcombo.png' acc_icon = 'ranking-accuracy.png' ranking_icon = 'ranking-title.png' rank_icon = 'ranking-%s.png' replay_icon = 'ranking-replay.png' score_icon = 'score-%s.png' score_x_icon = 'score-x.png' score_pp_icon = 'score-p.png' # 自制p字母 score_dot_icon = 'score-dot.png' score_p_icon = 'score-percent.png' hit0_icon = 'hit0.png' hit50_icon = 'hit50.png' hit50k_icon = 'hit50k.png' hit100_icon = 'hit100.png' hit100k_icon = 'hit100k.png' mod_icon_map={ 'NF': 'selection-mod-nofail.png', 'EZ': 'selection-mod-easy.png', 'NV': 'selection-mod-random.png', # 这个未知 'HD': 'selection-mod-hidden.png', 'HR': 'selection-mod-hardrock.png', 'SD': 'selection-mod-suddendeath.png', 'DT': 'selection-mod-doubletime.png', 'Relax': 'selection-mod-relax.png', 'HT': 'selection-mod-halftime.png', 'NC': 'selection-mod-nightcore.png', 'FL': 'selection-mod-flashlight.png', 'AT': 'selection-mod-autoplay.png', 'SO': 'selection-mod-spunout.png', 'AP': 'selection-mod-relax2.png', 'PF': 'selection-mod-perfect.png', } # ous ui songselecttop = 'songselect-top.png' uptips = 'selection-update.png' osu_icon = 'menu-osu.png' songselect_bottom = 'songselect-bottom.png' level_bar = 'levelbar.png' level_bar_bg = 'levelbar-bg.png' selection_approved = 'selection-approved.png' # 用户信息 uname = userjson.get('username', '') pp = f"{float(userjson.get('pp_raw', 0)):,.0f}" acc = round(float(userjson.get('accuracy', 0)), 2) lv = float(userjson.get('level', 0)) level = int(lv) lv_left = lv - level # 小数位,经验条 rank = userjson.get('pp_rank', 0) umod = 'mode-osu-small.png' #曲子信息 title = mapjson.get('title_unicode','') source = mapjson.get('source','') artist = mapjson.get('artist_unicode','') version = mapjson.get('version','') creator = mapjson.get('creator','') bpm = kw['bpm'] if kw.get("bpm") else mapjson.get('bpm','') max_combo = mapjson.get('max_combo','') difficultyrating = kw['star'] if kw.get("star") else round(float(mapjson.get('difficultyrating','')),2) #star diff_size = kw['cs'] if kw.get("cs") else mapjson.get('diff_size','') #CS diff_approach = kw['ar'] if kw.get("ar") else mapjson.get('diff_approach','') #AR diff_overall = kw['od'] if kw.get("od") else mapjson.get('diff_overall','') #OD diff_drain = kw['hp'] if kw.get("hp") else mapjson.get('diff_drain','') #HP count_normal = int(mapjson.get('count_normal', 0)) count_slider = int(mapjson.get('count_slider', 0)) count_spinner = int(mapjson.get('count_spinner', 0)) m, s = divmod(int(mapjson.get('total_length')), 60) h, m = divmod(m, 60) if h != 0: hit_length = "%02d:%02d:%02d" % (h, m, s) #sec else: hit_length = "%02d:%02d" % (m, s) #sec # 头像download me = userjson.get('user_id', '') draw_data.check_img([me], isup=1) skin_idx = random.randint(1, len(skin_map)) conf = skin_map[skin_idx] d = drawRank.DrawRec(skin=conf["path"]) # 第一层bg d.add_items(isresize=True, path='image/bg/%s'%bg, factor=0.95) # title黑层 d.add_items2(songselecttop) # 低下大黑条 d.add_items2(songselect_bottom, 0, 648, isresize=True, width=1366, height=120) # 大粉饼 d.add_items2(osu_icon, 1130, 550, isresize=True, width=300, height=300) # 返回 d.add_items(back_icon, 10, 615) # 设置项 d.add_items(mod_icon, 250, 678) # mode d.add_items(mods_icon, 340, 678) # mods选择 d.add_items(random_icon, 430, 678) # random d.add_items(options_icon, 520, 678) # options # 头像 d.add_items(x=690, y=675, path='image/userimg/%s.jpg'%me, isresize=True, width=90, height=90) # 用户信息 d.add_items2(umod, 998, 670, factor=0.5) d.add_text(968, 710, '# %s'%rank, font_size=16, ttype='en') d.add_text(788, 670, uname, font_size=24, ttype='en') d.add_text(788, 700, 'Performance:%spp'%pp, font_size=16, ttype='en') d.add_text(788, 720, 'Accuracy:%s%%'%acc, font_size=16, ttype='en') d.add_text(788, 740, 'Lv%s'%level, font_size=16, ttype='en') if lv_left > 0.1: d.add_items2(level_bar, 840, 745, isresize=True, width=int(lv_left*200), height=14) d.add_items2(level_bar_bg, 840, 745) # 曲子信息 bid = mapjson['beatmap_id'] d.add_text(35, 0, '%s (%s) - %s [%s]'%(source,artist,title,version), font_size=25, ttype='cn') d.add_items2(selection_approved, 7, 3) d.add_text(40, 30, '作者: %s [bid: %s]'%(creator, bid), font_size=16, ttype='cn') d.add_text(5, 50, '长度: %s BPM: %s 物件数: %s'%(hit_length,bpm,count_normal+count_slider+count_spinner), font_size=18, ttype='cn') d.add_text(5, 75, '圈数: %s 滑条数: %s 转盘数: %s'%(count_normal,count_slider,count_spinner), font_size=16, ttype='cn') d.add_text(5, 100, 'CS:%s AR:%s OD:%s HP:%s Star:%s★'%(diff_size,diff_approach,diff_overall,diff_drain,difficultyrating), font_size=16, ttype='en') # 个人最佳成绩区域 d.add_text(150, 550, '个人最佳成绩', font_size=24, ttype='cn') d.draw_rectangle(x=20, y=590, width=460, height=60, fill=(0, 0, 0, 90)) mds = int(bestinfo['enabled_mods']) mds_l = mods.getMod(mds) if 'NONE' in mds_l: mds_l.remove('NONE') m_str = ','.join(mds_l) if mds > 0 else '' rank = 'D' if bestinfo['rank'] == 'F' else bestinfo['rank'] d.add_items(x=20, y=590, path='image/userimg/%s.jpg'%me, isresize=True, width=60, height=60) d.add_items(rank_x%rank, 80, 595) d.add_text(120, 590, f"{uname} #{round(float(bestinfo.get('pp', kw['pp'])))}pp", font_size=25, ttype='en') d.add_text(120, 620, f"得分: {int(bestinfo['score']):,} ({int(bestinfo['maxcombo']):,}x)", font_size=20, ttype='cn') d.add_text(450-20*len(mds_l), 597, '%s'%(m_str), font_size=20, ttype='en') acc = mods.get_acc(bestinfo['count300'], bestinfo['count100'], bestinfo['count50'], bestinfo['countmiss']) d.add_text(410, 620, f"{acc:.2f}%", font_size=18, ttype='en') # 当前成绩区域 d.draw_rectangle(x=20, y=160, width=600, height=60, fill=(0, 0, 0, 90)) d.draw_rectangle(x=20, y=240, width=600, height=300, fill=(0, 0, 0, 90)) # 分数icon d.add_items(hit100_icon, 40, **conf["hit100_icon"]) d.add_items(hit50_icon, 40, **conf["hit50_icon"]) d.add_items(hit100k_icon, 350, **conf["hit100k_icon"]) d.add_items(hit0_icon, **conf["hit0_icon"]) d.add_items(maxcb_icon, 40, 440) d.add_items(acc_icon, 330, 440) # score for idx, s in enumerate(recinfo['score'][::-1]): d.add_items(score_icon%s, 550-50*idx, 170) for idx, s in enumerate(recinfo['count300']+'x'): d.add_items(score_icon%s, 180+idx*35, 260) for idx, s in enumerate(recinfo['count100']+'x'): d.add_items(score_icon%s, 180+idx*35, 320) for idx, s in enumerate(recinfo['count50']+'x'): d.add_items(score_icon%s, 180+idx*35, 380) for idx, s in enumerate(recinfo['countgeki']+'x'): d.add_items(score_icon%s, 490+idx*35, 260) for idx, s in enumerate(recinfo['countkatu']+'x'): d.add_items(score_icon%s, 490+idx*35, 320) for idx, s in enumerate(recinfo['countmiss']+'x'): d.add_items(score_icon%s, 490+idx*35, 380) # cb for idx, s in enumerate(recinfo['maxcombo']+'x'): d.add_items(score_icon%s, 60+idx*35, 480) # acc acc2 = mods.get_acc(recinfo['count300'], recinfo['count100'], recinfo['count50'], recinfo['countmiss']) acc_str = str(round(acc2, 2)) acc_start_x = 360 for idx, s in enumerate(acc_str): if s == '.': d.add_items(score_dot_icon, acc_start_x+idx*35, 480) acc_start_x -= 10 # 去掉间隙 else: d.add_items(score_icon%s, acc_start_x+idx*35, 480) if idx + 1 == len(acc_str): d.add_items(score_p_icon, acc_start_x+idx*35+35, 480) mds2 = int(recinfo['enabled_mods']) mds_l2 = mods.getMod(mds2) if 'NONE' in mds_l2: mds_l2.remove('NONE') rank2 = 'D' if recinfo['rank'] == 'F' else recinfo['rank'] # d.add_text(1180, 30, f"bid: {bid}", font_size=25, ttype='en') d.add_items(ranking_icon, 1000, 10) # 右上角 ranking d.add_items(replay_icon, 920, 470, factor=0.8) # replay d.add_items(rank_icon%rank2, 920, 100) # 评分 # mod for idx, mod in enumerate(mds_l2[::-1]): m_icon = mod_icon_map.get(mod) if not m_icon: continue d.add_items(m_icon, 1190-70*idx, 390) # pp区域 d.draw_rectangle(x=640, y=590, width=460, height=60, fill=(0, 0, 0, 90)) d.add_items(score_pp_icon, 650, 600) for idx, s in enumerate(str(round(kw["pp"]))): d.add_items(score_icon%s, 710+idx*30, 600) for idx, s in enumerate(str(round(kw["fcpp"]))): d.add_items(score_icon%s, 840+idx*30, 600) for idx, s in enumerate(str(round(kw["acpp"]))): d.add_items(score_icon%s, 980+idx*30, 600) if debug: d.RecImg.show() return "" else: uid = userjson.get('user_id', '') p = 'rctpp-%s.png' % uid pfs = 'rctpp-%s-fs8.png' % uid f = '/static/interbot/image/tmp/%s' % p d.save(f) # 压缩 os.system('pngquant -f %s' % f) logging.info('[%s]成绩生成成功!' % pfs) return pfs