rhythia-api 163.0.0 → 165.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/getLeaderboard.ts +20 -3
- package/api/getProfile.ts +11 -11
- package/api/getUserScores.ts +17 -1
- package/api/submitScore.ts +35 -15
- package/index.ts +7 -0
- package/package.json +1 -1
- package/types/database.ts +3 -0
package/api/getLeaderboard.ts
CHANGED
|
@@ -10,6 +10,7 @@ export const Schema = {
|
|
|
10
10
|
session: z.string(),
|
|
11
11
|
page: z.number().default(1),
|
|
12
12
|
flag: z.string().optional(),
|
|
13
|
+
spin: z.boolean().default(false),
|
|
13
14
|
}),
|
|
14
15
|
output: z.object({
|
|
15
16
|
error: z.string().optional(),
|
|
@@ -44,13 +45,23 @@ export async function POST(request: Request): Promise<NextResponse> {
|
|
|
44
45
|
export async function handler(
|
|
45
46
|
data: (typeof Schema)["input"]["_type"]
|
|
46
47
|
): Promise<NextResponse<(typeof Schema)["output"]["_type"]>> {
|
|
47
|
-
const result = await getLeaderboard(
|
|
48
|
+
const result = await getLeaderboard(
|
|
49
|
+
data.page,
|
|
50
|
+
data.session,
|
|
51
|
+
data.spin,
|
|
52
|
+
data.flag
|
|
53
|
+
);
|
|
48
54
|
return NextResponse.json(result);
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
const VIEW_PER_PAGE = 50;
|
|
52
58
|
|
|
53
|
-
export async function getLeaderboard(
|
|
59
|
+
export async function getLeaderboard(
|
|
60
|
+
page = 1,
|
|
61
|
+
session: string,
|
|
62
|
+
spin: boolean,
|
|
63
|
+
flag?: string
|
|
64
|
+
) {
|
|
54
65
|
const getUserData = (await getUserBySession(session)) as User;
|
|
55
66
|
|
|
56
67
|
let leaderPosition = 0;
|
|
@@ -86,7 +97,12 @@ export async function getLeaderboard(page = 1, session: string, flag?: string) {
|
|
|
86
97
|
query.eq("flag", flag);
|
|
87
98
|
}
|
|
88
99
|
|
|
89
|
-
|
|
100
|
+
if (spin) {
|
|
101
|
+
query.order("spin_skill_points", { ascending: false });
|
|
102
|
+
} else {
|
|
103
|
+
query.order("skill_points", { ascending: false });
|
|
104
|
+
}
|
|
105
|
+
|
|
90
106
|
query.range(startPage, endPage);
|
|
91
107
|
|
|
92
108
|
let { data: queryData, error } = await query;
|
|
@@ -100,6 +116,7 @@ export async function getLeaderboard(page = 1, session: string, flag?: string) {
|
|
|
100
116
|
id: user.id,
|
|
101
117
|
play_count: user.play_count,
|
|
102
118
|
skill_points: user.skill_points,
|
|
119
|
+
spin_skill_points: user.spin_skill_points,
|
|
103
120
|
total_score: user.total_score,
|
|
104
121
|
username: user.username,
|
|
105
122
|
})),
|
package/api/getProfile.ts
CHANGED
|
@@ -109,21 +109,21 @@ export async function handler(
|
|
|
109
109
|
profiles = queryData;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
|
|
113
|
-
const { data: activityData } = await supabase
|
|
114
|
-
.from("profileActivities")
|
|
115
|
-
.select("*")
|
|
116
|
-
.eq("uid", user.id)
|
|
117
|
-
.single();
|
|
118
|
-
|
|
119
|
-
//last 30 minutes
|
|
120
|
-
if (activityData && activityData.last_activity) {
|
|
121
|
-
isOnline = Date.now() - activityData.last_activity < 1800000;
|
|
122
|
-
}
|
|
123
112
|
}
|
|
124
113
|
|
|
125
114
|
const user = profiles[0];
|
|
126
115
|
|
|
116
|
+
const { data: activityData } = await supabase
|
|
117
|
+
.from("profileActivities")
|
|
118
|
+
.select("*")
|
|
119
|
+
.eq("uid", user.uid || "")
|
|
120
|
+
.single();
|
|
121
|
+
|
|
122
|
+
//last 30 minutes
|
|
123
|
+
if (activityData && activityData.last_activity) {
|
|
124
|
+
isOnline = Date.now() - activityData.last_activity < 1800000;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
127
|
// Query to count how many players have more skill points than the specific player
|
|
128
128
|
const { count: playersWithMorePoints, error: rankError } = await supabase
|
|
129
129
|
.from("profiles")
|
package/api/getUserScores.ts
CHANGED
|
@@ -50,6 +50,12 @@ export const Schema = {
|
|
|
50
50
|
})
|
|
51
51
|
)
|
|
52
52
|
.optional(),
|
|
53
|
+
stats: z
|
|
54
|
+
.object({
|
|
55
|
+
totalScores: z.number(),
|
|
56
|
+
spinScores: z.number(),
|
|
57
|
+
})
|
|
58
|
+
.optional(),
|
|
53
59
|
}),
|
|
54
60
|
};
|
|
55
61
|
|
|
@@ -105,13 +111,19 @@ export async function handler(
|
|
|
105
111
|
|
|
106
112
|
if (scores2 == null) return NextResponse.json({ error: "No scores" });
|
|
107
113
|
|
|
114
|
+
let spinScores = 0;
|
|
115
|
+
let totalScores = scores2.length;
|
|
108
116
|
let hashMap: Record<string, { awarded_sp: number; score: any }> = {};
|
|
109
117
|
|
|
110
118
|
for (const score of scores2) {
|
|
111
|
-
const { beatmapHash, awarded_sp } = score;
|
|
119
|
+
const { beatmapHash, awarded_sp, spin } = score;
|
|
112
120
|
|
|
113
121
|
if (!beatmapHash || !awarded_sp) continue;
|
|
114
122
|
|
|
123
|
+
if (score.spin) {
|
|
124
|
+
spinScores++;
|
|
125
|
+
}
|
|
126
|
+
|
|
115
127
|
if (!hashMap[beatmapHash] || hashMap[beatmapHash].awarded_sp < awarded_sp) {
|
|
116
128
|
hashMap[beatmapHash] = { awarded_sp, score };
|
|
117
129
|
}
|
|
@@ -155,5 +167,9 @@ export async function handler(
|
|
|
155
167
|
speed: s.speed,
|
|
156
168
|
spin: s.spin,
|
|
157
169
|
})),
|
|
170
|
+
stats: {
|
|
171
|
+
totalScores,
|
|
172
|
+
spinScores,
|
|
173
|
+
},
|
|
158
174
|
});
|
|
159
175
|
}
|
package/api/submitScore.ts
CHANGED
|
@@ -205,10 +205,9 @@ export async function handler({
|
|
|
205
205
|
});
|
|
206
206
|
console.log("p2");
|
|
207
207
|
|
|
208
|
-
let totalSp = 0;
|
|
209
208
|
let { data: scores2, error: errorsp } = await supabase
|
|
210
209
|
.from("scores")
|
|
211
|
-
.select(`awarded_sp,beatmapHash`)
|
|
210
|
+
.select(`awarded_sp,beatmapHash,spin`)
|
|
212
211
|
.eq("userId", userData.id)
|
|
213
212
|
.neq("awarded_sp", 0)
|
|
214
213
|
.eq("passed", true)
|
|
@@ -216,37 +215,58 @@ export async function handler({
|
|
|
216
215
|
|
|
217
216
|
if (scores2 == null) return NextResponse.json({ error: "No scores" });
|
|
218
217
|
|
|
219
|
-
let
|
|
218
|
+
let allHashMap: Record<string, number> = {};
|
|
219
|
+
let spinHashMap: Record<string, number> = {};
|
|
220
220
|
|
|
221
221
|
for (const score of scores2) {
|
|
222
222
|
const { beatmapHash, awarded_sp } = score;
|
|
223
223
|
|
|
224
224
|
if (!beatmapHash || !awarded_sp) continue;
|
|
225
225
|
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
// Normal Scores
|
|
227
|
+
if (!allHashMap[beatmapHash] || allHashMap[beatmapHash] < awarded_sp) {
|
|
228
|
+
allHashMap[beatmapHash] = awarded_sp;
|
|
228
229
|
}
|
|
229
|
-
}
|
|
230
|
-
let weight = 100;
|
|
231
|
-
const values = Object.values(hashMap);
|
|
232
|
-
values.sort((a, b) => b - a);
|
|
233
|
-
|
|
234
|
-
for (const score of values) {
|
|
235
|
-
totalSp += ((score || 0) * weight) / 100;
|
|
236
|
-
weight = weight * 0.97;
|
|
237
230
|
|
|
238
|
-
|
|
239
|
-
|
|
231
|
+
// Spin Scores
|
|
232
|
+
if (score.spin) {
|
|
233
|
+
if (!spinHashMap[beatmapHash] || spinHashMap[beatmapHash] < awarded_sp) {
|
|
234
|
+
spinHashMap[beatmapHash] = awarded_sp;
|
|
235
|
+
}
|
|
240
236
|
}
|
|
241
237
|
}
|
|
238
|
+
// All scores
|
|
239
|
+
const totalSp = weightCalculate(allHashMap);
|
|
240
|
+
|
|
241
|
+
// Only spin scores
|
|
242
|
+
const spinTotalSp = weightCalculate(spinHashMap);
|
|
242
243
|
|
|
243
244
|
await supabase.from("profiles").upsert({
|
|
244
245
|
id: userData.id,
|
|
245
246
|
play_count: (userData.play_count || 0) + 1,
|
|
246
247
|
skill_points: Math.round(totalSp * 100) / 100,
|
|
248
|
+
spin_skill_points: Math.round(spinTotalSp * 100) / 100,
|
|
247
249
|
squares_hit: (userData.squares_hit || 0) + data.hits,
|
|
248
250
|
});
|
|
249
251
|
console.log("p3");
|
|
250
252
|
|
|
251
253
|
return NextResponse.json({});
|
|
252
254
|
}
|
|
255
|
+
|
|
256
|
+
export function weightCalculate(hashMap: Record<string, number>) {
|
|
257
|
+
let totalSp = 0;
|
|
258
|
+
let weight = 100;
|
|
259
|
+
|
|
260
|
+
const values = Object.values(hashMap);
|
|
261
|
+
values.sort((a, b) => b - a);
|
|
262
|
+
|
|
263
|
+
for (const score of values) {
|
|
264
|
+
totalSp += ((score || 0) * weight) / 100;
|
|
265
|
+
weight = weight * 0.97;
|
|
266
|
+
|
|
267
|
+
if (weight < 5) {
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return totalSp;
|
|
272
|
+
}
|
package/index.ts
CHANGED
|
@@ -331,6 +331,7 @@ export const Schema = {
|
|
|
331
331
|
session: z.string(),
|
|
332
332
|
page: z.number().default(1),
|
|
333
333
|
flag: z.string().optional(),
|
|
334
|
+
spin: z.boolean().default(false),
|
|
334
335
|
}),
|
|
335
336
|
output: z.object({
|
|
336
337
|
error: z.string().optional(),
|
|
@@ -583,6 +584,12 @@ export const Schema = {
|
|
|
583
584
|
})
|
|
584
585
|
)
|
|
585
586
|
.optional(),
|
|
587
|
+
stats: z
|
|
588
|
+
.object({
|
|
589
|
+
totalScores: z.number(),
|
|
590
|
+
spinScores: z.number(),
|
|
591
|
+
})
|
|
592
|
+
.optional(),
|
|
586
593
|
}),
|
|
587
594
|
};*/
|
|
588
595
|
import { Schema as GetUserScores } from "./api/getUserScores"
|
package/package.json
CHANGED
package/types/database.ts
CHANGED
|
@@ -210,6 +210,7 @@ export type Database = {
|
|
|
210
210
|
profile_image: string | null
|
|
211
211
|
sigma_rank: number | null
|
|
212
212
|
skill_points: number | null
|
|
213
|
+
spin_skill_points: number
|
|
213
214
|
squares_hit: number | null
|
|
214
215
|
total_score: number | null
|
|
215
216
|
uid: string | null
|
|
@@ -231,6 +232,7 @@ export type Database = {
|
|
|
231
232
|
profile_image?: string | null
|
|
232
233
|
sigma_rank?: number | null
|
|
233
234
|
skill_points?: number | null
|
|
235
|
+
spin_skill_points?: number
|
|
234
236
|
squares_hit?: number | null
|
|
235
237
|
total_score?: number | null
|
|
236
238
|
uid?: string | null
|
|
@@ -252,6 +254,7 @@ export type Database = {
|
|
|
252
254
|
profile_image?: string | null
|
|
253
255
|
sigma_rank?: number | null
|
|
254
256
|
skill_points?: number | null
|
|
257
|
+
spin_skill_points?: number
|
|
255
258
|
squares_hit?: number | null
|
|
256
259
|
total_score?: number | null
|
|
257
260
|
uid?: string | null
|