123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- const _ = require('lodash')
- const Mutex = require('promise-mutex')
- const log = require('../util/log')
- const MAX_EMOTES_IN_GUILD = 50
- class EmoteStore {
- constructor(game, guildIDs) {
- this.game = game
- this.guildIDs = guildIDs
- this.emotes = new Map() // id -> Emoji
- this.mutex = new Mutex()
- log.info(
- `Emote store capacity = ${this.guildIDs.length * MAX_EMOTES_IN_GUILD}`
- )
- if (this.guildIDs.length === 0) {
- throw 'Need at least one emote store server'
- }
- }
- randomClient() {
- return _.sample(this.game.clientPool)
- }
- // Cleans up each emote-storage guild, by removing all channels and emotes
- // present there. RIP.
- async cleanUp() {
- await Promise.all(
- this.guildIDs.map(guildID => {
- const guild = this.randomClient().guilds.get(guildID)
- return Promise.all([
- ...guild.channels.map(c => c.delete()),
- ...guild.emojis.map(e => guild.deleteEmoji(e)),
- ])
- })
- )
- }
- // Finds a guild with emote slots available. If there are none, deletes an
- // old emote from a guild.
- async findGuildForNewEmote(makeSlots = false) {
- for (const guildID of _.shuffle(this.guildIDs)) {
- const guild = this.randomClient().guilds.get(guildID)
- if (guild.emojis.size === MAX_EMOTES_IN_GUILD) {
- // Full, make a slot
- if (makeSlots) {
- const emoteToDel = guild.emojis.random()
- this.emotes.delete(emoteToDel.name)
- await guild.deleteEmoji(emoteToDel)
- }
- } else {
- // Has slots, use it
- return guild
- }
- }
- return this.findGuildForNewEmote(true) // Make slots this time
- }
- // Gets an emote by name, uploading it if it isn't found. Returns an Emoji.
- async get(name, graphic) {
- // Don't upload it if it's already there.
- if (this.emotes.has(name)) {
- return this.emotes.get(name)
- }
- // Upload it.
- let emote
- await this.mutex.lock(async () => {
- const guild = await this.findGuildForNewEmote()
- emote = await guild.createEmoji(graphic, name)
- })
- this.emotes.set(name, emote)
- return emote
- }
- }
- module.exports = EmoteStore
|