import apfetch from "./auth-fetch.js";
import { encode } from "html-entities";
import * as sdk from "matrix-js-sdk";
import sdkExt from "./lib/ext.js";
import { resolve } from "node:path";
import fs from "node:fs";
import util from "util";
import { LocalStorage } from 'node-localstorage';
import fetch from "node-fetch";
global.fetch = fetch;
import Olm from "@matrix-org/olm";
global.Olm = Olm;
import env from "dotenv";
env.config();
const localStorage = new LocalStorage("./data/localstorage");
const cryptoStore = new sdk.LocalStorageCryptoStore(localStorage);
const store = new sdk.MemoryStore({ localStorage });
const client = sdk.createClient({
baseUrl: process.env.BASE_URL,
accessToken: process.env.ACCESS_TOKEN,
deviceId: process.env.DEVICE_ID,
userId: process.env.USER_ID,
cryptoStore,
store
});
sdkExt(client);
var prefixes = [process.env.PREFIX];
client.initialized = false;
client.modules = [];
client.commands = [];
for (const file of fs.readdirSync(resolve("modules"))) {
try {
if(file.startsWith(".")) continue;
var module = (await import(resolve("modules", file))).default;
client.modules.push(module);
client.log("[load:modules]", `loaded ${module.name}`);
} catch (err) {
client.error("[load:modules]", `failed to load "${file}":\n`, err);
}
}
for (const file of fs.readdirSync(resolve("commands"))) {
try {
if(file.startsWith(".")) continue;
var command = (await import(resolve("commands", file))).default;
command.usage = process.env.PREFIX + command.command + (command.usage ? " " + command.usage : '');
client.commands.push(command);
client.log("[load:commands]", `loaded ${command.name}`);
} catch (err) {
client.error("[load:commands]", `failed to load "${file}":`, err);
}
}
function doModule(client, event) {
client.modules.forEach(m => {
if(!m) return;
var config = client.config.get(event.sender.roomId);
if(config.get(m.name) === false) return;
try {
m.hooks?.message(client, event);
} catch(err) {
client.log("[hook]", err);
}
});
}
function doCommand(client, event, cmd, args) {
var command;
command = client.commands.filter(c=>c.command==cmd)[0];
if(!command)
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)) {
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.";
client.reply(event, addl, '
' + addl.replaceAll("\n", "
"));
return true;
}
try {
command.execute(client, event, args);
} catch(err) {
client.log("[cmd]", err);
}
return true;
}
client.once("sync", async function (state, prevState, data) {
if(state != "PREPARED") return;
client.setGlobalErrorOnUnknownDevices(false);
client.name = client._store.users[client.credentials.userId].displayName;
client.log("[sdk:sync]", "connected:", client.name);
prefixes.push(client.name + ": ");
prefixes.push(client.name + " ");
client.initialized = true;
});
client.on(sdk.RoomEvent.Timeline, async function (event, room, toStartOfTimeline) {
await client.decryptEventIfNeeded(event);
if (!client.initialized || toStartOfTimeline || event.getType() !== "m.room.message" || event.sender.userId == client.credentials.userId) {
return;
}
var content = event.getContent();
if(content["m.relates_to"] !== undefined)
content.body = content.body.substring(content.body.indexOf("\n\n") + 2);
event.sender = client.getRoom(event.sender.roomId).getMember(event.getSender());
var content = content.body;
var isCommand = false;
for(const prefix of prefixes) {
if(content.startsWith(prefix)) {
isCommand = true;
content = content.substring(prefix.length);
break;
}
}
if(!isCommand) {
doModule(client, event);
} else {
var args = content.split(/\s/g);
var cmd = args.shift();
args = content.substring(cmd.length + 1);
doCommand(client, event, cmd, args)
}
});
client.on("Room.myMembership", function (room, membership, prevMembership) {
if (membership === "invite") {
client.joinRoom(room.roomId).then(function () {
client.log("[client:autojoin] joined %s", room.roomId);
});
}
});
await client.initCrypto();
await client.startClient();