BIG COMMIT

switched to discord.js version 13
rewrite of js to ts
finally removed remporary logging
emotes are now in enum
fixed vypadni to working
This commit is contained in:
Histmy 2021-08-18 20:08:06 +02:00
parent 2bf36c9d28
commit c6aa30a80c
23 changed files with 2740 additions and 759 deletions

View File

@ -1,22 +0,0 @@
module.exports = {
shitFormat: obj => {
if (!obj) return console.log(obj, "\n");
const keys = Object.keys(obj);
const vals = Object.values(obj);
keys.forEach((key, i) => {
let output = vals[i];
if (typeof output === "object") output = "object";
console.log(key, output);
});
console.log("");
},
formatCas: c => {
const h = Math.floor(c / 3600);
const m = Math.floor(c % 3600 / 60);
const s = Math.floor(c % 3600 % 60);
return `${h} hodin ${m} mynut a ${s} se kund`;
}
};

107
app.js
View File

@ -1,107 +0,0 @@
const { Client } = require('discord.js');
const fs = require("fs");
const { formatCas } = require("./addons/utils");
const client = new Client();
require('dotenv').config();
const prefix = process.env.PREFIX || 'more';
const modulFolder = "./modules/";
const eventy = { on_message: [] };
const komandy = {};
const aliasy = {};
let spink = false;
const kuldan_log = {};
const runEvent = (name, args) => {
eventy[name].forEach(listener => {
listener(...args);
});
};
fs.readdirSync(modulFolder).forEach(function (soubor) {
if (soubor.endsWith(".js")) {
const modul = require(`${modulFolder}${soubor}`);
modul.client = client;
Object.keys(modul).forEach(name => {
if (name.startsWith('on_')) {
if (!eventy[name]) {
eventy[name] = [];
if (name !== 'on_message') client.on(name.substring(3), (...args) => runEvent(name, args));
}
eventy[name].push(modul[name]);
} else if (name === 'more_komandy') {
Object.keys(modul[name]).forEach(cmdName => {
const value = modul[name][cmdName];
if (typeof value !== "object") {
komandy[cmdName] = { run: value };
return;
}
komandy[cmdName] = { run: value.run, cd: value.cd };
value.als?.forEach(al => aliasy[al] = cmdName);
});
}
});
}
});
const spim = mes => {
if (mes.content.toLowerCase() === `${prefix} zapni se`) {
if (spink) {
spink = false;
mes.client.user.setStatus("online");
mes.channel.send("dobré ráno magoří");
}
else mes.channel.send("tak jsi kokot?");
} else if (!spink) {
if (mes.content.toLowerCase() === `${prefix} vypni se`) {
mes.react("855120055632134155");
[...mes.client.voice?.connections.values()].forEach(con => con.disconnect());
mes.client.user.setStatus("invisible");
spink = true;
}
else return false;
}
return true;
};
function maKuldan(id, komand, kuldan_komandu) {
if (!kuldan_log[komand]) kuldan_log[komand] = {};
const cas_ted = Date.now() / 1000;
const rozdil = cas_ted - kuldan_log[komand][id];
if (rozdil < kuldan_komandu) return kuldan_komandu - rozdil;
kuldan_log[komand][id] = cas_ted;
return false;
}
client.on("message", function (mes) {
if (process.env.IGNORE_MESS || spim(mes)) return;
runEvent('on_message', [mes]);
const [mes_prefix, komand, ...args] = mes.content.split(' ');
if (mes_prefix.toLowerCase() !== prefix) return;
if (!komand) return mes.channel.send("coe voe");
const celArgs = args.join(' ');
const cmdName = aliasy[komand] ?? komand;
const cmd = komandy[cmdName];
const akce = cmd?.run;
if (!akce) return 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 mes.channel.send(`si kkt vole maz kuldan jeste ${formatCas(zbyva)}`);
}
if (typeof akce === "string") return mes.channel.send(akce);
const result = akce(celArgs, mes);
if (result && !result.then) mes.channel.send(result);
});
client.on("debug", console.log);
client.on("error", console.error);
client.on("warn", console.warn);
client.login(process.env.TOKEN);

View File

@ -1,40 +0,0 @@
// Komandy, který pošlou jenom celArgs a random hovno
module.exports = {
more_komandy: {
rekni: (arg, mes) => {
if (mes.author.bot) return "ne";
const corict = arg ?? "co mam jako rict";
mes.delete();
return corict;
},
clap: (arg, mes) => {
mes.delete();
return `${arg} <a:DENIM3K_Clap:629991700571619328>`;
},
clap2: (arg, mes) => {
mes.delete();
return `<a:DENIM3K_Clap2:820793564043673650> ${arg}`;
},
voliz: {
als: ["voliž"],
run: (arg, mes) => {
mes.delete();
return `<a:DENIM3K_lickL:678025691207565313>${arg}<a:DENIM3K_lickR:678025693313105964>`;
}
},
pozdrav: arg => `zdravim ${arg}`,
zhejti: arg => `${arg} je pycovina zasrana vimrdana`,
uraz: {
als: ["uraž"],
run: arg => `${arg} , u suck`
}
}
};

View File

