From 4d181c8ad80fa11a77e88407b27f3afce07c0677 Mon Sep 17 00:00:00 2001 From: "Jill \"oatmealine\" Monoids" Date: Thu, 26 Oct 2023 00:43:23 +0300 Subject: [PATCH] markov improvements --- src/commands/markov.ts | 85 +++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 18 deletions(-) diff --git a/src/commands/markov.ts b/src/commands/markov.ts index 1d45c31..24cc3bc 100644 --- a/src/commands/markov.ts +++ b/src/commands/markov.ts @@ -3,6 +3,7 @@ import { GuildMember, Message, User, SlashCommandBuilder, Interaction } from 'di const DEFAULT_EMOJI = 'đŸĒ™'; const STOP_EMOJI = '⏚ī¸'; const DONE_EMOJI = '👍'; +const BAD_EMOJI = '👎'; const END_TEMPLATES = [ 'Alright! Here\'s the messages you all conjured:', @@ -34,23 +35,38 @@ function randomWord() { return RANDOM_WORDS[Math.floor(Math.random() * RANDOM_WORDS.length)]; } +function* chunks(arr: unknown[], n: number) { + for (let i = 0; i < arr.length; i += n) { + yield arr.slice(i, i + n); + } +} + module.exports = { data: new SlashCommandBuilder() .setName('markov') .setDescription('Play a Markov chain game') - .addIntegerOption((option) => + .addIntegerOption(option => option .setName('context') .setRequired(false) .setDescription('Amount of words to show as context') .setMinValue(1) - ), + .setMaxValue(100) + ) + .addIntegerOption(option => + option + .setName('iterations') + .setRequired(false) + .setDescription('Amount of rounds to do') + .setMinValue(1) + .setMaxValue(100)), execute: async (interaction: Interaction, member: GuildMember) => { if (!interaction.isChatInputCommand()) return; let participants: User[] = [member.user]; const context = interaction.options.getInteger('context') || 3; + const maxIterations = interaction.options.getInteger('iterations') || 10; const duration = 25_000; @@ -78,6 +94,10 @@ module.exports = { dispose: true }); + const updateInterval = setInterval(() => { + m.edit(formatMessage(participants, duration - (Date.now() - started))); + }, 3_000); + collector.on('collect', (reaction, user) => { if (reaction.emoji.name === STOP_EMOJI) { collector.stop(); @@ -93,34 +113,33 @@ module.exports = { }); collector.on('end', async () => { + clearInterval(updateInterval); m.edit(formatMessage(participants, 0)); let sentences: string[][] = Array(participants.length).fill(0); sentences = sentences.map(() => []); let iterations = 0; - const maxIterations = 10; // eslint-disable-next-line no-constant-condition while (true) { await Promise.all( participants.map(async (p, i) => { const sentence = sentences[(i + iterations) % sentences.length]; - const msg = await p.send(`Continue the following sentence: [${iterations}/${maxIterations}]\n\n> _${context < sentence.length ? 'â€Ļ' : ''}${sentence.length > 0 ? sentence.slice(-context).join(' ') : `start a sentence... (try working with: “${randomWord()}”)`}_` + (iterations === 0 ? '\n\n**Send a message to continue**' : '')); + const msg = await p.send((`Continue the following sentence: [${iterations}/${maxIterations}]\n\n> _${context < sentence.length ? 'â€Ļ' : ''}${sentence.length > 0 ? sentence.slice(-context).join(' ') : `start a sentence... (try working with: “${randomWord()}”)`}_` + (iterations === 0 ? '\n\n**Send a message to continue**' : '')).slice(0, 2000)); try { const collected = await msg.channel.awaitMessages({ max: 1, - time: 30_000, - errors: ['time'] + time: 45_000, + errors: ['time'], + filter: (msg) => { + const valid = msg.content !== '' && msg.content.length <= 2000; + if (!valid) msg.react(BAD_EMOJI); + return valid; + } }); const message = collected.first() as Message; - - if (sentence.join(' ').length + message.content.length >= 2000) { - message.reply('stop that'); - sentence.push(...randomWord().split(' ')); - } else { - sentence.push(...message.content.split(' ')); - await message.react(DONE_EMOJI); - } + sentence.push(...message.content.split(' ')); + await message.react(DONE_EMOJI); } catch (err) { await p.send('Took too long... Surprise... Added...... :)'); sentence.push(...randomWord().split(' ')); @@ -136,11 +155,41 @@ module.exports = { } const endTemplate = END_TEMPLATES[Math.floor(Math.random() * END_TEMPLATES.length)]; - await m.reply({ - content: endTemplate + '\n\n' + sentences.map(sentence => '- “' + sentence.join(' ') + '”').join('\n') + '\n\nThank you for participating :)', - allowedMentions: { - parse: ['users'] + + const segments = [ + endTemplate + '\n\n', + ...sentences.map(sentence => '- ' + sentence.join(' ')), + '\n\nThank you for participating :)' + ]; + + const content = []; + let contentBuffer = ''; + + while (segments.length > 0) { + const segment = segments.splice(0, 1)[0]; + const newMsg = contentBuffer + '\n' + segment; + if (newMsg.length > 2000) { + content.push(contentBuffer); + contentBuffer = ''; + + if (segment.length > 2000) { + content.push(...([...(chunks(segment.split(''), 2000))].map(s => s.join('')))); + } else { + contentBuffer = segment; + } + } else { + contentBuffer = newMsg; } + } + if (contentBuffer !== '') content.push(contentBuffer); + + content.forEach(async content => { + await m.channel.send({ + content: content, + allowedMentions: { + parse: ['users'] + } + }); }); }); }