rhythia-api 126.0.0 → 127.0.0
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.
- package/api/approveMap.ts +5 -1
- package/api/createBeatmap.ts +11 -2
- package/api/getBadgedUsers.ts +70 -0
- package/api/nominateMap.ts +5 -1
- package/api/submitScore.ts +19 -0
- package/index.ts +5 -0
- package/package.json +2 -1
package/api/approveMap.ts
CHANGED
|
@@ -42,7 +42,7 @@ export async function handler(data: (typeof Schema)["input"]["_type"]) {
|
|
|
42
42
|
|
|
43
43
|
const { data: mapData, error } = await supabase
|
|
44
44
|
.from("beatmapPages")
|
|
45
|
-
.select("id,nominations")
|
|
45
|
+
.select("id,nominations,owner")
|
|
46
46
|
.eq("id", data.mapId)
|
|
47
47
|
.single();
|
|
48
48
|
|
|
@@ -50,6 +50,10 @@ export async function handler(data: (typeof Schema)["input"]["_type"]) {
|
|
|
50
50
|
return NextResponse.json({ error: "Bad map" });
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
if (mapData.owner == queryUserData.id) {
|
|
54
|
+
return NextResponse.json({ error: "Can't approve own map" });
|
|
55
|
+
}
|
|
56
|
+
|
|
53
57
|
if ((mapData.nominations as number[])!.length < 2) {
|
|
54
58
|
return NextResponse.json({
|
|
55
59
|
error: "Maps can get approved only if they have 2 approvals",
|
package/api/createBeatmap.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { SSPMParser } from "../utils/star-calc/sspmParser";
|
|
|
5
5
|
import { supabase } from "../utils/supabase";
|
|
6
6
|
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
|
|
7
7
|
import { rateMap } from "../utils/star-calc";
|
|
8
|
-
|
|
8
|
+
import sharp from "sharp";
|
|
9
9
|
const s3Client = new S3Client({
|
|
10
10
|
region: "auto",
|
|
11
11
|
endpoint: "https://s3.eu-central-003.backblazeb2.com",
|
|
@@ -52,10 +52,19 @@ export async function handler({
|
|
|
52
52
|
sum.update(Buffer.from(bytes));
|
|
53
53
|
const digested = sum.digest("hex");
|
|
54
54
|
const imgkey = `beatmap-img-${Date.now()}-${digested}`;
|
|
55
|
+
|
|
56
|
+
let buffer = Buffer.from([]);
|
|
57
|
+
try {
|
|
58
|
+
buffer = await sharp(parsedData.cover)
|
|
59
|
+
.resize(250)
|
|
60
|
+
.jpeg({ mozjpeg: true })
|
|
61
|
+
.toBuffer();
|
|
62
|
+
} catch (error) {}
|
|
63
|
+
|
|
55
64
|
const command = new PutObjectCommand({
|
|
56
65
|
Bucket: "rhthia-avatars",
|
|
57
66
|
Key: imgkey,
|
|
58
|
-
Body:
|
|
67
|
+
Body: buffer,
|
|
59
68
|
ContentType: "image/jpeg",
|
|
60
69
|
});
|
|
61
70
|
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import z from "zod";
|
|
3
|
+
import { getUser, protectedApi } from "../utils/requestUtils";
|
|
4
|
+
import { supabase } from "../utils/supabase";
|
|
5
|
+
|
|
6
|
+
export const Schema = {
|
|
7
|
+
input: z.strictObject({
|
|
8
|
+
badge: z.string(),
|
|
9
|
+
}),
|
|
10
|
+
output: z.object({
|
|
11
|
+
error: z.string().optional(),
|
|
12
|
+
total: z.number(),
|
|
13
|
+
leaderboard: z
|
|
14
|
+
.array(
|
|
15
|
+
z.object({
|
|
16
|
+
flag: z.string().nullable(),
|
|
17
|
+
id: z.number(),
|
|
18
|
+
username: z.string().nullable(),
|
|
19
|
+
play_count: z.number().nullable(),
|
|
20
|
+
skill_points: z.number().nullable(),
|
|
21
|
+
total_score: z.number().nullable(),
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
.optional(),
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export async function POST(request: Request): Promise<NextResponse> {
|
|
29
|
+
return protectedApi({
|
|
30
|
+
request,
|
|
31
|
+
schema: Schema,
|
|
32
|
+
authorization: () => {},
|
|
33
|
+
activity: handler,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export async function handler(
|
|
38
|
+
data: (typeof Schema)["input"]["_type"]
|
|
39
|
+
): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
|
|
40
|
+
const result = await getLeaderboard(data.badge);
|
|
41
|
+
return NextResponse.json(result);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export async function getLeaderboard(badge: string) {
|
|
45
|
+
const countQuery = await supabase
|
|
46
|
+
.from("profiles")
|
|
47
|
+
.select("ban", { count: "exact", head: true })
|
|
48
|
+
.neq("ban", "excluded")
|
|
49
|
+
.ilike("badges", `%${badge}%`);
|
|
50
|
+
|
|
51
|
+
let { data: queryData, error } = await supabase
|
|
52
|
+
.from("profiles")
|
|
53
|
+
.select("*")
|
|
54
|
+
.neq("ban", "excluded")
|
|
55
|
+
.ilike("badges", `%${badge}%`)
|
|
56
|
+
.order("skill_points", { ascending: false })
|
|
57
|
+
.range(0, 200);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
total: countQuery.count || 0,
|
|
61
|
+
leaderboard: queryData?.map((user) => ({
|
|
62
|
+
flag: user.flag,
|
|
63
|
+
id: user.id,
|
|
64
|
+
play_count: user.play_count,
|
|
65
|
+
skill_points: user.skill_points,
|
|
66
|
+
total_score: user.total_score,
|
|
67
|
+
username: user.username,
|
|
68
|
+
})),
|
|
69
|
+
};
|
|
70
|
+
}
|
package/api/nominateMap.ts
CHANGED
|
@@ -42,7 +42,7 @@ export async function handler(data: (typeof Schema)["input"]["_type"]) {
|
|
|
42
42
|
|
|
43
43
|
const { data: mapData, error } = await supabase
|
|
44
44
|
.from("beatmapPages")
|
|
45
|
-
.select("id,nominations")
|
|
45
|
+
.select("id,nominations,owner")
|
|
46
46
|
.eq("id", data.mapId)
|
|
47
47
|
.single();
|
|
48
48
|
|
|
@@ -50,6 +50,10 @@ export async function handler(data: (typeof Schema)["input"]["_type"]) {
|
|
|
50
50
|
return NextResponse.json({ error: "Bad map" });
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
if (mapData.owner == queryUserData.id) {
|
|
54
|
+
return NextResponse.json({ error: "Can't nominate own map" });
|
|
55
|
+
}
|
|
56
|
+
|
|
53
57
|
if ((mapData.nominations as number[]).includes(queryUserData.id)) {
|
|
54
58
|
return NextResponse.json({ error: "Already nominated" });
|
|
55
59
|
}
|
package/api/submitScore.ts
CHANGED
|
@@ -64,6 +64,21 @@ export async function handler({
|
|
|
64
64
|
.eq("beatmapHash", data.mapHash)
|
|
65
65
|
.single();
|
|
66
66
|
|
|
67
|
+
let { data: beatmapPages, error: bpError } = await supabase
|
|
68
|
+
.from("beatmapPages")
|
|
69
|
+
.select("*")
|
|
70
|
+
.eq("latestBeatmapHash", data.mapHash)
|
|
71
|
+
.single();
|
|
72
|
+
|
|
73
|
+
if (!beatmapPages) {
|
|
74
|
+
return NextResponse.json(
|
|
75
|
+
{
|
|
76
|
+
error: "Map not submitted",
|
|
77
|
+
},
|
|
78
|
+
{ status: 500 }
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
67
82
|
let newPlaycount = 1;
|
|
68
83
|
|
|
69
84
|
if (beatmaps) {
|
|
@@ -79,6 +94,10 @@ export async function handler({
|
|
|
79
94
|
length: data.mapLength,
|
|
80
95
|
});
|
|
81
96
|
|
|
97
|
+
if (beatmapPages.status !== "RANKED") {
|
|
98
|
+
data.sspp = 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
82
101
|
console.log("p1");
|
|
83
102
|
await supabase.from("scores").upsert({
|
|
84
103
|
beatmapHash: data.mapHash,
|
package/index.ts
CHANGED
|
@@ -30,6 +30,11 @@ import { Schema as GetAvatarUploadUrl } from "./api/getAvatarUploadUrl"
|
|
|
30
30
|
export { Schema as SchemaGetAvatarUploadUrl } from "./api/getAvatarUploadUrl"
|
|
31
31
|
export const getAvatarUploadUrl = handleApi({url:"/api/getAvatarUploadUrl",...GetAvatarUploadUrl})
|
|
32
32
|
|
|
33
|
+
// ./api/getBadgedUsers.ts API
|
|
34
|
+
import { Schema as GetBadgedUsers } from "./api/getBadgedUsers"
|
|
35
|
+
export { Schema as SchemaGetBadgedUsers } from "./api/getBadgedUsers"
|
|
36
|
+
export const getBadgedUsers = handleApi({url:"/api/getBadgedUsers",...GetBadgedUsers})
|
|
37
|
+
|
|
33
38
|
// ./api/getBeatmapPage.ts API
|
|
34
39
|
import { Schema as GetBeatmapPage } from "./api/getBeatmapPage"
|
|
35
40
|
export { Schema as SchemaGetBeatmapPage } from "./api/getBeatmapPage"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rhythia-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "127.0.0",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"update": "bun ./scripts/update.ts",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"next": "^14.2.5",
|
|
33
33
|
"osu-parsers": "^4.1.7",
|
|
34
34
|
"osu-standard-stable": "^5.0.0",
|
|
35
|
+
"sharp": "^0.33.5",
|
|
35
36
|
"simple-git": "^3.25.0",
|
|
36
37
|
"supabase": "^1.204.3",
|
|
37
38
|
"tsx": "^4.17.0",
|