@ -1,123 +0,0 @@
// Komandy, který buď nějakým způsobem mění funkci nebo "vzhled" bota
// nebo donutí bota něco udělat (odeslání zprávy s výsledkem nebo smazání originální zprávy se nepočítá)
const zarizeni = { desktop: 'Počítač', mobile: 'Mobil', web: 'Web' };
const statusy = { online: '🟢', idle: '🟡', dnd: '🔴' };
const changeStatus = (mes, status) => {
mes.client.user.setStatus(status);
return "ano pane";
};
const changeActivity = (mes, activity, txt) => {
mes.client.user.setActivity(txt, activity);
mes.react("730175107313565717");
return "ano pane";
};
const ping = /^<@!?\d+>$/;
module.exports = {
more_komandy: {
online: {
als: ["onlajn", "zelenej"],
run: (_, mes) => changeStatus(mes, "online")
},
idle: {
als: ["žlutej", "zlutej", "afk", "idle", "nepřítomnej", "nepritomnej"],
run: (_, mes) => changeStatus(mes, "idle")
},
dnd: {
als: ["nerusit", "nerušit", "červenej", "cervenej"],
run: (_, mes) => changeStatus(mes, "dnd")
},
offline: {
als: ["oflajn", "neviditelnej"],
run: (_, mes) => changeStatus(mes, "invisible")
},
hraj: (arg, mes) => changeActivity(mes, "PLAYING", arg),
sleduj: (arg, mes) => changeActivity(mes, "WATCHING", arg),
poslouchej: (arg, mes) => changeActivity(mes, "LISTENING", arg),
soutez: {
als: ["soutěž"],
run: (arg, mes) => changeActivity(mes, "COMPETING", arg)
},
nedelej: (_, mes) => changeActivity(mes, ""),
fight: {
als: ["figh", "fajt"],
run: (arg, mes) => {
if (!ping.test(arg)) return 'tak si kokot ti kokote';
const vyherce = Math.random() < 0.5 ? mes.author : arg;
return `tento figh vyhrál: ${vyherce}!`;
}
},
status: (arg, mes) => {
if (!ping.test(arg)) return 'tak si kokot ti kokote';
const uzivatel = mes.mentions.users.first();
const embed = {
title: `Informace o statusech pro ${uzivatel.username}:`,
color: 431075
};
const presence = uzivatel.presence.clientStatus;
if (!presence) {
embed.description = '*Všude je offline*';
} else {
const uStatusy = [];
Object.keys(presence).forEach(status => {
uStatusy.push(`${zarizeni[status]}: ${statusy[presence[status]]}`);
});
embed.description = uStatusy.join('\n');
}
return { embed };
},
zareaguj: {
als: ["react"],
run: (arg, mes) => {
if (!arg) return 'retard';
const emouty = arg.match(/<a?:\w{1,32}:\d+>/g);
if (!emouty) return 'retard';
let naCo;
(async () => {
if (mes.reference) {
naCo = await mes.channel.messages.fetch(mes.reference.messageID);
} else {
const msgs = [...mes.channel.messages.cache.values()];
naCo = msgs[msgs.length - 2];
}
mes.delete();
emouty.forEach(emout => naCo.react(emout));
})();
}
},
odpocitej: (_, mes) => {
const randomshit = (dalsi, argument) => {
dalsi.edit(argument[0]);
argument.splice(0, 1);
if (argument.length) setTimeout(() => randomshit(dalsi, argument), 1000);
};
mes.channel.send(":stop_button:").then(mes => randomshit(mes, [":five:", ":four:", ":three:", ":two:", ":one:", ":ok:"]));
},
pocasi: {
als: ["počasí"],
run: _ => {
const embed = {
title: "Počasí",
image: { url: "attachment://pocasi.png" }
};
return { embed, files: ["https://util.deadfish.cz/morepocasi/v/49.4348358/12.8147250/pocasi.png"] };
}
}
}
};

View File

@ -1,5 +0,0 @@
// Prostě onready
module.exports = {
on_ready: () => console.log('A jedeš!')
};

View File

