rhythia-api 166.0.0 → 168.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/getPublicStats.ts +9 -1
- package/api/postBeatmapComment.ts +1 -0
- package/api/submitScore.ts +128 -1
- package/index.ts +2 -0
- package/package.json +1 -1
- package/types/database.ts +15 -0
- package/utils/requestUtils.ts +3 -0
package/api/getPublicStats.ts
CHANGED
|
@@ -9,6 +9,7 @@ export const Schema = {
|
|
|
9
9
|
profiles: z.number(),
|
|
10
10
|
beatmaps: z.number(),
|
|
11
11
|
scores: z.number(),
|
|
12
|
+
onlineUsers: z.number(),
|
|
12
13
|
lastBeatmaps: z.array(
|
|
13
14
|
z.object({
|
|
14
15
|
id: z.number().nullable().optional(),
|
|
@@ -118,12 +119,19 @@ export async function handler(data: (typeof Schema)["input"]["_type"]) {
|
|
|
118
119
|
|
|
119
120
|
const countScoresQuery = await supabase
|
|
120
121
|
.from("scores")
|
|
121
|
-
.select("
|
|
122
|
+
.select("id", { count: "exact", head: true });
|
|
123
|
+
|
|
124
|
+
// 30 minutes activity
|
|
125
|
+
const countOnline = await supabase
|
|
126
|
+
.from("profileActivities")
|
|
127
|
+
.select("*", { count: "exact", head: true })
|
|
128
|
+
.gt("last_activity", Date.now() - 1800000);
|
|
122
129
|
|
|
123
130
|
return NextResponse.json({
|
|
124
131
|
beatmaps: countBeatmapsQuery.count,
|
|
125
132
|
profiles: countProfilesQuery.count,
|
|
126
133
|
scores: countScoresQuery.count,
|
|
134
|
+
onlineUsers: countOnline.count,
|
|
127
135
|
lastBeatmaps: beatmapPage?.map((e) => ({
|
|
128
136
|
playcount: e.beatmaps?.playcount,
|
|
129
137
|
created_at: e.created_at,
|
|
@@ -40,6 +40,7 @@ export async function handler({
|
|
|
40
40
|
.single();
|
|
41
41
|
|
|
42
42
|
if (!userData) return NextResponse.json({ error: "No user." });
|
|
43
|
+
if (userData.ban !== "cool") return NextResponse.json({ error: "Error" });
|
|
43
44
|
|
|
44
45
|
const upserted = await supabase
|
|
45
46
|
.from("beatmapPageComments")
|
package/api/submitScore.ts
CHANGED
|
@@ -21,6 +21,7 @@ export const Schema = {
|
|
|
21
21
|
mods: z.array(z.string()),
|
|
22
22
|
additionalData: z.any(),
|
|
23
23
|
spin: z.boolean(),
|
|
24
|
+
virtualStars: z.number(),
|
|
24
25
|
}),
|
|
25
26
|
}),
|
|
26
27
|
output: z.object({
|
|
@@ -75,6 +76,7 @@ export async function handler({
|
|
|
75
76
|
mods: data.mods,
|
|
76
77
|
additionalData: data.additionalData,
|
|
77
78
|
spin: data.spin,
|
|
79
|
+
virtualStars: data.virtualStars,
|
|
78
80
|
})
|
|
79
81
|
) {
|
|
80
82
|
return NextResponse.json(
|
|
@@ -172,7 +174,7 @@ export async function handler({
|
|
|
172
174
|
multiplierMod *= Math.pow(0.95, data.misses);
|
|
173
175
|
}
|
|
174
176
|
|
|
175
|
-
if (beatmaps.starRating) {
|
|
177
|
+
if (beatmaps.starRating && beatmaps.starRating == data.virtualStars) {
|
|
176
178
|
awarded_sp = calculatePerformancePoints(
|
|
177
179
|
data.speed * beatmaps.starRating * multiplierMod,
|
|
178
180
|
accurracy
|
|
@@ -250,6 +252,22 @@ export async function handler({
|
|
|
250
252
|
});
|
|
251
253
|
console.log("p3");
|
|
252
254
|
|
|
255
|
+
if (awarded_sp > 99) {
|
|
256
|
+
await postToWebhooks({
|
|
257
|
+
rp: Math.round(awarded_sp * 100) / 100,
|
|
258
|
+
username: userData.username || "",
|
|
259
|
+
userid: userData.id,
|
|
260
|
+
avatar: userData.avatar_url || "",
|
|
261
|
+
mapimage: beatmaps.imageLarge || "",
|
|
262
|
+
spin: data.spin,
|
|
263
|
+
speed: data.speed,
|
|
264
|
+
accuracy: accurracy,
|
|
265
|
+
mapname: beatmaps.title || "",
|
|
266
|
+
mapid: beatmapPages.id || 0,
|
|
267
|
+
misses: data.misses || 0,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
253
271
|
return NextResponse.json({});
|
|
254
272
|
}
|
|
255
273
|
|
|
@@ -270,3 +288,112 @@ export function weightCalculate(hashMap: Record<string, number>) {
|
|
|
270
288
|
}
|
|
271
289
|
return totalSp;
|
|
272
290
|
}
|
|
291
|
+
|
|
292
|
+
const webHookTemplate = {
|
|
293
|
+
content: null,
|
|
294
|
+
embeds: [
|
|
295
|
+
{
|
|
296
|
+
title: "Captain Lou Albano - Do the Mario",
|
|
297
|
+
url: "https://www.rhythia.com/maps/4469",
|
|
298
|
+
color: 9633967,
|
|
299
|
+
fields: [
|
|
300
|
+
{
|
|
301
|
+
name: "Rhythm Points",
|
|
302
|
+
value: "424 RP",
|
|
303
|
+
inline: true,
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
name: "Accuracy",
|
|
307
|
+
value: "100%",
|
|
308
|
+
inline: true,
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: "Speed",
|
|
312
|
+
value: "1.45x",
|
|
313
|
+
inline: true,
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
name: "Playstyle",
|
|
317
|
+
value: "Spin",
|
|
318
|
+
inline: true,
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: "Misses",
|
|
322
|
+
value: "0",
|
|
323
|
+
inline: true,
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
author: {
|
|
327
|
+
name: "cunev",
|
|
328
|
+
url: "https://www.rhythia.com/player/0",
|
|
329
|
+
icon_url:
|
|
330
|
+
"https://static.rhythia.com/user-avatar-1735149648551-a2a8cfbe-af5d-46e8-a19a-be2339c1679a",
|
|
331
|
+
},
|
|
332
|
+
footer: {
|
|
333
|
+
text: "Sun, 22 Dec 2024 22:40:17 GMT",
|
|
334
|
+
},
|
|
335
|
+
thumbnail: {
|
|
336
|
+
url: "https://static.rhythia.com/beatmap-img-1735223264605-eliuka_dj_sharpnel_-_we_luv_lamalarge",
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
],
|
|
340
|
+
attachments: [],
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
export async function postToWebhooks({
|
|
344
|
+
rp,
|
|
345
|
+
username,
|
|
346
|
+
userid,
|
|
347
|
+
avatar,
|
|
348
|
+
mapimage,
|
|
349
|
+
spin,
|
|
350
|
+
speed,
|
|
351
|
+
accuracy,
|
|
352
|
+
mapname,
|
|
353
|
+
mapid,
|
|
354
|
+
misses,
|
|
355
|
+
}: {
|
|
356
|
+
rp: number;
|
|
357
|
+
username: string;
|
|
358
|
+
userid: number;
|
|
359
|
+
avatar: string;
|
|
360
|
+
mapimage: string;
|
|
361
|
+
spin: boolean;
|
|
362
|
+
speed: number;
|
|
363
|
+
accuracy: number;
|
|
364
|
+
mapname: string;
|
|
365
|
+
mapid: number;
|
|
366
|
+
misses: number;
|
|
367
|
+
}) {
|
|
368
|
+
const webHooks = await supabase.from("discordWebhooks").select("*");
|
|
369
|
+
|
|
370
|
+
if (!webHooks.data) return;
|
|
371
|
+
|
|
372
|
+
for (const webhook of webHooks.data) {
|
|
373
|
+
const webhookUrl = webhook.webhook_link;
|
|
374
|
+
|
|
375
|
+
const embed = webHookTemplate.embeds[0];
|
|
376
|
+
embed.title = mapname;
|
|
377
|
+
embed.url = `https://www.rhythia.com/maps/${mapid}`;
|
|
378
|
+
embed.fields[0].value = `${rp} RP`;
|
|
379
|
+
embed.fields[1].value = `${Math.round(accuracy * 10000) / 100}%`;
|
|
380
|
+
embed.fields[2].value = `${speed}x`;
|
|
381
|
+
embed.fields[3].value = spin ? "Spin" : "Lock";
|
|
382
|
+
embed.fields[4].value = `${misses} misses`;
|
|
383
|
+
embed.author.name = username;
|
|
384
|
+
embed.author.url = `https://www.rhythia.com/player/${userid}`;
|
|
385
|
+
embed.author.icon_url = avatar;
|
|
386
|
+
embed.thumbnail.url = mapimage;
|
|
387
|
+
if (mapimage.includes("backfill")) {
|
|
388
|
+
embed.thumbnail.url = "https://www.rhythia.com/unkimg.png";
|
|
389
|
+
}
|
|
390
|
+
embed.footer.text = new Date().toUTCString();
|
|
391
|
+
await fetch(webhookUrl, {
|
|
392
|
+
method: "POST",
|
|
393
|
+
headers: {
|
|
394
|
+
"Content-Type": "application/json",
|
|
395
|
+
},
|
|
396
|
+
body: JSON.stringify(webHookTemplate),
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
}
|
package/index.ts
CHANGED
|
@@ -445,6 +445,7 @@ export const Schema = {
|
|
|
445
445
|
profiles: z.number(),
|
|
446
446
|
beatmaps: z.number(),
|
|
447
447
|
scores: z.number(),
|
|
448
|
+
onlineUsers: z.number(),
|
|
448
449
|
lastBeatmaps: z.array(
|
|
449
450
|
z.object({
|
|
450
451
|
id: z.number().nullable().optional(),
|
|
@@ -704,6 +705,7 @@ export const Schema = {
|
|
|
704
705
|
mods: z.array(z.string()),
|
|
705
706
|
additionalData: z.any(),
|
|
706
707
|
spin: z.boolean(),
|
|
708
|
+
virtualStars: z.number(),
|
|
707
709
|
}),
|
|
708
710
|
}),
|
|
709
711
|
output: z.object({
|
package/package.json
CHANGED
package/types/database.ts
CHANGED
|
@@ -153,6 +153,21 @@ export type Database = {
|
|
|
153
153
|
}
|
|
154
154
|
Relationships: []
|
|
155
155
|
}
|
|
156
|
+
discordWebhooks: {
|
|
157
|
+
Row: {
|
|
158
|
+
id: number
|
|
159
|
+
webhook_link: string
|
|
160
|
+
}
|
|
161
|
+
Insert: {
|
|
162
|
+
id?: number
|
|
163
|
+
webhook_link?: string
|
|
164
|
+
}
|
|
165
|
+
Update: {
|
|
166
|
+
id?: number
|
|
167
|
+
webhook_link?: string
|
|
168
|
+
}
|
|
169
|
+
Relationships: []
|
|
170
|
+
}
|
|
156
171
|
passkeys: {
|
|
157
172
|
Row: {
|
|
158
173
|
email: string
|
package/utils/requestUtils.ts
CHANGED
|
@@ -22,6 +22,9 @@ export async function protectedApi({
|
|
|
22
22
|
try {
|
|
23
23
|
const toParse = await request.json();
|
|
24
24
|
const data = schema.input.parse(toParse);
|
|
25
|
+
|
|
26
|
+
console.log({ ...data, session: undefined });
|
|
27
|
+
|
|
25
28
|
setActivity(data);
|
|
26
29
|
if (authorization) {
|
|
27
30
|
const authorizationResponse = await authorization(data);
|