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)}`);
|
logger.debug(`data provided to ${req.path}: ${String(req.body)}`);
|
||||||
const payload = JSON.parse(String(req.body)) as ILeaderboardRequest;
|
const payload = JSON.parse(String(req.body)) as ILeaderboardRequest;
|
||||||
res.json({
|
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;
|
after: number;
|
||||||
guildId?: string;
|
guildId?: string;
|
||||||
pivotId?: string;
|
pivotId?: string;
|
||||||
|
guildTier?: number;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@ const leaderboardEntrySchema = new Schema<ILeaderboardEntryDatabase>(
|
|||||||
displayName: { type: String, required: true },
|
displayName: { type: String, required: true },
|
||||||
score: { type: Number, required: true },
|
score: { type: Number, required: true },
|
||||||
guildId: Schema.Types.ObjectId,
|
guildId: Schema.Types.ObjectId,
|
||||||
expiry: { type: Date, required: true }
|
expiry: { type: Date, required: true },
|
||||||
|
guildTier: Number
|
||||||
},
|
},
|
||||||
{ id: false }
|
{ id: false }
|
||||||
);
|
);
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
|
import { Guild } from "../models/guildModel";
|
||||||
import { Leaderboard, TLeaderboardEntryDocument } from "../models/leaderboardModel";
|
import { Leaderboard, TLeaderboardEntryDocument } from "../models/leaderboardModel";
|
||||||
import { ILeaderboardEntryClient } from "../types/leaderboardTypes";
|
import { ILeaderboardEntryClient } from "../types/leaderboardTypes";
|
||||||
|
|
||||||
export const submitLeaderboardScore = async (
|
export const submitLeaderboardScore = async (
|
||||||
|
schedule: "weekly" | "daily",
|
||||||
leaderboard: string,
|
leaderboard: string,
|
||||||
ownerId: string,
|
ownerId: string,
|
||||||
displayName: string,
|
displayName: string,
|
||||||
score: number,
|
score: number,
|
||||||
guildId?: string
|
guildId?: string
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const schedule = leaderboard.split(".")[0] as "daily" | "weekly";
|
|
||||||
let expiry: Date;
|
let expiry: Date;
|
||||||
if (schedule == "daily") {
|
if (schedule == "daily") {
|
||||||
expiry = new Date(Math.trunc(Date.now() / 86400000) * 86400000 + 86400000);
|
expiry = new Date(Math.trunc(Date.now() / 86400000) * 86400000 + 86400000);
|
||||||
@ -21,10 +22,18 @@ export const submitLeaderboardScore = async (
|
|||||||
expiry = new Date(weekEnd);
|
expiry = new Date(weekEnd);
|
||||||
}
|
}
|
||||||
await Leaderboard.findOneAndUpdate(
|
await Leaderboard.findOneAndUpdate(
|
||||||
{ leaderboard, ownerId },
|
{ leaderboard: `${schedule}.accounts.${leaderboard}`, ownerId },
|
||||||
{ $max: { score }, $set: { displayName, guildId, expiry } },
|
{ $max: { score }, $set: { displayName, guildId, expiry } },
|
||||||
{ upsert: true }
|
{ 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 (
|
export const getLeaderboard = async (
|
||||||
@ -32,12 +41,16 @@ export const getLeaderboard = async (
|
|||||||
before: number,
|
before: number,
|
||||||
after: number,
|
after: number,
|
||||||
guildId?: string,
|
guildId?: string,
|
||||||
pivotId?: string
|
pivotId?: string,
|
||||||
|
guildTier?: number
|
||||||
): Promise<ILeaderboardEntryClient[]> => {
|
): Promise<ILeaderboardEntryClient[]> => {
|
||||||
const filter: { leaderboard: string; guildId?: string } = { leaderboard };
|
const filter: { leaderboard: string; guildId?: string; guildTier?: number } = { leaderboard };
|
||||||
if (guildId) {
|
if (guildId) {
|
||||||
filter.guildId = guildId;
|
filter.guildId = guildId;
|
||||||
}
|
}
|
||||||
|
if (guildTier) {
|
||||||
|
filter.guildTier = guildTier;
|
||||||
|
}
|
||||||
|
|
||||||
let entries: TLeaderboardEntryDocument[];
|
let entries: TLeaderboardEntryDocument[];
|
||||||
let r: number;
|
let r: number;
|
||||||
|
@ -286,6 +286,15 @@ export const updateStats = async (accountOwnerId: string, payload: IStatsUpdate)
|
|||||||
} else {
|
} else {
|
||||||
playerStats.Missions.push({ type: type, highScore });
|
playerStats.Missions.push({ type: type, highScore });
|
||||||
}
|
}
|
||||||
|
await submitLeaderboardScore(
|
||||||
|
"weekly",
|
||||||
|
type,
|
||||||
|
accountOwnerId,
|
||||||
|
payload.displayName,
|
||||||
|
highScore,
|
||||||
|
payload.guildId
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -304,27 +313,42 @@ export const updateStats = async (accountOwnerId: string, payload: IStatsUpdate)
|
|||||||
}
|
}
|
||||||
|
|
||||||
await submitLeaderboardScore(
|
await submitLeaderboardScore(
|
||||||
"daily.accounts." + race,
|
"daily",
|
||||||
|
race,
|
||||||
accountOwnerId,
|
accountOwnerId,
|
||||||
payload.displayName,
|
payload.displayName,
|
||||||
highScore
|
highScore,
|
||||||
|
payload.guildId
|
||||||
Sainan marked this conversation as resolved
Outdated
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "ZephyrScore":
|
case "ZephyrScore":
|
||||||
case "SentinelGameScore":
|
|
||||||
case "CaliberChicksScore":
|
case "CaliberChicksScore":
|
||||||
playerStats[category] ??= 0;
|
playerStats[category] ??= 0;
|
||||||
if (data > playerStats[category]) playerStats[category] = data as number;
|
if (data > playerStats[category]) playerStats[category] = data as number;
|
||||||
break;
|
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":
|
case "DojoObstacleScore":
|
||||||
playerStats[category] ??= 0;
|
playerStats[category] ??= 0;
|
||||||
if (data > playerStats[category]) playerStats[category] = data as number;
|
if (data > playerStats[category]) playerStats[category] = data as number;
|
||||||
await submitLeaderboardScore(
|
await submitLeaderboardScore(
|
||||||
"weekly.accounts." + category,
|
"weekly",
|
||||||
|
category,
|
||||||
accountOwnerId,
|
accountOwnerId,
|
||||||
payload.displayName,
|
payload.displayName,
|
||||||
data as number,
|
data as number,
|
||||||
@ -350,7 +374,8 @@ export const updateStats = async (accountOwnerId: string, payload: IStatsUpdate)
|
|||||||
}
|
}
|
||||||
if (data > playerStats[category]) playerStats[category] = data as number;
|
if (data > playerStats[category]) playerStats[category] = data as number;
|
||||||
await submitLeaderboardScore(
|
await submitLeaderboardScore(
|
||||||
"weekly.accounts." + category,
|
"weekly",
|
||||||
|
category,
|
||||||
accountOwnerId,
|
accountOwnerId,
|
||||||
payload.displayName,
|
payload.displayName,
|
||||||
data as number
|
data as number
|
||||||
|
@ -7,6 +7,7 @@ export interface ILeaderboardEntryDatabase {
|
|||||||
score: number;
|
score: number;
|
||||||
guildId?: Types.ObjectId;
|
guildId?: Types.ObjectId;
|
||||||
expiry: Date;
|
expiry: Date;
|
||||||
|
guildTier?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ILeaderboardEntryClient {
|
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...