From 8363627d7430e3df6346fa30bc25566705b06b2c Mon Sep 17 00:00:00 2001 From: O3H Date: Wed, 24 Jul 2024 18:03:07 +0100 Subject: [PATCH] Update nation.ts --- aurora/slashcommands/nation.ts | 409 +++++++++++++++++---------------- 1 file changed, 212 insertions(+), 197 deletions(-) diff --git a/aurora/slashcommands/nation.ts b/aurora/slashcommands/nation.ts index dfaf9485..1156ffb4 100644 --- a/aurora/slashcommands/nation.ts +++ b/aurora/slashcommands/nation.ts @@ -26,7 +26,6 @@ import type { SquaremapTown } from 'earthmc' import { Aurora, NotFoundError } from 'earthmc' import type { DBSquaremapNation, NationItem, TownItem } from '../../bot/types.js' -import { } from "../../bot/utils/fn.js" export default { name: "nation", @@ -156,210 +155,226 @@ export default { .paginate(allData, "```", "```") .editInteraction(interaction) } - } - else if (subCmd == "activity" && interaction.options.getString("name") != null) { - const nation = nations.find(n => n.name.toLowerCase() == interaction.options.getString("name").toLowerCase()) - - if (!nation) { - nationEmbed.setTitle("Invalid Nation") - nationEmbed.setDescription(interaction.options.getString("name") + " is not a valid nation, please try again.") - nationEmbed.setColor(Colors.Red) - - return interaction.editReply({ embeds: [nationEmbed] }) - } - - const players = await database.getPlayers() - if (!players) return await interaction.editReply({ embeds: [databaseError] }) - .then(() => setTimeout(() => interaction.deleteReply(), 10000)) - - // Sort by highest offline duration - nation.residents.sort((a, b) => { - const foundPlayerA = players.find(p => p.name == a) - const foundPlayerB = players.find(p => p.name == b) - - if (foundPlayerA && !foundPlayerB) return -1 - if (!foundPlayerA && foundPlayerB) return 1 - - if (foundPlayerA && foundPlayerB) { - const loA = foundPlayerA.lastOnline - const loB = foundPlayerB.lastOnline - - // Identical? don't sort. - if (loA.aurora === loB.aurora) return 0 - if (!loA) return 1 - if (!loB) return -1 - - const dateB = unixFromDate(loB.aurora) - const dateA = unixFromDate(loA.aurora) - - return dateB - dateA + } else { + const nameArg = interaction.options.getString("name", true) + + if (subCmd == "activity") { + const nation = nations.find(n => n.name.toLowerCase() == nameArg.toLowerCase()) + + if (!nation) { + nationEmbed.setTitle("Invalid Nation!") + nationEmbed.setDescription(`No nation with name \`${nameArg}\` exists.`) + nationEmbed.setColor(Colors.Red) + + return interaction.editReply({ embeds: [nationEmbed] }) } - }) - - let page = 1 - if (isNaN(page)) page = 0 - else page-- - - const allData = nation.residents.map(resident => { - const residentInPlayers = players.find(p => p.name == resident) - - if (residentInPlayers && residentInPlayers.lastOnline != null) - return "``" + resident + "`` - " + `` - - return "" + resident + " | Unknown" - }).join('\n').match(/(?:^.*$\n?){1,10}/mg) - - new CustomEmbed(client, `Nation Info | Activity in ${nation.name}`) - .setType(EntityType.Nation) - .paginate(allData) - .editInteraction(interaction) - } // /n - else if (subCmd == "lookup" && interaction.options.getString("name") != null) { - const nation = nations.find(n => n.name.toLowerCase() == interaction.options.getString("name").toLowerCase()) - if (!nation) { - nationEmbed.setTitle("Invalid Nation") - nationEmbed.setDescription(interaction.options.getString("name") + " is not a valid nation, please try again.") - nationEmbed.setColor(Colors.Red) - - return interaction.editReply({ embeds: [nationEmbed] }) + + const players = await database.getPlayers() + if (!players) return await interaction.editReply({ embeds: [databaseError] }) + .then(() => setTimeout(() => interaction.deleteReply(), 10000)) + + // Sort by highest offline duration + nation.residents.sort((a, b) => { + const foundPlayerA = players.find(p => p.name == a) + const foundPlayerB = players.find(p => p.name == b) + + if (foundPlayerA && !foundPlayerB) return -1 + if (!foundPlayerA && foundPlayerB) return 1 + + if (foundPlayerA && foundPlayerB) { + const loA = foundPlayerA.lastOnline + const loB = foundPlayerB.lastOnline + + // Identical? don't sort. + if (loA.aurora === loB.aurora) return 0 + if (!loA) return 1 + if (!loB) return -1 + + const dateB = unixFromDate(loB.aurora) + const dateA = unixFromDate(loA.aurora) + + return dateB - dateA + } + }) + + let page = 1 + if (isNaN(page)) page = 0 + else page-- + + const allData = nation.residents.map(resident => { + const residentInPlayers = players.find(p => p.name == resident) + + if (residentInPlayers && residentInPlayers.lastOnline != null) + return "``" + resident + "`` - " + `` + + return "" + resident + " | Unknown" + }).join('\n').match(/(?:^.*$\n?){1,10}/mg) + + return new CustomEmbed(client, `Nation Info | Activity in ${nation.name}`) + .setType(EntityType.Nation) + .paginate(allData) + .editInteraction(interaction) } - - const capitalColours = await Aurora.Towns.get(nation.capital.name).then((t: SquaremapTown) => { - return t instanceof NotFoundError ? null : t.colours - }) - - const colour = capitalColours ? parseInt(capitalColours.fill.replace('#', '0x')) : Colors.Aqua - nationEmbed.setColor(colour) - - //#region Prefixes - const nationResLength = nation.residents.length - const nationLeaderPrefix = nationResLength >= 60 ? "God Emperor " - : nationResLength >= 40 ? "Emperor " - : nationResLength >= 30 ? "King " - : nationResLength >= 20 ? "Duke " - : nationResLength >= 10 ? "Count " - : nationResLength >= 0 ? "Leader " : "" - - // Includes prefix - const nationName = nationResLength >= 60 ? "The " + nation.name + " Realm" - : nationResLength >= 40 ? "The " + nation.name + " Empire" - : nationResLength >= 30 ? "Kingdom of " + nation.name - : nationResLength >= 20 ? "Dominion of " + nation.name - : nationResLength >= 10 ? "Federation of " + nation.name - : "Land of " + nation.name - //#endregion - - nations = defaultSort(nations) - - const nationRank = (nations.findIndex(n => n.name == nation.name)) + 1 - const kingPrefix = nation.kingPrefix ? nation.kingPrefix + " " : nationLeaderPrefix - - //#region Embed Stuff - const [capitalX, capitalZ] = [nation.capital.x, nation.capital.z] - const mapUrl = Aurora.buildMapLink({ x: capitalX, z: capitalZ }, 5) - - nationEmbed.setTitle("Nation Info | " + nationName + " | #" + nationRank) - .setThumbnail(nation.flag || 'attachment://aurora.png') - .setFooter(devsFooter(client)) - .addFields( - embedField("King", backtick(nation.king, { prefix: kingPrefix }), true), - embedField("Capital", `\`${nation.capital.name}\``, true), - embedField("Location", `[${capitalX}, ${capitalZ}](${mapUrl.toString()})`, true), - embedField("Size/Worth", `Chunks: \`${nation.area.toString()}\`\nGold: \`${(nation.area * 16)}\``, true), - embedField("Residents", `\`${nationResLength.toString()}\``, true), - embedField("Bonus Grant", `\`${auroraNationBonus(nationResLength).toString()}\``, true) - ) - - if (nation.discord) - nationEmbed.setURL(nation.discord) - const onlinePlayers = await Aurora.Players.online().catch(() => {}) - if (onlinePlayers) { - // Filter nation residents by which are online - const onlineNationResidents = removeDuplicates( - nation.residents.filter(resident => onlinePlayers.find(op => resident == op.name))) + // /n + if (subCmd == "lookup") { + const nation = nations.find(n => n.name.toLowerCase() == nameArg.toLowerCase()) + if (!nation) { + nationEmbed.setTitle("Invalid Nation!") + nationEmbed.setDescription(`No nation with name \`${nameArg}\` exists.`) + nationEmbed.setColor(Colors.Red) + + return interaction.editReply({ embeds: [nationEmbed] }) + } - if (onlineNationResidents.length >= 1) nationEmbed.addFields(embedField( - "Online Residents [" + onlineNationResidents.length + "]", - "```" + onlineNationResidents.join(", ") + "```" - )) - } - //#endregion - - //#region Recent news logic - const newsChannel = client.channels.cache.get(AURORA.newsChannel) as TextChannel - const newsChannelMessages = await newsChannel?.messages.fetch() - - const filterNews = (msg: Message) => msg.content.toLowerCase().includes(nation.name.replace(/_/g, " ").toLowerCase() || nation.name.toLowerCase()) - - // Get news descriptions that include the nation name - // Then sort/get most recent description - const filteredMessages = newsChannelMessages?.filter(msg => filterNews(msg)) - const mostRecentDate = new Date(Math.max.apply(null, filteredMessages?.map(e => new Date(e.createdTimestamp)))) - - const recentNews = filteredMessages?.find(e => { - const d = new Date(e.createdTimestamp) - return d.getTime() == mostRecentDate.getTime() - }) - //#endregion - - const nationTowns = nation.towns.join(", ") - const nationTownsString = nationTowns.toString().replace(/^\s+|\s+$/gm, "") + const capitalColours = await Aurora.Towns.get(nation.capital.name).then((t: SquaremapTown) => { + return t instanceof NotFoundError ? null : t.colours + }) + + const colour = capitalColours ? parseInt(capitalColours.fill.replace('#', '0x')) : Colors.Aqua + nationEmbed.setColor(colour) + + //#region Prefixes + const nationResLength = nation.residents.length + const nationLeaderPrefix = nationResLength >= 60 ? "God Emperor " + : nationResLength >= 40 ? "Emperor " + : nationResLength >= 30 ? "King " + : nationResLength >= 20 ? "Duke " + : nationResLength >= 10 ? "Count " + : nationResLength >= 0 ? "Leader " : "" + + // Includes prefix + const nationName = nationResLength >= 60 ? "The " + nation.name + " Realm" + : nationResLength >= 40 ? "The " + nation.name + " Empire" + : nationResLength >= 30 ? "Kingdom of " + nation.name + : nationResLength >= 20 ? "Dominion of " + nation.name + : nationResLength >= 10 ? "Federation of " + nation.name + : "Land of " + nation.name + //#endregion + + nations = defaultSort(nations) + + const nationRank = (nations.findIndex(n => n.name == nation.name)) + 1 + const kingPrefix = nation.kingPrefix ? nation.kingPrefix + " " : nationLeaderPrefix + + //#region Embed Stuff + const [capitalX, capitalZ] = [nation.capital.x, nation.capital.z] + const mapUrl = Aurora.buildMapLink({ x: capitalX, z: capitalZ }, 5) + + nationEmbed.setTitle("Nation Info | " + nationName + " | #" + nationRank) + .setThumbnail(nation.flag || 'attachment://aurora.png') + .setFooter(devsFooter(client)) + .addFields( + embedField("King", backtick(nation.king, { prefix: kingPrefix }), true), + embedField("Capital", `\`${nation.capital.name}\``, true), + embedField("Location", `[${capitalX}, ${capitalZ}](${mapUrl.toString()})`, true), + embedField("Size/Worth", `Chunks: \`${nation.area.toString()}\`\nGold: \`${(nation.area * 16)}\``, true), + embedField("Residents", `\`${nationResLength.toString()}\``, true), + embedField("Bonus Grant", `\`${auroraNationBonus(nationResLength).toString()}\``, true) + ) + + if (nation.discord) + nationEmbed.setURL(nation.discord) + + const onlinePlayers = await Aurora.Players.online().catch(() => {}) + if (onlinePlayers) { + // Filter nation residents by which are online + const onlineNationResidents = removeDuplicates( + nation.residents.filter(resident => onlinePlayers.find(op => resident == op.name))) + + if (onlineNationResidents.length >= 1) nationEmbed.addFields(embedField( + "Online Residents [" + onlineNationResidents.length + "]", + "```" + onlineNationResidents.join(", ") + "```" + )) + } + //#endregion + + //#region Recent news logic + const newsChannel = client.channels.cache.get(AURORA.newsChannel) as TextChannel + const newsChannelMessages = await newsChannel?.messages.fetch() + + const filterNews = (msg: Message) => msg.content.toLowerCase().includes(nation.name.replace(/_/g, " ").toLowerCase() || nation.name.toLowerCase()) + + // Get news descriptions that include the nation name + // Then sort/get most recent description + const filteredMessages = newsChannelMessages?.filter(msg => filterNews(msg)) + const mostRecentDate = new Date(Math.max.apply(null, filteredMessages?.map(e => new Date(e.createdTimestamp)))) + + const recentNews = filteredMessages?.find(e => { + const d = new Date(e.createdTimestamp) + return d.getTime() == mostRecentDate.getTime() + }) + //#endregion + + const nationTowns = nation.towns.join(", ") + const nationTownsString = nationTowns.toString().replace(/^\s+|\s+$/gm, "") + + if (nationTownsString.length >= 1024) { + nationEmbed.addFields(embedField( + `Towns [${nation.towns.length}]`, + "Too many towns to display!\nClick the **View All Towns** button to see the full list." + )) - if (nationTownsString.length >= 1024) { - nationEmbed.addFields(embedField( - `Towns [${nation.towns.length}]`, - "Too many towns to display!\nClick the **View All Towns** button to see the full list." - )) - - nationEmbed.addButton('view_all_towns', 'View All Towns', ButtonStyle.Primary) - } else { - nationEmbed.addFields(embedField( - `Towns [${nation.towns.length}]`, - "```" + nationTownsString + "```" - )) - } - - const alliances = await database.Aurora.getAlliances() - if (alliances) { - const nationAlliances = alliances - .filter(A => A.nations.map(e => e.toLowerCase()).includes(nation.name.toLowerCase())) - .map(a => a.allianceName) - - const len = nationAlliances?.length - if (len > 0) nationEmbed.addFields(embedField( - `Alliances [${len}]`, - "```" + nationAlliances.join(", ") + "```" - )) - } - - if (recentNews) { - const news = new News(recentNews) - const img = news?.images ? news.images[0] : null - - nationEmbed.addFields(embedField( - "Recent News", - news.message + (img ? " ([Image](" + img + "))" : "") - )) + nationEmbed.addButton('view_all_towns', 'View All Towns', ButtonStyle.Primary) + } else { + nationEmbed.addFields(embedField( + `Towns [${nation.towns.length}]`, + "```" + nationTownsString + "```" + )) + } + + const alliances = await database.Aurora.getAlliances() + if (alliances) { + const nationAlliances = alliances + .filter(A => A.nations.map(e => e.toLowerCase()).includes(nation.name.toLowerCase())) + .map(a => a.allianceName) + + const len = nationAlliances?.length + if (len > 0) nationEmbed.addFields(embedField( + `Alliances [${len}]`, + "```" + nationAlliances.join(", ") + "```" + )) + } + + if (recentNews) { + const news = new News(recentNews) + const img = news?.images ? news.images[0] : null + + nationEmbed.addFields(embedField( + "Recent News", + news.message + (img ? " ([Image](" + img + "))" : "") + )) + } + + const thumbnail = nation.flag ? [] : [AURORA.thumbnail] + nationEmbed.setFiles(thumbnail) + nationEmbed.editInteraction(interaction) } - - const thumbnail = nation.flag ? [] : [AURORA.thumbnail] - nationEmbed.setFiles(thumbnail) - nationEmbed.editInteraction(interaction) } }, data: new SlashCommandBuilder() .setName("nation") .setDescription("Displays info for a nation.") - .addSubcommand(subcommand => subcommand - .setName('lookup') - .setDescription('Get detailed information for a nation') - .addStringOption(option => option.setName("name").setDescription("The name of the nation to lookup.").setRequired(true))) - .addSubcommand(subcommand => subcommand - .setName('activity') - .setDescription('Gets activity data for members of a nation.') - .addStringOption(option => option.setName("name").setDescription("The name of the nation to get activity data for.").setRequired(true))) - .addSubcommand(subcommand => subcommand - .setName('list') - .setDescription('List nations using various comparators.') - .addStringOption(option => option.setName("comparator").setDescription("The comparator to use. Available: online, residents, chunks & name."))) + .addSubcommand(subCmd => subCmd.setName('lookup') + .setDescription('Get detailed information for a nation') + .addStringOption(option => option + .setName("name") + .setDescription("The name of the nation to lookup.") + .setRequired(true) + ) + ) + .addSubcommand(subCmd => subCmd.setName('activity') + .setDescription('Gets activity data for members of a nation.') + .addStringOption(option => option + .setName("name") + .setDescription("The name of the nation to get activity data for.") + .setRequired(true) + ) + ) + .addSubcommand(subCmd => subCmd.setName('list') + .setDescription('List nations using various comparators.') + .addStringOption(option => option + .setName("comparator") + .setDescription("The comparator to use. Available: online, residents, chunks & name.") + ) + ) } \ No newline at end of file