@ -1,100 +0,0 @@
const fetch = require("node-fetch");
const role = { online: "Online", idle: "Idle", dnd: "DND", offline: "Offline" };
const statusy = { Offline: "0", Online: "1", Idle: "2", DND: "3", OnlinePhone: "11", IdlePhone: "12", DNDPhone: "13" };
const prepSend = pair => {
const changes = [];
pair.forEach(par => {
const us = par[0];
changes.push({ id: us.id, status: par[1], nick: us.username, pfp: us.avatar ?? "" });
});
poslatData({ changes });
};
const poslatData = data => {
data.pwd = process.env.STAT_PASS;
fetch("http://deadfish.cz:4629/endpoint-pro-denimka/", { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
};
const statusOnFoun = (bef, aft) => {
if (!bef) bef = { status: 'offline', clientStatus: {} };
const predAPo = ["", ""];
[bef, aft].forEach((s, i) => {
const mobile = s.clientStatus.mobile;
if (mobile && mobile !== s.clientStatus.desktop) {
predAPo[i] = `${role[mobile]}Phone`;
}
else {
predAPo[i] = role[s.status];
}
});
return predAPo;
};
const ziju = () => {
poslatData({ nejsemPoslej: !0 });
setTimeout(ziju, 60_000);
};
if (!process.env.IGNORE_PRESENCE) ziju();
const getRole = (status, server) =>
server.roles.cache.find(role => role.name === `Status${status}`);
module.exports = {
// Změna rolí podle statusu a odeslání statusu
on_presenceUpdate: (bef, aft) => {
if (process.env.IGNORE_PRESENCE) return;
const [statusPred, statusPo] = statusOnFoun(bef, aft);
if (statusPred === statusPo) return;
const rolePred = getRole(statusPred, aft.guild);
const rolePo = getRole(statusPo, aft.guild);
if (rolePred) aft.member.roles.remove(rolePred);
if (rolePo) aft.member.roles.add(rolePo);
prepSend([[aft.user, statusy[statusPo]]]);
},
// Odeslání statusů při startu bota
on_ready: () => {
if (process.env.IGNORE_PRESENCE) return;
const client = module.exports.client;
const guildy = client.guilds.cache;
const memberove = client.users.cache.clone();
const presence = [];
const changes = [];
guildy.each(guilda => {
guilda.presences.cache.each(pres => {
if (!presence.filter(prs => prs.userID === pres.userID).length) presence.push(pres);
});
});
presence.forEach(presenc => {
const status = statusOnFoun(null, presenc)[1];
changes.push([memberove.get(presenc.userID), statusy[status]]);
memberove.delete(presenc.userID);
});
memberove.each(member => {
changes.push([member, 0]);
});
prepSend(changes);
},
// Odeslání statusu při změně jména nebo profilovky
on_userUpdate: (bef, aft) => {
if (!process.env.IGNORE_PRESENCE)
prepSend([[aft, statusy[statusOnFoun(null, aft.presence)[1]]]]);
}
};

View File

@ -1,148 +0,0 @@
// Cokoliv co má něco společnýho s vojsem
const { formatCas } = require("../addons/utils.js");
let vojsKuldan = 0;
function vypocitatCas(vojsl) {
let c = new Date();
let d = new Date();
let hod = d.getHours();
let min = d.getMinutes();
if (min >= 30) {
min = 0;
if (hod == 23) {
hod = 0;
d.setDate(c.getDate() + 1);
} else {
hod++;
}
} else {
min = 30;
}
d.setHours(hod);
d.setMinutes(min);
d.setSeconds(0);
timeouty[vojsl.channel.guild.id] = setTimeout(function () {
rekniCas(vojsl, `${nula(hod)}${nula(min)}`);
}, d - c + 3000);
}
function rekniCas(vojsl, cas) {
if (!vojsl) return;
const d1 = vojsl.play(`./zvuky/intro.mp3`, { volume: 0.8 });
d1.on('finish', function () {
const d2 = vojsl.play(`./zvuky/${cas}.mp3`, { volume: 1.5 });
d2.on('finish', function () {
vojsl.play(`./zvuky/grg.mp3`, { volume: 0.5 });
});
});
vypocitatCas(vojsl);
}
function nula(a) {
return a < 10 ? "0" + a : a;
}
const vytahnout = (clen, patro) => {
const vojs = clen.voice.channel;
if (!vojs) return;
const aktPatro = Number(vojs.name) || 0;
let dalsiPatro = aktPatro;
if (patro < aktPatro) dalsiPatro--; else if (patro > aktPatro) dalsiPatro++; else return;
if (dalsiPatro === 0) dalsiPatro = 'P';
const dalsiVojsy = [...clen.guild.channels.cache.values()].filter(channel => channel.type === 'voice' && channel.name === String(dalsiPatro));
if (!dalsiVojsy) return;
clen.voice.setChannel(dalsiVojsy[0]);
setTimeout(() => vytahnout(clen, patro), 1000);
};
const timeouty = {};
module.exports = {
more_komandy: {
wojs: (_, mes) => `vojs se pise s normalnim v ti kriple ${mes.author}`,
vojs: {
cd: 1800,
run: (arg, mes) => {
const channel = mes.member.voice.channel;
if (!channel) return `di si tam sam ne ty gadzo ${mes.author}`;
if (arg !== 'potichu') mes.channel.send('<@&591306633196339261> vojs');
if (mes.guild.voice?.channel === channel && mes.guild.connection) return;
channel.join()
.then(con => {
if (!timeouty[mes.guild.id]) {
vypocitatCas(con);
con.on('disconnect', () => {
if (timeouty[mes.guild.id]) {
clearTimeout(timeouty[mes.guild.id]);
delete timeouty[mes.guild.id];
}
});
}
setTimeout(() => con.play('./zvuky/nazdar.ogg'), 500);
});
}
},
vypadni: {
als: ["odejdi", "disconnect", "leave", "odpoj", "votpoj", "vodpoj", "vodprejskni", "tahni", "táhni"],
run: _ => {
let vojs = mes.guild.voice;
if (!vojs) vojs = {};
if (!vojs.channel) return mes.channel.send('nejsem ve vojsu');
vojs.channel.leave();
mes.react('855120055632134155');
}
},
vytah: {
als: ["vitah"],
run: (arg, mes) => {
if (!mes.member) return 'kokot';
if (!mes.member.voice.channel) return `nejsi ve vojsu ty gadzo ${mes.author}`;
if (!arg) return `napis do jakiho patra ${mes.author}`;
vytahnout(mes.member, Number(celArgs) || 0);
}
},
krkacek: {
als: ["krkáček", "krkácek", "krkaček", "krk", "grg", "grgnisi", "krknisi", "grgacek", "grgáček", "grgácek", "grgaček"],
run: async (_, mes) => {
let vojs = mes.guild.voice?.connection;
let odpojit = false;
if (!vojs) {
const chanel = mes.member.voice.channel;
if (!chanel) return mes.channel.send("***grrrrrrrrg***");
vojs = await chanel.join();
odpojit = true;
}
vojs.play(`./zvuky/grg.mp3`, { volume: 0.5 }).on("finish", _ => { if (odpojit) vojs.channel.leave(); });
}
}
},
// Neodposlouchávej
on_voiceStateUpdate: (bef, aft) => {
if (!aft.channel || !aft.guild.voice?.connection || aft.member.user === aft.guild.client.user) return;
if (aft.selfMute && !aft.deaf) {
aft.guild.voice.connection.play('./zvuky/neodposlouchavej.ogg', { volume: 0.38 })
.on('finish', () => { if (aft.selfMute) aft.setDeaf(true, 'otposlouchávala ta gadza'); });
}
if (!bef.channel) return;
if (bef.mute && bef.deaf && !aft.mute && aft.deaf) aft.setDeaf(false, 'us muze poslouchat gadza');
}
};

2134
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,31 @@
{ {
"name": "denim_3001", "name": "denim_3001",
"version": "3001.20", "version": "3001.21.0",
"description": "Toto je velmi kvalitní bot.", "description": "Toto je velmi kvalitní bot.",
"repository": { "repository": {
"url": "https://github.com/Histmy/Denim-Bot/" "url": "https://github.com/Histmy/Denim-Bot/"
}, },
"main": "app.js", "main": "out/app.js",
"scripts": { "scripts": {
"start": "node ." "start": "node .",
"test": "tsc && node ."
}, },
"author": "Histmy + det-fys", "author": "Histmy + det-fys",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@discordjs/opus": "github:discordjs/opus", "@discordjs/opus": "github:discordjs/opus",
"discord.js": "^12.4.1", "@discordjs/voice": "^0.6.0",
"discord.js": "^13.0.1",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"download-file-sync": "^1.0.4", "fluent-ffmpeg": "^2.1.2",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",
"prism-media": "^1.3.2",
"tweetnacl": "^1.0.3",
"yt-search": "^2.7.5", "yt-search": "^2.7.5",
"ytdl": "^1.4.1", "ytdl": "^1.4.1",
"ytdl-core": "^4.9.0" "ytdl-core": "^4.9.1"
},
"devDependencies": {
"@types/node-fetch": "^2.5.12"
} }
} }

109
src/app.ts Normal file
View File

