NoMoreAcronyms/main.cjs

335 lines
12 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

"use strict";
// Require the necessary discord.js classes
const { Client, Events, GatewayIntentBits, REST, Routes, Collection, FLAGS, MessageMentionOptions, codeBlock, SlashCommandBuilder, blockQuote } = require('discord.js');
const Discord = require('discord.js');
const { clientId, guildId, token } = require('./key.json');
let fs = require('node:fs');
let path = require('node:path');
global.madlibState = { gameChannel: undefined, storyTitle:undefined, currentStory: undefined, storyIterate: 0, storyReplaceContent: [], storyLength: undefined, numberOfStories: undefined};
//export {madlibState};
//Get number of stories
const madlib = require("./madlibs/stories.json");
global.madlibState.numberOfStories = Object.keys(madlib.stories).length;
// Create a new client instance
const client = new Discord.Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers,
],
});
// When the client is ready, run this code (only once)
// We use 'c' for the event parameter to keep it separate from the already defined 'client'
client.once(Events.ClientReady, c => {
console.log(`Ready! Logged in as ${c.user.tag}`);
});
// Log in to Discord with your client's token
client.login(token);
// Retrieve commands
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.cjs'));
for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);
// Set a new item in the Collection with the key as the command name and the value as the exported module
if ('data' in command && 'execute' in command) {
client.commands.set(command.data.name, command);
} else {
console.log(`[WARNING] The command at ${filePath} is missing a required "data" or "execute" property.`);
}
}
client.on(Events.InteractionCreate, async interaction => {
if (!interaction.isChatInputCommand()) return;
const command = interaction.client.commands.get(interaction.commandName);
if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`);
return;
}
try {
await command.execute(interaction, client);
} catch (error) {
console.error(error);
if (interaction.replied || interaction.deferred) {
await interaction.followUp({ content: 'There was an error while executing this command!', ephemeral: true });
} else {
await interaction.reply({ content: 'There was an error while executing this command!', ephemeral: true });
}
}
});
// My code
var abbreviationKey = require("./abbreviation_key.json");
const { start } = require('node:repl');
function arrayRotate(arr, reverse, amount) {
for (let i = 0; i < amount; i++) {
if (reverse) arr.unshift(arr.pop());
else arr.push(arr.shift());
return arr;
}
}
function matchAbbr(abbrTarget) {
console.log("Looking for: " + abbrTarget);
for (var abbr in abbreviationKey.target_phrases) {
if (abbreviationKey.target_phrases[abbr] == abbrTarget) {
//console.log("abbrTarget: " + typeof (abbrTarget));
//console.log("abbr: " + typeof (abbr));
return abbr;
} else {
//console.log("abbrTarget: " + typeof (abbrTarget));
//console.log("abbr: " + typeof (abbr));
}
}
return "";
}
function replyMessage(message, correctedMessage, abbrsUsed) {
var plural = "";
if (abbrsUsed == 1) {
plural = "an acronym";
} else {
plural = abbrsUsed + " acronyms"
}
var replyString = "Your message contains " + plural + "! Let me fix that for you: \n"+ " \|\|btw I was written by Caleb Fontenot\|\| \n \n" + blockQuote(correctedMessage);
var stringLength = replyString.length;
if (stringLength > 2000) {
replyString = "Sorry, I detected " + plural + ", but the resultant response was " + stringLength + " characters long, and Discord only allows a maximum of 2000."
}
message.reply({ content: replyString, allowedMentions: { repliedUser: false } });
}
client.on('messageCreate', message => {
if (global.madlibState.gameChannel == message.channel.id && message.author.id != "1091120267851485215") { // Pass message to madlib game handler if message was sent in the active game channel.
madlibNextMessage(message.content, client);
}
checkMessage(message, false);
});
client.on('messageUpdate', (undefined, newMessage) => {
checkMessage(newMessage, false);
});
function getMatchingPhrase(inputString, targetCharacter) {
const words = inputString.split(/\s+/);
let matchingPhrase = null;
for (let i = 0; i < words.length; i++) {
const word = words[i];
if (word.includes(targetCharacter)) {
matchingPhrase = abbreviationKey.target_phrases[word];
if (matchingPhrase) {
break;
}
}
}
return matchingPhrase;
}
global.checkMessage = function checkMessage(message, runFromGlobal) {
if (!runFromGlobal) {
checkInsult(message);
if (message.content == "<@1091120267851485215>, what are your pronouns?") {
message.reply({ content: "My pronouns are she/her ☺️", allowedMentions: { repliedUser: false } })
}
if (message.author.id == "1091120267851485215") {
return;
}
console.log(`${message.author.tag} in #${message.channel.name} sent: ${message.content}`);
}
//console.log(message.author);
var matchMessageArray = message.content.toLowerCase().split(/\W/g);
// /[\\\' ,!?\"@#$%^&*().;:|]+/
console.log(matchMessageArray);
let correctedMessage = message.content;
let matchDetected = false;
let abbrsUsed = 0;
for (let i = 0; i < matchMessageArray.length; ++i) {
let rebuildMessageArray = [];
//console.log("Corrected Message: " + correctedMessage);
if (abbreviationKey.target_phrases[matchMessageArray[i]] !== undefined) {
checkIfGirlfriend(message);
if (!runFromGlobal) {
if (checkIfExempt(message)) {
return;
}
}
matchDetected = true;
abbrsUsed++;
//Return key
let phrase = abbreviationKey.target_phrases[matchMessageArray[i]];
let abbr = matchAbbr(phrase); //abbreviationKey.target_phrases[phrase];
//console.log(typeof(abbr));
console.log("Found abbreviation: " + abbr);
console.log("Phrase that matches used acronym: " + phrase);
if (abbr !== "") {
// let regex = new RegExp(`^(.*?)${ '\\b' + abbr + '\\b'}`, 'i');
let regex = new RegExp(`^((?:.*?\n)*?.*?)${ '\\b' + abbr + '\\b'}`, 'i');
rebuildMessageArray = correctedMessage.split(regex);
console.log("rebuildMessageArray: ", rebuildMessageArray);
} else {
message.reply("Detected abbreviation, but regex matching broke. Caleb is working on this...");
return;
}
//https://gitea.calebfontenot.com/CCF_100/NoMoreAcronyms/issues/1
//Insert phrase into string
arrayRotate(rebuildMessageArray, true, 1);
rebuildMessageArray.unshift("`" + phrase + "`");
arrayRotate(rebuildMessageArray, true, 2);
console.log(rebuildMessageArray);
// Build into string and set to variable!
correctedMessage = "" // clear old message.
for (let j = 0; j < rebuildMessageArray.length; j++) {
correctedMessage += rebuildMessageArray[j];
}
console.log(correctedMessage);
//break;
}
}
if (matchDetected) {
replyMessage(message, correctedMessage, abbrsUsed);
}
}
function checkIfGirlfriend(message) {
if (message.author.id == "698360641731166238") {
message.react('☺️');
message.react('❤️');
}
}
function checkIfExempt(message) {
console.log("Has role? " + message.member.roles.cache.some(role => role.name == "Exempt from NoMoreAcronyms"));
if (!message.author.bot) {
if (message.member.roles.cache.some(role => role.name == "Exempt from NoMoreAcronyms")) {
if (!message.member.roles.cache.some(role => role.name == "NoReactions")) {
message.react('🇵');
message.react('🇴');
message.react('🇬');
return true;
}
return true;
}
}
return false;
}
function checkInsult(message) {
if (!message.author.bot) {
if (!message.member.roles.cache.some(role => role.name == "Exempt from NoMoreAcronyms")) {
if (message.content.includes("bot", "annoying")) {
message.react('🇳');
message.react('🇴');
message.react('❌');
message.react('🇺');
}
}
}
}
// Madlib game logic
// Setup story
function startMadlib(selectedStory) {
// Load story
const madlib = require("./madlibs/stories.json");
console.log("Madlib story count: " + Object.keys(madlib.stories).length);
let storyCount = Object.keys(madlib.stories).length;
let storyTitle;
console.log(selectedStory);
if (selectedStory == 0) {
//Pick random story:
storyTitle = Object.keys(madlib.stories)[Math.trunc(Math.random() * storyCount)];
} else {
storyTitle = Object.keys(madlib.stories)[selectedStory - 1];
}
console.log("Current story: " + storyTitle);
let currentStory = madlib.stories[storyTitle];
let storyLength = currentStory.match(/<([^>]+)>/g).length;
// Update global variables with states.
global.madlibState.storyTitle = storyTitle;
global.madlibState.currentStory = currentStory;
global.madlibState.storyLength = storyLength;
//Print story title
const channel = client.channels.cache.get(madlibState.gameChannel);
channel.send("Current story: " + storyTitle);
}
/*
* This function sends a prompt for the next keyword for the madlib story.
*/
global.madlibNextPrompt = function madlibNextPrompt(client, iteration, selectedStory) {
console.log("Next prompt requested");
if (global.madlibState.currentStory == undefined) {
startMadlib(selectedStory);
}
let currentStory = global.madlibState.currentStory;
//Find all <> in the string and return it.
let phrase = currentStory.match(/(?<=<)[^>]+(?=>)/g);
//remove every other element in array, so we only have the prompts
console.log(phrase);
// Send a message in the gameChannel with the next prompt.
const channel = client.channels.cache.get(madlibState.gameChannel);
let aAn;
let vowelArray = ["a", "e", "i", "o", "u"];
aAn = "a ";
for (let i = 0; i < vowelArray.length; ++i) {
if (phrase[iteration].toLowerCase().charAt(0) == (vowelArray[i].charAt(0))) {
aAn = "an ";
}
}
channel.send("Give me " + aAn + phrase[iteration] + ":\n(" + (phrase.length - iteration) + " words remain)");
}
/*
* This function is executed when a player is sending a new message.
*/
global.madlibNextMessage = function madlibNextMessage(promptAnswerString, client) {
global.madlibState.storyIterate++;
//Process message
console.log("Processing next message...");
console.log("Player responded with: \"" + promptAnswerString +"\"");
global.madlibState.storyReplaceContent.push("`" + promptAnswerString + "`");
console.log(madlibState.storyReplaceContent);
// Check how many times we've iterated, and if we're not done collecting content for the story, continue
if (global.madlibState.storyIterate < global.madlibState.storyLength) {
global.madlibNextPrompt(client, global.madlibState.storyIterate, undefined);
} else { //Story content has been obtained! Now we just need to build the story and return it.
endMadlib();
}
}
function endMadlib() {
// Build story string, send the message, and set all of the madlibState variables to their defaults.
let currentStory = global.madlibState.currentStory;
let storyReplaceContent = global.madlibState.storyReplaceContent;
for (let i = 0; i < storyReplaceContent.length; ++i) {
currentStory = currentStory.replace(/<([^>]+)>/, storyReplaceContent[i]);
}
console.log(currentStory);
const channel = client.channels.cache.get(madlibState.gameChannel);
channel.send("Story is complete! \n" + currentStory);
//Reset madlibState.
global.madlibState = { gameChannel: undefined, storyTitle:undefined, currentStory: undefined, storyIterate: 0, storyReplaceContent: [], storyLength: undefined};
}