diff --git a/package-lock.json b/package-lock.json index 1735931..6af42e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@discordjs/opus": "github:discordjs/opus", "@discordjs/voice": "^0.6.0", "discord.js": "^13.0.1", + "js-levenshtein": "^1.1.6", "node-fetch": "^2.6.1", "tweetnacl": "^1.0.3", "yt-search": "^2.10.1", @@ -19,6 +20,7 @@ "ytdl-core": "^4.9.1" }, "devDependencies": { + "@types/js-levenshtein": "^1.1.0", "@types/node-fetch": "^2.5.12" } }, @@ -173,6 +175,12 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, + "node_modules/@types/js-levenshtein": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/js-levenshtein/-/js-levenshtein-1.1.0.tgz", + "integrity": "sha512-14t0v1ICYRtRVcHASzes0v/O+TIeASb8aD55cWF1PidtInhFWSXcmhzhHqGjUWf9SUq1w70cvd1cWKUULubAfQ==", + "dev": true + }, "node_modules/@types/node": { "version": "16.7.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.5.tgz", @@ -1000,6 +1008,14 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/jsonpath-plus": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-5.0.7.tgz", @@ -1749,6 +1765,12 @@ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==" }, + "@types/js-levenshtein": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/js-levenshtein/-/js-levenshtein-1.1.0.tgz", + "integrity": "sha512-14t0v1ICYRtRVcHASzes0v/O+TIeASb8aD55cWF1PidtInhFWSXcmhzhHqGjUWf9SUq1w70cvd1cWKUULubAfQ==", + "dev": true + }, "@types/node": { "version": "16.7.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.5.tgz", @@ -2412,6 +2434,11 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==" + }, "jsonpath-plus": { "version": "5.0.7", "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-5.0.7.tgz", diff --git a/package.json b/package.json index 8bc539b..ce9ef54 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@discordjs/opus": "github:discordjs/opus", "@discordjs/voice": "^0.6.0", "discord.js": "^13.0.1", + "js-levenshtein": "^1.1.6", "node-fetch": "^2.6.1", "tweetnacl": "^1.0.3", "yt-search": "^2.10.1", @@ -23,6 +24,7 @@ "ytdl-core": "^4.9.1" }, "devDependencies": { + "@types/js-levenshtein": "^1.1.0", "@types/node-fetch": "^2.5.12" } } diff --git a/src/app.ts b/src/app.ts index f276576..0bcc716 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,7 +1,9 @@ -import { Client, Intents } from "discord.js"; +import { Client, Collection, Intents, Message, MessageActionRow, MessageButton } from "discord.js"; import { readdirSync } from "fs"; import { EventSOn, KoamndNaExport, Komand, ListenerFunkce, Modul, RunFunkce, SRecord, SuperListenerFunkce } from "./utils/types"; import { formatCas, loadEnv, oddiakritikovat } from "./utils/utils.js"; +import levenshtein from "js-levenshtein"; +import { emouty } from "./utils/emotes"; loadEnv(); @@ -95,26 +97,64 @@ const maKuldan = (id: string, komand: string, kuldan_komandu: number) => { client.on("messageCreate", async mes => { if (process.env.ignoreMess) return; - const [mes_prefix, komandSDiakritikou, ...args] = mes.content.split(" "); - if (oddiakritikovat(mes_prefix.toLowerCase()) != prefix) return void runEvent("message", [mes]); + const [mesPrefix, komandSDiakritikou, ...args] = mes.content.split(" "); + if (oddiakritikovat(mesPrefix.toLowerCase()) != prefix) return void runEvent("message", [mes]); if (!komandSDiakritikou) return void mes.channel.send("coe voe"); - const komand = oddiakritikovat(komandSDiakritikou).toLowerCase(); const celArgs = args.join(" "); + + async function runKomand(cmd: Komand, cmdName: string) { + if (cmd.cd) { + const zbyva = Math.round(maKuldan(mes.author.id, cmdName, cmd.cd)); + if (zbyva) return void mes.channel.send(`si kkt vole maz kuldan jeste ${formatCas(zbyva)}`); + } + + const akce = cmd.run; + if (typeof akce === "string") return void mes.channel.send(akce); + const result = await akce(mes, celArgs); + if (result && !(result instanceof Promise)) mes.channel.send(result); + } + const komand = oddiakritikovat(komandSDiakritikou).toLowerCase(); + const cmdName = aliasy[komand] ?? komand; if (runEvent("message", [mes, cmdName])) return; const cmd = komandy[cmdName]; - if (!cmd) return void mes.channel.send("co to znamena ti gadzovko"); - if (cmd.cd) { - const zbyva = Math.round(maKuldan(mes.author.id, cmdName, cmd.cd)); - if (zbyva) return void mes.channel.send(`si kkt vole maz kuldan jeste ${formatCas(zbyva)}`); + if (!cmd) { + const slova: string[] = []; + [...Object.keys(komandy), ...Object.keys(aliasy)].forEach(cmnd => { + const distance = levenshtein(cmnd, cmdName); + if (distance <= Math.ceil(cmdName.length * 0.3)) slova.push(cmnd); + }); + if (!slova.length) return void mes.channel.send("co to znamena ti gadzovko"); + const nabidka = slova.sort().slice(0, 5); + + const radek = new MessageActionRow(); + nabidka.forEach((cmnd, i) => { + radek.addComponents(new MessageButton({ customId: `${i}`, label: cmnd, style: "PRIMARY" })); + }); + + const zprava = await mes.channel.send({ content: "nemnel sy na misli:", components: [radek] }); + const collector = mes.channel.createMessageComponentCollector({ filter: i => i.message.id == zprava.id && mes.author.id == i.user.id, time: 18e4 }); + collector.on("collect", i => { + const lookupId = Number(i.customId); + if (isNaN(lookupId)) return void mes.channel.send("neco nefunguje idk"); + const komand = nabidka[lookupId]; + const cmdName = aliasy[komand] ?? komand; + const cmd = komandy[cmdName]; + radek.components.forEach(btn => btn.setDisabled()); + i.update({ content: `ok vole ${emouty.d3k}`, components: [radek] }); + runKomand(cmd, cmdName); + }); + collector.on("end", (c: Collection) => { + if (c.size) return; + radek.components.forEach(btn => btn.setDisabled()); + zprava.edit({ content: "pozde", components: [radek] }); + }); + return; } - const akce = cmd.run; - if (typeof akce === "string") return void mes.channel.send(akce); - const result = await akce(mes, celArgs); - if (result && !(result instanceof Promise)) mes.channel.send(result); + runKomand(cmd, cmdName); }); client.login(process.env.token); diff --git a/src/modules/muzika.ts b/src/modules/muzika.ts index 46eb3be..93a29fe 100644 --- a/src/modules/muzika.ts +++ b/src/modules/muzika.ts @@ -1,6 +1,6 @@ // Tady bude muzika, vole -import * as ytdl from "ytdl-core"; +import ytdl from "ytdl-core"; import { Modul } from "../utils/types"; import { joinVoice, play } from "../utils/utils"; @@ -10,7 +10,7 @@ const exp: Modul = { if (!ytdl.validateURL(url)) return "tuto neni validni youtube url a to je zatim jedini co hodlam hrat"; const kanel = mes.member?.voice.channel; if (!kanel) return "nejsi ve vojsu ty kkt"; - const { conn } = await joinVoice(kanel, mes.guild!); + const { conn } = await joinVoice(kanel); play(conn, ytdl(url).on("error", e => console.log(e))); } } diff --git a/tsconfig.json b/tsconfig.json index 2016e2a..49af3d6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "forceConsistentCasingInFileNames": true, "allowSyntheticDefaultImports": true, "removeComments": true, + "esModuleInterop": true }, "include": [ "src"