@ -0,0 +1,109 @@
import { getVoiceConnections } from "@discordjs/voice";
import { Client, Intents, Message } from "discord.js";
import { config } from "dotenv";
import { readdirSync } from "fs";
import { emouty } from "./utils/emotes";
import { Komand, ListenerFunkce, Modul } from "./utils/types";
import { formatCas } from "./utils/utils.js";
const ints = Intents.FLAGS;
const client = new Client({ intents: [ints.GUILDS, ints.GUILD_VOICE_STATES, ints.GUILD_PRESENCES, ints.GUILD_MESSAGES] });
config();
const prefix = process.env.PREFIX || "more";
const modulFolder = `${__dirname}/modules/`;
const eventy: Record<string, ListenerFunkce[]> = { on_message: [] };
const komandy: Record<string, Komand> = {};
const aliasy: Record<string, string> = {};
let spink = false;
const kuldan_log: Record<string, Record<string, number>> = {};
const runEvent = (name: string, args: any[]) => {
eventy[name].forEach(listener => {
listener(...args);
});
};
readdirSync(modulFolder).forEach(soubor => {
if (!soubor.endsWith(".js")) return;
const modul: Modul = require(`${modulFolder}${soubor}`);
console.log(`Načet sem: ${modulFolder}${soubor}`);
modul.client = client;
Object.keys(modul).forEach(name => {
if (name.startsWith("on_")) {
if (!eventy[name]) {
eventy[name] = [];
if (name !== "on_message") client.on(name.slice(3), (...args) => runEvent(name, args));
}
eventy[name].push(modul[name]);
} else if (name === "more_komandy") {
Object.keys(modul[name]).forEach(cmdName => {
const value = modul[name][cmdName];
if (typeof value !== "object") {
komandy[cmdName] = { run: value };
} else {
komandy[cmdName] = { run: value.run, cd: value.cd };
value.als?.forEach(al => aliasy[al] = cmdName);
}
});
}
});
});
const spim = (mes: Message) => {
const cont = mes.content.toLocaleLowerCase();
if (cont === `${prefix} zapni se`) {
if (spink) {
spink = false;
mes.client.user?.setStatus("online");
mes.channel.send("dobré ráno magoří");
}
else mes.channel.send("tak jsi kokot?");
} else if (!spink) {
if (cont === `${prefix} vypni se`) {
mes.react(emouty.purfieRIP);
getVoiceConnections().forEach(con => con.disconnect());
mes.client.user?.setStatus("invisible");
spink = true;
}
else return false;
}
return true;
};
const maKuldan = (id: string, komand: string, kuldan_komandu: number) => {
if (!kuldan_log[komand]) kuldan_log[komand] = {};
const cas_ted = Date.now() / 1000;
const rozdil = cas_ted - kuldan_log[komand][id];
if (rozdil < kuldan_komandu) return kuldan_komandu - rozdil;
kuldan_log[komand][id] = cas_ted;
return 0;
};
client.on("messageCreate", mes => {
if (process.env.IGNORE_MESS || spim(mes)) return;
runEvent("on_message", [mes]);
const [mes_prefix, komand, ...args] = mes.content.split(" ");
if (mes_prefix.toLowerCase() !== prefix) return;
if (!komand) return void mes.channel.send("coe voe");
const celArgs = args.join(" ");
const cmdName = aliasy[komand] ?? komand;
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)}`);
}
const akce = cmd.run;
if (typeof akce === "string") return void mes.channel.send(akce);
const result = akce(celArgs, mes);
if (result && !(result instanceof Promise)) mes.channel.send(result);
});
client.login(process.env.TOKEN);

42
src/modules/komArgs.ts Normal file
View File

@ -0,0 +1,42 @@
// Komandy, který pošlou jenom celArgs a random hovno
import { Message } from "discord.js";
import { emouty } from "../utils/emotes";
module.exports = {
more_komandy: {
rekni: (arg: string, mes: Message) => {
if (mes.author.bot) return "ne";
const corict = arg ?? "co mam jako rict";
mes.delete();
return corict;
},
clap: (arg: string, mes: Message) => {
mes.delete();
return `${arg} ${emouty.clap}`;
},
clap2: (arg: string, mes: Message) => {
mes.delete();
return `${emouty.clap2} ${arg}`;
},
voliz: {
als: ["voliž"],
run: (arg: string, mes: Message) => {
mes.delete();
return `${emouty.lickL}${arg}${emouty.lickR}`;
}
},
pozdrav: (arg: string) => `zdravim ${arg}`,
zhejti: (arg: string) => `${arg} je pycovina zasrana vimrdana`,
uraz: {
als: ["uraž"],
run: (arg: string) => `${arg} , u suck`
}
}
};

127
src/modules/komComplex.ts Normal file
View File

@ -0,0 +1,127 @@
// Komandy, který buď nějakým způsobem mění funkci nebo "vzhled" bota
// nebo donutí bota něco udělat (odeslání zprávy nebo smazání originální zprávy se nepočítá)
import { ActivityType, Message, PresenceStatusData } from "discord.js";
import { emouty } from "../utils/emotes";
const changeStatus = (mes: Message, status: PresenceStatusData) => {
mes.client.user?.setStatus(status);
return "ano pane";
};
const changeActivity = (mes: Message, activity: ActivityType | undefined = undefined, txt: string = "") => {
mes.client.user?.setActivity({ name: txt, type: activity });
mes.react(emouty.d3k);
return "ano pane";
};
const ping = /^<@!?\d+>$/;
module.exports = {
more_komandy: {
online: {
als: ["onlajn", "zelenej"],
run: (_: any, mes: Message) => changeStatus(mes, "online")
},
idle: {
als: ["žlutej", "zlutej", "afk", "idle", "nepřítomnej", "nepritomnej"],
run: (_: any, mes: Message) => changeStatus(mes, "idle")
},
dnd: {
als: ["nerusit", "nerušit", "červenej", "cervenej"],
run: (_: any, mes: Message) => changeStatus(mes, "dnd")
},
offline: {
als: ["oflajn", "neviditelnej"],
run: (_: any, mes: Message) => changeStatus(mes, "invisible")
},
hraj: (arg: string, mes: Message) => changeActivity(mes, "PLAYING", arg),
sleduj: (arg: string, mes: Message) => changeActivity(mes, "WATCHING", arg),
poslouchej: (arg: string, mes: Message) => changeActivity(mes, "LISTENING", arg),
soutez: {
als: ["soutěž"],
run: (arg: string, mes: Message) => changeActivity(mes, "COMPETING", arg)
},
nedelej: (_: any, mes: Message) => changeActivity(mes),
fight: {
als: ["figh", "fajt"],
run: (arg: string, mes: Message) => {
if (!ping.test(arg)) return "tak si kokot ti kokote";
const vyherce = Math.random() < 0.5 ? mes.author : arg;
return `tento figh vyhrál: ${vyherce}!`;
}
},
status: (arg: string, mes: Message) => {
if (!ping.test(arg)) return "tak si kokot ti kokote";
const uzivatel = mes.mentions.members!.first()!;
const embed = {
title: `Informace o statusech pro ${uzivatel.displayName}:`,
color: 431075,
description: ""
};
const presence = uzivatel.presence?.clientStatus;
if (!(presence && Object.keys(presence).length)) {
embed.description = "*Všude je offline*";
} else {
const zarizeni: Record<string, string> = { desktop: "Počítač", mobile: "Mobil", web: "Web" };
const statusy = { online: "🟢", idle: "🟡", dnd: "🔴" };
const uStatusy: string[] = [];
const klice = Object.keys(presence) as ("web" | "mobile" | "desktop")[];
klice.forEach(status => {
uStatusy.push(`${zarizeni[status]}: ${statusy[presence[status]!]}`);
});
embed.description = uStatusy.join("\n");
}
return { embeds: [embed] };
},
zareaguj: {
als: ["react"],
run: (arg: string, mes: Message) => {
if (!arg) return "retard";
const emouty = arg.match(/<a?:\w{1,32}:\d+>/g);
if (!emouty) return "retard";
let naCo: Message;
(async () => {
if (mes.reference) {
naCo = await mes.channel.messages.fetch(mes.reference.messageId!);
} else {
const msgs = [...mes.channel.messages.cache.values()];
naCo = msgs[msgs.length - 2];
}
mes.delete();
emouty.forEach(emout => naCo.react(emout));
})();
}
},
odpocitej: (_: any, mes: Message) => {
const randomshit = (mes: Message, argument: string[]) => {
mes.edit(argument[0]);
argument.splice(0, 1);
if (argument.length) setTimeout(() => randomshit(mes, argument), 1000);
};
mes.channel.send(":stop_button:").then(mes => randomshit(mes, [":five:", ":four:", ":three:", ":two:", ":one:", ":ok:"]));
},
pocasi: {
als: ["počasí"],
run: (_: any) => {
const embed = {
title: "Počasí",
image: { url: "attachment://pocasi.png" }
};
return { embeds: [embed], files: ["https://util.deadfish.cz/morepocasi/v/49.4348358/12.8147250/pocasi.png"] };
}
}
}
};

View File

@ -1,39 +1,40 @@
// Komandy, který jenom pošlou random hovno a jsou nějakým způsobem ovlivněný RNG // Komandy, který jenom pošlou random hovno a jsou nějakým způsobem ovlivněný RNG
const ftipy = JSON.parse(require('fs').readFileSync('addons/ftipy.json')); import { readFileSync } from "fs";
const mista = ['na šroťák', 'na vrakoviště', 'na smetiště', 'do kontejneru', 'na skládku', 'do kriminálu', 'pod most', 'do sběru', 'do hospody', 'do najt klubu', 'na folmavu']; const ftipy: string[] = JSON.parse(readFileSync(`${__dirname}/../../addons/ftipy.json`).toString());
const mista = ["na šroťák", "na vrakoviště", "na smetiště", "do kontejneru", "na skládku", "do kriminálu", "pod most", "do sběru", "do hospody", "do najt klubu", "na folmavu"];
const uz = ["ne", "jeste ne", "jiz brzy", "za chvili", "vubec", "nikdy", "za dlouho", "za 5 let", "zejtra", "davno", "jo", "mozna"]; const uz = ["ne", "jeste ne", "jiz brzy", "za chvili", "vubec", "nikdy", "za dlouho", "za 5 let", "zejtra", "davno", "jo", "mozna"];
const rand = max => Math.floor(Math.random() * max); const rand = (max: number) => Math.floor(Math.random() * max);
module.exports = { module.exports = {
more_komandy: { more_komandy: {
vtip: { vtip: {
als: ["ftip"], als: ["ftip"],
run: _ => ftipy[rand(ftipy.length)] run: () => ftipy[rand(ftipy.length)]
}, },
kam: _ => mista[rand(mista.length)], kam: () => mista[rand(mista.length)],
je: { je: {
cd: 1800, cd: 1800,
run: _ => rand(2) ? "jo je" : "ne neni" run: () => rand(2) ? "jo je" : "ne neni"
}, },
ma: { ma: {
als: ["má"], als: ["má"],
run: _ => rand(2) ? "jo ma" : "ne nema" run: () => rand(2) ? "jo ma" : "ne nema"
}, },
nazor: { nazor: {
als: ["názor"], als: ["názor"],
run: arg => rand(2) ? `mam rad ${arg}` : `${arg} je picovina` run: (arg: string) => rand(2) ? `mam rad ${arg}` : `${arg} je picovina`
}, },
si: { si: {
als: ["jsi"], als: ["jsi"],
run: arg => { run: (arg: string) => {
const corict = arg.replace(/\?/g, ""); const corict = arg.replace(/\?/g, "");
return rand(2) ? `jo sem ${corict}` : `ne nejsem ${corict}`; return rand(2) ? `jo sem ${corict}` : `ne nejsem ${corict}`;
} }
@ -41,7 +42,7 @@ module.exports = {
mas: { mas: {
als: ["máš"], als: ["máš"],
run: arg => { run: (arg: string) => {
const corict = arg.replace(/\?/g, ""); const corict = arg.replace(/\?/g, "");
return rand(2) ? `jo mam ${corict}` : `ne nemam ${corict}`; return rand(2) ? `jo mam ${corict}` : `ne nemam ${corict}`;
} }
@ -49,18 +50,18 @@ module.exports = {
jakmoc: { jakmoc: {
cd: 1800, cd: 1800,
run: arg => `${arg} na ${rand(101)}%` run: (arg: string) => `${arg} na ${rand(101)}%`
}, },
jakmoc0: { jakmoc0: {
cd: 1800, cd: 1800,
run: arg => `${arg} na ${rand(1001)}%` run: (arg: string) => `${arg} na ${rand(1001)}%`
}, },
uz: { uz: {
als: ["už", "uz?", "už?"], als: ["už", "uz?", "už?"],
run: _ => uz[rand(uz.length)] run: () => uz[rand(uz.length)]
} }
} }
}; };

View File

@ -1,13 +1,13 @@
// Sekce pro komandy, který jenom pošlou nějaký hovno bez a nevyžadují argumenty // Sekce pro komandy, který jenom pošlou nějaký hovno bez a nevyžadují argumenty
const pomoc = JSON.parse(require('fs').readFileSync('addons/pomoc.json')); const pomoc: [string[], {}] = require("../../addons/pomoc.json");
module.exports = { module.exports = {
more_komandy: { more_komandy: {
vole: _ => "coe voe more gadzo", vole: () => "coe voe more gadzo",
kobel: _ => "kde?", kobel: () => "kde?",
ano: { ano: {
als: ["jo", "ne"], als: ["jo", "ne"],
@ -29,8 +29,8 @@ module.exports = {
pomoc: pomoc[0].join("\n"), pomoc: pomoc[0].join("\n"),
pomoc2: _ => { return { embed: pomoc[1] }; }, pomoc2: () => { return { embeds: [pomoc[1]] }; },
verze: _ => `${require("../package.json").version}\nčenžlog mas tady https://denim3001.deadfish.cz/morehovna` verze: () => `${require("../../package.json").version}\nčenžlog mas tady https://denim3001.deadfish.cz/morehovna`
} }
}; };

