feat: refactor fk and add manual user exceptions
This commit is contained in:
parent
2034c56208
commit
f9c7adc7b4
217
commands/fk.js
Normal file
217
commands/fk.js
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
import { SlashCommandBuilder } from "discord.js";
|
||||||
|
import { ADDUP_ID, PICKING_ID } from "../config.json";
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
const fkPath = path.join(__dirname, "..", "fk.json");
|
||||||
|
|
||||||
|
const storeFk = async (idArr) => {
|
||||||
|
// store fk history to avoid repeats
|
||||||
|
if (!idArr || typeof idArr !== "object")
|
||||||
|
return console.error("Cannot store fk history");
|
||||||
|
|
||||||
|
if (!fs.existsSync(fkPath)) {
|
||||||
|
fs.writeFileSync(fkPath, "[]");
|
||||||
|
}
|
||||||
|
let fkHistory = JSON.parse(fs.readFileSync(fkPath));
|
||||||
|
|
||||||
|
// add to history
|
||||||
|
fkHistory.push(idArr);
|
||||||
|
if (fkHistory.length > 10) fkHistory.shift();
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(fkPath, JSON.stringify(fkHistory));
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getPastFk = async () => {
|
||||||
|
// get 3 most recent sets of fks to avoid repeats
|
||||||
|
if (!fs.existsSync(fkPath)) {
|
||||||
|
fs.writeFileSync(fkPath, "[]");
|
||||||
|
}
|
||||||
|
let fkHistory = JSON.parse(fs.readFileSync(fkPath));
|
||||||
|
let recentFk = fkHistory.slice(-3);
|
||||||
|
|
||||||
|
if (!recentFk || typeof recentFk !== "object")
|
||||||
|
console.error("Invalid fk history");
|
||||||
|
if (recentFk.length === 0) return [[], [], []];
|
||||||
|
return recentFk;
|
||||||
|
};
|
||||||
|
|
||||||
|
const data = new SlashCommandBuilder()
|
||||||
|
.setName("fk")
|
||||||
|
.setDescription(
|
||||||
|
"Moves added players to picking and randomly sits players out"
|
||||||
|
)
|
||||||
|
.addUserOption((option) =>
|
||||||
|
option
|
||||||
|
.setName("exception1")
|
||||||
|
.setDescription("Player to protect from sitting out, intended for medic")
|
||||||
|
)
|
||||||
|
.addUserOption((option) =>
|
||||||
|
option
|
||||||
|
.setName("exception2")
|
||||||
|
.setDescription("Player to protect from sitting out, intended for medic")
|
||||||
|
);
|
||||||
|
|
||||||
|
const execute = async (interaction) => {
|
||||||
|
// pull users in addup into picking, then randomly select other users in picking to be sat out until there are 18 in picking
|
||||||
|
await interaction.reply("Randomly choosing fatkids from picking...");
|
||||||
|
|
||||||
|
// get voice channels
|
||||||
|
const addup = interaction.guild.channels.cache.find(
|
||||||
|
(channel) => channel.name === "add-up" || channel.id === ADDUP_ID
|
||||||
|
);
|
||||||
|
const picking = interaction.guild.channels.cache.find(
|
||||||
|
(channel) => channel.name === "picking" || channel.id === PICKING_ID
|
||||||
|
);
|
||||||
|
|
||||||
|
// get members in voice channel
|
||||||
|
const addupPlayers = [];
|
||||||
|
const pickingPlayers = [];
|
||||||
|
addup.members.forEach((member) => addupPlayers.push(member));
|
||||||
|
picking.members.forEach((member) => pickingPlayers.push(member));
|
||||||
|
|
||||||
|
if (pickingPlayers.length < addupPlayers.length) {
|
||||||
|
// move all addup into empty picking
|
||||||
|
addup.members.forEach((member) => {
|
||||||
|
member.voice.setChannel(picking);
|
||||||
|
});
|
||||||
|
return await interaction.followUp(
|
||||||
|
"Found too few players in picking to fatkid, moved all addup players to picking instead"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetPlayerCount = 18;
|
||||||
|
if (pickingPlayers.length + addupPlayers.length < targetPlayerCount) {
|
||||||
|
return await interaction.followUp(
|
||||||
|
`Can't find enough total players, expected ${targetPlayerCount} (found ${
|
||||||
|
pickingPlayers.length + addupPlayers.length
|
||||||
|
})`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up past fk protection
|
||||||
|
let fatkids = [],
|
||||||
|
recentFkSets = [],
|
||||||
|
protectedFk = [],
|
||||||
|
protectedDict = {},
|
||||||
|
fkAttempts = 0;
|
||||||
|
try {
|
||||||
|
recentFkSets = await getPastFk();
|
||||||
|
protectedFk = recentFkSets.flat();
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
await interaction.followUp(
|
||||||
|
"Failed to get history, fk protection may not be applied"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get exceptions
|
||||||
|
let exceptions = [];
|
||||||
|
for (const option of ["exception1", "exception2"]) {
|
||||||
|
const exception = interaction.options.getUser(option);
|
||||||
|
if (exception) exceptions.push(exception);
|
||||||
|
}
|
||||||
|
if (addupPlayers.length > targetPlayerCount - exceptions.length) {
|
||||||
|
exceptions = [];
|
||||||
|
return await interaction.followUp(
|
||||||
|
"Could not apply exceptions as too many players in addup were found"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// select excess players to be sat out
|
||||||
|
while (pickingPlayers.length + addupPlayers.length > targetPlayerCount) {
|
||||||
|
if (pickingPlayers.length === 0) {
|
||||||
|
return await interaction.followUp(
|
||||||
|
"Error: ran out of players in picking to fatkid"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// remove earliest fk sets as attempts become unreasonably high
|
||||||
|
if (fkAttempts === 100 || fkAttempts === 250 || fkAttempts === 500) {
|
||||||
|
console.log(`Shifting fk history ${fkAttempts}`);
|
||||||
|
recentFkSets.shift();
|
||||||
|
protectedFk = recentFkSets.flat();
|
||||||
|
}
|
||||||
|
fkAttempts++;
|
||||||
|
const idx = Math.floor(Math.random() * pickingPlayers.length);
|
||||||
|
let fk = pickingPlayers[idx];
|
||||||
|
if (exceptions.includes(fk)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (protectedFk.includes(fk.id)) {
|
||||||
|
if (!protectedDict[fk.id]) protectedDict[fk.id] = 0; // todo: once this works change it to hold the member object so that we don't have to fetch it later
|
||||||
|
protectedDict[fk.id]++;
|
||||||
|
} else {
|
||||||
|
pickingPlayers.splice(idx, 1);
|
||||||
|
fatkids.push(fk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Object.keys(protectedDict).length > 0) {
|
||||||
|
console.log(`Protected fks: ${JSON.stringify(protectedDict)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let errCount = 0;
|
||||||
|
|
||||||
|
// move players from addup to picking
|
||||||
|
for (const newPlayer of addupPlayers) {
|
||||||
|
try {
|
||||||
|
await newPlayer.voice.setChannel(picking);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
errCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let fkIds = [];
|
||||||
|
|
||||||
|
// move players from picking to fatkid
|
||||||
|
for (const fk of fatkids) {
|
||||||
|
try {
|
||||||
|
fkIds.push(fk.id);
|
||||||
|
await fk.voice.setChannel(addup);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
errCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// store fatkid history
|
||||||
|
try {
|
||||||
|
storeFk(fkIds);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// build response
|
||||||
|
let fkStr = `Sat out ${fatkids.length} players${
|
||||||
|
fatkids.length > 0 ? ": " : ""
|
||||||
|
}`;
|
||||||
|
for (const fk of fatkids) {
|
||||||
|
fkStr += `${fk.displayName}, `;
|
||||||
|
}
|
||||||
|
fkStr = fkStr.slice(0, -2);
|
||||||
|
if (Object.keys(protectedDict).length > 0) {
|
||||||
|
fkStr += "Players that were protected at least once: ";
|
||||||
|
for (const fkId in protectedDict) {
|
||||||
|
await interaction.guild.members
|
||||||
|
.fetch(fkId)
|
||||||
|
.then((member) => {
|
||||||
|
if (member) {
|
||||||
|
fkStr += `${member.displayName}, `;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
}
|
||||||
|
fkStr = fkStr.slice(0, -2);
|
||||||
|
}
|
||||||
|
if (fkAttempts > 100)
|
||||||
|
fkStr += `\n(fk protection sets ignored: ${3 - recentFkSets.length}/3)`;
|
||||||
|
if (errCount > 0) fkStr += `\n(error moving ${errCount} members)`;
|
||||||
|
|
||||||
|
interaction.followUp(fkStr);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { data, execute };
|
||||||
8
index.js
8
index.js
@ -269,7 +269,7 @@ client.on("error", (error) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
client.on("interactionCreate", async (interaction) => {
|
client.on("interactionCreate", async (interaction) => {
|
||||||
const command = interaction.commandName;
|
let command = interaction.commandName;
|
||||||
if (!interaction.isChatInputCommand()) return;
|
if (!interaction.isChatInputCommand()) return;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -400,7 +400,7 @@ client.on("interactionCreate", async (interaction) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command === "fk" || command === "fatkid") {
|
/*if (command === "fk" || command === "fatkid") {
|
||||||
// pull users in addup into picking, then randomly select other users in picking to be sat out until there are 18 in picking
|
// pull users in addup into picking, then randomly select other users in picking to be sat out until there are 18 in picking
|
||||||
await interaction.reply("Randomly choosing fatkids from picking...");
|
await interaction.reply("Randomly choosing fatkids from picking...");
|
||||||
|
|
||||||
@ -521,7 +521,7 @@ client.on("interactionCreate", async (interaction) => {
|
|||||||
: ""
|
: ""
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/*if (command === "testfk") {
|
/*if (command === "testfk") {
|
||||||
// debug fk
|
// debug fk
|
||||||
@ -831,6 +831,8 @@ client.on("interactionCreate", async (interaction) => {
|
|||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command === "fatkid") command = "fk";
|
||||||
|
|
||||||
const fileCommand = client.fileCommands.get(command);
|
const fileCommand = client.fileCommands.get(command);
|
||||||
if (!fileCommand) return;
|
if (!fileCommand) return;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user