Skip to content
This repository has been archived by the owner on Oct 27, 2024. It is now read-only.

Commit

Permalink
add #1 leaderboards count leaderboard
Browse files Browse the repository at this point in the history
  • Loading branch information
mat-1 committed Aug 2, 2021
1 parent c5f65b7 commit 3c60dd9
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 49 deletions.
2 changes: 1 addition & 1 deletion build/cleaners/skyblock/stats.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ exports.statUnits = {
time: ['_best_time', '_best_time_2'],
date: ['first_join'],
coins: ['purse'],
leaderboards: ['leaderboards_count']
leaderboards: ['leaderboards_count', 'top_1_leaderboards_count']
};
function getStatUnit(name) {
for (const [unitName, statMatchers] of Object.entries(exports.statUnits)) {
Expand Down
63 changes: 45 additions & 18 deletions build/database.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ let accountsCollection;
const leaderboardInfos = {
highest_crit_damage: 'This leaderboard is capped at the integer limit because Hypixel, look at the <a href="/leaderboard/highest_critical_damage">highest critical damage leaderboard</a> instead.',
highest_critical_damage: 'uhhhhh yeah idk either',
leaderboards_count: 'This leaderboard counts how many leaderboards people are in the top 100 for.',
leaderboards_count: 'This leaderboard counts how many leaderboards players are in the top 100 for.',
top_1_leaderboards_count: 'This leaderboard counts how many leaderboards players are #1 for.',
};
async function connect() {
if (!process.env.db_uri)
Expand Down Expand Up @@ -183,7 +184,8 @@ async function fetchAllMemberLeaderboardAttributes() {
'first_join',
'purse',
'visited_zones',
'leaderboards_count'
'leaderboards_count',
'top_1_leaderboards_count'
];
}
exports.fetchAllMemberLeaderboardAttributes = fetchAllMemberLeaderboardAttributes;
Expand Down Expand Up @@ -369,54 +371,79 @@ async function fetchMemberLeaderboardSpots(player, profile) {
}
exports.fetchMemberLeaderboardSpots = fetchMemberLeaderboardSpots;
async function getLeaderboardRequirement(name, leaderboardType) {
var _a, _b;
let leaderboard;
if (leaderboardType === 'member')
leaderboard = await fetchMemberLeaderboardRaw(name);
else if (leaderboardType === 'profile')
leaderboard = await fetchProfileLeaderboardRaw(name);
// if there's more than 100 items, return the 100th. if there's less, return null
if (leaderboard.length >= leaderboardMax)
return leaderboard[leaderboardMax - 1].value;
return {
top_100: leaderboard[leaderboardMax - 1].value,
top_1: leaderboard[1].value
};
else if (leaderboard.length >= 1)
return {
top_100: null,
top_1: (_b = (_a = leaderboard[1]) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : null
};
else
return null;
return {
top_100: null,
top_1: null
};
}
/** Get the attributes for the member, but only ones that would put them on the top 100 for leaderboards */
async function getApplicableMemberLeaderboardAttributes(member) {
const leaderboardAttributes = getMemberLeaderboardAttributes(member);
const applicableAttributes = {};
const applicableTop1Attributes = {};
for (const [leaderboard, attributeValue] of Object.entries(leaderboardAttributes)) {
const requirement = await getLeaderboardRequirement(leaderboard, 'member');
const leaderboardReversed = isLeaderboardReversed(leaderboard);
if ((requirement === null)
|| (leaderboardReversed ? attributeValue < requirement : attributeValue > requirement)) {
if ((requirement.top_100 === null)
|| (leaderboardReversed ? attributeValue < requirement.top_100 : attributeValue > requirement.top_100)) {
applicableAttributes[leaderboard] = attributeValue;
}
if ((requirement.top_1 === null)
|| (leaderboardReversed ? attributeValue < requirement.top_1 : attributeValue > requirement.top_1)) {
applicableTop1Attributes[leaderboard] = attributeValue;
}
}
let leaderboardsCount = Object.keys(applicableAttributes).length;
// add the "leaderboards count" attribute
const leaderboardsCount = Object.keys(applicableAttributes).length;
const leaderboardsCountRequirement = await getLeaderboardRequirement('leaderboards_count', 'member');
if ((leaderboardsCountRequirement === null)
|| (leaderboardsCount > leaderboardsCountRequirement)) {
if ((leaderboardsCountRequirement.top_100 === null)
|| (leaderboardsCount > leaderboardsCountRequirement.top_100))
applicableAttributes['leaderboards_count'] = leaderboardsCount;
}
// add the "first leaderboards count" attribute
const top1LeaderboardsCount = Object.keys(applicableTop1Attributes).length;
const top1LeaderboardsCountRequirement = await getLeaderboardRequirement('top_1_leaderboards_count', 'member');
if ((top1LeaderboardsCountRequirement.top_100 === null)
|| (top1LeaderboardsCount > top1LeaderboardsCountRequirement.top_100))
applicableAttributes['top_1_leaderboards_count'] = top1LeaderboardsCount;
console.log('top_1_leaderboards_count', applicableTop1Attributes, top1LeaderboardsCount, 'requirement', top1LeaderboardsCountRequirement);
return applicableAttributes;
}
/** Get the attributes for the profile, but only ones that would put them on the top 100 for leaderboards */
async function getApplicableProfileLeaderboardAttributes(profile) {
const leaderboardAttributes = getProfileLeaderboardAttributes(profile);
const applicableAttributes = {};
const applicableTop1Attributes = {};
for (const [leaderboard, attributeValue] of Object.entries(leaderboardAttributes)) {
const requirement = await getLeaderboardRequirement(leaderboard, 'profile');
const leaderboardReversed = isLeaderboardReversed(leaderboard);
if ((requirement === null)
|| (leaderboardReversed ? attributeValue < requirement : attributeValue > requirement)) {
if ((requirement.top_100 === null)
|| (leaderboardReversed ? attributeValue < requirement.top_100 : attributeValue > requirement.top_100
&& attributeValue !== 0)) {
applicableAttributes[leaderboard] = attributeValue;
}
}
let leaderboardsCount = Object.keys(applicableAttributes).length;
const leaderboardsCountRequirement = await getLeaderboardRequirement('leaderboards_count', 'member');
if (leaderboardsCountRequirement === null
|| leaderboardsCount > leaderboardsCountRequirement) {
applicableAttributes['leaderboards_count'] = leaderboardsCount;
if ((requirement.top_1 === null)
|| (leaderboardReversed ? attributeValue < requirement.top_1 : attributeValue > requirement.top_1
&& attributeValue !== 0)) {
applicableTop1Attributes[leaderboard] = attributeValue;
}
}
return applicableAttributes;
}
Expand Down
2 changes: 1 addition & 1 deletion build/hypixelCached.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ async function fetchBasicPlayer(user) {
return exports.basicPlayerCache.get(playerUuid);
const player = await fetchPlayer(playerUuid);
if (!player) {
console.debug('no player? this should never happen', user, playerUuid);
console.debug('no player? this should never happen, perhaps the uuid is invalid or the player hasn\'t played hypixel', playerUuid);
return null;
}
delete player.profiles;
Expand Down
2 changes: 1 addition & 1 deletion src/cleaners/skyblock/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const statUnits = {
time: ['_best_time', '_best_time_2'],
date: ['first_join'],
coins: ['purse'],
leaderboards: ['leaderboards_count']
leaderboards: ['leaderboards_count', 'top_1_leaderboards_count']
}

export interface StatItem {
Expand Down
86 changes: 59 additions & 27 deletions src/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ let accountsCollection: Collection<AccountSchema>
const leaderboardInfos: { [ leaderboardName: string ]: string } = {
highest_crit_damage: 'This leaderboard is capped at the integer limit because Hypixel, look at the <a href="/leaderboard/highest_critical_damage">highest critical damage leaderboard</a> instead.',
highest_critical_damage: 'uhhhhh yeah idk either',
leaderboards_count: 'This leaderboard counts how many leaderboards people are in the top 100 for.',
leaderboards_count: 'This leaderboard counts how many leaderboards players are in the top 100 for.',
top_1_leaderboards_count: 'This leaderboard counts how many leaderboards players are #1 for.',
}


Expand Down Expand Up @@ -259,7 +260,8 @@ export async function fetchAllMemberLeaderboardAttributes(): Promise<string[]> {
'first_join',
'purse',
'visited_zones',
'leaderboards_count'
'leaderboards_count',
'top_1_leaderboards_count'
]
}

Expand Down Expand Up @@ -487,7 +489,7 @@ export async function fetchMemberLeaderboardSpots(player: string, profile: strin
return memberLeaderboardSpots
}

async function getLeaderboardRequirement(name: string, leaderboardType: 'member' | 'profile'): Promise<number | null> {
async function getLeaderboardRequirement(name: string, leaderboardType: 'member' | 'profile'): Promise<{ top_100: number | null, top_1: number | null }> {
let leaderboard: memberRawLeaderboardItem[] | profileRawLeaderboardItem[]
if (leaderboardType === 'member')
leaderboard = await fetchMemberLeaderboardRaw(name)
Expand All @@ -496,66 +498,96 @@ async function getLeaderboardRequirement(name: string, leaderboardType: 'member'

// if there's more than 100 items, return the 100th. if there's less, return null
if (leaderboard!.length >= leaderboardMax)
return leaderboard![leaderboardMax - 1].value
return {
top_100: leaderboard![leaderboardMax - 1].value,
top_1: leaderboard![1].value
}
else if (leaderboard!.length >= 1)
return {
top_100: null,
top_1: leaderboard![1]?.value ?? null
}
else
return null
return {
top_100: null,
top_1: null
}
}

/** Get the attributes for the member, but only ones that would put them on the top 100 for leaderboards */
async function getApplicableMemberLeaderboardAttributes(member: CleanMember): Promise<StringNumber> {
const leaderboardAttributes = getMemberLeaderboardAttributes(member)
const applicableAttributes = {}
const applicableTop1Attributes = {}

for (const [ leaderboard, attributeValue ] of Object.entries(leaderboardAttributes)) {
const requirement = await getLeaderboardRequirement(leaderboard, 'member')
const leaderboardReversed = isLeaderboardReversed(leaderboard)
if (
(requirement === null)
|| (leaderboardReversed ? attributeValue < requirement : attributeValue > requirement)
(requirement.top_100 === null)
|| (
leaderboardReversed ? attributeValue < requirement.top_100 : attributeValue > requirement.top_100)
) {
applicableAttributes[leaderboard] = attributeValue
}
if (
(requirement.top_1 === null)
|| (leaderboardReversed ? attributeValue < requirement.top_1 : attributeValue > requirement.top_1)
) {
applicableTop1Attributes[leaderboard] = attributeValue
}
}


let leaderboardsCount: number = Object.keys(applicableAttributes).length
const leaderboardsCountRequirement: number | null = await getLeaderboardRequirement('leaderboards_count', 'member')
// add the "leaderboards count" attribute
const leaderboardsCount: number = Object.keys(applicableAttributes).length
const leaderboardsCountRequirement = await getLeaderboardRequirement('leaderboards_count', 'member')

if (
(leaderboardsCountRequirement === null)
|| (leaderboardsCount > leaderboardsCountRequirement)
) {
(leaderboardsCountRequirement.top_100 === null)
|| (leaderboardsCount > leaderboardsCountRequirement.top_100)
)
applicableAttributes['leaderboards_count'] = leaderboardsCount
}

// add the "first leaderboards count" attribute
const top1LeaderboardsCount: number = Object.keys(applicableTop1Attributes).length
const top1LeaderboardsCountRequirement = await getLeaderboardRequirement('top_1_leaderboards_count', 'member')

if (
(top1LeaderboardsCountRequirement.top_100 === null)
|| (top1LeaderboardsCount > top1LeaderboardsCountRequirement.top_100)
)
applicableAttributes['top_1_leaderboards_count'] = top1LeaderboardsCount
console.log('top_1_leaderboards_count', applicableTop1Attributes, top1LeaderboardsCount, 'requirement', top1LeaderboardsCountRequirement)
return applicableAttributes
}

/** Get the attributes for the profile, but only ones that would put them on the top 100 for leaderboards */
async function getApplicableProfileLeaderboardAttributes(profile: CleanFullProfile): Promise<StringNumber> {
const leaderboardAttributes = getProfileLeaderboardAttributes(profile)
const applicableAttributes = {}
const applicableTop1Attributes = {}

for (const [ leaderboard, attributeValue ] of Object.entries(leaderboardAttributes)) {
const requirement = await getLeaderboardRequirement(leaderboard, 'profile')
const leaderboardReversed = isLeaderboardReversed(leaderboard)
if (
(requirement === null)
|| (leaderboardReversed ? attributeValue < requirement : attributeValue > requirement)
(requirement.top_100 === null)
|| (
leaderboardReversed ? attributeValue < requirement.top_100 : attributeValue > requirement.top_100
&& attributeValue !== 0
)
) {
applicableAttributes[leaderboard] = attributeValue
}
}


let leaderboardsCount: number = Object.keys(applicableAttributes).length
const leaderboardsCountRequirement: number | null = await getLeaderboardRequirement('leaderboards_count', 'member')

if (
leaderboardsCountRequirement === null
|| leaderboardsCount > leaderboardsCountRequirement
) {
applicableAttributes['leaderboards_count'] = leaderboardsCount
if (
(requirement.top_1 === null)
|| (
leaderboardReversed ? attributeValue < requirement.top_1 : attributeValue > requirement.top_1
&& attributeValue !== 0
)
) {
applicableTop1Attributes[leaderboard] = attributeValue
}
}

return applicableAttributes
Expand Down
2 changes: 1 addition & 1 deletion src/hypixelCached.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ export async function fetchBasicPlayer(user: string): Promise<CleanPlayer | null

const player = await fetchPlayer(playerUuid)
if (!player) {
console.debug('no player? this should never happen', user, playerUuid)
console.debug('no player? this should never happen, perhaps the uuid is invalid or the player hasn\'t played hypixel', playerUuid)
return null
}

Expand Down

0 comments on commit 3c60dd9

Please sign in to comment.