diff --git a/src/index.ts b/src/index.ts index c555f1d..8d61b46 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,6 +8,7 @@ import { handler as launcherVersionsHandler } from './routes/launcher/versions' import { handler as launcherLatestHandler } from './routes/launcher/latest' import { handler as launcherLoaderLatestHandler } from './routes/launcher/loader/latest' import { handler as launcherLoaderUpdateDataHandler } from './routes/launcher/loader/update-data' +import { handler as berrydashLeaderboardsHandler } from './routes/berrydash/leaderboards' dotenv.config() @@ -25,6 +26,21 @@ app.get('/launcher/loader/latest', launcherLoaderLatestHandler) app.get('/launcher/loader/update-data', context => launcherLoaderUpdateDataHandler(context) ) +app.get('/berrydash/leaderboards/score', context => + berrydashLeaderboardsHandler(context, 0) +) +app.post('/berrydash/leaderboards/berry', context => + berrydashLeaderboardsHandler(context, 1) +) +app.get('/berrydash/leaderboards/coin', context => + berrydashLeaderboardsHandler(context, 2) +) +app.get('/berrydash/leaderboards/legacy', context => + berrydashLeaderboardsHandler(context, 3) +) +app.get('/berrydash/leaderboards/total', context => + berrydashLeaderboardsHandler(context, 4) +) app.all('*', () => jsonResponse( { diff --git a/src/routes/berrydash/leaderboards.ts b/src/routes/berrydash/leaderboards.ts new file mode 100644 index 0000000..dbba77b --- /dev/null +++ b/src/routes/berrydash/leaderboards.ts @@ -0,0 +1,144 @@ +import { Context } from 'elysia' +import { getDatabaseConnection, jsonResponse } from '../../lib/util' +import { + berryDashMarketplaceIcons, + berryDashUserData, + users +} from '../../lib/tables' +import { eq } from 'drizzle-orm' + +export async function handler (context: Context, type: number) { + const dbInfo0 = getDatabaseConnection(0) + const dbInfo1 = getDatabaseConnection(1) + + if (!dbInfo0 || !dbInfo1) + return jsonResponse({ error: 'Failed to connect to database' }, 500) + + const { connection: connection0, db: db0 } = dbInfo0 + const { connection: connection1, db: db1 } = dbInfo1 + + let request_value = '' + if (type == 0) { + request_value = 'highScore' + } else if (type == 1) { + const body = context.body as { type: number } + switch (body.type) { + case 1: + request_value = 'totalPoisonBerries' + break + case 2: + request_value = 'totalSlowBerries' + break + case 3: + request_value = 'totalUltraBerries' + break + case 4: + request_value = 'totalSpeedyBerries' + break + case 5: + request_value = 'totalCoinBerries' + break + case 6: + request_value = 'totalRandomBerries' + break + case 7: + request_value = 'totalAntiBerries' + break + default: + request_value = 'totalNormalBerries' + break + } + } else if (type != 2 && type != 3 && type != 4) { + connection0.end() + connection1.end() + return jsonResponse({ success: false, message: 'Invalid Type', data: null }) + } + + const userList = await db0 + .select({ + username: users.username, + id: users.id + }) + .from(users) + .where(eq(users.leaderboardsBanned, false)) + .execute() + const userDataList = await db1 + .select({ + id: berryDashUserData.id, + saveData: berryDashUserData.saveData, + legacyHighScore: berryDashUserData.legacyHighScore + }) + .from(berryDashUserData) + .execute() + const completeUserList = userList.map(user => { + const data = userDataList.find(d => d.id === user.id) + return { + ...user, + ...(data ? data : {}) + } + }) + + let mapped: Record = {} + let icons: Record = {} + for (const row of completeUserList) { + const savedata = row.saveData ? JSON.parse(row.saveData) : null + if (!savedata) continue + + let value = 0 + if (type === 4) { + const berries = [ + 'totalNormalBerries', + 'totalPoisonBerries', + 'totalSlowBerries', + 'totalUltraBerries', + 'totalSpeedyBerries', + 'totalCoinBerries', + 'totalRandomBerries', + 'totalAntiBerries' + ] + value = berries.reduce( + (acc, b) => acc + parseInt(savedata.gameStore?.[b] ?? 0, 10), + 0 + ) + } else if (type === 2) { + value = parseInt(savedata.bird?.customIcon?.balance ?? 0, 10) + } else if (type === 3) { + value = parseInt(String(row.legacyHighScore ?? 0), 10) + } else { + value = parseInt(savedata.gameStore?.[request_value] ?? 0, 10) + } + if (value <= 0) continue + + const customIcon = savedata.bird?.customIcon?.selected ?? null + + if (customIcon && customIcon.length === 36 && !icons[customIcon]) { + const [iconRow] = await db1 + .select({ data: berryDashMarketplaceIcons.data }) + .from(berryDashMarketplaceIcons) + .where(eq(berryDashMarketplaceIcons.uuid, customIcon)) + .limit(1) + .execute() + + if (iconRow) icons[customIcon] = iconRow.data + } + + mapped[row.id] = { + username: row.username, + value, + icon: savedata.bird?.icon ?? 1, + overlay: savedata.bird?.overlay ?? 0, + birdColor: savedata.settings?.colors?.icon ?? [255, 255, 255], + overlayColor: savedata.settings?.colors?.overlay ?? [255, 255, 255], + customIcon + } + } + + connection0.end() + connection1.end() + + return jsonResponse({ + success: true, + message: null, + data: { entries: mapped, customIcons: icons } + }) +}