Fix autocomplete bugs, bulk upload
This commit is contained in:
parent
4cd8f68e92
commit
4ec01a6ab9
5 changed files with 269 additions and 170 deletions
|
@ -1,54 +1,58 @@
|
||||||
import { InteractionResponseTypes } from "@discordeno/types"
|
import { InteractionResponseTypes } from "@discordeno/types";
|
||||||
import REST from "../lib/handlers/RESTHandler"
|
import REST from "../lib/handlers/RESTHandler";
|
||||||
import { staged } from "../lib/modpack"
|
import { staged } from "../lib/modpack";
|
||||||
import { getAllMods } from "../lib/database"
|
import { getAllMods } from "../lib/database";
|
||||||
|
|
||||||
function search(arr, search) {
|
function search(arr, search) {
|
||||||
if (!search.length) return false
|
if (!search.length) return false;
|
||||||
|
|
||||||
var matches = arr.filter(function (str) {
|
var matches = arr.filter(function (str) {
|
||||||
const regex = new RegExp(search, "i")
|
const regex = new RegExp(search, "i");
|
||||||
return str.search(regex) > -1
|
return str.search(regex) > -1;
|
||||||
})
|
});
|
||||||
|
|
||||||
return matches.length > 0 ? matches : false
|
return matches.length > 0 ? matches : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Autocomplete {
|
export default class Autocomplete {
|
||||||
static name = "modify"
|
static name = "modify";
|
||||||
|
|
||||||
constructor(data) {}
|
constructor(data) {}
|
||||||
|
|
||||||
async run(interaction) {
|
async run(interaction) {
|
||||||
const entry = interaction.data.options[0].options[0].value
|
const entry = interaction.data.options[0].options.find((_) => _.name == "name").value;
|
||||||
const from_modpack = interaction.data.options[0].options[1]?.value
|
const from_modpack = interaction.data.options[0].options.find((_) => _.name == "from_modpack")?.value;
|
||||||
|
|
||||||
if (!from_modpack) {
|
if (!from_modpack) {
|
||||||
const keys = Array.from(staged.keys())
|
const keys = Array.from(staged.keys());
|
||||||
let choices = search(keys, entry)
|
let choices = search(keys, entry);
|
||||||
if (!choices) choices = keys
|
if (!choices) choices = keys;
|
||||||
|
|
||||||
return REST.sendInteractionResponse(interaction.id, interaction.token, {
|
return REST.sendInteractionResponse(interaction.id, interaction.token, {
|
||||||
type: InteractionResponseTypes.ApplicationCommandAutocompleteResult,
|
type: InteractionResponseTypes.ApplicationCommandAutocompleteResult,
|
||||||
data: {
|
data: {
|
||||||
choices: choices.map((_) => {
|
choices: choices
|
||||||
return { name: _, value: _ }
|
.map((_) => {
|
||||||
}),
|
return { name: _, value: _ };
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
.slice(0, 24),
|
||||||
|
},
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
const keys = getAllMods.all().map((_) => _.name)
|
const keys = getAllMods.all().map((_) => _.name);
|
||||||
let choices = search(keys, entry)
|
let choices = search(keys, entry);
|
||||||
if (!choices) choices = keys
|
if (!choices) choices = keys;
|
||||||
|
|
||||||
return REST.sendInteractionResponse(interaction.id, interaction.token, {
|
return REST.sendInteractionResponse(interaction.id, interaction.token, {
|
||||||
type: InteractionResponseTypes.ApplicationCommandAutocompleteResult,
|
type: InteractionResponseTypes.ApplicationCommandAutocompleteResult,
|
||||||
data: {
|
data: {
|
||||||
choices: choices.map((_) => {
|
choices: choices
|
||||||
return { name: _, value: _ }
|
.map((_) => {
|
||||||
}),
|
return { name: _, value: _ };
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
.slice(0, 24),
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
88
src/commands/bulk.js
Normal file
88
src/commands/bulk.js
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
import BaseCommand from "../lib/classes/BaseCommand";
|
||||||
|
import { getModFromId } from "../lib/curseforge";
|
||||||
|
import { staged } from "../lib/modpack";
|
||||||
|
|
||||||
|
function progress(percent) {
|
||||||
|
return "#".repeat(percent * 25).padEnd(25, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Command extends BaseCommand {
|
||||||
|
static type = 1;
|
||||||
|
static name = "bulk";
|
||||||
|
static description = "Make changes in builk";
|
||||||
|
static options = [
|
||||||
|
{
|
||||||
|
type: 1,
|
||||||
|
name: "add",
|
||||||
|
description: "Add mods in bulk",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
type: 11,
|
||||||
|
name: "file",
|
||||||
|
description: "A CurseForge manifest file",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 1,
|
||||||
|
name: "remove",
|
||||||
|
description: "Remove mods in bulk",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
type: 11,
|
||||||
|
name: "file",
|
||||||
|
description: "A curseforge manifest file",
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(data) {
|
||||||
|
super(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async run(interaction) {
|
||||||
|
const subcommand = interaction.data.options[0].name;
|
||||||
|
const subcommandOptions = interaction.data.options[0].options;
|
||||||
|
const attachmentId = BigInt(subcommandOptions[0].value);
|
||||||
|
const file = interaction.data.resolved.attachments.get(attachmentId);
|
||||||
|
|
||||||
|
let succeeded = [];
|
||||||
|
let failed = [];
|
||||||
|
|
||||||
|
if (subcommand == "add") {
|
||||||
|
await interaction.defer();
|
||||||
|
|
||||||
|
if (file.contentType !== "application/json; charset=utf-8" || file.filename !== "manifest.json")
|
||||||
|
return interaction.respond("That is not a valid manifest.json file.", { isPrivate: true });
|
||||||
|
|
||||||
|
const manifest = await (await fetch(file.url)).json();
|
||||||
|
|
||||||
|
for (let i = 0; i < manifest.files.length; i++) {
|
||||||
|
const { projectID, fileID } = manifest.files[i];
|
||||||
|
const mod = (await getModFromId(projectID)).data;
|
||||||
|
|
||||||
|
if (mod && !staged.get(mod.name)) {
|
||||||
|
staged.set(mod.name, {
|
||||||
|
modId: mod.id,
|
||||||
|
fileId: fileID,
|
||||||
|
provider: "curseforge",
|
||||||
|
url: mod.links.websiteUrl,
|
||||||
|
action: "add",
|
||||||
|
});
|
||||||
|
|
||||||
|
succeeded.push(mod.name);
|
||||||
|
|
||||||
|
if (succeeded.length % 5 == 0) await interaction.edit(`[${progress(i / manifest.files.length)}]`);
|
||||||
|
} else {
|
||||||
|
failed.push({ modId: projectID });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return interaction.edit(`Bulk added **${succeeded.length} mods**. (${failed.length} failed)`);
|
||||||
|
} else if (subcommand == "remove") {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,24 +1,25 @@
|
||||||
import BaseCommand from "../lib/classes/BaseCommand"
|
import BaseCommand from "../lib/classes/BaseCommand";
|
||||||
import { staged } from "../lib/modpack"
|
import { staged } from "../lib/modpack";
|
||||||
|
|
||||||
export default class Command extends BaseCommand {
|
export default class Command extends BaseCommand {
|
||||||
static type = 1
|
static type = 1;
|
||||||
static name = "changes"
|
static name = "changes";
|
||||||
static description = "Get staged changes to the modpack"
|
static description = "Get staged changes to the modpack";
|
||||||
|
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
super(data)
|
super(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async run(interaction) {
|
async run(interaction) {
|
||||||
let text = ""
|
let text = "";
|
||||||
|
|
||||||
if (!staged.size) return interaction.respond("No changes to the modpack have been staged.")
|
if (!staged.size) return interaction.respond("No changes to the modpack have been staged.");
|
||||||
|
|
||||||
for (let [key, value] of staged.entries()) {
|
for (let [key, value] of staged.entries()) {
|
||||||
text += (value.action == "add" ? "+" : "-") + " " + key + " (" + value.url + ")\n"
|
text += (value.action == "add" ? "+" : "-") + " " + key + " (" + value.url + ")\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
interaction.respond("```diff\n" + text + "\n```")
|
if (text.length >= 2000) return interaction.respond("Too many changes to display.");
|
||||||
|
interaction.respond("```diff\n" + text + "\n```");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import BaseCommand from "../lib/classes/BaseCommand"
|
import BaseCommand from "../lib/classes/BaseCommand";
|
||||||
import { staged } from "../lib/modpack"
|
import { staged } from "../lib/modpack";
|
||||||
import * as curseforge from "../lib/curseforge"
|
import * as curseforge from "../lib/curseforge";
|
||||||
import { getMod } from "../lib/database"
|
import { getMod } from "../lib/database";
|
||||||
|
|
||||||
export default class Command extends BaseCommand {
|
export default class Command extends BaseCommand {
|
||||||
static type = 1
|
static type = 1;
|
||||||
static name = "modify"
|
static name = "modify";
|
||||||
static description = "Modify the modpack"
|
static description = "Modify the modpack";
|
||||||
static options = [
|
static options = [
|
||||||
{
|
{
|
||||||
type: 1,
|
type: 1,
|
||||||
|
@ -41,28 +41,30 @@ export default class Command extends BaseCommand {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
super(data)
|
super(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async run(interaction) {
|
async run(interaction) {
|
||||||
const subcommand = interaction.data.options[0].name
|
const subcommand = interaction.data.options[0].name;
|
||||||
const subcommandOptions = interaction.data.options[0].options
|
const subcommandOptions = interaction.data.options[0].options;
|
||||||
|
|
||||||
if (subcommand == "add") {
|
if (subcommand == "add") {
|
||||||
const url = subcommandOptions.find((_) => _.name == "url").value
|
const url = subcommandOptions.find((_) => _.name == "url").value;
|
||||||
const parsedUrl = new URL(url)
|
const parsedUrl = new URL(url);
|
||||||
|
|
||||||
if (parsedUrl.host.includes("curseforge.com")) {
|
if (parsedUrl.host.includes("curseforge.com")) {
|
||||||
const mod = await curseforge.getMod(url)
|
const mod = await curseforge.getMod(url);
|
||||||
if (!mod) return interaction.respond("Mod not found.")
|
if (!mod) return interaction.respond("Mod not found.");
|
||||||
|
|
||||||
const file = await curseforge.getModFiles(mod.id)
|
const file = await curseforge.getModFiles(mod.id);
|
||||||
|
|
||||||
if (staged.get(mod.name)) return interaction.respond(`**${mod.name}** is already in the staged mods.`, { isPrivate: true })
|
if (staged.get(mod.name))
|
||||||
if (getMod.get(mod.name)) return interaction.respond(`**${mod.name}** is already in the modpack.`, { isPrivate: true })
|
return interaction.respond(`**${mod.name}** is already in the staged mods.`, { isPrivate: true });
|
||||||
|
if (getMod.get(mod.name))
|
||||||
|
return interaction.respond(`**${mod.name}** is already in the modpack.`, { isPrivate: true });
|
||||||
|
|
||||||
staged.set(mod.name, {
|
staged.set(mod.name, {
|
||||||
modId: mod.id,
|
modId: mod.id,
|
||||||
|
@ -70,36 +72,36 @@ export default class Command extends BaseCommand {
|
||||||
provider: "curseforge",
|
provider: "curseforge",
|
||||||
url: mod.links.websiteUrl,
|
url: mod.links.websiteUrl,
|
||||||
action: "add",
|
action: "add",
|
||||||
})
|
});
|
||||||
|
|
||||||
interaction.respond(`Added **${mod.name}** to the staged mods.`)
|
interaction.respond(`Added **${mod.name}** to the staged mods.`);
|
||||||
} else if (parsedUrl.host.includes("modrinth.com")) {
|
} else if (parsedUrl.host.includes("modrinth.com")) {
|
||||||
console.log("Modrinth mod detected")
|
console.log("Modrinth mod detected");
|
||||||
}
|
}
|
||||||
} else if (subcommand == "remove") {
|
} else if (subcommand == "remove") {
|
||||||
const name = subcommandOptions.find((_) => _.name == "name").value
|
const name = subcommandOptions.find((_) => _.name == "name").value;
|
||||||
const from_modpack = subcommandOptions.find((_) => _.name == "from_modpack")?.value
|
const from_modpack = subcommandOptions.find((_) => _.name == "from_modpack")?.value;
|
||||||
|
|
||||||
if (!from_modpack) {
|
if (!from_modpack) {
|
||||||
const mod = staged.get(name)
|
const mod = staged.get(name);
|
||||||
if (!mod) return interaction.respond("Mod not found.")
|
if (!mod) return interaction.respond("Mod not found.");
|
||||||
|
|
||||||
staged.delete(name)
|
staged.delete(name);
|
||||||
|
|
||||||
interaction.respond(`Removed **${name}** from the staged mods.`)
|
interaction.respond(`Removed **${name}** from the staged mods.`);
|
||||||
} else {
|
} else {
|
||||||
const mod = getMod.get(name)
|
const mod = getMod.get(name);
|
||||||
if (!mod) return interaction.respond("Mod not found.")
|
if (!mod) return interaction.respond("Mod not found.");
|
||||||
const modData = await curseforge.getModFromId(mod.modId)
|
const modData = await curseforge.getModFromId(mod.modId);
|
||||||
|
|
||||||
staged.set(mod.name, {
|
staged.set(mod.name, {
|
||||||
modId: mod.modId,
|
modId: mod.modId,
|
||||||
url: modData.data.links.websiteUrl,
|
url: modData.data.links.websiteUrl,
|
||||||
provider: "curseforge",
|
provider: "curseforge",
|
||||||
action: "remove",
|
action: "remove",
|
||||||
})
|
});
|
||||||
|
|
||||||
interaction.respond(`Staged the removal of **${name}**.`)
|
interaction.respond(`Staged the removal of **${name}**.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,37 @@
|
||||||
import { createBot, Intents, logger } from "@discordeno/bot"
|
import { createBot, Intents, logger } from "@discordeno/bot";
|
||||||
|
|
||||||
import EventHandler from "./lib/handlers/EventHandler"
|
import EventHandler from "./lib/handlers/EventHandler";
|
||||||
|
|
||||||
export default async function discord() {
|
export default async function discord() {
|
||||||
const client = createBot({
|
const client = createBot({
|
||||||
token: import.meta.env.DISCORD_TOKEN,
|
token: import.meta.env.DISCORD_TOKEN,
|
||||||
// intents: [],
|
// intents: [],
|
||||||
})
|
});
|
||||||
|
|
||||||
client.events = await new EventHandler(client).load()
|
client.events = await new EventHandler(client).load();
|
||||||
|
|
||||||
client.transformers.desiredProperties.message.content = true
|
client.transformers.desiredProperties.message.content = true;
|
||||||
client.transformers.desiredProperties.message.author = true
|
client.transformers.desiredProperties.message.author = true;
|
||||||
|
|
||||||
client.transformers.desiredProperties.user.id = true
|
client.transformers.desiredProperties.user.id = true;
|
||||||
client.transformers.desiredProperties.user.username = true
|
client.transformers.desiredProperties.user.username = true;
|
||||||
client.transformers.desiredProperties.user.avatar = true
|
client.transformers.desiredProperties.user.avatar = true;
|
||||||
|
|
||||||
client.transformers.desiredProperties.member.user = true
|
client.transformers.desiredProperties.member.user = true;
|
||||||
client.transformers.desiredProperties.member.roles = true
|
client.transformers.desiredProperties.member.roles = true;
|
||||||
client.transformers.desiredProperties.member.permissions = true
|
client.transformers.desiredProperties.member.permissions = true;
|
||||||
|
|
||||||
client.transformers.desiredProperties.interaction.id = true
|
client.transformers.desiredProperties.interaction.id = true;
|
||||||
client.transformers.desiredProperties.interaction.type = true
|
client.transformers.desiredProperties.interaction.type = true;
|
||||||
client.transformers.desiredProperties.interaction.data = true
|
client.transformers.desiredProperties.interaction.data = true;
|
||||||
client.transformers.desiredProperties.interaction.token = true
|
client.transformers.desiredProperties.interaction.token = true;
|
||||||
client.transformers.desiredProperties.interaction.guildId = true
|
client.transformers.desiredProperties.interaction.guildId = true;
|
||||||
client.transformers.desiredProperties.interaction.channelId = true
|
client.transformers.desiredProperties.interaction.channelId = true;
|
||||||
client.transformers.desiredProperties.interaction.member = true
|
client.transformers.desiredProperties.interaction.member = true;
|
||||||
|
|
||||||
client.start()
|
client.transformers.desiredProperties.attachment.contentType = true;
|
||||||
|
client.transformers.desiredProperties.attachment.filename = true;
|
||||||
|
client.transformers.desiredProperties.attachment.url = true;
|
||||||
|
|
||||||
|
client.start();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue