feat(leaderboard): missions & guilds leaderboard #1338
@ -6,7 +6,14 @@ export const leaderboardController: RequestHandler = async (req, res) => {
|
||||
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
|
||||
const payload = JSON.parse(String(req.body)) as ILeaderboardRequest;
|
||||
res.json({
|
||||
results: await getLeaderboard(payload.field, payload.before, payload.after, payload.guildId, payload.pivotId)
|
||||
results: await getLeaderboard(
|
||||
payload.field,
|
||||
payload.before,
|
||||
payload.after,
|
||||
payload.guildId,
|
||||
payload.pivotId,
|
||||
payload.guildTier
|
||||
)
|
||||
});
|
||||
};
|
||||
|
||||
@ -16,4 +23,5 @@ interface ILeaderboardRequest {
|
||||
after: number;
|
||||
guildId?: string;
|
||||
pivotId?: string;
|
||||
guildTier?: number;
|
||||
}
|
||||
|
@ -8,7 +8,8 @@ const leaderboardEntrySchema = new Schema<ILeaderboardEntryDatabase>(
|
||||
displayName: { type: String, required: true },
|
||||
score: { type: Number, required: true },
|
||||
guildId: Schema.Types.ObjectId,
|
||||
expiry: { type: Date, required: true }
|
||||
expiry: { type: Date, required: true },
|
||||
guildTier: Number
|
||||
},
|
||||
{ id: false }
|
||||
);
|
||||
|
@ -1,14 +1,15 @@
|
||||
import { Guild } from "../models/guildModel";
|
||||
import { Leaderboard, TLeaderboardEntryDocument } from "../models/leaderboardModel";
|
||||
import { ILeaderboardEntryClient } from "../types/leaderboardTypes";
|
||||
|
||||
export const submitLeaderboardScore = async (
|
||||
schedule: "weekly" | "daily",
|
||||
leaderboard: string,
|
||||
ownerId: string,
|
||||
displayName: string,
|
||||
score: number,
|
||||
guildId?: string
|
||||
): Promise<void> => {
|
||||
const schedule = leaderboard.split(".")[0] as "daily" | "weekly";
|
||||
let expiry: Date;
|
||||
if (schedule == "daily") {
|
||||
expiry = new Date(Math.trunc(Date.now() / 86400000) * 86400000 + 86400000);
|
||||
@ -21,10 +22,18 @@ export const submitLeaderboardScore = async (
|
||||
expiry = new Date(weekEnd);
|
||||
}
|
||||
await Leaderboard.findOneAndUpdate(
|
||||
{ leaderboard, ownerId },
|
||||
{ leaderboard: `${schedule}.accounts.${leaderboard}`, ownerId },
|
||||
{ $max: { score }, $set: { displayName, guildId, expiry } },
|
||||
{ upsert: true }
|
||||
);
|
||||
if (guildId) {
|
||||
const guild = (await Guild.findById(guildId, "Name Tier"))!;
|
||||
await Leaderboard.findOneAndUpdate(
|
||||
{ leaderboard: `${schedule}.guilds.${leaderboard}`, ownerId: guildId },
|
||||
{ $max: { score }, $set: { displayName: guild.Name, guildTier: guild.Tier, expiry } },
|
||||
{ upsert: true }
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const getLeaderboard = async (
|
||||
@ -32,12 +41,16 @@ export const getLeaderboard = async (
|
||||
before: number,
|
||||
after: number,
|
||||
guildId?: string,
|
||||
pivotId?: string
|
||||
pivotId?: string,
|
||||
guildTier?: number
|
||||
): Promise<ILeaderboardEntryClient[]> => {
|
||||
const filter: { leaderboard: string; guildId?: string } = { leaderboard };
|
||||
const filter: { leaderboard: string; guildId?: string; guildTier?: number } = { leaderboard };
|
||||
if (guildId) {
|
||||
filter.guildId = guildId;
|
||||
}
|
||||
if (guildTier) {
|
||||
filter.guildTier = guildTier;
|
||||
}
|
||||
|
||||
let entries: TLeaderboardEntryDocument[];
|
||||
let r: number;
|
||||
|
@ -286,6 +286,15 @@ export const updateStats = async (accountOwnerId: string, payload: IStatsUpdate)
|
||||
} else {
|
||||
playerStats.Missions.push({ type: type, highScore });
|
||||
}
|
||||
await submitLeaderboardScore(
|
||||
"weekly",
|
||||
type,
|
||||
accountOwnerId,
|
||||
payload.displayName,
|
||||
highScore,
|
||||
payload.guildId
|
||||
);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
@ -304,27 +313,42 @@ export const updateStats = async (accountOwnerId: string, payload: IStatsUpdate)
|
||||
}
|
||||
|
||||
await submitLeaderboardScore(
|
||||
"daily.accounts." + race,
|
||||
"daily",
|
||||
race,
|
||||
accountOwnerId,
|
||||
payload.displayName,
|
||||
highScore
|
||||
highScore,
|
||||
payload.guildId
|
||||
Sainan marked this conversation as resolved
Outdated
|
||||
);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "ZephyrScore":
|
||||
case "SentinelGameScore":
|
||||
case "CaliberChicksScore":
|
||||
playerStats[category] ??= 0;
|
||||
if (data > playerStats[category]) playerStats[category] = data as number;
|
||||
break;
|
||||
|
||||
case "SentinelGameScore":
|
||||
playerStats[category] ??= 0;
|
||||
if (data > playerStats[category]) playerStats[category] = data as number;
|
||||
await submitLeaderboardScore(
|
||||
"weekly",
|
||||
category,
|
||||
accountOwnerId,
|
||||
payload.displayName,
|
||||
data as number,
|
||||
payload.guildId
|
||||
);
|
||||
break;
|
||||
|
||||
case "DojoObstacleScore":
|
||||
playerStats[category] ??= 0;
|
||||
if (data > playerStats[category]) playerStats[category] = data as number;
|
||||
await submitLeaderboardScore(
|
||||
"weekly.accounts." + category,
|
||||
"weekly",
|
||||
category,
|
||||
accountOwnerId,
|
||||
payload.displayName,
|
||||
data as number,
|
||||
@ -350,7 +374,8 @@ export const updateStats = async (accountOwnerId: string, payload: IStatsUpdate)
|
||||
}
|
||||
if (data > playerStats[category]) playerStats[category] = data as number;
|
||||
await submitLeaderboardScore(
|
||||
"weekly.accounts." + category,
|
||||
"weekly",
|
||||
category,
|
||||
accountOwnerId,
|
||||
payload.displayName,
|
||||
data as number
|
||||
|
@ -7,6 +7,7 @@ export interface ILeaderboardEntryDatabase {
|
||||
score: number;
|
||||
guildId?: Types.ObjectId;
|
||||
expiry: Date;
|
||||
guildTier?: number;
|
||||
}
|
||||
|
||||
export interface ILeaderboardEntryClient {
|
||||
|
Loading…
x
Reference in New Issue
Block a user
You should revert this change, it is not correct or faithful.
K-drive races have clans leaderboard in ESC menu
But not for clan tiers I mean. Also, the
guildId
is undefined in the upload request for K-Drive races, so this is wrong either way.They have buttons for that leaderboards but seams missing

guildId
is bugYeah exactly. Then again, maybe the bug is in the way the client sends the request...