276 lines
7.4 KiB
JavaScript
276 lines
7.4 KiB
JavaScript
const Dysnomia = require("@projectdysnomia/dysnomia");
|
|
const logger = require("./lib/logger.js");
|
|
const fs = require("node:fs");
|
|
const {resolve} = require("node:path");
|
|
const sqlite3 = require("sqlite3");
|
|
const {instead, before} = require("spitroast");
|
|
|
|
const config = require("../config.json");
|
|
const apikeys = require("../apikeys.json");
|
|
|
|
const events = require("./lib/events.js");
|
|
const timer = require("./lib/timer.js");
|
|
const Command = require("./lib/command.js");
|
|
const InteractionCommand = require("./lib/interactionCommand.js");
|
|
|
|
const bot = new Dysnomia.Client(config.token, {
|
|
defaultImageFormat: "png",
|
|
defaultImageSize: 1024,
|
|
gateway: {
|
|
intents: Object.values(Dysnomia.Constants.Intents),
|
|
},
|
|
restMode: true,
|
|
});
|
|
|
|
const commands = new Dysnomia.Collection();
|
|
const interactionCommands = new Dysnomia.Collection();
|
|
|
|
const database = new sqlite3.Database(resolve(__dirname, "..", "database.db"));
|
|
|
|
function registerCommand(cmdObj) {
|
|
if (cmdObj instanceof Command) {
|
|
commands.set(cmdObj.name, cmdObj);
|
|
const aliases = cmdObj.getAliases();
|
|
logger.info(
|
|
"hf:cmd",
|
|
`Registered command '${cmdObj.name}'${
|
|
aliases.length > 0 ? ` (aliases: ${aliases.join(", ")})` : ""
|
|
}`
|
|
);
|
|
} else if (cmdObj instanceof InteractionCommand) {
|
|
interactionCommands.set(cmdObj.name, cmdObj);
|
|
logger.info("hf:cmd", `Registered interaction command '${cmdObj.name}'`);
|
|
}
|
|
}
|
|
|
|
global.hf = {
|
|
bot,
|
|
config,
|
|
apikeys,
|
|
commands,
|
|
interactionCommands,
|
|
registerCommand,
|
|
events,
|
|
timer,
|
|
database,
|
|
};
|
|
|
|
const {formatUsername} = require("./lib/utils.js");
|
|
const CommandDispatcher = require("./lib/commandDispatcher.js");
|
|
const {InteractionDispatcher} = require("./lib/interactionDispatcher.js");
|
|
|
|
for (const file of fs.readdirSync(resolve(__dirname, "modules"))) {
|
|
require(resolve(__dirname, "modules", file));
|
|
logger.info("hf:modules", `Loaded module: '${file}'`);
|
|
}
|
|
|
|
bot.on("messageCreate", async (msg) => {
|
|
try {
|
|
// fix DMs cause of gateway v8 changes
|
|
if (
|
|
!(msg.channel instanceof Dysnomia.Channel) &&
|
|
msg.author.id != bot.user.id &&
|
|
!msg.guildID
|
|
) {
|
|
const newChannel = await bot.getDMChannel(msg.author.id);
|
|
if (msg.channel.id == newChannel.id) msg.channel = newChannel;
|
|
}
|
|
|
|
if (!(msg.channel instanceof Dysnomia.Channel)) return;
|
|
|
|
await CommandDispatcher(msg);
|
|
} catch (err) {
|
|
const stack = (err?.stack ?? err.message).split("\n");
|
|
const error = stack.shift();
|
|
logger.error(
|
|
"hf:main",
|
|
`Failed to dispatch command: ${error}\n\t${stack.join("\n\t")}`
|
|
);
|
|
}
|
|
});
|
|
bot.on("messageUpdate", async (msg, oldMsg) => {
|
|
try {
|
|
const oneDay = Date.now() - 86400000;
|
|
if (
|
|
msg.timestamp > oneDay &&
|
|
!msg.hasRan &&
|
|
oldMsg &&
|
|
oldMsg.content !== msg.content
|
|
) {
|
|
await CommandDispatcher(msg);
|
|
}
|
|
} catch (err) {
|
|
const stack = (err?.stack ?? err.message).split("\n");
|
|
const error = stack.shift();
|
|
logger.error(
|
|
"hf:main",
|
|
`Failed to dispatch command update: ${error}\n\t${stack.join("\n\t")}`
|
|
);
|
|
}
|
|
});
|
|
bot.on("messageReactionAdd", async (msg, reaction, reactor) => {
|
|
if (msg?.author?.id !== bot.user.id) return;
|
|
if (reaction.name !== "\u274c") return;
|
|
|
|
try {
|
|
let channel = msg.channel;
|
|
if (!(channel instanceof Dysnomia.Channel)) {
|
|
const newChannel = hf.bot.getChannel(channel.id);
|
|
if (newChannel) {
|
|
channel = newChannel;
|
|
} else {
|
|
channel = await hf.bot.getRESTChannel(channel.id);
|
|
}
|
|
}
|
|
|
|
if (!msg.messageReference) {
|
|
msg = await channel.getMessage(msg.id);
|
|
}
|
|
|
|
if (!msg.messageReference) return;
|
|
|
|
const ref = await channel.getMessage(msg.messageReference.messageID);
|
|
if (!ref) return;
|
|
if (ref.author.id !== reactor.id) return;
|
|
|
|
await msg.delete("Command sender requested output deletion.");
|
|
} catch (err) {
|
|
const stack = (err?.stack ?? err.message).split("\n");
|
|
const error = stack.shift();
|
|
logger.error(
|
|
"hf:main",
|
|
`Failed to self-delete message: ${error}\n\t${stack.join("\n\t")}`
|
|
);
|
|
}
|
|
});
|
|
bot.on("interactionCreate", async (interaction) => {
|
|
try {
|
|
if (!(interaction.channel instanceof Dysnomia.Channel)) {
|
|
const newChannel = hf.bot.getChannel(interaction.channel.id);
|
|
if (newChannel) {
|
|
interaction.channel = newChannel;
|
|
} else {
|
|
interaction.channel = await hf.bot.getRESTChannel(
|
|
interaction.channel.id
|
|
);
|
|
}
|
|
}
|
|
|
|
await InteractionDispatcher(interaction);
|
|
} catch (err) {
|
|
const stack = (err?.stack ?? err.message).split("\n");
|
|
const error = stack.shift();
|
|
logger.error(
|
|
"hf:main",
|
|
`Failed to dispatch interaction command: ${error}\n\t${stack.join(
|
|
"\n\t"
|
|
)}`
|
|
);
|
|
}
|
|
});
|
|
|
|
bot.once("ready", async () => {
|
|
logger.info("hf:main", "Connected to Discord.");
|
|
logger.info(
|
|
"hf:main",
|
|
`Logged in as: ${formatUsername(bot.user)} (${bot.user.id})`
|
|
);
|
|
|
|
const channel = await bot.getDMChannel(config.owner_id);
|
|
if (channel) {
|
|
channel.createMessage({
|
|
content: "<:ms_tick:503341995348066313> Loaded HiddenPhox.",
|
|
});
|
|
}
|
|
bot.on("ready", () => {
|
|
logger.info("hf:main", "Reconnected to Discord.");
|
|
});
|
|
|
|
const commands = [];
|
|
for (const command of interactionCommands.values()) {
|
|
const options = Object.values(command.options);
|
|
for (const option of options) {
|
|
delete option.default;
|
|
}
|
|
|
|
// stupid hack
|
|
const send = options.shift();
|
|
options.push(send);
|
|
|
|
const formattedCommand = {
|
|
name: command.name,
|
|
type: command.type,
|
|
description: command.helpText,
|
|
options: options,
|
|
integration_types: [0],
|
|
contexts: [0],
|
|
};
|
|
|
|
if (!command.guildOnly) {
|
|
formattedCommand.integration_types.push(1);
|
|
formattedCommand.contexts.push(1, 2);
|
|
}
|
|
|
|
if (command.type === Dysnomia.Constants.ApplicationCommandTypes.CHAT_INPUT)
|
|
formattedCommand.name = formattedCommand.name.toLowerCase();
|
|
|
|
if (command.permissions !== undefined) {
|
|
formattedCommand.default_member_permissions =
|
|
command.permissions instanceof Dysnomia.Permission
|
|
? String(command.permissions.allow)
|
|
: String(command.permissions);
|
|
}
|
|
|
|
commands.push(formattedCommand);
|
|
}
|
|
|
|
await bot.requestHandler.request(
|
|
"PUT",
|
|
`/applications/${bot.application.id}/commands`,
|
|
true,
|
|
commands
|
|
);
|
|
});
|
|
|
|
bot.on("error", (err) => {
|
|
logger.error("hf:main", "Catching error: " + err);
|
|
});
|
|
bot.on("warn", (err) => {
|
|
logger.warn("hf:main", "Catching warn: " + err);
|
|
});
|
|
|
|
bot.on("shardDisconnect", (err, id) => {
|
|
logger.verbose("hf:shard", `Disconnecting from shard ${id}: ${err}`);
|
|
});
|
|
bot.on("shardResume", (id) => {
|
|
logger.verbose("hf:shard", "Resuming on shard " + id);
|
|
});
|
|
bot.on("shardPreReady", (id) => {
|
|
logger.verbose("hf:shard", `Shard ${id} getting ready`);
|
|
});
|
|
bot.on("shardReady", (id) => {
|
|
logger.verbose("hf:shard", `Shard ${id} ready`);
|
|
});
|
|
bot.on("unknown", (packet, id) => {
|
|
logger.verbose(
|
|
"hf:main",
|
|
`Shard ${id} caught unknown packet: ${JSON.stringify(packet)}`
|
|
);
|
|
});
|
|
|
|
instead("spawn", bot.shards, function (args, orig) {
|
|
const ret = orig.apply(this, args);
|
|
const shard = this.get(args[0]);
|
|
if (shard) {
|
|
before("sendWS", shard.__proto__, function ([op, _data]) {
|
|
if (op === Dysnomia.Constants.GatewayOPCodes.IDENTIFY) {
|
|
_data.properties.browser = "Discord Embedded";
|
|
delete _data.properties.device;
|
|
}
|
|
});
|
|
}
|
|
|
|
return ret;
|
|
});
|
|
|
|
bot.connect();
|