5
src/modules/onReady.ts Normal file
View File

@ -0,0 +1,5 @@
// Prostě onready
module.exports = {
on_ready: () => console.log("A jedeš!")
};

View File

@ -1,19 +1,23 @@
// Modul dedikovaný funkci spinkáček // Modul dedikovaný funkci spinkáček
const fetch = require('node-fetch'); import { Message, VoiceState } from "discord.js";
const { formatCas } = require("../addons/utils.js"); import fetch from "node-fetch";
const spinkacky = []; import { emouty } from "../utils/emotes";
import { Spinkackar } from "../utils/types";
import { formatCas } from "../utils/utils";
const contactSpinkServer = async (akce, id, nick, avatar) => { const spinkacky: string[] = [];
const options = `heslo=${process.env.SPINK_PASS}&akce=${akce}&id=${id}&nick=${encodeURIComponent(nick)}&avatar=${encodeURIComponent(avatar)}`;
const contactSpinkServer = async (akce: string, id: string, nick: string = "", avatar: string | null = "") => {
const options = `heslo=${process.env.SPINK_PASS}&akce=${akce}&id=${id}&nick=${encodeURIComponent(nick)}&avatar=${encodeURIComponent(avatar ?? "")}`;
return await fetch(`https://spinkacek.ga/extapi.php?${options}`) return await fetch(`https://spinkacek.ga/extapi.php?${options}`)
.then(r => r.text()) .then(r => r.text())
.then(text => text); .then(text => text);
}; };
const syncSpink = async () => { const syncSpink = async () => {
await fetch('https://spinkacek.ga/api/spinkacky') await fetch("https://spinkacek.ga/api/spinkacky")
.then(r => r.json()) .then(r => r.json() as Promise<Record<string, Spinkackar>>)
.then(d => { .then(d => {
const data = d.spinkacky; const data = d.spinkacky;
const keys = Object.keys(data); const keys = Object.keys(data);
@ -21,7 +25,7 @@ const syncSpink = async () => {
spinkacky.splice(0); spinkacky.splice(0);
for (let i = 0; i < keys.length; i++) { for (let i = 0; i < keys.length; i++) {
if (!values[i].spinkacek || keys[i][0] === 'i') continue; if (!values[i].spinkacek || keys[i][0] === "i") continue;
spinkacky.push(keys[i].slice(8)); spinkacky.push(keys[i].slice(8));
} }
}); });
@ -34,11 +38,11 @@ module.exports = {
spinkacek: { spinkacek: {
als: ["spinkáček"], als: ["spinkáček"],
run: (_, mes) => { run: (_: any, mes: Message) => {
if (mes.author.bot) return "až někdy<:kapp:677916836418813953>"; if (mes.author.bot) return `až někdy${emouty.kapp}`;
(async () => { (async () => {
if (await contactSpinkServer('spinkacek', mes.author.id, mes.author.username, mes.author.avatarURL()) === "OK") if (await contactSpinkServer('spinkacek', mes.author.id, mes.author.username, mes.author.avatarURL()) === "OK")
mes.react("761652251966046208"); mes.react(emouty.spinkacek);
else mes.channel.send('nespis uz?????'); else mes.channel.send('nespis uz?????');
})(); })();
} }
@ -46,21 +50,19 @@ module.exports = {
vstavacek: { vstavacek: {
als: ["vstáváček"], als: ["vstáváček"],
run: (_, mes) => { run: (_: any, mes: Message) => {
if (mes.author.bot) return "<:sjeta:623216247953424426>"; if (mes.author.bot) return emouty.sjeta;
(async () => { (async () => {
const odpoved = await contactSpinkServer('vstavacek', mes.author.id); const odpoved = await contactSpinkServer('vstavacek', mes.author.id);
const [ok, cas] = odpoved.split(" "); const [ok, casTxt] = odpoved.split(" ");
if (ok !== "OK") { const cas = Number(casTxt);
mes.channel.send("uz jsi vzhuru ty hajzle"); if (ok !== "OK") return mes.channel.send("uz jsi vzhuru ty hajzle");
return;
}
const formatedCas = formatCas(cas); const formatedCas = formatCas(cas);
let zpr = ""; let zpr = "";
if (cas < 3600) zpr = "dobrej fake spink debile"; if (cas >= 57600) zpr = "mas dat more vstavacek uz kdyz vstanes retarde";
else if (cas > 35999 && cas < 43200) zpr = "fakt bídák"; else if (cas >= 43200) zpr = "extrémní bídák";
else if (cas > 43199 && cas < 57600) zpr = "extrémní bídák"; else if (cas >= 36000) zpr = "fakt bídák";
else if (cas > 57599) zpr = "mas dat more vstavacek uz kdyz vstanes retarde"; else if (cas < 10800) zpr = "dobrej fake spink debile";
mes.channel.send(`dobry rano hajzle\nspal sy ${formatedCas}\n${zpr}`); mes.channel.send(`dobry rano hajzle\nspal sy ${formatedCas}\n${zpr}`);
})(); })();
@ -68,13 +70,13 @@ module.exports = {
} }
}, },
on_voiceStateUpdate: (bef, aft) => { on_voiceStateUpdate: (bef: VoiceState, aft: VoiceState) => {
if (!aft.channel || bef.channel) return; if (!aft.channel || bef.channel) return;
if (spinkacky.includes(aft.id)) aft.kick() if (spinkacky.includes(aft.id)) aft.disconnect("spinkacek")
.catch(() => { }); .catch(err => console.log("spinkacek odpojit se nepovedlo nebo co:", err));
}, },
on_message: mes => { on_message: (mes: Message) => {
if (mes.author.id === '831318260493844494') { if (mes.author.id === '831318260493844494') {
syncSpink(); syncSpink();
if (mes.content[0] !== 's') return; if (mes.content[0] !== 's') return;
@ -82,10 +84,10 @@ module.exports = {
if (!uzivatel) return; if (!uzivatel) return;
for (const [_, guild] of mes.client.guilds.cache) { for (const [_, guild] of mes.client.guilds.cache) {
for (const [_, channel] of guild.channels.cache) { for (const [_, channel] of guild.channels.cache) {
if (channel.type !== "voice") continue; if (channel.type !== "GUILD_VOICE") continue;
for (const [_, member] of channel.members) { for (const [_, member] of channel.members) {
if (member.id !== uzivatel) continue; if (member.id !== uzivatel) continue;
member.voice.kick("spinkacek"); member.voice.disconnect("spinkacek");
return; return;
} }
} }

110
src/modules/status.ts Normal file
View File

@ -0,0 +1,110 @@
// Trekování statusů všech lidí o kterých bot ví
import { Client, Guild, Presence, User } from "discord.js";
import fetch from "node-fetch";
import { FakePresence, StatusyINaFounu, UserChange, ZmenovejObjekt } from "../utils/types";
const role = { online: "Online", idle: "Idle", dnd: "DND", offline: "Offline" };
const statusy = { Offline: "0", Online: "1", Idle: "2", DND: "3", OnlinePhone: "11", IdlePhone: "12", DNDPhone: "13" };
const prepSend = (zmeny: UserChange[]) => {
const changes: ZmenovejObjekt[] = [];
zmeny.forEach(zmena => {
const us = zmena.user;
const objekt: ZmenovejObjekt = { id: us.id };
if (zmena.ch === "user" || !zmena.ch) {
objekt.nick = us.username;
objekt.pfp = us.avatar ?? "";
}
if (zmena.ch === "stat" || !zmena.ch) {
objekt.status = zmena.stat;
}
changes.push(objekt);
});
poslatData({ changes });
};
const poslatData = (data: Record<string, any>) => {
data.pwd = process.env.STAT_PASS;
fetch("http://deadfish.cz:4629/endpoint-pro-denimka/", { method: "POST", headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) });
};
const statusOnFoun = (bef: FakePresence | null, aft: FakePresence) => {
if (!bef) bef = { status: 'offline', clientStatus: {} };
const predAPo: StatusyINaFounu[] = [];
[bef, aft].forEach((s, i) => {
const mobile = s.clientStatus?.mobile;
if (mobile && mobile !== s.clientStatus?.desktop) {
predAPo[i] = `${role[mobile]}Phone` as StatusyINaFounu;
} else {
predAPo[i] = role[s.status] as StatusyINaFounu;
}
});
return predAPo;
};
const ziju = () => {
poslatData({ nejsemPoslej: !0 });
setTimeout(ziju, 60_000);
};
if (!process.env.IGNORE_PRESENCE) ziju();
const getRole = (status: StatusyINaFounu, server: Guild) =>
server.roles.cache.find(role => role.name === `Status${status}`);
module.exports = {
// Změna rolí podle statusu a odeslání statusu
on_presenceUpdate: (bef: Presence, aft: Presence) => {
if (process.env.IGNORE_PRESENCE) return;
const [statusPred, statusPo] = statusOnFoun(bef as FakePresence, aft as FakePresence);
if (statusPred === statusPo) return;
const rolePred = getRole(statusPred, aft.guild!);
const rolePo = getRole(statusPo, aft.guild!);
if (rolePred) aft.member!.roles.remove(rolePred);
if (rolePo) aft.member!.roles.add(rolePo);
prepSend([{ ch: "stat", user: aft.user!, stat: statusy[statusPo] }]);
},
// Odeslání statusů při startu bota
on_ready: () => {
if (process.env.IGNORE_PRESENCE) return;
const client: Client = module.exports.client;
const guildy = client.guilds.cache;
const userove = client.users.cache.clone();
const presence: Presence[] = [];
const changes: UserChange[] = [];
guildy.each(guilda => {
guilda.presences.cache.each(pres => {
if (!presence.filter(prs => prs.userId === pres.userId).length) presence.push(pres);
});
});
presence.forEach(presenc => {
const status = statusOnFoun(null, presenc as FakePresence)[1];
changes.push({ user: userove.get(presenc.userId)!, stat: statusy[status] });
userove.delete(presenc.userId);
});
userove.each(member => {
changes.push({ user: member, stat: "0" });
});
prepSend(changes);
},
// Odeslání statusu při změně jména nebo profilovky
on_userUpdate: (_: any, aft: User) => {
if (!process.env.IGNORE_PRESENCE && aft.id !== aft.client.user?.id)
prepSend([{ ch: "user", user: aft }]);
}
};

123
src/modules/vojs.ts Normal file
View File

@ -0,0 +1,123 @@
// Cokoliv co má něco společnýho s vojsem
import { getVoiceConnection, VoiceConnection, VoiceConnectionStatus } from "@discordjs/voice";
import { GuildMember, Message, VoiceChannel, VoiceState } from "discord.js";
import { emouty } from "../utils/emotes";
import { joinVoice, leave, play } from "../utils/utils";
const timeouty: Record<string, NodeJS.Timeout> = {};
const vypocitatCas = (conn: VoiceConnection) => {
const c = new Date();
const d = new Date();
let hod = d.getHours();
let min = d.getMinutes();
if (min >= 30) {
min = 0;
if (hod == 23) {
hod = 0;
d.setDate(c.getDate() + 1);
} else {
hod++;
}
} else {
min = 30;
}
d.setHours(hod);
d.setMinutes(min);
d.setSeconds(0);
timeouty[conn.joinConfig.guildId] = setTimeout(() => rekniCas(conn, `${nula(hod)}${nula(min)}`), Number(d) - Number(c));
};
const nula = (a: Number) => a < 10 ? `0${a}` : a;
const rekniCas = (conn: VoiceConnection, cas: string) => {
play(conn, [{ name: "../zvuky/intro.mp3", volume: 0.8 }, { name: `../zvuky/${cas}.mp3`, volume: 2 }, { name: "../zvuky/grg.mp3", volume: 0.5 }])
.then(() => {
vypocitatCas(conn);
})
.catch(err => { console.log("cas error:", err); });
};
const vytahnout = (member: GuildMember, patro: number) => {
const vojs = member.voice.channel;
if (!vojs) return;
const aktPatro = Number(vojs.name) || 0;
let dalsiPatro: number | string = aktPatro;
if (patro < aktPatro) dalsiPatro--; else if (patro > aktPatro) dalsiPatro++; else return;
if (dalsiPatro === 0) dalsiPatro = "P";
const dalsiVojs = member.guild.channels.cache.filter(channel => channel.type === "GUILD_VOICE" && channel.name === String(dalsiPatro)).first() as VoiceChannel | undefined;
if (!dalsiVojs) return;
member.voice.setChannel(dalsiVojs);
setTimeout(() => vytahnout(member, patro), 1e3);
};
module.exports = {
more_komandy: {
wojs: (_: any, mes: Message) => `vojs se pise s normalnim v ti kriple ${mes.author}`,
vojs: {
// cd: 1800,
run: (arg: string, mes: Message) => {
const channel = mes.member?.voice.channel;
if (!channel) return `di si tam sam ne ty gadzo ${mes.author}`;
// if (arg !== "potichu") mes.channel.send("<@&591306633196339261> vojs");
joinVoice(channel)
.then(obj => {
const conn = obj.conn;
if (!timeouty[mes.guildId!]) {
vypocitatCas(conn);
conn.on(VoiceConnectionStatus.Disconnected, () => conn.destroy());
conn.on(VoiceConnectionStatus.Destroyed, () => {
clearTimeout(timeouty[mes.guildId!]);
delete timeouty[mes.guildId!];
});
}
play(conn, "../zvuky/nazdar.ogg");
});
}
},
vypadni: {
als: ["odejdi", "disconnect", "leave", "odpoj", "votpoj", "vodpoj", "vodprejskni", "tahni", "táhni"],
run: (_: any, mes: Message) => {
const vojs = getVoiceConnection(mes.guildId!);
if (!vojs) return 'nejsem ve vojsu';
vojs.destroy();
mes.react(emouty.purfieRIP);
}
},
vytah: {
als: ["vitah", "výtah"],
run: (arg: string, mes: Message) => {
if (!mes.member?.voice.channel) return `nejsi ve vojsu ty gadzo ${mes.author}`;
if (!arg) return `napis do jakiho patra ${mes.author}`;
vytahnout(mes.member, Number(arg) || 0);
}
},
krkacek: {
als: ["krkáček", "krkácek", "krkaček", "krk", "grg", "grgnisi", "krknisi", "grgacek", "grgáček", "grgácek", "grgaček"],
run: async (_: any, mes: Message) => {
const channel = mes.member?.voice.channel;
if (!channel) return mes.channel.send("***grrrrrrrrg***");
const { conn, prev } = await joinVoice(channel);
await play(conn, "../zvuky/grg.mp3");
if (prev === true) return; // Byl jsem v tomdle vojsu
if (prev === false) return leave(mes.guildId!); // Nebyl jsem ve vojsu vůbec
joinVoice(prev as string, mes.guild!); // Byl jsem jinde
}
}
}
};

View File

@ -1,17 +1,20 @@
// Komandy nebo handelery který se nikam jinam nehodí // Komandy nebo handelery který se nikam jinam nehodí
import { getVoiceConnections } from "@discordjs/voice";
import { Message } from "discord.js";
module.exports = { module.exports = {
more_komandy: { more_komandy: {
debug_log: arg => { debug_log: (arg: string) => {
console.log('log: ', arg); console.log("log: ", arg);
return 'je to v konzoli'; return "je to v konzoli";
}, },
update: (_, mes) => { update: (_: any, mes: Message) => {
if (mes.channel.id != process.env.ADMIN_CHANNEL && mes.author.id != process.env.ADMIN_ID) return "nato nemas prava kokote"; if (mes.channel.id != process.env.ADMIN_CHANNEL && mes.author.id != process.env.ADMIN_ID) return "nato nemas prava kokote";
[...mes.client.voice?.connections.values()].forEach(con => con.disconnect()); getVoiceConnections().forEach(con => con.disconnect());
mes.react("👋") mes.react("👋")
.then(() => process.exit()); .then(() => process.exit());
} }

11
src/utils/emotes.ts Normal file
View File

@ -0,0 +1,11 @@
export enum emouty {
purfieRIP = "<:purfieRIP:855120055632134155>",
clap = "<a:DENIM3K_Clap:629991700571619328>",
clap2 = "<a:DENIM3K_Clap2:820793564043673650>",
lickL = "<a:DENIM3K_lickL:678025691207565313>",
lickR = "<a:DENIM3K_lickR:678025693313105964>",
d3k = "<:D3K:730175107313565717>",
kapp = "<:kapp:677916836418813953>",
spinkacek = "<:spinkacek:761652251966046208>",
sjeta = "<:sjeta:623216247953424426>"
}

50
src/utils/types.ts Normal file
View File

@ -0,0 +1,50 @@
import { Client, ClientPresenceStatusData, Message, User } from "discord.js";
type RunFunkce = (argumenty: string, message: Message) => undefined | string | Promise<unknown>;
interface KomandRaw {
als?: string[];
cd?: number;
run: RunFunkce;
};
export type ListenerFunkce = (...args: any[]) => void;
export type Modul = {
more_komandy: Record<string, RunFunkce | KomandRaw | string>;
client: Client<boolean>;
} & Record<string, ListenerFunkce>;
export interface Komand {
run: RunFunkce | string;
cd?: number;
}
export interface Spinkackar {
spinkacek: boolean;
}
export interface FakePresence {
status: "online" | "idle" | "dnd" | "offline";
clientStatus: ClientPresenceStatusData;
}
export interface UserChange {
user: User;
ch?: "user" | "stat";
stat?: string;
}
export type StatusyINaFounu = "Online" | "OnlinePhone" | "Idle" | "IdlePhone" | "DND" | "DNDPhone" | "Offline";
export interface ZmenovejObjekt {
id: string,
nick?: string,
pfp?: string,
status?: string;
}
export interface MuzikaFace {
name: string,
volume?: number;
}

99
src/utils/utils.ts Normal file
View File

@ -0,0 +1,99 @@
import { AudioPlayerStatus, AudioResource, createAudioPlayer, createAudioResource, entersState, getVoiceConnection, joinVoiceChannel, PlayerSubscription, VoiceConnection, VoiceConnectionStatus } from "@discordjs/voice";
import { Guild, StageChannel, VoiceChannel } from "discord.js";
import { once } from "events";
import { MuzikaFace } from "./types";
const pripojeni: Record<string, PlayerSubscription> = {};
export const formatCas = (cas: number) => {
const h = Math.floor(cas / 3600);
const m = Math.floor(cas % 3600 / 60);
const s = Math.floor(cas % 3600 % 60);
return `${h} hodin ${m} mynut a ${s} se kund`;
};
export const joinVoice = async (channel: VoiceChannel | StageChannel | string, guild?: Guild) => {
const channelId = typeof channel === "string" ? channel : channel.id;
const guildId = typeof channel === "string" ? guild!.id : channel.guildId;
const guilda = typeof channel === "string" ? guild! : channel.guild;
let conn = getVoiceConnection(guildId);
let prev: Boolean | string = false;
if (conn) {
if (conn.joinConfig.channelId === channelId) return { conn, prev: true };
prev = conn.joinConfig.channelId!;
}
conn = joinVoiceChannel({
channelId,
guildId,
adapterCreator: guilda.voiceAdapterCreator
});
await entersState(conn, VoiceConnectionStatus.Ready, 3e4)
.catch((err: Error) => {
conn!.destroy();
throw err;
});
if (!prev) {
const player = createAudioPlayer();
pripojeni[guildId] = conn.subscribe(player)!;
}
return { conn, prev };
};
const makeAudioPlayer = (co: string | MuzikaFace) => {
if (typeof co === "string") return createAudioResource(co);
const res = createAudioResource(co.name, { inlineVolume: !!co.volume });
if (co.volume) res.volume?.setVolume(co.volume);
return res;
};
export const play = (conn: VoiceConnection, co: string | MuzikaFace | MuzikaFace[]) => {
return new Promise<void>(async (res, rej) => {
if (conn.state.status !== VoiceConnectionStatus.Ready) return rej("conn není ready");
const player = pripojeni[conn.joinConfig.guildId].player;
if (!Array.isArray(co)) {
let aud = makeAudioPlayer(co);
player.play(aud);
const funkce = () => {
res();
player.removeListener(AudioPlayerStatus.Idle, funkce);
};
player.on(AudioPlayerStatus.Idle, funkce);
return;
}
const resources: AudioResource[] = [];
co.forEach(c => {
const res = makeAudioPlayer(c);
resources.push(res);
});
for (const res of resources) {
await once(res.playStream, "readable");
}
player.play(resources[0]);
let i = 1;
const funkce = () => {
player.play(resources[i]);
i++;
if (i === resources.length) {
res();
player.removeListener(AudioPlayerStatus.Idle, funkce);
}
};
player.on(AudioPlayerStatus.Idle, funkce);
});
};
export const leave = (guildId: string) => {
const conn = getVoiceConnection(guildId);
if (!conn) return;
conn.destroy();
delete pripojeni[guildId];
};

17
tsconfig.json Normal file
View File

@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ES2021",
"module": "CommonJS",
"rootDir": "./src",
"outDir": "./out",
"moduleResolution": "Node",
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"allowSyntheticDefaultImports": true,
"removeComments": true,
},
"include": [
"src"
]
}