Skip to content

Commit

Permalink
index position role lookups & make council leaderboard task more effi…
Browse files Browse the repository at this point in the history
…cient
  • Loading branch information
WhatCats committed Feb 26, 2024
1 parent 71c5df9 commit a1c13bb
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-unused-vars": "off",
"@typescript-eslint/prefer-as-const": "error",
"@typescript-eslint/prefer-nullish-coalescing": "error",
"@typescript-eslint/prefer-nullish-coalescing": "warn",
"eqeqeq": ["error", "smart"],
"no-multi-assign": "error",
"no-unsafe-optional-chaining": "error",
Expand Down
2 changes: 2 additions & 0 deletions src/lib/db/DocumentCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export class DocumentCache<T extends Document> extends Map<string, T> {
}

set(key: string, value: T): this {
const old = this.get(key)
if (old && old !== value) this.events.emit("delete", old)
this.events.emit("set", value)
return super.set(key, value)
}
Expand Down
29 changes: 25 additions & 4 deletions src/lib/db/models/PositionRole.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,17 @@ class PositionRoleSchema {
}

static getRoles(position: string, guildId: string) {
return PositionRole.cache
.filter((v) => v.position === position && v.guildId === guildId)
return this.getPositionRoles(position, guildId)
.map((v) => v.role())
.filter((v): v is Role => !!v)
.filter((v): v is Role => v !== undefined)
}

static getPositionRoles(position: string, guildId: string) {
return [...(indexed.get(guildId)?.get(position) ?? [])]
}

static getPermittedRoles(position: string, guildId: string) {
return this.getRoles(position, guildId).filter((v) => ScrimsBot.INSTANCE!.hasRolePermissions(v))
return this.resolvePermittedRoles(this.getPositionRoles(position, guildId))
}

static resolvePermittedRoles(positionRoles: PositionRole[]) {
Expand Down Expand Up @@ -66,3 +69,21 @@ class PositionRoleSchema {
const schema = getSchemaFromClass(PositionRoleSchema)
export const PositionRole = modelSchemaWithCache(schema, PositionRoleSchema)
export type PositionRole = SchemaDocument<typeof schema>

const indexed = new Map<string, Map<string, Set<PositionRole>>>()

PositionRole.cache.on("set", (posRole) => {
let guildMap = indexed.get(posRole.guildId)
if (!guildMap) {
guildMap = new Map()
indexed.set(posRole.guildId, guildMap)
}

if (!guildMap.get(posRole.position)?.add(posRole)) {
guildMap.set(posRole.position, new Set([posRole]))
}
})

PositionRole.cache.on("delete", (posRole) => {
indexed.get(posRole.guildId)?.get(posRole.position)?.delete(posRole)
})
11 changes: 2 additions & 9 deletions src/lib/discord/PermissionsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ export class PermissionsManager {
)
}

getPositionRoles(position: string, guildId: string): Role[] {
return PositionRole.cache
.filter((v) => v.position === position && v.guildId === guildId)
.map((v) => v.role())
.filter((v): v is Role => !!v)
}

hasPosition(
user: User | GuildMember,
position: string,
Expand All @@ -51,15 +44,15 @@ export class PermissionsManager {

if (this.hasPosition(user, Positions.Banned, guildId)) return false

const positionRoles = this.getPositionRoles(position, guildId).map((v) => v.id)
const positionRoles = PositionRole.getPositionRoles(position, guildId).map((v) => v.roleId)
const member = this.getGuild(guildId)?.members.resolve(user)
if (!positionRoles.length || !member) return undefined

return member.roles.cache.hasAny(...positionRoles) && { expiration }
}

hasPositionLevel(user: User | GuildMember, positionLevel: string, guildId = this.bot.hostGuildId) {
const positionRoles = this.getPositionRoles(positionLevel, guildId)
const positionRoles = PositionRole.getRoles(positionLevel, guildId)
const positionRoleIds = new Set(positionRoles.map((r) => r.id))
const highest = positionRoles.sort((a, b) => b.comparePositionTo(a))[0]
if (highest)
Expand Down
24 changes: 18 additions & 6 deletions src/modules/council/leaderboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,36 +48,48 @@ export class LeaderboardFeature extends BotModule {
async buildMessage(guild: Guild, role: string) {
const embed = new EmbedBuilder().setTitle(`${role} Council Leaderboard`)

const council = ScrimsBot.INSTANCE?.host?.members?.cache.filter((m) =>
ScrimsBot.INSTANCE?.permissions.hasPosition(m, `${role} Council`),
const council = ScrimsBot.INSTANCE?.host?.members?.cache.filter(
(m) => ScrimsBot.INSTANCE?.permissions.hasPosition(m, `${role} Council`),
)

const councilRole = PositionRole.getRoles(`${role} Council`, guild.id)[0]
if (councilRole) embed.setColor(councilRole.color)

const vouches = await Vouch.find({ position: role })
const councilVouches: Record<string, Vouch[]> = {}
const councilVouchesPositive: Record<string, Vouch[]> = {}
const councilVouchesNegative: Record<string, Vouch[]> = {}
for (const vouch of vouches) {
const key = vouch.executorId
if (councilVouches[key]?.push(vouch) === undefined) {
councilVouches[key] = [vouch]
}

if (vouch.isPositive()) {
if (councilVouchesPositive[key]?.push(vouch) === undefined) {
councilVouchesPositive[key] = [vouch]
}
} else {
if (councilVouchesNegative[key]?.push(vouch) === undefined) {
councilVouchesNegative[key] = [vouch]
}
}
}

const getVouches = (id: string) => councilVouches[id] ?? []
const getLength = (id: string, map: Record<string, unknown[]>) => map[id]?.length ?? 0

embed.setDescription(
council
?.sort((a, b) => getVouches(b.id).length - getVouches(a.id).length)
?.sort((a, b) => getLength(b.id, councilVouches) - getLength(a.id, councilVouches))
.map((council) => {
return (
inlineCode("•") +
" " +
userMention(council.id) +
" | " +
`✅ ${getVouches(council.id).filter((v) => v.isPositive()).length}` +
`✅ ${getLength(council.id, councilVouchesPositive)}` +
" | " +
`⛔ ${getVouches(council.id).filter((v) => !v.isPositive()).length}`
`⛔ ${getLength(council.id, councilVouchesNegative)}`
)
})
.join("\n") || "None",
Expand Down

0 comments on commit a1c13bb

Please sign in to comment.