woah is that a refactor???
This commit is contained in:
parent
c94fbfec4e
commit
7218b22b2b
27 changed files with 482 additions and 379 deletions
|
@ -1,41 +0,0 @@
|
||||||
var meows = [
|
|
||||||
"mreow",
|
|
||||||
"miau",
|
|
||||||
"mewo",
|
|
||||||
"maow",
|
|
||||||
"mrow",
|
|
||||||
"mrao",
|
|
||||||
"meow",
|
|
||||||
"mew",
|
|
||||||
"nya",
|
|
||||||
];
|
|
||||||
|
|
||||||
var emoticons = [
|
|
||||||
":3",
|
|
||||||
"^w^",
|
|
||||||
"=^w^=",
|
|
||||||
"-w-",
|
|
||||||
":333"
|
|
||||||
];
|
|
||||||
|
|
||||||
async function execute(client, event) {
|
|
||||||
var reply = "";
|
|
||||||
for(let i = 0;i < Math.random() * 15; i++)
|
|
||||||
reply += " " + meows.random();
|
|
||||||
|
|
||||||
reply += "!".repeat(Math.random() * 5);
|
|
||||||
|
|
||||||
if(Math.random() > 0.5) {
|
|
||||||
reply += " " + emoticons.random();
|
|
||||||
}
|
|
||||||
|
|
||||||
await client.reply(event, reply);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
command: "catgpt",
|
|
||||||
name: "catgpt",
|
|
||||||
usage: "[prompt]",
|
|
||||||
desc: "advanced NAI-based language meowdel",
|
|
||||||
execute
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
import { xxh64 } from "@node-rs/xxhash";
|
|
||||||
import { encode } from "html-entities";
|
|
||||||
import { JSDOM } from "jsdom";
|
|
||||||
import util from "util";
|
|
||||||
import fs from "fs";
|
|
||||||
|
|
||||||
function execute(client, event, args) {
|
|
||||||
var c = "";
|
|
||||||
try {
|
|
||||||
var result = eval(args);
|
|
||||||
c = util.format(result).replaceAll(process.env.ACCESS_TOKEN, "*".repeat(process.env.ACCESS_TOKEN.length));
|
|
||||||
} catch(err) {
|
|
||||||
c = util.format(err);
|
|
||||||
}
|
|
||||||
client.reply(event, c, `<pre><code>${encode(c)}</code></pre>`);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
command: "eval",
|
|
||||||
name: "eval",
|
|
||||||
usage: "<code>",
|
|
||||||
owner: true,
|
|
||||||
desc: "run JS code and reply with the result",
|
|
||||||
execute
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
import { encode } from "html-entities";
|
|
||||||
|
|
||||||
function execute(client, event, args) {
|
|
||||||
var name = args.toLowerCase();
|
|
||||||
|
|
||||||
var command = client.commands.filter(c=>(c.name.toLowerCase()==name || c.command.toLowerCase()==name))[0];
|
|
||||||
var module = client.modules.filter(m=>m.name.toLowerCase()==name)[0];
|
|
||||||
var specific = command ?? module ?? false;
|
|
||||||
|
|
||||||
if(args != "") {
|
|
||||||
if(!command && !module) {
|
|
||||||
client.reply(event, `section "${args}" not found.\nrun "${process.env.PREFIX}help" for a list of commands and modules.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(module) {
|
|
||||||
var reply = module.name + "\n";
|
|
||||||
reply += module.desc;
|
|
||||||
|
|
||||||
var replyHTML = `<b>${encode(module.name)}</b><br>` +
|
|
||||||
`<i>${encode(module.desc)}</i>`;
|
|
||||||
|
|
||||||
client.reply(event, reply, replyHTML);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var reply = command.name + "\n" +
|
|
||||||
command.desc + "\n\n" +
|
|
||||||
command.usage;
|
|
||||||
|
|
||||||
var replyHTML = `<b>${encode(command.name)}</b><br>` +
|
|
||||||
`<i>${encode(command.desc)}</i>` +
|
|
||||||
`<br><code>${encode(command.usage)}</code>`;
|
|
||||||
|
|
||||||
client.reply(event, reply, replyHTML);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var reply = `commands: ${client.commands.map(m => m.name).join(", ")}\n` +
|
|
||||||
`modules: ${client.modules.map(m => m.name).join(", ")}\n` +
|
|
||||||
`run ${process.env.PREFIX}help <module/command> for more information.`;
|
|
||||||
|
|
||||||
var replyHTML = `commands: <code>${client.commands.map(m => encode(m.name)).join("</code>, <code>")}</code><br>` +
|
|
||||||
`modules: <code>${client.modules.map(m => encode(m.name)).join("</code>, <code>")}</code><br>` +
|
|
||||||
encode(`run ${process.env.PREFIX}help <module/command> for more information.`);
|
|
||||||
|
|
||||||
client.reply(event, reply, replyHTML);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
command: "help",
|
|
||||||
name: "help",
|
|
||||||
desc: "show list of commands and modules",
|
|
||||||
execute
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
function execute(client, event, args) {
|
|
||||||
var info = `source code: https://git.lgbt/root/possumbot\n`;
|
|
||||||
info += `commands: ${client.commands.length}\n`;
|
|
||||||
info += `modules: ${client.modules.length}\n`;
|
|
||||||
info += `prefix: ${process.env.PREFIX} (you can also mention the bot!)\n`;
|
|
||||||
info += `owner: ${process.env.OWNER_ID}`;
|
|
||||||
|
|
||||||
client.reply(event, info);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
command: "info",
|
|
||||||
name: "info",
|
|
||||||
desc: "show general info about the bot",
|
|
||||||
execute
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
import { exec } from "node:child_process";
|
|
||||||
|
|
||||||
function execute(client, event, args) {
|
|
||||||
client.joinRoom(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
command: "join",
|
|
||||||
name: "join",
|
|
||||||
owner: true,
|
|
||||||
desc: "join a room",
|
|
||||||
execute
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
import { exec } from "node:child_process";
|
|
||||||
|
|
||||||
function execute(client, event, args) {
|
|
||||||
process.exit(255);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
command: "restart",
|
|
||||||
name: "restart",
|
|
||||||
owner: true,
|
|
||||||
desc: "restarts the bot",
|
|
||||||
execute
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
import { encode } from "html-entities";
|
|
||||||
|
|
||||||
function execute(client, event, args) {
|
|
||||||
var name = args.toLowerCase();
|
|
||||||
|
|
||||||
var command = client.commands.filter(c=>(c.name.toLowerCase()==name || c.command.toLowerCase()==name))[0];
|
|
||||||
var module = client.modules.filter(m=>m.name.toLowerCase()==name)[0];
|
|
||||||
var specific = command ?? module ?? false;
|
|
||||||
|
|
||||||
var config = client.config.get(event.sender.roomId);
|
|
||||||
|
|
||||||
if(args != "") {
|
|
||||||
if(!module) {
|
|
||||||
client.reply(event, `Module "${args}" not found.\nRun "${process.env.PREFIX}help" for a list of commands and modules.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
config.set(module.name, !(config.get(module.name) ?? true));
|
|
||||||
var state = (config.get(module.name) ? "En" : "Dis") + "abled";
|
|
||||||
|
|
||||||
var reply = state + " " + module.name;
|
|
||||||
var replyHTML = `<b>${state}</b> <code>${encode(module.name)}</code>`;
|
|
||||||
|
|
||||||
client.reply(event, reply, replyHTML);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var modules = client.modules.map(m=>m.name);
|
|
||||||
var enabled = modules.filter(m=>config.get(m)!==false);
|
|
||||||
|
|
||||||
var reply = `enabled modules:\n${enabled.join(", ")}`;
|
|
||||||
var replyHTML = `enabled modules:<br><code>${enabled.join("</code>, <code>")}</code>`;
|
|
||||||
|
|
||||||
reply += `\navailable modules:\n${modules.join(", ")}`;
|
|
||||||
replyHTML += `<br>available modules:<br><code>${modules.join("</code>, <code>")}</code>`;
|
|
||||||
|
|
||||||
client.reply(event, reply, replyHTML);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
command: "toggle",
|
|
||||||
name: "toggle",
|
|
||||||
usage: "<module>",
|
|
||||||
minPwr: 50,
|
|
||||||
desc: "toggle a module on or off in current channel",
|
|
||||||
execute
|
|
||||||
}
|
|
|
@ -1,81 +0,0 @@
|
||||||
import fedimbed from "../lib/fedimbed.js";
|
|
||||||
import { encode } from "html-entities";
|
|
||||||
import { JSDOM } from "jsdom";
|
|
||||||
import util from "util";
|
|
||||||
|
|
||||||
async function onMessage(client, event) {
|
|
||||||
const embed = await fedimbed(event.getContent().body);
|
|
||||||
if(!embed) return;
|
|
||||||
const dom = new JSDOM("<!DOCTYPE html><body></body>");
|
|
||||||
const document = dom.window.document;
|
|
||||||
var quote = document.createElement("blockquote");
|
|
||||||
if(!embed.embeds) {
|
|
||||||
var c = util.format(embed);
|
|
||||||
client.reply(event, c, `<pre><code>${encode(c)}</code></pre>`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const emb of embed.embeds) {
|
|
||||||
var link = document.createElement("a");
|
|
||||||
link.href = emb.url;
|
|
||||||
|
|
||||||
if(emb.thumbnail && emb.thumbnail.url) {
|
|
||||||
var avatar = document.createElement("img");
|
|
||||||
avatar.src = await client.uploadMedia(emb.thumbnail.url);
|
|
||||||
avatar.height = "16";
|
|
||||||
link.appendChild(avatar);
|
|
||||||
}
|
|
||||||
|
|
||||||
var linkText = document.createElement("span");
|
|
||||||
linkText.innerHTML = ((emb.thumbnail?.url) ? " " : "") + emb.title;
|
|
||||||
link.appendChild(linkText);
|
|
||||||
|
|
||||||
quote.appendChild(link);
|
|
||||||
|
|
||||||
var text = document.createElement("p");
|
|
||||||
text.innerHTML = emb.description;
|
|
||||||
|
|
||||||
for(const emote of embed.emotes) {
|
|
||||||
console.log(text.innerHTML);
|
|
||||||
var img = document.createElement("img");
|
|
||||||
img.src = await client.uploadMedia(emote.url);
|
|
||||||
img.height = "16";
|
|
||||||
img.alt = emote.name;
|
|
||||||
text.innerHTML = text.innerHTML.replaceAll(emote.name, img.outerHTML);
|
|
||||||
}
|
|
||||||
|
|
||||||
quote.appendChild(text);
|
|
||||||
}
|
|
||||||
for(const file of embed.files) {
|
|
||||||
var media;
|
|
||||||
switch(file.type.split("/")[0]) {
|
|
||||||
case "audio":
|
|
||||||
media = document.createElement("audio");
|
|
||||||
break;
|
|
||||||
case "video":
|
|
||||||
media = document.createElement("video");
|
|
||||||
break;
|
|
||||||
case "image":
|
|
||||||
media = document.createElement("img");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
media.src = await client.uploadMedia(file.url);
|
|
||||||
media.alt = media.title = file.desc ?? "";
|
|
||||||
quote.appendChild(media);
|
|
||||||
}
|
|
||||||
document.body.appendChild(quote);
|
|
||||||
|
|
||||||
let x = document.createElement("small");
|
|
||||||
x.innerHTML = "Powered by <a href=\"https://gitdab.com/Cynosphere/HiddenPhox/src/branch/rewrite/src/modules/fedimbed.js\">HF Fedimbed</a>";
|
|
||||||
document.body.appendChild(x);
|
|
||||||
|
|
||||||
client.reply(event, "This message uses HTML, which your client does not support.", document.body.outerHTML);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "fedimbed",
|
|
||||||
desc: "embed fediverse post contents",
|
|
||||||
hooks: {
|
|
||||||
message: onMessage
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
var meows = [
|
|
||||||
"mreow",
|
|
||||||
"miau",
|
|
||||||
"mewo",
|
|
||||||
"maow",
|
|
||||||
"mrow",
|
|
||||||
"mrao",
|
|
||||||
"meow",
|
|
||||||
"mew",
|
|
||||||
"nya",
|
|
||||||
];
|
|
||||||
|
|
||||||
var re = new RegExp("\\b(n+y+a+n*?|m+[re]*([yiaou]+[wu]+|w+))(ing|er|s)?\\b", "gi");
|
|
||||||
|
|
||||||
var emoticons = [
|
|
||||||
":3",
|
|
||||||
"^w^",
|
|
||||||
"=^w^=",
|
|
||||||
"-w-",
|
|
||||||
":333"
|
|
||||||
];
|
|
||||||
|
|
||||||
async function onMessage(client, event) {
|
|
||||||
var content = event.getContent();
|
|
||||||
|
|
||||||
if(content["m.new_content"] != null) return;
|
|
||||||
|
|
||||||
for(const meow of meows) {
|
|
||||||
if(re.test(content.body.toLowerCase())) {
|
|
||||||
var reply = meows.random();
|
|
||||||
reply += "!".repeat(Math.random()*5)
|
|
||||||
|
|
||||||
if(Math.random() > 0.5) {
|
|
||||||
reply += " " + emoticons.random();
|
|
||||||
}
|
|
||||||
|
|
||||||
client.reply(event, reply);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "meow",
|
|
||||||
desc: ":33",
|
|
||||||
hooks: {
|
|
||||||
message: onMessage
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,11 +3,11 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"description": "General purpose Matrix bot",
|
"description": "General purpose Matrix bot",
|
||||||
"main": "index.js",
|
"main": "src/index.js",
|
||||||
"author": "Ashley Graves",
|
"author": "Ashley Graves",
|
||||||
"license": "GPL-v3",
|
"license": "GPL-v3",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"login": "node login.js"
|
"login": "node src/login.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@matrix-org/olm": "^3.2.15",
|
"@matrix-org/olm": "^3.2.15",
|
||||||
|
|
45
src/commands/catgpt.js
Normal file
45
src/commands/catgpt.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import BaseCommand from "../lib/base/command.js";
|
||||||
|
|
||||||
|
var meows = [
|
||||||
|
"mreow",
|
||||||
|
"miau",
|
||||||
|
"mewo",
|
||||||
|
"maow",
|
||||||
|
"mrow",
|
||||||
|
"mrao",
|
||||||
|
"meow",
|
||||||
|
"mew",
|
||||||
|
"nya",
|
||||||
|
];
|
||||||
|
|
||||||
|
var emoticons = [
|
||||||
|
":3",
|
||||||
|
"^w^",
|
||||||
|
"=^w^=",
|
||||||
|
"-w-",
|
||||||
|
":333"
|
||||||
|
];
|
||||||
|
|
||||||
|
class CatGPTCommand extends BaseCommand {
|
||||||
|
command = "catgpt";
|
||||||
|
name = "catgpt";
|
||||||
|
usage = "[prompt]";
|
||||||
|
description = "advanced NAI-based language meowdel";
|
||||||
|
|
||||||
|
/** @type {BaseCommand['execute']} */
|
||||||
|
async execute(client, event) {
|
||||||
|
var reply = "";
|
||||||
|
for (let i = 0; i < Math.random() * 15; i++)
|
||||||
|
reply += " " + meows.random();
|
||||||
|
|
||||||
|
reply += "!".repeat(Math.random() * 5);
|
||||||
|
|
||||||
|
if (Math.random() > 0.5) {
|
||||||
|
reply += " " + emoticons.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.reply(event, reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new CatGPTCommand();
|
29
src/commands/eval.js
Normal file
29
src/commands/eval.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import BaseCommand from "../lib/base/command.js";
|
||||||
|
import { xxh64 } from "@node-rs/xxhash";
|
||||||
|
import { encode } from "html-entities";
|
||||||
|
import { JSDOM } from "jsdom";
|
||||||
|
import util from "util";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
class EvalCommand extends BaseCommand {
|
||||||
|
name = "eval";
|
||||||
|
command = "eval";
|
||||||
|
usage = "<code>";
|
||||||
|
ownerOnly = true;
|
||||||
|
description = "run JS code and reply with the result";
|
||||||
|
|
||||||
|
/** @type {BaseCommand['execute']} */
|
||||||
|
async execute(client, event, args) {
|
||||||
|
var c = "";
|
||||||
|
try {
|
||||||
|
var result = eval(args);
|
||||||
|
c = util.format(result).replaceAll(process.env.ACCESS_TOKEN, "*".repeat(process.env.ACCESS_TOKEN.length));
|
||||||
|
} catch (err) {
|
||||||
|
c = util.format(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
await client.reply(event, c, `<pre><code>${encode(c)}</code></pre>`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new EvalCommand();
|
62
src/commands/help.js
Normal file
62
src/commands/help.js
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import { encode } from "html-entities";
|
||||||
|
import BaseCommand from "../lib/base/command.js";
|
||||||
|
|
||||||
|
class HelpCommand extends BaseCommand {
|
||||||
|
command = "help";
|
||||||
|
name = "help";
|
||||||
|
desc = "show list of commands and modules";
|
||||||
|
|
||||||
|
/** @type {BaseCommand['execute']} */
|
||||||
|
async execute(client, event, args) {
|
||||||
|
var name = args.toLowerCase();
|
||||||
|
|
||||||
|
var command = client.commands.filter(c => (c.name.toLowerCase() == name || c.command.toLowerCase() == name))[0];
|
||||||
|
var module = client.modules.filter(m => m.name.toLowerCase() == name)[0];
|
||||||
|
|
||||||
|
if (args != "") {
|
||||||
|
if (!command && !module) {
|
||||||
|
client.reply(event, `section "${args}" not found.\nrun "${process.env.PREFIX}help" for a list of commands and modules.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module) {
|
||||||
|
module.desc = module.desc ?? module.description;
|
||||||
|
|
||||||
|
var reply = module.name + "\n";
|
||||||
|
reply += module.desc;
|
||||||
|
|
||||||
|
var replyHTML = `<b>${encode(module.name)}</b><br>` +
|
||||||
|
`<i>${encode(module.desc)}</i>`;
|
||||||
|
|
||||||
|
client.reply(event, reply, replyHTML);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
command.desc = command.desc ?? command.description;
|
||||||
|
|
||||||
|
var reply = command.name + "\n" +
|
||||||
|
command.desc + "\n\n" +
|
||||||
|
command.usage;
|
||||||
|
|
||||||
|
var replyHTML = `<b>${encode(command.name)}</b><br>` +
|
||||||
|
`<i>${encode(command.desc)}</i>` +
|
||||||
|
`<br><code>${encode(command.usage)}</code>`;
|
||||||
|
|
||||||
|
client.reply(event, reply, replyHTML);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var reply = `commands: ${client.commands.map(m => m.name).join(", ")}\n` +
|
||||||
|
`modules: ${client.modules.map(m => m.name).join(", ")}\n` +
|
||||||
|
`run ${process.env.PREFIX}help <module/command> for more information.`;
|
||||||
|
|
||||||
|
var replyHTML = `commands: <code>${client.commands.map(m => encode(m.name)).join("</code>, <code>")}</code><br>` +
|
||||||
|
`modules: <code>${client.modules.map(m => encode(m.name)).join("</code>, <code>")}</code><br>` +
|
||||||
|
encode(`run ${process.env.PREFIX}help <module/command> for more information.`);
|
||||||
|
|
||||||
|
client.reply(event, reply, replyHTML);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new HelpCommand();
|
20
src/commands/info.js
Normal file
20
src/commands/info.js
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import BaseCommand from "../lib/base/command.js";
|
||||||
|
|
||||||
|
class InfoCommand extends BaseCommand {
|
||||||
|
command = "info";
|
||||||
|
name = "info";
|
||||||
|
desc = "show general info about the bot";
|
||||||
|
|
||||||
|
/** @type {BaseCommand['execute']} */
|
||||||
|
async execute(client, event, args) {
|
||||||
|
var info = `source code: https://git.lgbt/root/possumbot\n`;
|
||||||
|
info += `commands: ${client.commands.length}\n`;
|
||||||
|
info += `modules: ${client.modules.length}\n`;
|
||||||
|
info += `prefix: ${process.env.PREFIX} (you can also mention the bot!)\n`;
|
||||||
|
info += `owner: ${process.env.OWNER_ID}`;
|
||||||
|
|
||||||
|
await client.reply(event, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new InfoCommand();
|
16
src/commands/join.js
Normal file
16
src/commands/join.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { exec } from "node:child_process";
|
||||||
|
import BaseCommand from "../lib/base/command.js";
|
||||||
|
|
||||||
|
class JoinCommand extends BaseCommand {
|
||||||
|
command = "join";
|
||||||
|
name = "join";
|
||||||
|
ownerOnly = true;
|
||||||
|
description = "join a room";
|
||||||
|
|
||||||
|
/** @type {BaseCommand['execute']} */
|
||||||
|
async execute(client, event, args) {
|
||||||
|
client.joinRoom(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new JoinCommand();
|
16
src/commands/restart.js
Normal file
16
src/commands/restart.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import BaseCommand from "../lib/base/command.js";
|
||||||
|
|
||||||
|
class RestartCommand extends BaseCommand {
|
||||||
|
name = "restart";
|
||||||
|
command = "restart";
|
||||||
|
description = "restarts the bot";
|
||||||
|
ownerOnly = true;
|
||||||
|
|
||||||
|
/** @type {BaseCommand['execute']} */
|
||||||
|
async execute(client, event, args) {
|
||||||
|
await client.reply(event, "Restarting, please wait...");
|
||||||
|
process.exit(255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new RestartCommand();
|
50
src/commands/toggle.js
Normal file
50
src/commands/toggle.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { encode } from "html-entities";
|
||||||
|
import BaseCommand from "../lib/base/command.js";
|
||||||
|
|
||||||
|
class ToggleCommand extends BaseCommand {
|
||||||
|
command = "toggle";
|
||||||
|
name = "toggle";
|
||||||
|
usage = "<module>";
|
||||||
|
minPowerLevel = 50;
|
||||||
|
description = "toggle a module on or off in current channel";
|
||||||
|
|
||||||
|
/** @type {BaseCommand['execute']} */
|
||||||
|
async execute(client, event, args) {
|
||||||
|
var name = args.toLowerCase();
|
||||||
|
|
||||||
|
var command = client.commands.filter(c => (c.name.toLowerCase() == name || c.command.toLowerCase() == name))[0];
|
||||||
|
var module = client.modules.filter(m => m.name.toLowerCase() == name)[0];
|
||||||
|
var specific = command ?? module ?? false;
|
||||||
|
|
||||||
|
var config = client.config.get(event.sender.roomId);
|
||||||
|
|
||||||
|
if (args != "") {
|
||||||
|
if (!module) {
|
||||||
|
client.reply(event, `Module "${args}" not found.\nRun "${process.env.PREFIX}help" for a list of commands and modules.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.set(module.name, !(config.get(module.name) ?? true));
|
||||||
|
var state = (config.get(module.name) ? "En" : "Dis") + "abled";
|
||||||
|
|
||||||
|
var reply = state + " " + module.name;
|
||||||
|
var replyHTML = `<b>${state}</b> <code>${encode(module.name)}</code>`;
|
||||||
|
|
||||||
|
client.reply(event, reply, replyHTML);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var modules = client.modules.map(m => m.name);
|
||||||
|
var enabled = modules.filter(m => config.get(m) !== false);
|
||||||
|
|
||||||
|
var reply = `enabled modules:\n${enabled.join(", ")}`;
|
||||||
|
var replyHTML = `enabled modules:<br><code>${enabled.join("</code>, <code>")}</code>`;
|
||||||
|
|
||||||
|
reply += `\navailable modules:\n${modules.join(", ")}`;
|
||||||
|
replyHTML += `<br>available modules:<br><code>${modules.join("</code>, <code>")}</code>`;
|
||||||
|
|
||||||
|
client.reply(event, reply, replyHTML);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new ToggleCommand();
|
|
@ -6,6 +6,9 @@ import sdkExt from "./lib/ext.js";
|
||||||
import { resolve } from "node:path";
|
import { resolve } from "node:path";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import { LocalStorage } from 'node-localstorage';
|
import { LocalStorage } from 'node-localstorage';
|
||||||
|
import { dirname } from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
global.__dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
|
||||||
import fetch from "node-fetch";
|
import fetch from "node-fetch";
|
||||||
global.fetch = fetch;
|
global.fetch = fetch;
|
||||||
|
@ -14,6 +17,8 @@ import Olm from "@matrix-org/olm";
|
||||||
global.Olm = Olm;
|
global.Olm = Olm;
|
||||||
|
|
||||||
import env from "dotenv";
|
import env from "dotenv";
|
||||||
|
import BaseCommand from "./lib/base/command.js";
|
||||||
|
import { format } from "node:util";
|
||||||
env.config();
|
env.config();
|
||||||
|
|
||||||
const localStorage = new LocalStorage("./data/localstorage");
|
const localStorage = new LocalStorage("./data/localstorage");
|
||||||
|
@ -49,10 +54,11 @@ client.initialized = false;
|
||||||
client.modules = [];
|
client.modules = [];
|
||||||
client.commands = [];
|
client.commands = [];
|
||||||
|
|
||||||
for (const file of fs.readdirSync(resolve("modules"))) {
|
var modulesDir = resolve(__dirname, "modules");
|
||||||
|
for (const file of fs.readdirSync(modulesDir)) {
|
||||||
try {
|
try {
|
||||||
if (file.startsWith(".")) continue;
|
if (file.startsWith(".")) continue;
|
||||||
var module = (await import(resolve("modules", file))).default;
|
var module = (await import(resolve(modulesDir, file))).default;
|
||||||
client.modules.push(module);
|
client.modules.push(module);
|
||||||
client.log("[load:modules]", `loaded ${module.name}`);
|
client.log("[load:modules]", `loaded ${module.name}`);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -60,10 +66,11 @@ for (const file of fs.readdirSync(resolve("modules"))) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const file of fs.readdirSync(resolve("commands"))) {
|
var commandsDir = resolve(__dirname, "commands");
|
||||||
|
for (const file of fs.readdirSync(commandsDir)) {
|
||||||
try {
|
try {
|
||||||
if (file.startsWith(".")) continue;
|
if (file.startsWith(".")) continue;
|
||||||
var command = (await import(resolve("commands", file))).default;
|
var command = (await import(resolve(commandsDir, file))).default;
|
||||||
command.usage = process.env.PREFIX + command.command + (command.usage ? " " + command.usage : '');
|
command.usage = process.env.PREFIX + command.command + (command.usage ? " " + command.usage : '');
|
||||||
client.commands.push(command);
|
client.commands.push(command);
|
||||||
client.log("[load:commands]", `loaded ${command.name}`);
|
client.log("[load:commands]", `loaded ${command.name}`);
|
||||||
|
@ -74,27 +81,36 @@ for (const file of fs.readdirSync(resolve("commands"))) {
|
||||||
|
|
||||||
function doModule(client, event) {
|
function doModule(client, event) {
|
||||||
client.modules.forEach(m => {
|
client.modules.forEach(m => {
|
||||||
if (!m) return;
|
if (!m.onMessage) return;
|
||||||
|
|
||||||
var config = client.config.get(event.sender.roomId);
|
var config = client.config.get(event.sender.roomId);
|
||||||
if (config.get(m.name) === false) return;
|
if (config.get(m.name) === false) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
m.hooks?.message(client, event);
|
m.onMessage(client, event);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
client.log("[hook]", err);
|
client.log("[hook]", err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MatrixClient} client
|
||||||
|
* @param {MatrixEvent} event
|
||||||
|
* @param {string} cmd
|
||||||
|
* @param {string} args
|
||||||
|
* @returns {Boolean} Success?
|
||||||
|
*/
|
||||||
function doCommand(client, event, cmd, args) {
|
function doCommand(client, event, cmd, args) {
|
||||||
var command;
|
/**
|
||||||
command = client.commands.filter(c => c.command == cmd)[0];
|
* @type {BaseCommand}
|
||||||
|
*/
|
||||||
|
var command = client.commands.filter(c => c.command == cmd)[0];
|
||||||
if (!command)
|
if (!command)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((command.owner && event.sender.userId != process.env.OWNER_ID) || (command.minPwr && event.sender.powerLevel < command.minPwr && event.sender.userId != process.env.OWNER_ID)) {
|
if ((command.ownerOnly && event.sender.userId != process.env.OWNER_ID) || (command.minPowerLevel > 0 && event.sender.powerLevel < command.minPowerLevel && event.sender.userId != process.env.OWNER_ID)) {
|
||||||
var addl = command.minPwr ? `this command requires a power level of ${command.minPwr}\nyour power level is ${event.sender.powerLevel}` : "this command is owner-only.";
|
var addl = command.minPowerLevel ? `this command requires a power level of ${command.minPowerLevel}\nyour power level is ${event.sender.powerLevel}` : "this command is owner-only.";
|
||||||
client.reply(event, addl, '<img src="mxc://nyx.ftp.sh/2kAXPyosdaz1M6Fv8t2V9SyxcJZEscdR" alt="nuh uh" /><br>' + addl.replaceAll("\n", "<br>"));
|
client.reply(event, addl, '<img src="mxc://nyx.ftp.sh/2kAXPyosdaz1M6Fv8t2V9SyxcJZEscdR" alt="nuh uh" /><br>' + addl.replaceAll("\n", "<br>"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -107,35 +123,57 @@ function doCommand(client, event, cmd, args) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function verifyCallback(request) {
|
/** @param {import("matrix-js-sdk/lib/crypto-api.js").VerificationRequest} request */
|
||||||
|
client.verifyCallback = async function (request) {
|
||||||
console.log("### VERIFICATION ### Starting for " + request.otherUserId);
|
console.log("### VERIFICATION ### Starting for " + request.otherUserId);
|
||||||
|
|
||||||
if (!request.initiatedByMe) {
|
if (!request.initiatedByMe) {
|
||||||
await request.accept();
|
await request.accept();
|
||||||
var verifier = await request.startVerification(VerificationMethod.Sas);
|
try {
|
||||||
verifier.on(VerifierEvent.ShowSas, async function () {
|
var verifier = await request.startVerification(VerificationMethod.Sas);
|
||||||
console.log("### VERIFICATION ### Confirming");
|
verifier.on(VerifierEvent.ShowSas, async function () {
|
||||||
await verifier.getShowSasCallbacks().confirm();
|
console.log("### VERIFICATION ### Confirming");
|
||||||
});
|
await verifier.getShowSasCallbacks().confirm();
|
||||||
|
});
|
||||||
|
verifier.on(VerifierEvent.Cancel, async function (e) {
|
||||||
|
console.log("### VERIFICATION ### ", e);
|
||||||
|
await client.sendMessage(request.roomId, {
|
||||||
|
body: format(e),
|
||||||
|
msgtype: sdk.MsgType.Text
|
||||||
|
})
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
client.sendMessage(request.roomId, {
|
||||||
|
body: err,
|
||||||
|
msgtype: sdk.MsgType.Notice
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
request.on(VerificationRequestEvent.Change, async function () {
|
request.on(VerificationRequestEvent.Change, async function () {
|
||||||
switch (request.phase) {
|
try {
|
||||||
case 3:
|
switch (request.phase) {
|
||||||
break;
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
var verifier = await request.startVerification(VerificationMethod.Sas);
|
var verifier = await request.startVerification(VerificationMethod.Sas);
|
||||||
verifier.on(VerifierEvent.ShowSas, async function () {
|
verifier.on(VerifierEvent.ShowSas, async function () {
|
||||||
console.log("### VERIFICATION ### Confirming");
|
console.log("### VERIFICATION ### Confirming");
|
||||||
await verifier.getShowSasCallbacks().confirm();
|
await verifier.getShowSasCallbacks().confirm();
|
||||||
});
|
});
|
||||||
case 5:
|
case 5:
|
||||||
console.log("### VERIFICATION ### Cancelled!");
|
console.log("### VERIFICATION ### Cancelled!");
|
||||||
case 6:
|
case 6:
|
||||||
console.log("### VERIFICATION ### Done!");
|
console.log("### VERIFICATION ### Done!");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("### VERIFICATION ### " + request.phase);
|
console.log("### VERIFICATION ### " + request.phase);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
client.sendMessage(request.roomId, {
|
||||||
|
body: err,
|
||||||
|
msgtype: sdk.MsgType.Notice
|
||||||
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -149,15 +187,14 @@ client.once("sync", async function (state, prevState, data) {
|
||||||
prefixes.push(client.name + " ");
|
prefixes.push(client.name + " ");
|
||||||
client.initialized = true;
|
client.initialized = true;
|
||||||
|
|
||||||
while (!await client.getCrypto().isCrossSigningReady()) { }
|
|
||||||
var status = await client.getCrypto().getDeviceVerificationStatus(client.getUserId(), client.getDeviceId());
|
var status = await client.getCrypto().getDeviceVerificationStatus(client.getUserId(), client.getDeviceId());
|
||||||
if (!status || Object.keys(status).map(v => status[v]).includes(false)) {
|
if (!status || Object.keys(status).map(v => status[v]).includes(false)) {
|
||||||
const request = await client.getCrypto().requestOwnUserVerification();
|
const request = await client.getCrypto().requestOwnUserVerification();
|
||||||
verifyCallback(request);
|
client.verifyCallback(request);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on(sdk.CryptoEvent.VerificationRequestReceived, verifyCallback);
|
client.on(sdk.CryptoEvent.VerificationRequestReceived, client.verifyCallback);
|
||||||
|
|
||||||
client.on(sdk.RoomEvent.Timeline, async function (event, room, toStartOfTimeline) {
|
client.on(sdk.RoomEvent.Timeline, async function (event, room, toStartOfTimeline) {
|
||||||
await client.decryptEventIfNeeded(event);
|
await client.decryptEventIfNeeded(event);
|
||||||
|
@ -184,7 +221,7 @@ client.on(sdk.RoomEvent.Timeline, async function (event, room, toStartOfTimeline
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isCommand) {
|
if (!isCommand) {
|
||||||
doModule(client, event);
|
doModule(client, event)
|
||||||
} else {
|
} else {
|
||||||
var args = content.split(/\s/g);
|
var args = content.split(/\s/g);
|
||||||
var cmd = args.shift();
|
var cmd = args.shift();
|
19
src/lib/base/command.js
Normal file
19
src/lib/base/command.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { MatrixClient, MatrixEvent } from "matrix-js-sdk";
|
||||||
|
import BaseEvent from "./event.js";
|
||||||
|
|
||||||
|
export default class BaseCommand extends BaseEvent {
|
||||||
|
command = "";
|
||||||
|
usage = "";
|
||||||
|
minPowerLevel = 0;
|
||||||
|
ownerOnly = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MatrixClient} client
|
||||||
|
* @param {MatrixEvent} event
|
||||||
|
* @param {string} args
|
||||||
|
* @returns {Boolean} Success?
|
||||||
|
*/
|
||||||
|
async execute(client, event, args) {
|
||||||
|
throw new Error("Not implemented.");
|
||||||
|
}
|
||||||
|
}
|
7
src/lib/base/event.js
Normal file
7
src/lib/base/event.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { MatrixClient, MatrixEvent } from "matrix-js-sdk";
|
||||||
|
|
||||||
|
export default class BaseEvent {
|
||||||
|
name = "";
|
||||||
|
description = "";
|
||||||
|
hooks = {};
|
||||||
|
}
|
15
src/lib/base/module.js
Normal file
15
src/lib/base/module.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import BaseEvent from "./event.js";
|
||||||
|
|
||||||
|
export default class BaseModule extends BaseEvent {
|
||||||
|
name = "";
|
||||||
|
description = "";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MatrixClient} client
|
||||||
|
* @param {MatrixEvent} event
|
||||||
|
* @returns {Boolean} Success?
|
||||||
|
*/
|
||||||
|
async onMessage(client, event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
79
src/modules/fedimbed.js
Normal file
79
src/modules/fedimbed.js
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
import fedimbed from "../lib/fedimbed.js";
|
||||||
|
import { encode } from "html-entities";
|
||||||
|
import { JSDOM } from "jsdom";
|
||||||
|
import util from "util";
|
||||||
|
import BaseModule from "../lib/base/module.js";
|
||||||
|
|
||||||
|
export default class FedimbedModule extends BaseModule {
|
||||||
|
name = "fedimbed";
|
||||||
|
description = "embed fediverse post contents";
|
||||||
|
|
||||||
|
async onMessage(client, event) {
|
||||||
|
const embed = await fedimbed(event.getContent().body);
|
||||||
|
if (!embed) return;
|
||||||
|
const dom = new JSDOM("<!DOCTYPE html><body></body>");
|
||||||
|
const document = dom.window.document;
|
||||||
|
var quote = document.createElement("blockquote");
|
||||||
|
if (!embed.embeds) {
|
||||||
|
var c = util.format(embed);
|
||||||
|
client.reply(event, c, `<pre><code>${encode(c)}</code></pre>`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const emb of embed.embeds) {
|
||||||
|
var link = document.createElement("a");
|
||||||
|
link.href = emb.url;
|
||||||
|
|
||||||
|
if (emb.thumbnail && emb.thumbnail.url) {
|
||||||
|
var avatar = document.createElement("img");
|
||||||
|
avatar.src = await client.uploadMedia(emb.thumbnail.url);
|
||||||
|
avatar.height = "16";
|
||||||
|
link.appendChild(avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
var linkText = document.createElement("span");
|
||||||
|
linkText.innerHTML = ((emb.thumbnail?.url) ? " " : "") + emb.title;
|
||||||
|
link.appendChild(linkText);
|
||||||
|
|
||||||
|
quote.appendChild(link);
|
||||||
|
|
||||||
|
var text = document.createElement("p");
|
||||||
|
text.innerHTML = emb.description;
|
||||||
|
|
||||||
|
for (const emote of embed.emotes) {
|
||||||
|
console.log(text.innerHTML);
|
||||||
|
var img = document.createElement("img");
|
||||||
|
img.src = await client.uploadMedia(emote.url);
|
||||||
|
img.height = "16";
|
||||||
|
img.alt = emote.name;
|
||||||
|
text.innerHTML = text.innerHTML.replaceAll(emote.name, img.outerHTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
quote.appendChild(text);
|
||||||
|
}
|
||||||
|
for (const file of embed.files) {
|
||||||
|
var media;
|
||||||
|
switch (file.type.split("/")[0]) {
|
||||||
|
case "audio":
|
||||||
|
media = document.createElement("audio");
|
||||||
|
break;
|
||||||
|
case "video":
|
||||||
|
media = document.createElement("video");
|
||||||
|
break;
|
||||||
|
case "image":
|
||||||
|
media = document.createElement("img");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
media.src = await client.uploadMedia(file.url);
|
||||||
|
media.alt = media.title = file.desc ?? "";
|
||||||
|
quote.appendChild(media);
|
||||||
|
}
|
||||||
|
document.body.appendChild(quote);
|
||||||
|
|
||||||
|
let x = document.createElement("small");
|
||||||
|
x.innerHTML = "Powered by <a href=\"https://gitdab.com/Cynosphere/HiddenPhox/src/branch/rewrite/src/modules/fedimbed.js\">HF Fedimbed</a>";
|
||||||
|
document.body.appendChild(x);
|
||||||
|
|
||||||
|
client.reply(event, "This message uses HTML, which your client does not support.", document.body.outerHTML);
|
||||||
|
}
|
||||||
|
}
|
48
src/modules/meow.js
Normal file
48
src/modules/meow.js
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import BaseModule from "../lib/base/module.js";
|
||||||
|
|
||||||
|
var meows = [
|
||||||
|
"mreow",
|
||||||
|
"miau",
|
||||||
|
"mewo",
|
||||||
|
"maow",
|
||||||
|
"mrow",
|
||||||
|
"mrao",
|
||||||
|
"meow",
|
||||||
|
"mew",
|
||||||
|
"nya",
|
||||||
|
];
|
||||||
|
|
||||||
|
var re = new RegExp("\\b(n+y+a+n*?|m+[re]*([yiaou]+[wu]+|w+))(ing|er|s)?\\b", "gi");
|
||||||
|
|
||||||
|
var emoticons = [
|
||||||
|
":3",
|
||||||
|
"^w^",
|
||||||
|
"=^w^=",
|
||||||
|
"-w-",
|
||||||
|
":333"
|
||||||
|
];
|
||||||
|
|
||||||
|
export default class MeowModule extends BaseModule {
|
||||||
|
name = "meow";
|
||||||
|
description = ":33";
|
||||||
|
|
||||||
|
async onMessage(client, event) {
|
||||||
|
var content = event.getContent();
|
||||||
|
|
||||||
|
if (content["m.new_content"] != null) return;
|
||||||
|
|
||||||
|
for (const meow of meows) {
|
||||||
|
if (re.test(content.body.toLowerCase())) {
|
||||||
|
var reply = meows.random();
|
||||||
|
reply += "!".repeat(Math.random() * 5)
|
||||||
|
|
||||||
|
if (Math.random() > 0.5) {
|
||||||
|
reply += " " + emoticons.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
client.reply(event, reply);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue