diff --git a/bun.lockb b/bun.lockb index 67d0bba..59b7915 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index e9571a0..777e1fe 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,22 @@ { - "name": "mpp-saturn", - "module": "src/index.ts", - "type": "module", - "scripts": { - "build": "bun scripts/build.ts" - }, - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - } + "name": "mpp-saturn", + "module": "src/index.ts", + "type": "module", + "scripts": { + "build": "bun scripts/build.ts", + "watch": "bun run build --watch --debug" + }, + "devDependencies": { + "@types/react": "^18.2.21", + "@types/react-dom": "^18.2.7", + "bun-types": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "mppclone-client": "^1.1.3", + "react": "^18.2.0", + "react-dom": "^18.2.0" + } } diff --git a/scripts/build.ts b/scripts/build.ts index 859f995..e2111ca 100644 --- a/scripts/build.ts +++ b/scripts/build.ts @@ -1,13 +1,63 @@ import fs from "fs"; -await Bun.build({ - entrypoints: ["src/index.tsx"], - outdir: "./build/index.js", +let watch = false; +let debug = false; + +process.argv.forEach(c => { + if (c.includes("--watch")) watch = true; + if (c.includes("--debug")) debug = true; }); -const userscriptHeader = fs - .readFileSync("scripts/userscriptHeader.js") - .toString(); -const artifact = fs.readFileSync("build/index.js").toString(); +if (watch) { + console.log("Watch mode enabled"); + const watcher = fs.watch( + "./src/", + { + recursive: true + }, + async (event, filename) => { + if (event !== "change" && event !== "rename") return; + console.log(""); + console.log("Rebuilding..."); + await build(); + } + ); +} -fs.writeFileSync("build/Saturn.user.js", userscriptHeader + artifact); +async function build() { + console.log("Removing old build..."); + + if (fs.existsSync("build")) { + fs.rmSync("build", { + recursive: true, + force: true + }); + } + + console.log("Compiling scripts..."); + + const build = await Bun.build({ + entrypoints: ["src/index.ts"], + target: "browser", + minify: true, + outdir: "./build/" + }); + + if (build.logs.length > 0) { + console.log("Build logs:", build.logs); + } + + if (!build.success) return; + + console.log("Adding userscript header..."); + + const userscriptHeader = fs + .readFileSync("scripts/userscriptHeader.js") + .toString(); + const artifact = fs.readFileSync("build/index.js").toString(); + + fs.writeFileSync("build/Saturn.user.js", userscriptHeader + artifact); + console.log("Done"); +} + +await build(); diff --git a/src/chat/commands/general/help.ts b/src/chat/commands/general/help.ts new file mode 100644 index 0000000..fed4fab --- /dev/null +++ b/src/chat/commands/general/help.ts @@ -0,0 +1,12 @@ +import { Command } from ".."; + +export const help = new Command( + ["help", "h", "commands", "cmds"], + "Returns a list of commands", + "%Phelp [command]", + msg => { + return "help menu TODO"; + } +); + +console.log(help); diff --git a/src/chat/commands/index.inc.ts b/src/chat/commands/index.inc.ts new file mode 100644 index 0000000..6990f7b --- /dev/null +++ b/src/chat/commands/index.inc.ts @@ -0,0 +1,9 @@ +import { CommandGroup, CommandHandler } from "."; +import { help } from "./general/help"; + +console.log("Adding things"); + +const GROUP_GENERAL = new CommandGroup("General"); +GROUP_GENERAL.addCommand(help); + +CommandHandler.addCommandGroup(GROUP_GENERAL); diff --git a/src/chat/commands/index.ts b/src/chat/commands/index.ts new file mode 100644 index 0000000..0d8630f --- /dev/null +++ b/src/chat/commands/index.ts @@ -0,0 +1,43 @@ +import { type CustomChatMessage } from ".."; +import { type ChatMessage } from "../../util/MPP"; + +export class Command { + public static getUsage(usage: string, prefix: string) { + return usage.split("%P").join(prefix); + } + + constructor( + public aliases: string[], + public description: string, + public usage: string, + public callback: (msg: ChatMessage) => void + ) {} +} + +export class CommandHandler { + public static commandGroups = new Array(); + + public static handleCommand(msg: CustomChatMessage) { + for (const group of this.commandGroups) { + for (const command of group.commands) { + command.callback(msg); + } + } + } + + public static addCommandGroup(commandGroup: CommandGroup) { + this.commandGroups.push(commandGroup); + } +} + +export class CommandGroup { + public commands = new Array(); + + constructor(public id: string) {} + + public addCommand(command: Command) { + this.commands.push(command); + } +} + +require("./index.inc"); diff --git a/src/chat/index.ts b/src/chat/index.ts new file mode 100644 index 0000000..9876ba4 --- /dev/null +++ b/src/chat/index.ts @@ -0,0 +1,32 @@ +import { ChatMessage } from "../util/MPP"; +import { CommandHandler } from "./commands"; + +export interface CustomChatMessage extends ChatMessage { + prefix: string; +} + +export class ChatBot { + public static prefixes = ["sat"]; + + public static handleMessage(msg: ChatMessage) { + console.log(`[Saturn] ${msg.p.name}: ${msg.a}`); + + let usedPrefix: string | undefined; + + for (const prefix of this.prefixes) { + if (!msg.a.startsWith(prefix)) continue; + usedPrefix = prefix; + } + + if (!usedPrefix) return; + + const nmsg = msg as CustomChatMessage; + nmsg.prefix = usedPrefix; + + CommandHandler.handleCommand(nmsg); + } +} + +MPP.client.on("a", msg => { + ChatBot.handleMessage(msg); +}); diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..191f78d --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +import "./ui"; +import "./chat"; diff --git a/src/index.tsx b/src/index.tsx deleted file mode 100644 index b2a242f..0000000 --- a/src/index.tsx +++ /dev/null @@ -1 +0,0 @@ -console.log(typeof (globalThis as any).MPP); diff --git a/src/ui/index.tsx b/src/ui/index.tsx new file mode 100644 index 0000000..8786b3b --- /dev/null +++ b/src/ui/index.tsx @@ -0,0 +1,12 @@ +import ReactDOM from "react-dom/client"; +import React from "react"; + +const document = (globalThis as any).document; +const reactRoot = document.createElement("div"); + +reactRoot.setAttribute("id", "saturn"); +document.body.appendChild(reactRoot); +const root = ReactDOM.createRoot(reactRoot); + +const test =

; +root.render(test); diff --git a/src/util/MPP.d.ts b/src/util/MPP.d.ts index e69de29..638d23a 100644 --- a/src/util/MPP.d.ts +++ b/src/util/MPP.d.ts @@ -0,0 +1,25 @@ +import Client from "mppclone-client"; + +declare global { + var MPP: { + client: Client; + }; +} + +declare interface ChatMessage { + m: "a"; + a: string; + p: Participant; + t: number; +} + +declare interface Participant { + _id: string; + id: string; + name: string; + color: string; + tag?: { + text: string; + color: string; + }; +} diff --git a/tsconfig.json b/tsconfig.json index 1449bc3..9e85aee 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "preserve", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } + "compilerOptions": { + "lib": ["ESNext", "dom"], + "module": "ESNext", + "target": "ESNext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "preserve", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types" // add Bun global + ] + } }