nonebot-plugin-osubot 6.20.0__py3-none-any.whl → 6.21.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of nonebot-plugin-osubot might be problematic. Click here for more details.
- nonebot_plugin_osubot/api.py +1 -0
- nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/PalpableCatchHitObject.js +21 -2
- nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/bananashower.js +1 -0
- nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/catch.js +66 -14
- nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/juicestream.js +6 -1
- nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/curve.js +21 -1
- nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/slider.js +2 -0
- nonebot_plugin_osubot/draw/score.py +198 -141
- nonebot_plugin_osubot/draw/static.py +3 -2
- nonebot_plugin_osubot/draw/utils.py +17 -2
- nonebot_plugin_osubot/matcher/utils.py +6 -4
- nonebot_plugin_osubot/osufile/pfm_ctb.png +0 -0
- nonebot_plugin_osubot/osufile/pfm_mania.png +0 -0
- nonebot_plugin_osubot/osufile/pfm_std.png +0 -0
- nonebot_plugin_osubot/osufile/pfm_taiko.png +0 -0
- {nonebot_plugin_osubot-6.20.0.dist-info → nonebot_plugin_osubot-6.21.0.dist-info}/METADATA +1 -1
- {nonebot_plugin_osubot-6.20.0.dist-info → nonebot_plugin_osubot-6.21.0.dist-info}/RECORD +18 -18
- {nonebot_plugin_osubot-6.20.0.dist-info → nonebot_plugin_osubot-6.21.0.dist-info}/WHEEL +0 -0
nonebot_plugin_osubot/api.py
CHANGED
|
@@ -170,6 +170,7 @@ async def get_user_scores(
|
|
|
170
170
|
return all_scores[:limit]
|
|
171
171
|
|
|
172
172
|
elif source == "ppysb":
|
|
173
|
+
limit = min(limit, 100)
|
|
173
174
|
url = f"https://api.ppy.sb/v1/get_player_scores?scope={scope}&id={uid}&mode={FGM[mode]}&limit={limit}&include_failed={int(include_failed)}"
|
|
174
175
|
data = await make_request(url, {}, "未找到该玩家BP")
|
|
175
176
|
data = ScoresResponse(**data)
|
|
@@ -6,8 +6,24 @@ function PalpableCatchHitObject(data, beatmap) {
|
|
|
6
6
|
this.color = data.color;
|
|
7
7
|
this.radius = data.radius;
|
|
8
8
|
this.hyperDash = false;
|
|
9
|
+
this.edge = false;
|
|
9
10
|
this.XDistToNext = [1, 1, 1];
|
|
11
|
+
this.hitSound = data.hitSound || "0";
|
|
10
12
|
}
|
|
13
|
+
|
|
14
|
+
PalpableCatchHitObject.prototype.getHitsoundLabel = function (){
|
|
15
|
+
let hsLabels = [];
|
|
16
|
+
if (this.hitSound == null || this.hitSound == undefined || !this.hitSound) // hs = null | undifined | "" | "0"
|
|
17
|
+
return null;
|
|
18
|
+
else {
|
|
19
|
+
if (this.hitSound & 2) hsLabels.push("W");
|
|
20
|
+
if (this.hitSound & 8) hsLabels.push("C");
|
|
21
|
+
if (this.hitSound & 4) hsLabels.push("F");
|
|
22
|
+
if (hsLabels.length === 0) return null;
|
|
23
|
+
return hsLabels.join("|");
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
11
27
|
PalpableCatchHitObject.prototype.draw = function (time, ctx) {
|
|
12
28
|
var dt = this.time - time;
|
|
13
29
|
if (dt >= -this.beatmap.FALLOUT_TIME) {
|
|
@@ -24,7 +40,10 @@ PalpableCatchHitObject.prototype.draw2 = function (obj, SCALE, ctx, BORDER_WIDTH
|
|
|
24
40
|
if (this.hyperDash) this.drawDashCircle2({ x: obj.x + BORDER_WIDTH, y: obj.y + BORDER_HEIGHT }, SCALE, ctx);
|
|
25
41
|
this.drawCircle2({ x: obj.x + BORDER_WIDTH, y: obj.y + BORDER_HEIGHT }, SCALE, ctx);
|
|
26
42
|
}
|
|
27
|
-
if (combo)
|
|
43
|
+
if (combo) {
|
|
44
|
+
if (typeof(combo) === "number") this.drawCombo2({ x: obj.x + BORDER_WIDTH, y: obj.y + BORDER_HEIGHT }, SCALE, "x" + combo, ctx);
|
|
45
|
+
else this.drawCombo2({ x: obj.x + BORDER_WIDTH, y: obj.y + BORDER_HEIGHT }, SCALE, combo, ctx);
|
|
46
|
+
}
|
|
28
47
|
}
|
|
29
48
|
PalpableCatchHitObject.prototype.predraw2 = function (SCREENSHEIGHT, COLMARGIN, SCALE, offset) {
|
|
30
49
|
// 去除offset
|
|
@@ -83,7 +102,7 @@ PalpableCatchHitObject.prototype.drawCombo2 = function (position, SCALE, combo,
|
|
|
83
102
|
ctx.font = "normal 16px 'Segoe UI'";
|
|
84
103
|
ctx.textBaseline = "middle";
|
|
85
104
|
ctx.textAlign = "start";
|
|
86
|
-
ctx.fillText(
|
|
105
|
+
ctx.fillText(combo, position.x + this.radius * SCALE * 2, position.y);
|
|
87
106
|
ctx.restore();
|
|
88
107
|
};
|
|
89
108
|
PalpableCatchHitObject.prototype.drawBanana = function (position, ctx) {
|
|
@@ -150,6 +150,7 @@ function Catch(osu, mods) {
|
|
|
150
150
|
x: hitObject.position.x,
|
|
151
151
|
color: hitObject.color,
|
|
152
152
|
radius: this.circleRadius,
|
|
153
|
+
hitSound: hitObject.hitSound,
|
|
153
154
|
}, this);
|
|
154
155
|
|
|
155
156
|
this.palpableObjects.push(pch);
|
|
@@ -289,6 +290,8 @@ function Catch(osu, mods) {
|
|
|
289
290
|
else {
|
|
290
291
|
lastExcess = Math.clamp(distanceToHyper, 0, this.halfCatcherWidth);
|
|
291
292
|
//this.whiteDashes.push({ score: distanceToHyper, time: currentObject.time });
|
|
293
|
+
// 标注再加20像素就变红果的白果跳
|
|
294
|
+
if (distanceToNext > 2 * this.halfCatcherWidth && distanceToHyper < 20) currentObject.edge = true;
|
|
292
295
|
}
|
|
293
296
|
|
|
294
297
|
lastDirection = thisDirection;
|
|
@@ -357,7 +360,7 @@ Catch.prototype.draw = function (time, ctx) {
|
|
|
357
360
|
/**
|
|
358
361
|
* @param {number} SCALE 缩放大小(0.2=缩放为1/5)
|
|
359
362
|
* @param {number} SPEED 播放速度 DT=1.5 HT=0.75 在ctb不影响谱面,只影响时间和BPM标注
|
|
360
|
-
* @param {{
|
|
363
|
+
* @param {{showLabelType: number, distanceStart: number, distanceEnd: number, distanceType: number}} params 其他参数
|
|
361
364
|
*/
|
|
362
365
|
Catch.prototype.draw2 = function (SCALE, SPEED = 1, params = {}) {
|
|
363
366
|
// 初定每一列20个屏幕大小,不够换列
|
|
@@ -405,7 +408,7 @@ Catch.prototype.draw2 = function (SCALE, SPEED = 1, params = {}) {
|
|
|
405
408
|
if (this.TimingPoints[i].kiai) lastKiaiStart = this.TimingPoints[i].time - offset;
|
|
406
409
|
}
|
|
407
410
|
// 绿线在ctb无关紧要,正常模式不用加,标注距离时只加变化的
|
|
408
|
-
if (params.
|
|
411
|
+
if (params.showLabelType === 1) {
|
|
409
412
|
if (this.TimingPoints[i].parent) {
|
|
410
413
|
if (Math.abs(this.TimingPoints[i].sliderVelocity - lastSV) < 0.001) {
|
|
411
414
|
lastSV = this.TimingPoints[i].sliderVelocity;
|
|
@@ -670,25 +673,69 @@ Catch.prototype.draw2 = function (SCALE, SPEED = 1, params = {}) {
|
|
|
670
673
|
// 按总物件数/时间控制密度
|
|
671
674
|
let totalTime = this.fullCatchObjects[this.fullCatchObjects.length - 1].time - this.fullCatchObjects[0].time;
|
|
672
675
|
if (this.fullCatchObjects.length * 1000 / totalTime > 2) comboSplit = Math.ceil(this.fullCatchObjects.length * 1000 / totalTime) * 10;
|
|
673
|
-
// 按0.5
|
|
674
|
-
let roundBy = Math.pow(10, comboSplit.toString().length) * 0.5;
|
|
676
|
+
// 按0.5*(10^(位数-1&&最小为2))修约 60=>50 270=>250 820=>800 1434=>1500 1834=>2000
|
|
677
|
+
let roundBy = Math.pow(10, Math.max(comboSplit.toString().length - 1, 2)) * 0.5;
|
|
675
678
|
comboSplit = Math.round(comboSplit / roundBy) * roundBy;
|
|
679
|
+
if (comboSplit <= 0) comboSplit = 20;
|
|
676
680
|
for (let i = 0; i < this.fullCatchObjects.length; i++) {
|
|
677
681
|
let showCombo = null;
|
|
678
682
|
if (objs[i].type === "Fruit" || objs[i].type === "Droplet") {
|
|
679
683
|
combo += 1;
|
|
680
684
|
}
|
|
681
685
|
// 借用combo位显示距离,省事!
|
|
682
|
-
if (params.
|
|
686
|
+
if (params.showLabelType === 1) {
|
|
683
687
|
if (objs[i].type === "Fruit" || objs[i].type === "Droplet") {
|
|
684
688
|
let distanceType = params.distanceType;
|
|
685
689
|
if (this.fullCatchObjects[i].XDistToNext[distanceType] >= params.distanceStart && this.fullCatchObjects[i].XDistToNext[distanceType] <= params.distanceEnd)
|
|
686
690
|
showCombo = this.fullCatchObjects[i].XDistToNext[distanceType];
|
|
687
691
|
}
|
|
688
692
|
}
|
|
693
|
+
// 借用combo位显示音效,省事!
|
|
694
|
+
else if (params.showLabelType === 2) {
|
|
695
|
+
if (objs[i].type === "Fruit" || objs[i].type === "Banana") {
|
|
696
|
+
showCombo = this.fullCatchObjects[i].getHitsoundLabel();
|
|
697
|
+
}
|
|
698
|
+
}
|
|
689
699
|
|
|
690
|
-
else if (combo > lastCombo && combo > 0 && combo % comboSplit === 0) showCombo = combo;
|
|
700
|
+
else if (combo > lastCombo && combo > 0 && (combo % comboSplit === 0 || this.fullCatchObjects[i].edge)) showCombo = combo;
|
|
691
701
|
this.fullCatchObjects[i].draw2(objs[i], SCALE, ctx2, BORDER_WIDTH, BORDER_HEIGHT, showCombo);
|
|
702
|
+
|
|
703
|
+
// 标注edge
|
|
704
|
+
if (this.fullCatchObjects[i].edge && i < this.fullCatchObjects.length - 1) {
|
|
705
|
+
ctx2.save();
|
|
706
|
+
ctx2.beginPath();
|
|
707
|
+
let _x1 = objs[i].x + BORDER_WIDTH;
|
|
708
|
+
let _y1 = objs[i].y + BORDER_HEIGHT;
|
|
709
|
+
let _x2 = objs[i+1].x + BORDER_WIDTH;
|
|
710
|
+
let _y2 = objs[i+1].y + BORDER_HEIGHT;
|
|
711
|
+
if (_y1 > _y2) {
|
|
712
|
+
ctx2.moveTo(_x1, _y1);
|
|
713
|
+
ctx2.lineTo(_x2, _y2);
|
|
714
|
+
}
|
|
715
|
+
// 不在同一轨道上
|
|
716
|
+
else if (_y1 < _y2) {
|
|
717
|
+
let line_end_x2 = _x2 - Beatmap.WIDTH * SCALE - 2 * COLMARGIN;
|
|
718
|
+
let line_end_y2 = _y2 + 2 * BORDER_HEIGHT - height;
|
|
719
|
+
let line_middle_y2 = BORDER_HEIGHT;
|
|
720
|
+
let line_middle_x2 = (line_end_x2 - _x1) * (line_end_y2 - line_middle_y2) / (_y1 - line_end_y2) + line_end_x2;
|
|
721
|
+
if (line_middle_x2) {
|
|
722
|
+
ctx2.moveTo(_x1, _y1);
|
|
723
|
+
ctx2.lineTo(line_middle_x2, line_middle_y2);
|
|
724
|
+
}
|
|
725
|
+
let line_start_x1 = _x1 + Beatmap.WIDTH * SCALE + 2 * COLMARGIN;
|
|
726
|
+
let line_start_y1 = _y1 + height - 2 * BORDER_HEIGHT;
|
|
727
|
+
let line_middle_y1 = height - BORDER_HEIGHT;
|
|
728
|
+
let line_middle_x1 = (_x2 - line_start_x1) * (_y2 - line_middle_y1) / (line_start_y1 - _y2) + _x2;
|
|
729
|
+
if (line_middle_x1) {
|
|
730
|
+
ctx2.moveTo(line_middle_x1, line_middle_y1);
|
|
731
|
+
ctx2.lineTo(_x2, _y2);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
ctx2.strokeStyle = '#fff';
|
|
735
|
+
ctx2.lineWidth = 3;
|
|
736
|
+
ctx2.stroke();
|
|
737
|
+
}
|
|
738
|
+
|
|
692
739
|
lastCombo = combo;
|
|
693
740
|
}
|
|
694
741
|
|
|
@@ -698,18 +745,23 @@ Catch.prototype.draw2 = function (SCALE, SPEED = 1, params = {}) {
|
|
|
698
745
|
extraBarTimes.map((_barTime) => {
|
|
699
746
|
let _objs = objs.filter((obj) => Math.abs(obj.time - _barTime * 1000) < EDGE_OFFSET);
|
|
700
747
|
_objs.map((_obj) => {
|
|
701
|
-
let
|
|
702
|
-
|
|
703
|
-
|
|
748
|
+
let label = null;
|
|
749
|
+
if (params.showLabelType === 1) {
|
|
750
|
+
let distanceType = params.distanceType;
|
|
751
|
+
label = this.fullCatchObjects[_obj.index].XDistToNext[distanceType];
|
|
752
|
+
if (label < params.distanceStart || label > params.distanceEnd) label = null;
|
|
753
|
+
}
|
|
754
|
+
else if (params.showLabelType === 2) {
|
|
755
|
+
label = this.fullCatchObjects[_obj.index].getHitsoundLabel();
|
|
756
|
+
}
|
|
757
|
+
|
|
704
758
|
if (_obj.y > SCREENSHEIGHT * SCALE - 5) {
|
|
705
759
|
// note靠近下边缘,在上一列的上边缘再画一个
|
|
706
|
-
|
|
707
|
-
else this.fullCatchObjects[_obj.index].draw2({ time: _obj.time, type: _obj.type, x: _obj.x - (Beatmap.WIDTH * SCALE + 2 * COLMARGIN), y: 0, col: _obj.col - 1 }, SCALE, ctx2, BORDER_WIDTH, BORDER_HEIGHT);
|
|
760
|
+
this.fullCatchObjects[_obj.index].draw2({ time: _obj.time, type: _obj.type, x: _obj.x - (Beatmap.WIDTH * SCALE + 2 * COLMARGIN), y: 0, col: _obj.col - 1 }, SCALE, ctx2, BORDER_WIDTH, BORDER_HEIGHT, label);
|
|
708
761
|
}
|
|
709
762
|
else if (_obj.y < 5) {
|
|
710
763
|
// note靠近上边缘,在下一列的下边缘再画一个
|
|
711
|
-
|
|
712
|
-
else this.fullCatchObjects[_obj.index].draw2({ time: _obj.time, type: _obj.type, x: _obj.x + (Beatmap.WIDTH * SCALE + 2 * COLMARGIN), y: SCREENSHEIGHT * SCALE, col: _obj.col + 1 }, SCALE, ctx2, BORDER_WIDTH, BORDER_HEIGHT);
|
|
764
|
+
this.fullCatchObjects[_obj.index].draw2({ time: _obj.time, type: _obj.type, x: _obj.x + (Beatmap.WIDTH * SCALE + 2 * COLMARGIN), y: SCREENSHEIGHT * SCALE, col: _obj.col + 1 }, SCALE, ctx2, BORDER_WIDTH, BORDER_HEIGHT, label);
|
|
713
765
|
}
|
|
714
766
|
});
|
|
715
767
|
});
|
|
@@ -748,4 +800,4 @@ Catch.prototype.processProgressBar = function (ctx, totalTime) {
|
|
|
748
800
|
ctx.fillRect(ctxwidth * time / totalTime, 0, ctxwidth * (endtime - time) / totalTime, ctxheight);
|
|
749
801
|
}
|
|
750
802
|
}
|
|
751
|
-
};
|
|
803
|
+
};
|
|
@@ -6,12 +6,14 @@ function JuiceStream(data, beatmap)
|
|
|
6
6
|
this.sliderType = this.points[0];
|
|
7
7
|
this.points[0] = this.position;
|
|
8
8
|
for (var i = 1; i < this.points.length; i++)
|
|
9
|
-
{
|
|
9
|
+
{
|
|
10
10
|
this.points[i] = new Point(this.points[i].split(':'));
|
|
11
11
|
}
|
|
12
12
|
this.repeat = data[6] | 0;
|
|
13
13
|
this.pixelLength = +data[7];
|
|
14
14
|
|
|
15
|
+
this.hitSounds = this.hitSoundString.split('|');
|
|
16
|
+
|
|
15
17
|
this.timingPoint = this.beatmap.timingPointAt(this.time);
|
|
16
18
|
this.beatLength = this.timingPoint.beatLength;
|
|
17
19
|
this.timingPointStart = this.timingPoint.time;
|
|
@@ -99,6 +101,7 @@ JuiceStream.prototype.generateTicks = function(spanIndex, spanStartTime, spanDur
|
|
|
99
101
|
JuiceStream.prototype.buildNested = function() {
|
|
100
102
|
this.nested = [];
|
|
101
103
|
|
|
104
|
+
let nestedIndex = 0;
|
|
102
105
|
let lastEvent = null;
|
|
103
106
|
for(let i = 0; i < this.events.length; i++) {
|
|
104
107
|
// generate tiny droplets since the last point
|
|
@@ -151,7 +154,9 @@ JuiceStream.prototype.buildNested = function() {
|
|
|
151
154
|
x: this.curve.pointAt(this.events[i].pathProgress).x,
|
|
152
155
|
color: this.color,
|
|
153
156
|
radius: this.beatmap.circleRadius,
|
|
157
|
+
hitSound: this.hitSounds[nestedIndex] || "0",
|
|
154
158
|
}, this.beatmap));
|
|
159
|
+
nestedIndex++;
|
|
155
160
|
break;
|
|
156
161
|
}
|
|
157
162
|
}
|
|
@@ -21,5 +21,25 @@ Curve.parse = function(sliderType, points, pixelLength)
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
catch(e) {}
|
|
24
|
-
|
|
24
|
+
try
|
|
25
|
+
{
|
|
26
|
+
return new LinearBezier(points, pixelLength, sliderType == 'L');
|
|
27
|
+
}
|
|
28
|
+
catch(e)
|
|
29
|
+
{
|
|
30
|
+
return new SingleNoteCurve(points[0]);
|
|
31
|
+
}
|
|
25
32
|
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
function SingleNoteCurve(point)
|
|
37
|
+
{
|
|
38
|
+
this.path = [point];
|
|
39
|
+
};
|
|
40
|
+
SingleNoteCurve.prototype = Object.create(Curve.prototype);
|
|
41
|
+
SingleNoteCurve.prototype.constructor = SingleNoteCurve;
|
|
42
|
+
SingleNoteCurve.prototype.pointAt = function(t)
|
|
43
|
+
{
|
|
44
|
+
return this.path[0];
|
|
45
|
+
};
|
|
@@ -12,6 +12,8 @@ function Slider(data, beatmap)
|
|
|
12
12
|
this.repeat = data[6] | 0;
|
|
13
13
|
this.pixelLength = +data[7];
|
|
14
14
|
|
|
15
|
+
this.hitSoundString = data[8] || "";
|
|
16
|
+
|
|
15
17
|
var sliderTime = this.beatmap.timingPointAt(this.time).beatLength * (
|
|
16
18
|
this.pixelLength / this.beatmap.SliderMultiplier
|
|
17
19
|
) / 100;
|
|
@@ -28,14 +28,18 @@ from .utils import (
|
|
|
28
28
|
open_user_icon,
|
|
29
29
|
filter_scores_with_regex,
|
|
30
30
|
trim_text_with_ellipsis,
|
|
31
|
+
draw_text_with_outline,
|
|
31
32
|
)
|
|
32
33
|
from .static import (
|
|
33
34
|
Image,
|
|
34
35
|
IconLs,
|
|
35
|
-
|
|
36
|
+
Venera_60,
|
|
37
|
+
Torus_Regular_15,
|
|
36
38
|
Torus_Regular_20,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
Torus_Regular_25,
|
|
40
|
+
Torus_Regular_50,
|
|
41
|
+
Torus_Regular_60,
|
|
42
|
+
Torus_SemiBold_15,
|
|
39
43
|
Torus_SemiBold_20,
|
|
40
44
|
Torus_SemiBold_25,
|
|
41
45
|
Torus_SemiBold_30,
|
|
@@ -197,15 +201,23 @@ async def draw_score_pic(score_info: UnifiedScore, info: UnifiedUser, map_json,
|
|
|
197
201
|
original_ss_pp_info = get_ss_pp(str(osu.absolute()), 0, is_lazer)
|
|
198
202
|
if_pp, ss_pp = get_if_pp_ss_pp(score_info, str(osu.absolute()), is_lazer)
|
|
199
203
|
# 新建图片
|
|
200
|
-
im = Image.new("RGBA", (
|
|
204
|
+
im = Image.new("RGBA", (1280, 720))
|
|
201
205
|
draw = ImageDraw.Draw(im)
|
|
202
206
|
# 获取cover并裁剪,高斯,降低亮度
|
|
203
207
|
try:
|
|
204
208
|
bg = await get_bg(mapinfo.id, mapinfo.beatmapset_id)
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
+
cover_crop_left = await crop_bg((1280, 720), bg)
|
|
210
|
+
cover_gb_left = cover_crop_left.filter(ImageFilter.GaussianBlur(10))
|
|
211
|
+
cover_gb_left = ImageEnhance.Brightness(cover_gb_left).enhance(1)
|
|
212
|
+
cover_img_left = ImageEnhance.Brightness(cover_gb_left).enhance(2 / 4.0)
|
|
213
|
+
im.alpha_composite(cover_img_left, (0, 0))
|
|
214
|
+
# 新小图 BG
|
|
215
|
+
cover_crop_right = await crop_bg((650, 270), bg)
|
|
216
|
+
cover_gb_right = cover_crop_right.filter(ImageFilter.GaussianBlur(1))
|
|
217
|
+
cover_gb_right = ImageEnhance.Brightness(cover_gb_right).enhance(0.9)
|
|
218
|
+
cover_img_right = ImageEnhance.Brightness(cover_gb_right).enhance(1)
|
|
219
|
+
cover_img_right = draw_fillet(cover_img_right, 15)
|
|
220
|
+
im.alpha_composite(cover_img_right, (0, 50))
|
|
209
221
|
except NetworkError:
|
|
210
222
|
...
|
|
211
223
|
# 获取成绩背景做底图
|
|
@@ -213,58 +225,65 @@ async def draw_score_pic(score_info: UnifiedScore, info: UnifiedUser, map_json,
|
|
|
213
225
|
recent_bg = Image.open(bg).convert("RGBA")
|
|
214
226
|
im.alpha_composite(recent_bg)
|
|
215
227
|
# 模式
|
|
216
|
-
|
|
228
|
+
draw_text_with_outline(
|
|
229
|
+
draw,
|
|
230
|
+
(30, 80),
|
|
231
|
+
IconLs[score_info.ruleset_id],
|
|
232
|
+
extra_30,
|
|
233
|
+
anchor="lm",
|
|
234
|
+
fill=(255, 255, 255, 255),
|
|
235
|
+
)
|
|
217
236
|
# 难度星星
|
|
218
237
|
stars_bg = stars_diff(pp_info.difficulty.stars)
|
|
219
238
|
stars_img = stars_bg.resize((85, 37))
|
|
220
|
-
im.alpha_composite(stars_img, (
|
|
239
|
+
im.alpha_composite(stars_img, (552, 67))
|
|
221
240
|
if pp_info.difficulty.stars < 6.5:
|
|
222
241
|
color = (0, 0, 0, 255)
|
|
223
242
|
else:
|
|
224
243
|
color = (255, 217, 102, 255)
|
|
225
244
|
# 星级
|
|
226
245
|
draw.text(
|
|
227
|
-
(
|
|
246
|
+
(556, 85),
|
|
228
247
|
f"★{pp_info.difficulty.stars:.2f}",
|
|
229
248
|
font=Torus_SemiBold_20,
|
|
230
249
|
anchor="lm",
|
|
231
250
|
fill=color,
|
|
232
251
|
)
|
|
233
252
|
# mods
|
|
234
|
-
if any(i in score_info.mods for i in (Mod(acronym="HD"), Mod(acronym="FL"), Mod(acronym="FI"))):
|
|
235
|
-
|
|
236
|
-
else:
|
|
237
|
-
|
|
253
|
+
# if any(i in score_info.mods for i in (Mod(acronym="HD"), Mod(acronym="FL"), Mod(acronym="FI"))):
|
|
254
|
+
# ranking = ["XH", "SH", "A", "B", "C", "D", "F"]
|
|
255
|
+
# else:
|
|
256
|
+
# ranking = ["X", "S", "A", "B", "C", "D", "F"]
|
|
238
257
|
if score_info.mods:
|
|
239
258
|
for mods_num, s_mods in enumerate(score_info.mods):
|
|
240
259
|
mods_bg = osufile / "mods" / f"{s_mods.acronym}.png"
|
|
241
260
|
try:
|
|
242
261
|
mods_img = Image.open(mods_bg).convert("RGBA")
|
|
243
|
-
im.alpha_composite(mods_img, (
|
|
262
|
+
im.alpha_composite(mods_img, (880 + 50 * mods_num, 100))
|
|
244
263
|
except FileNotFoundError:
|
|
245
264
|
pass
|
|
246
265
|
# 成绩S-F
|
|
247
|
-
rank_ok = False
|
|
248
|
-
for rank_num, i in enumerate(ranking):
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
266
|
+
# rank_ok = False
|
|
267
|
+
# for rank_num, i in enumerate(ranking):
|
|
268
|
+
# rank_img = osufile / "ranking" / f"ranking-{i}.png"
|
|
269
|
+
# if rank_ok:
|
|
270
|
+
# rank_b = Image.open(rank_img).convert("RGBA").resize((48, 24))
|
|
271
|
+
# rank_new = Image.new("RGBA", rank_b.size, (0, 0, 0, 0))
|
|
272
|
+
# rank_bg = Image.blend(rank_new, rank_b, 0.5)
|
|
273
|
+
# elif i != score_info.rank:
|
|
274
|
+
# rank_b = Image.open(rank_img).convert("RGBA").resize((48, 24))
|
|
275
|
+
# rank_new = Image.new("RGBA", rank_b.size, (0, 0, 0, 0))
|
|
276
|
+
# rank_bg = Image.blend(rank_new, rank_b, 0.2)
|
|
277
|
+
# else:
|
|
278
|
+
# rank_bg = Image.open(rank_img).convert("RGBA").resize((48, 24))
|
|
279
|
+
# rank_ok = True
|
|
280
|
+
# im.alpha_composite(rank_bg, (75, 163 + 39 * rank_num))
|
|
262
281
|
# 成绩+acc
|
|
263
282
|
im = draw_acc(im, score_info.accuracy, score_info.ruleset_id)
|
|
264
283
|
# 地区
|
|
265
284
|
country = osufile / "flags" / f"{info.country_code}.png"
|
|
266
285
|
country_bg = Image.open(country).convert("RGBA").resize((66, 45))
|
|
267
|
-
im.alpha_composite(country_bg, (
|
|
286
|
+
im.alpha_composite(country_bg, (208, 597))
|
|
268
287
|
if info.team and info.team.flag_url:
|
|
269
288
|
team_path = team_cache_path / f"{info.team.id}.png"
|
|
270
289
|
if not team_path.exists():
|
|
@@ -273,11 +292,11 @@ async def draw_score_pic(score_info: UnifiedScore, info: UnifiedUser, map_json,
|
|
|
273
292
|
team_img.save(team_path)
|
|
274
293
|
try:
|
|
275
294
|
team_img = Image.open(team_path).convert("RGBA").resize((80, 40))
|
|
276
|
-
im.alpha_composite(team_img, (
|
|
295
|
+
im.alpha_composite(team_img, (208, 660))
|
|
277
296
|
except UnidentifiedImageError:
|
|
278
297
|
team_path.unlink()
|
|
279
298
|
raise NetworkError("team 图片下载错误,请重试!")
|
|
280
|
-
draw.text((
|
|
299
|
+
draw.text((297, 675), info.team.name, font=Torus_Regular_20, anchor="lt")
|
|
281
300
|
# supporter
|
|
282
301
|
# if info.is_supporter:
|
|
283
302
|
# im.alpha_composite(SupporterBg.resize((40, 40)), (250, 640))
|
|
@@ -309,38 +328,38 @@ async def draw_score_pic(score_info: UnifiedScore, info: UnifiedUser, map_json,
|
|
|
309
328
|
]
|
|
310
329
|
|
|
311
330
|
for num, (orig, new) in enumerate(zip(original_mapdiff, mapdiff)):
|
|
312
|
-
orig_difflen = int(
|
|
313
|
-
new_difflen = int(
|
|
331
|
+
orig_difflen = int(400 * max(0, orig) / 10) if orig <= 10 else 400
|
|
332
|
+
new_difflen = int(400 * max(0, new) / 10) if new <= 10 else 400
|
|
314
333
|
if is_close(new, orig):
|
|
315
334
|
color = (255, 255, 255, 255)
|
|
316
335
|
diff_len = Image.new("RGBA", (orig_difflen, 8), color)
|
|
317
|
-
im.alpha_composite(diff_len, (
|
|
336
|
+
im.alpha_composite(diff_len, (165, 352 + 35 * num))
|
|
318
337
|
elif new > orig and not (score_info.ruleset_id == 3 and mapinfo.mode == "osu"):
|
|
319
338
|
color = (198, 92, 102, 255)
|
|
320
339
|
orig_color = (246, 136, 144, 255)
|
|
321
340
|
new_diff_len = Image.new("RGBA", (new_difflen, 8), color)
|
|
322
|
-
im.alpha_composite(new_diff_len, (
|
|
341
|
+
im.alpha_composite(new_diff_len, (165, 352 + 35 * num))
|
|
323
342
|
orig_diff_len = Image.new("RGBA", (orig_difflen, 8), orig_color)
|
|
324
|
-
im.alpha_composite(orig_diff_len, (
|
|
343
|
+
im.alpha_composite(orig_diff_len, (165, 352 + 35 * num))
|
|
325
344
|
elif new < orig and not (score_info.ruleset_id == 3 and mapinfo.mode == "osu"):
|
|
326
345
|
color = (161, 212, 238, 255)
|
|
327
346
|
orig_color = (255, 255, 255, 255)
|
|
328
347
|
orig_diff_len = Image.new("RGBA", (orig_difflen, 8), orig_color)
|
|
329
|
-
im.alpha_composite(orig_diff_len, (
|
|
348
|
+
im.alpha_composite(orig_diff_len, (165, 352 + 35 * num))
|
|
330
349
|
new_diff_len = Image.new("RGBA", (new_difflen, 8), color)
|
|
331
|
-
im.alpha_composite(new_diff_len, (
|
|
350
|
+
im.alpha_composite(new_diff_len, (165, 352 + 35 * num))
|
|
332
351
|
else:
|
|
333
352
|
raise Exception("没有这种情况")
|
|
334
353
|
if new == round(new):
|
|
335
354
|
draw.text(
|
|
336
|
-
(
|
|
355
|
+
(610, 355 + 35 * num),
|
|
337
356
|
f"{new:.0f}",
|
|
338
357
|
font=Torus_SemiBold_20,
|
|
339
358
|
anchor="mm",
|
|
340
359
|
)
|
|
341
360
|
else:
|
|
342
361
|
draw.text(
|
|
343
|
-
(
|
|
362
|
+
(610, 355 + 35 * num),
|
|
344
363
|
f"{new:.2f}" if new != round(new, 1) else f"{new:.1f}",
|
|
345
364
|
font=Torus_SemiBold_20,
|
|
346
365
|
anchor="mm",
|
|
@@ -351,253 +370,291 @@ async def draw_score_pic(score_info: UnifiedScore, info: UnifiedUser, map_json,
|
|
|
351
370
|
if stars > original_stars:
|
|
352
371
|
color = (198, 92, 102, 255)
|
|
353
372
|
orig_color = (246, 111, 34, 255)
|
|
354
|
-
new_difflen = int(
|
|
373
|
+
new_difflen = int(400 * max(0.0, stars) / 10) if stars <= 10 else 400
|
|
355
374
|
new_diff_len = Image.new("RGBA", (new_difflen, 8), color)
|
|
356
|
-
im.alpha_composite(new_diff_len, (
|
|
357
|
-
orig_difflen = int(
|
|
375
|
+
im.alpha_composite(new_diff_len, (165, 490))
|
|
376
|
+
orig_difflen = int(400 * max(0.0, original_stars) / 10) if original_stars <= 10 else 400
|
|
358
377
|
orig_diff_len = Image.new("RGBA", (orig_difflen, 8), orig_color)
|
|
359
|
-
im.alpha_composite(orig_diff_len, (
|
|
378
|
+
im.alpha_composite(orig_diff_len, (165, 490))
|
|
360
379
|
elif stars < original_stars:
|
|
361
380
|
color = (161, 187, 127, 255)
|
|
362
381
|
orig_color = (255, 204, 34, 255)
|
|
363
|
-
orig_difflen = int(
|
|
382
|
+
orig_difflen = int(400 * max(0.0, original_stars) / 10) if original_stars <= 10 else 400
|
|
364
383
|
orig_diff_len = Image.new("RGBA", (orig_difflen, 8), orig_color)
|
|
365
|
-
im.alpha_composite(orig_diff_len, (
|
|
366
|
-
new_difflen = int(
|
|
384
|
+
im.alpha_composite(orig_diff_len, (165, 490))
|
|
385
|
+
new_difflen = int(400 * max(0.0, stars) / 10) if stars <= 10 else 400
|
|
367
386
|
new_diff_len = Image.new("RGBA", (new_difflen, 8), color)
|
|
368
|
-
im.alpha_composite(new_diff_len, (
|
|
387
|
+
im.alpha_composite(new_diff_len, (165, 490))
|
|
369
388
|
else:
|
|
370
389
|
color = (255, 204, 34, 255)
|
|
371
|
-
difflen = int(
|
|
390
|
+
difflen = int(400 * stars / 10) if stars <= 10 else 400
|
|
372
391
|
diff_len = Image.new("RGBA", (difflen, 8), color)
|
|
373
|
-
im.alpha_composite(diff_len, (
|
|
374
|
-
draw.text((
|
|
392
|
+
im.alpha_composite(diff_len, (165, 490))
|
|
393
|
+
draw.text((610, 493), f"{stars:.2f}", font=Torus_SemiBold_20, anchor="mm")
|
|
375
394
|
# 时长 - 滑条
|
|
376
|
-
diff_info =
|
|
395
|
+
diff_info = [
|
|
377
396
|
calc_songlen(mapinfo.total_length),
|
|
378
397
|
f"{mapinfo.bpm:.1f}",
|
|
379
398
|
mapinfo.count_circles,
|
|
380
399
|
mapinfo.count_sliders,
|
|
381
|
-
)
|
|
400
|
+
] + ([mapinfo.count_spinners] if score_info.ruleset_id != 3 else [])
|
|
382
401
|
for num, i in enumerate(diff_info):
|
|
383
|
-
|
|
384
|
-
|
|
402
|
+
draw_text_with_outline(
|
|
403
|
+
draw,
|
|
404
|
+
(70 + 120 * num, 300),
|
|
385
405
|
f"{i}",
|
|
386
406
|
font=Torus_Regular_20,
|
|
387
407
|
anchor="lm",
|
|
388
408
|
fill=(255, 204, 34, 255),
|
|
389
409
|
)
|
|
390
410
|
# 状态
|
|
391
|
-
|
|
411
|
+
draw_text_with_outline(
|
|
412
|
+
draw,
|
|
413
|
+
(595, 115),
|
|
414
|
+
mapinfo.status.capitalize(),
|
|
415
|
+
Torus_SemiBold_15,
|
|
416
|
+
anchor="mm",
|
|
417
|
+
fill=(255, 255, 255, 255),
|
|
418
|
+
)
|
|
419
|
+
# setid
|
|
420
|
+
draw.text((20, 25), f"Setid:{mapinfo.beatmapset_id}", font=Torus_SemiBold_20, anchor="lm")
|
|
392
421
|
# mapid
|
|
393
|
-
draw.text((
|
|
422
|
+
draw.text((650, 25), f"Mapid: {mapinfo.id}", font=Torus_SemiBold_20, anchor="rm")
|
|
394
423
|
# 曲名
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
424
|
+
title = trim_text_with_ellipsis(mapinfo.beatmapset.title, 600, Torus_SemiBold_30)
|
|
425
|
+
draw_text_with_outline(
|
|
426
|
+
draw,
|
|
427
|
+
(30, 200),
|
|
428
|
+
title,
|
|
429
|
+
Torus_SemiBold_30,
|
|
399
430
|
anchor="lm",
|
|
431
|
+
fill=(255, 255, 255, 255),
|
|
400
432
|
)
|
|
401
|
-
#
|
|
433
|
+
# 艺术家
|
|
434
|
+
artist = trim_text_with_ellipsis(mapinfo.beatmapset.artist, 600, Torus_SemiBold_20)
|
|
435
|
+
draw_text_with_outline(
|
|
436
|
+
draw,
|
|
437
|
+
(30, 230),
|
|
438
|
+
artist,
|
|
439
|
+
Torus_SemiBold_20,
|
|
440
|
+
anchor="lm",
|
|
441
|
+
fill=(255, 255, 255, 255),
|
|
442
|
+
)
|
|
443
|
+
# mapper
|
|
402
444
|
if mapinfo.owners:
|
|
403
445
|
owner_names = [owner.username for owner in mapinfo.owners]
|
|
404
446
|
owners_str = ", ".join(owner_names)
|
|
405
|
-
mapper = f"
|
|
447
|
+
mapper = f"谱师: {owners_str}"
|
|
406
448
|
|
|
407
449
|
else:
|
|
408
|
-
mapper = f"
|
|
409
|
-
mapper = trim_text_with_ellipsis(mapper,
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
(
|
|
450
|
+
mapper = f"谱师: {mapinfo.beatmapset.creator}"
|
|
451
|
+
mapper = trim_text_with_ellipsis(mapper, 600, Torus_SemiBold_15)
|
|
452
|
+
draw_text_with_outline(
|
|
453
|
+
draw,
|
|
454
|
+
(30, 265),
|
|
413
455
|
mapper,
|
|
414
|
-
|
|
456
|
+
Torus_SemiBold_15,
|
|
457
|
+
anchor="lm",
|
|
458
|
+
fill=(255, 255, 255, 255),
|
|
459
|
+
)
|
|
460
|
+
# 谱面版本
|
|
461
|
+
version = trim_text_with_ellipsis(mapinfo.version, 450, Torus_SemiBold_15)
|
|
462
|
+
draw_text_with_outline(
|
|
463
|
+
draw,
|
|
464
|
+
(65, 80),
|
|
465
|
+
version,
|
|
466
|
+
Torus_SemiBold_15,
|
|
415
467
|
anchor="lm",
|
|
468
|
+
fill=(255, 255, 255, 255),
|
|
416
469
|
)
|
|
417
470
|
# 评价
|
|
418
|
-
draw.text((
|
|
471
|
+
draw.text((772, 185), score_info.rank, font=Venera_60, anchor="mm")
|
|
419
472
|
# 分数
|
|
420
473
|
draw.text(
|
|
421
|
-
(
|
|
474
|
+
(880, 165),
|
|
422
475
|
f"{score_info.legacy_total_score or score_info.total_score:,}",
|
|
423
|
-
font=
|
|
476
|
+
font=Torus_Regular_60,
|
|
424
477
|
anchor="lm",
|
|
425
478
|
)
|
|
426
479
|
# 时间
|
|
427
|
-
draw.text((
|
|
428
|
-
draw.text((
|
|
480
|
+
draw.text((883, 260), "达成时间:", font=Torus_SemiBold_20, anchor="lm")
|
|
481
|
+
draw.text((985, 260), score_info.ended_at.strftime("%Y-%m-%d %H:%M:%S"), font=Torus_SemiBold_20, anchor="lm")
|
|
429
482
|
# 全球排名
|
|
430
|
-
draw.text((
|
|
483
|
+
draw.text((715, 300), "全球排行:" if grank else "", font=Torus_SemiBold_20, anchor="lm")
|
|
484
|
+
draw.text((817, 300), f"#{grank}" if grank else "", font=Torus_SemiBold_25, anchor="lm")
|
|
431
485
|
# 左下玩家名
|
|
432
|
-
draw.text((
|
|
486
|
+
draw.text((208, 550), info.username, font=Torus_SemiBold_30, anchor="lm")
|
|
433
487
|
# 国内排名
|
|
434
488
|
draw.text(
|
|
435
|
-
(
|
|
489
|
+
(283, 630),
|
|
436
490
|
f"#{info.statistics.country_rank}",
|
|
437
491
|
font=Torus_SemiBold_25,
|
|
438
492
|
anchor="lm",
|
|
439
493
|
)
|
|
440
494
|
if score_info.ruleset_id in {0, 4, 8}:
|
|
441
|
-
draw.text((
|
|
442
|
-
draw.text((
|
|
443
|
-
draw.text((
|
|
444
|
-
draw.text((
|
|
445
|
-
draw.text((
|
|
446
|
-
draw.text((
|
|
495
|
+
draw.text((1066, 393), ss_pp, font=Torus_Regular_25, anchor="mm")
|
|
496
|
+
draw.text((933, 393), if_pp, font=Torus_Regular_25, anchor="mm")
|
|
497
|
+
draw.text((768, 438), f"{pp_info.pp:.0f}", font=Torus_Regular_50, anchor="mm")
|
|
498
|
+
draw.text((933, 482), f"{pp_info.pp_aim:.0f}", font=Torus_Regular_25, anchor="mm")
|
|
499
|
+
draw.text((1066, 482), f"{pp_info.pp_speed:.0f}", font=Torus_Regular_25, anchor="mm")
|
|
500
|
+
draw.text((1200, 482), f"{pp_info.pp_accuracy:.0f}", font=Torus_Regular_25, anchor="mm")
|
|
447
501
|
draw.text(
|
|
448
|
-
(
|
|
502
|
+
(768, 577),
|
|
449
503
|
f"{score_info.accuracy:.2f}%",
|
|
450
|
-
font=
|
|
504
|
+
font=Torus_Regular_25,
|
|
451
505
|
anchor="mm",
|
|
452
506
|
)
|
|
453
507
|
draw.text(
|
|
454
|
-
(
|
|
508
|
+
(768, 666),
|
|
455
509
|
f"{score_info.max_combo:,}/{pp_info.difficulty.max_combo}",
|
|
456
|
-
font=
|
|
510
|
+
font=Torus_Regular_25,
|
|
457
511
|
anchor="mm",
|
|
458
512
|
)
|
|
459
513
|
draw.text(
|
|
460
|
-
(
|
|
514
|
+
(933, 577),
|
|
461
515
|
f"{score_info.statistics.great or 0}",
|
|
462
|
-
font=
|
|
516
|
+
font=Torus_Regular_25,
|
|
463
517
|
anchor="mm",
|
|
464
518
|
)
|
|
465
519
|
draw.text(
|
|
466
|
-
(
|
|
520
|
+
(1066, 577),
|
|
467
521
|
f"{score_info.statistics.ok or 0}",
|
|
468
|
-
font=
|
|
522
|
+
font=Torus_Regular_25,
|
|
469
523
|
anchor="mm",
|
|
470
524
|
)
|
|
471
525
|
draw.text(
|
|
472
|
-
(
|
|
526
|
+
(933, 666),
|
|
473
527
|
f"{score_info.statistics.meh or 0}",
|
|
474
|
-
font=
|
|
528
|
+
font=Torus_Regular_25,
|
|
475
529
|
anchor="mm",
|
|
476
530
|
)
|
|
477
531
|
draw.text(
|
|
478
|
-
(
|
|
532
|
+
(1066, 666),
|
|
479
533
|
f"{score_info.statistics.miss or 0}",
|
|
480
|
-
font=
|
|
534
|
+
font=Torus_Regular_25,
|
|
481
535
|
anchor="mm",
|
|
482
536
|
)
|
|
483
537
|
elif score_info.ruleset_id in {1, 5}:
|
|
484
538
|
draw.text(
|
|
485
|
-
(
|
|
539
|
+
(768, 577),
|
|
486
540
|
f"{score_info.accuracy:.2f}%",
|
|
487
|
-
font=
|
|
541
|
+
font=Torus_Regular_25,
|
|
488
542
|
anchor="mm",
|
|
489
543
|
)
|
|
490
|
-
draw.text((
|
|
491
|
-
draw.text((
|
|
544
|
+
draw.text((768, 666), f"{score_info.max_combo:,}", font=Torus_Regular_25, anchor="mm")
|
|
545
|
+
draw.text((768, 438), f"{pp_info.pp:.0f}", font=Torus_Regular_50, anchor="mm")
|
|
546
|
+
draw.text((933, 393), f"{ss_pp}", font=Torus_Regular_25, anchor="mm")
|
|
492
547
|
draw.text(
|
|
493
|
-
(
|
|
548
|
+
(933, 577),
|
|
494
549
|
f"{score_info.statistics.great or 0}",
|
|
495
|
-
font=
|
|
550
|
+
font=Torus_Regular_25,
|
|
496
551
|
anchor="mm",
|
|
497
552
|
)
|
|
498
553
|
draw.text(
|
|
499
|
-
(
|
|
554
|
+
(1066, 577),
|
|
500
555
|
f"{score_info.statistics.ok or 0}",
|
|
501
|
-
font=
|
|
556
|
+
font=Torus_Regular_25,
|
|
502
557
|
anchor="mm",
|
|
503
558
|
)
|
|
504
559
|
draw.text(
|
|
505
|
-
(
|
|
560
|
+
(933, 666),
|
|
506
561
|
f"{score_info.statistics.miss or 0}",
|
|
507
|
-
font=
|
|
562
|
+
font=Torus_Regular_25,
|
|
508
563
|
anchor="mm",
|
|
509
564
|
)
|
|
510
565
|
elif score_info.ruleset_id in {2, 6}:
|
|
511
566
|
draw.text(
|
|
512
|
-
(
|
|
567
|
+
(768, 577),
|
|
513
568
|
f"{score_info.accuracy:.2f}%",
|
|
514
|
-
font=
|
|
569
|
+
font=Torus_Regular_25,
|
|
515
570
|
anchor="mm",
|
|
516
571
|
)
|
|
517
572
|
draw.text(
|
|
518
|
-
(
|
|
573
|
+
(768, 666),
|
|
519
574
|
f"{score_info.max_combo}/{pp_info.difficulty.max_combo}",
|
|
520
|
-
font=
|
|
575
|
+
font=Torus_Regular_25,
|
|
521
576
|
anchor="mm",
|
|
522
577
|
)
|
|
523
|
-
draw.text((
|
|
578
|
+
draw.text((768, 438), f"{pp_info.pp:.0f}", font=Torus_Regular_50, anchor="mm")
|
|
579
|
+
draw.text((933, 393), f"{ss_pp}", font=Torus_Regular_25, anchor="mm")
|
|
524
580
|
draw.text(
|
|
525
|
-
(
|
|
581
|
+
(933, 577),
|
|
526
582
|
f"{score_info.statistics.great or 0}",
|
|
527
|
-
font=
|
|
583
|
+
font=Torus_Regular_25,
|
|
528
584
|
anchor="mm",
|
|
529
585
|
)
|
|
530
586
|
draw.text(
|
|
531
|
-
(
|
|
587
|
+
(1066, 577),
|
|
532
588
|
f"{score_info.statistics.large_tick_hit or 0}",
|
|
533
|
-
font=
|
|
589
|
+
font=Torus_Regular_25,
|
|
534
590
|
anchor="mm",
|
|
535
591
|
)
|
|
536
592
|
draw.text(
|
|
537
|
-
(
|
|
593
|
+
(933, 666),
|
|
538
594
|
f"{score_info.statistics.small_tick_miss or 0}",
|
|
539
|
-
font=
|
|
595
|
+
font=Torus_Regular_25,
|
|
540
596
|
anchor="mm",
|
|
541
597
|
)
|
|
542
598
|
draw.text(
|
|
543
|
-
(
|
|
599
|
+
(1066, 666),
|
|
544
600
|
f"{score_info.statistics.miss or 0}",
|
|
545
|
-
font=
|
|
601
|
+
font=Torus_Regular_25,
|
|
546
602
|
anchor="mm",
|
|
547
603
|
)
|
|
548
604
|
else:
|
|
549
605
|
draw.text(
|
|
550
|
-
(
|
|
606
|
+
(933, 600),
|
|
551
607
|
(
|
|
552
608
|
f"{score_info.statistics.perfect / score_info.statistics.great:.1f}:1"
|
|
553
609
|
if (score_info.statistics.great or 0) != 0
|
|
554
610
|
else "∞:1"
|
|
555
611
|
),
|
|
556
|
-
font=
|
|
612
|
+
font=Torus_Regular_15,
|
|
557
613
|
anchor="mm",
|
|
558
614
|
)
|
|
559
615
|
draw.text(
|
|
560
|
-
(
|
|
616
|
+
(768, 577),
|
|
561
617
|
f"{score_info.accuracy:.2f}%",
|
|
562
|
-
font=
|
|
618
|
+
font=Torus_Regular_25,
|
|
563
619
|
anchor="mm",
|
|
564
620
|
)
|
|
565
|
-
draw.text((
|
|
566
|
-
draw.text((
|
|
621
|
+
draw.text((768, 666), f"{score_info.max_combo}", font=Torus_Regular_25, anchor="mm")
|
|
622
|
+
draw.text((768, 438), f"{pp_info.pp:.0f}", font=Torus_Regular_50, anchor="mm")
|
|
623
|
+
draw.text((933, 393), f"{ss_pp}", font=Torus_Regular_25, anchor="mm")
|
|
567
624
|
draw.text(
|
|
568
|
-
(
|
|
625
|
+
(933, 577),
|
|
569
626
|
f"{score_info.statistics.perfect or 0}",
|
|
570
|
-
font=
|
|
627
|
+
font=Torus_Regular_25,
|
|
571
628
|
anchor="mm",
|
|
572
629
|
)
|
|
573
630
|
draw.text(
|
|
574
|
-
(
|
|
631
|
+
(1066, 577),
|
|
575
632
|
f"{score_info.statistics.great or 0}",
|
|
576
|
-
font=
|
|
633
|
+
font=Torus_Regular_25,
|
|
577
634
|
anchor="mm",
|
|
578
635
|
)
|
|
579
636
|
draw.text(
|
|
580
|
-
(
|
|
637
|
+
(1200, 577),
|
|
581
638
|
f"{score_info.statistics.good or 0}",
|
|
582
|
-
font=
|
|
639
|
+
font=Torus_Regular_25,
|
|
583
640
|
anchor="mm",
|
|
584
641
|
)
|
|
585
642
|
draw.text(
|
|
586
|
-
(
|
|
643
|
+
(933, 666),
|
|
587
644
|
f"{score_info.statistics.ok or 0}",
|
|
588
|
-
font=
|
|
645
|
+
font=Torus_Regular_25,
|
|
589
646
|
anchor="mm",
|
|
590
647
|
)
|
|
591
648
|
draw.text(
|
|
592
|
-
(
|
|
649
|
+
(1066, 666),
|
|
593
650
|
f"{score_info.statistics.meh or 0}",
|
|
594
|
-
font=
|
|
651
|
+
font=Torus_Regular_25,
|
|
595
652
|
anchor="mm",
|
|
596
653
|
)
|
|
597
654
|
draw.text(
|
|
598
|
-
(
|
|
655
|
+
(1200, 666),
|
|
599
656
|
f"{score_info.statistics.miss or 0}",
|
|
600
|
-
font=
|
|
657
|
+
font=Torus_Regular_25,
|
|
601
658
|
anchor="mm",
|
|
602
659
|
)
|
|
603
660
|
user_icon = await open_user_icon(info, source)
|
|
@@ -607,7 +664,7 @@ async def draw_score_pic(score_info: UnifiedScore, info: UnifiedUser, map_json,
|
|
|
607
664
|
if not getattr(user_icon, "is_animated", False):
|
|
608
665
|
icon_bg = user_icon.convert("RGBA").resize((170, 170))
|
|
609
666
|
icon_img = draw_fillet(icon_bg, 15)
|
|
610
|
-
im.alpha_composite(icon_img, (
|
|
667
|
+
im.alpha_composite(icon_img, (27, 532))
|
|
611
668
|
byt = BytesIO()
|
|
612
669
|
im.convert("RGB").save(byt, "jpeg")
|
|
613
670
|
im.close()
|
|
@@ -620,7 +677,7 @@ async def draw_score_pic(score_info: UnifiedScore, info: UnifiedUser, map_json,
|
|
|
620
677
|
# 创建一个新的 RGBA 图片,将 PNG 图片作为背景,将当前帧添加到背景上
|
|
621
678
|
rgba_frame = Image.new("RGBA", im.size, (0, 0, 0, 0))
|
|
622
679
|
rgba_frame.paste(im, (0, 0), im)
|
|
623
|
-
rgba_frame.paste(gif_frame, (
|
|
680
|
+
rgba_frame.paste(gif_frame, (27, 532), gif_frame)
|
|
624
681
|
# 将 RGBA 图片转换为 RGB 模式,并添加到 GIF 图片中
|
|
625
682
|
gif_frames.append(rgba_frame)
|
|
626
683
|
gif_bytes = BytesIO()
|
|
@@ -15,14 +15,15 @@ Torus_Regular_35 = ImageFont.truetype(str(osufile / "fonts" / "Torus Regular.otf
|
|
|
15
15
|
Torus_Regular_40 = ImageFont.truetype(str(osufile / "fonts" / "Torus Regular.otf"), 40)
|
|
16
16
|
Torus_Regular_45 = ImageFont.truetype(str(osufile / "fonts" / "Torus Regular.otf"), 45)
|
|
17
17
|
Torus_Regular_50 = ImageFont.truetype(str(osufile / "fonts" / "Torus Regular.otf"), 50)
|
|
18
|
-
|
|
18
|
+
Torus_Regular_60 = ImageFont.truetype(str(osufile / "fonts" / "Torus Regular.otf"), 60)
|
|
19
|
+
Torus_SemiBold_15 = ImageFont.truetype(str(osufile / "fonts" / "Torus SemiBold.otf"), 15)
|
|
19
20
|
Torus_SemiBold_20 = ImageFont.truetype(str(osufile / "fonts" / "Torus SemiBold.otf"), 20)
|
|
20
21
|
Torus_SemiBold_25 = ImageFont.truetype(str(osufile / "fonts" / "Torus SemiBold.otf"), 25)
|
|
21
22
|
Torus_SemiBold_30 = ImageFont.truetype(str(osufile / "fonts" / "Torus SemiBold.otf"), 30)
|
|
22
23
|
Torus_SemiBold_40 = ImageFont.truetype(str(osufile / "fonts" / "Torus SemiBold.otf"), 40)
|
|
23
24
|
Torus_SemiBold_45 = ImageFont.truetype(str(osufile / "fonts" / "Torus SemiBold.otf"), 45)
|
|
24
25
|
Torus_SemiBold_50 = ImageFont.truetype(str(osufile / "fonts" / "Torus SemiBold.otf"), 50)
|
|
25
|
-
|
|
26
|
+
Venera_60 = ImageFont.truetype(str(osufile / "fonts" / "Venera.otf"), 60)
|
|
26
27
|
extra_30 = ImageFont.truetype(str(osufile / "fonts" / "Extra.otf"), 30)
|
|
27
28
|
|
|
28
29
|
InfoImg = Image.open(osufile / "info.png").convert("RGBA")
|
|
@@ -120,8 +120,8 @@ def draw_acc(img: Image, acc: float, mode: int):
|
|
|
120
120
|
ax.clear()
|
|
121
121
|
fig.clf()
|
|
122
122
|
fig.clear()
|
|
123
|
-
score_acc_img = Image.open(acc_img).convert("RGBA").resize((
|
|
124
|
-
img.alpha_composite(score_acc_img, (
|
|
123
|
+
score_acc_img = Image.open(acc_img).convert("RGBA").resize((384, 288))
|
|
124
|
+
img.alpha_composite(score_acc_img, (580, 35))
|
|
125
125
|
return img
|
|
126
126
|
|
|
127
127
|
|
|
@@ -438,3 +438,18 @@ def trim_text_with_ellipsis(text, max_width, font):
|
|
|
438
438
|
|
|
439
439
|
# 返回截断后的字符串 + 省略号
|
|
440
440
|
return truncated_text + ellipsis_symbol if truncated_text else ellipsis_symbol
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
# 字体描边函数
|
|
444
|
+
def draw_text_with_outline(draw, position, text, font, anchor, fill):
|
|
445
|
+
for dx in [-1, 0, 1]:
|
|
446
|
+
for dy in [-1, 0, 1]:
|
|
447
|
+
if dx != 0 or dy != 0:
|
|
448
|
+
draw.text(
|
|
449
|
+
(position[0] + dx, position[1] + dy),
|
|
450
|
+
text,
|
|
451
|
+
font=font,
|
|
452
|
+
anchor=anchor,
|
|
453
|
+
fill=(0, 0, 0, 255),
|
|
454
|
+
)
|
|
455
|
+
draw.text(position, text, font=font, anchor=anchor, fill=fill)
|
|
@@ -33,7 +33,9 @@ def split_msg():
|
|
|
33
33
|
state["query"] = []
|
|
34
34
|
state["target"] = None
|
|
35
35
|
state["is_lazer"] = True if not user_data else user_data.lazer_mode
|
|
36
|
-
arg =
|
|
36
|
+
arg = (
|
|
37
|
+
arg.extract_plain_text().strip().replace("=", "=").replace(":", ":").replace("&", "&").replace("#", "#")
|
|
38
|
+
)
|
|
37
39
|
matches = re.findall(pattern, arg)
|
|
38
40
|
for match in matches:
|
|
39
41
|
if match[0]:
|
|
@@ -85,9 +87,9 @@ def split_msg():
|
|
|
85
87
|
if state["source"] == "ppysb" and not arg.strip():
|
|
86
88
|
sb_user_data = await SbUserData.get_or_none(user_id=qq)
|
|
87
89
|
if sb_user_data:
|
|
88
|
-
state["user"] = sb_user_data.osu_id
|
|
89
|
-
state["username"] = sb_user_data.osu_name
|
|
90
|
+
state["user"] = sb_user_data.osu_id
|
|
91
|
+
state["username"] = sb_user_data.osu_name
|
|
90
92
|
else:
|
|
91
|
-
state["error"] = "该账号尚未绑定sb 服务器,请输入 /sbbind 用户名 绑定账号"
|
|
93
|
+
state["error"] = "该账号尚未绑定 sb 服务器,请输入 /sbbind 用户名 绑定账号"
|
|
92
94
|
|
|
93
95
|
return Depends(dependency)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
nonebot_plugin_osubot/__init__.py,sha256=Q-mTTnOIdKiKG6JrVm-kqpPrAhOP9lWyiKHNRqA7gpc,1478
|
|
2
|
-
nonebot_plugin_osubot/api.py,sha256=
|
|
2
|
+
nonebot_plugin_osubot/api.py,sha256=8GXbumU7_1D0gyYuGtjHgNT82rSXKZUV-WG5mpUubYE,16336
|
|
3
3
|
nonebot_plugin_osubot/beatmap_stats_moder.py,sha256=mNNTufc-gvO4NdYa3TnealSZI4-LBoiTlb599SeLBck,2915
|
|
4
4
|
nonebot_plugin_osubot/config.py,sha256=Ub2s5Ny09-d1ZwT6x8cirB6zWy0brtO-oZV3W0qEM5Q,311
|
|
5
5
|
nonebot_plugin_osubot/database/__init__.py,sha256=7CDo9xU_DGLQ6uTj_mU_Px92phg_DMU5mP6WvgOxFLY,101
|
|
@@ -15,23 +15,23 @@ nonebot_plugin_osubot/draw/catch_preview_templates/js/beatmap/point.js,sha256=AX
|
|
|
15
15
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/beatmap/scroll.js,sha256=wR9dkpKabP1TyMssfs8i2WLUxyR_ZX7RRc7KLXUjoXo,1833
|
|
16
16
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/beatmap/timingpoint.js,sha256=boHMAQOT-860VOi-jQIrq4cwKgCo1kZvNDy0bzUxZLE,803
|
|
17
17
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/LegacyRandom.js,sha256=HDiks3FCVQBtVK5VzN7YV9Ekkk_WHYi0fPk3-XCQaj8,2155
|
|
18
|
-
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/PalpableCatchHitObject.js,sha256=
|
|
19
|
-
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/bananashower.js,sha256=
|
|
20
|
-
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/catch.js,sha256=
|
|
18
|
+
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/PalpableCatchHitObject.js,sha256=CnUBiIkAqFUaCrc5TXRtL_fuK20NeK1yMti1Sp4dJAE,5702
|
|
19
|
+
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/bananashower.js,sha256=sPISMifUWVXK9nXuOD7JUPeXBNPBKquiDNKpYzbSJyg,988
|
|
20
|
+
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/catch.js,sha256=uLbMrZBZfvj1YxJVIeirFWVVJ2apLPfB1VY_KHq-hSE,34561
|
|
21
21
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/fruit.js,sha256=ABvFMbmXP0t5wACUhSVbu8sVJ845mWJ9sWiQJtMV5co,437
|
|
22
|
-
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/juicestream.js,sha256=
|
|
22
|
+
nonebot_plugin_osubot/draw/catch_preview_templates/js/catch/juicestream.js,sha256=kWjmPtT_UgnUlg5G-_8q-1AyNTv6GLRp0bOOfiMcojc,7347
|
|
23
23
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/fakeaudio.js,sha256=gJrdVwNrAVjWx80z_XkzybL9ldfV97nKl7k1v7NulBg,1211
|
|
24
24
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/preview.js,sha256=5zKNenhzhMdP_SPuA74wbtgsqiqUNL8PIJ4OYFW2r-U,2875
|
|
25
25
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/bezier2.js,sha256=J3wvdScuhYCngTvZ3vg9ld6yoDE09ht5g4Etsp4bJkE,955
|
|
26
26
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/catmullcurve.js,sha256=aGmfIAONuOoy87W5Pyl1X8ifr3w6W9mkM_AENmZRUF0,932
|
|
27
27
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/centripetalcatmullrom.js,sha256=bndps8pDX4JMEbqLxIVb-aO7IoHHXnT8-jkWJnLlfq0,1203
|
|
28
28
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/circumstancedcircle.js,sha256=qf7wZMH3-thilEoB1Grrhr9W-U-JIClRNkhZh2RzGTY,1558
|
|
29
|
-
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/curve.js,sha256=
|
|
29
|
+
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/curve.js,sha256=KeR8szJ0N2FWBTYMnXBcnQFWYHxqRRh0f-oaALSXvYs,1002
|
|
30
30
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/curvetype.js,sha256=y3uiQSz1BjGIhIMn4fNlplPRGqxozHOuIa8jN-G06Vs,496
|
|
31
31
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/equaldistancemulticurve.js,sha256=U8sjoBG1ETEa9vlToqc32hyQYj41KrcRVvEdxnD-uGo,2280
|
|
32
32
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/curve/linearbezier.js,sha256=sGe0u0Aqwh8R4y2BP91Dsz1MfhvtvTrrOVMV_gYsQhY,1075
|
|
33
33
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/hitcircle.js,sha256=erJCRQYojmlCnTvnkrWMJHkJxBabeWopE8PACr1aSUw,2391
|
|
34
|
-
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/slider.js,sha256=
|
|
34
|
+
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/slider.js,sha256=alosJJRDgXreSrheROxwVi4Dt9S3lxq9aZfG_EQCbWU,3873
|
|
35
35
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/standard/spinner.js,sha256=9El2G7UfJv1xikHmfO5-VJJ7e6f-1tOPLyrMf2huh7g,1668
|
|
36
36
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/util.js,sha256=XveUlX-d0vrUnXaGbR8y428s6Nw2zhDR235pFko_MxM,1504
|
|
37
37
|
nonebot_plugin_osubot/draw/catch_preview_templates/js/viewbox.js,sha256=RPsUyoKNAQub2n7oUGwWyFppZu0iVuy6DD5gggQZS3E,1641
|
|
@@ -42,14 +42,14 @@ nonebot_plugin_osubot/draw/info.py,sha256=i2YcJmSdTpwhZl_nDe7GJv4jQTB8_9oBfpq2Zw
|
|
|
42
42
|
nonebot_plugin_osubot/draw/map.py,sha256=4M8xRd0dIbC5g1s8I4eTZ3vRglM6r_TSznFOZ62K2wk,8654
|
|
43
43
|
nonebot_plugin_osubot/draw/match_history.py,sha256=GBJl6lAA27U7NSMC2isEzD_YsoIPAeG6ijDu7Oflcl0,997
|
|
44
44
|
nonebot_plugin_osubot/draw/rating.py,sha256=pA7mGLI4IujmYB6kQf_tSkR7mZGpUAVLRLyaAsZhqTM,20397
|
|
45
|
-
nonebot_plugin_osubot/draw/score.py,sha256=
|
|
46
|
-
nonebot_plugin_osubot/draw/static.py,sha256=
|
|
45
|
+
nonebot_plugin_osubot/draw/score.py,sha256=izYS28IovyFXACLkyQL9Qtp8fUrguoO63xKdawZv70Y,29414
|
|
46
|
+
nonebot_plugin_osubot/draw/static.py,sha256=28_ta4ivORxdX_-P7OdOp1VzJK_Tw0-VudfJOY9kW8I,4059
|
|
47
47
|
nonebot_plugin_osubot/draw/taiko_preview.py,sha256=tqhuHSdxUJEuXqKHMJDeSLdusuJhSnMMiaG5FbUnaJw,11441
|
|
48
48
|
nonebot_plugin_osubot/draw/templates/bpa_chart.html,sha256=cnpM0qRvvyCMTRP-mIOABQlaaqxQwG5kLUxlo4h7F7w,7012
|
|
49
49
|
nonebot_plugin_osubot/draw/templates/echarts.min.js,sha256=IF32ooP8NPIzQg_fs7lVHpwG92JcCPE1TZAEyFSgGZU,1022939
|
|
50
50
|
nonebot_plugin_osubot/draw/templates/mod_chart.html,sha256=Iz71KM5v9z_Rt2vqJ5WIZumRIHgDfcGIUmWGvVGZ-nQ,1508
|
|
51
51
|
nonebot_plugin_osubot/draw/templates/pp_rank_line_chart.html,sha256=Gyf-GR8ZBlWQTks0TlB3M8EWUBMVwiUaesFAmDISxLo,1417
|
|
52
|
-
nonebot_plugin_osubot/draw/utils.py,sha256=
|
|
52
|
+
nonebot_plugin_osubot/draw/utils.py,sha256=r-It_mt4o3ckkjanAynJ28ICGxTYk3o2XMnAH__0rUQ,15764
|
|
53
53
|
nonebot_plugin_osubot/exceptions.py,sha256=N_FsEk-9Eu2QnuznhdfWn6OoyA1HH73Q7bUaY89gVi0,40
|
|
54
54
|
nonebot_plugin_osubot/file.py,sha256=GhG54EdVsxFf8_8GZOPh4YGvw9iw5bAX9JFz4Mg4kMg,4379
|
|
55
55
|
nonebot_plugin_osubot/info/__init__.py,sha256=I7YlMQiuHExEeJWqyzZb2I-Vl2uql3Py2LdhSH2Z9N0,136
|
|
@@ -80,7 +80,7 @@ nonebot_plugin_osubot/matcher/score.py,sha256=Nk6dpDlszKJKdboTSQRBf-wMGioHIPqKSV
|
|
|
80
80
|
nonebot_plugin_osubot/matcher/update.py,sha256=MHpxoJmU0hKW82XuM9YpyCxUUjjiNKwejnRgYwueR4Q,3168
|
|
81
81
|
nonebot_plugin_osubot/matcher/update_mode.py,sha256=0Wy6Y1-rN7XcqBZyo37mYFdixq-4HxCwZftUaiYhZqE,1602
|
|
82
82
|
nonebot_plugin_osubot/matcher/url_match.py,sha256=opx4DYSQ83tk0qlMOBirl4TC49WXHgMZ04lMr9NCHNs,746
|
|
83
|
-
nonebot_plugin_osubot/matcher/utils.py,sha256=
|
|
83
|
+
nonebot_plugin_osubot/matcher/utils.py,sha256=gWmNa31wUxcY_PNSNLy348x5_7sTY9ttMKH-5V5jkuE,4304
|
|
84
84
|
nonebot_plugin_osubot/mods.py,sha256=vxIWYX0HwTxetPAHWZK5ojEMfqV9HFlWT0YC4Yncgb8,1402
|
|
85
85
|
nonebot_plugin_osubot/network/__init__.py,sha256=WOijcd81yhnpGKYeiDIOxbBDVI12GHPRGoOFfxrUuQk,61
|
|
86
86
|
nonebot_plugin_osubot/network/auto_retry.py,sha256=vDfYGbEVPF6WZLYXmRVkNvaxf6_6RyIqEAcA7TRwV_k,565
|
|
@@ -372,10 +372,10 @@ nonebot_plugin_osubot/osufile/mods/SD.png,sha256=JptCZkXv8kOpIksYimWdC7hRJXShL7N
|
|
|
372
372
|
nonebot_plugin_osubot/osufile/mods/SO.png,sha256=qKPoP-LXNU3nSVn8e7z2d6LddFOG-v4gbBEUOb6BtXU,1493
|
|
373
373
|
nonebot_plugin_osubot/osufile/mods/TD.png,sha256=ZAprUMXNcqs_tXPF0HU34qa_NUZo6U-NemMjVxBOk10,1309
|
|
374
374
|
nonebot_plugin_osubot/osufile/mods/V2.png,sha256=Y3ju7KMECnGiECRM1MnZUuuwQqbflkdz6I7XjCCTw2E,1354
|
|
375
|
-
nonebot_plugin_osubot/osufile/pfm_ctb.png,sha256=
|
|
376
|
-
nonebot_plugin_osubot/osufile/pfm_mania.png,sha256=
|
|
377
|
-
nonebot_plugin_osubot/osufile/pfm_std.png,sha256=
|
|
378
|
-
nonebot_plugin_osubot/osufile/pfm_taiko.png,sha256=
|
|
375
|
+
nonebot_plugin_osubot/osufile/pfm_ctb.png,sha256=9JJu8J1gR_nQhb1EWOuJUOjNitYK_gcH6MRGiYtvsGI,53451
|
|
376
|
+
nonebot_plugin_osubot/osufile/pfm_mania.png,sha256=PKlAezcKALo0UMnrYvTCL3pd-oJNEU76qLVPhfDLFdk,52208
|
|
377
|
+
nonebot_plugin_osubot/osufile/pfm_std.png,sha256=ts7e7IUeoalLuw0Pww0X3trXUpZwnWRsOqdQ1RzcdFM,57032
|
|
378
|
+
nonebot_plugin_osubot/osufile/pfm_taiko.png,sha256=7OAhXVfL_j7pZ4MZAXexgSMNmUyVNsvvq1Ij2XzFEgc,55756
|
|
379
379
|
nonebot_plugin_osubot/osufile/ranking/ranking-A.png,sha256=nA4kI67IbnC-gfu1pCnPupHC45Uoqa6LYmJKawzV_L0,4364
|
|
380
380
|
nonebot_plugin_osubot/osufile/ranking/ranking-B.png,sha256=KJCEGr7OkQ12rqng6_JL9r6qLTAclPO_PtHHmLFQooY,4214
|
|
381
381
|
nonebot_plugin_osubot/osufile/ranking/ranking-C.png,sha256=SsIWOTOymgMze521v4G_rdqL6QqpE64R1dhxpmhzBAc,3862
|
|
@@ -403,6 +403,6 @@ nonebot_plugin_osubot/schema/sayo_beatmap.py,sha256=lS1PQZ-HvHl0VhkzlI0-pNLeJrLY
|
|
|
403
403
|
nonebot_plugin_osubot/schema/score.py,sha256=zHU-w2e7RzMDL8vdPkX5vggcqalBo83JTvu96abcflo,3124
|
|
404
404
|
nonebot_plugin_osubot/schema/user.py,sha256=sxNmqymG_kIVuGuzfchSv9UML6NPG70cqo2_h5xDIpM,2250
|
|
405
405
|
nonebot_plugin_osubot/utils/__init__.py,sha256=pyv8XxBcCOeQVDj1E4dgvktzcefgQXfKBlarsYGx1sg,815
|
|
406
|
-
nonebot_plugin_osubot-6.
|
|
407
|
-
nonebot_plugin_osubot-6.
|
|
408
|
-
nonebot_plugin_osubot-6.
|
|
406
|
+
nonebot_plugin_osubot-6.21.0.dist-info/WHEEL,sha256=B19PGBCYhWaz2p_UjAoRVh767nYQfk14Sn4TpIZ-nfU,87
|
|
407
|
+
nonebot_plugin_osubot-6.21.0.dist-info/METADATA,sha256=uKS_5rmuhM8-4dD90UGo6kb-p5n90veBEKDQR6aDB5Y,4476
|
|
408
|
+
nonebot_plugin_osubot-6.21.0.dist-info/RECORD,,
|
|
File without changes
|