Merge branch 'main' of git.hri7566.info:Hri7566/supercosmic

This commit is contained in:
Hri7566 2023-12-01 15:49:13 -05:00
commit 411f9c3ab1
19 changed files with 1576 additions and 39 deletions

View File

@ -4,3 +4,7 @@ desiredUser:
agents:
wss://mppclone.com:
- id: "✧𝓓𝓔𝓥 𝓡𝓸𝓸𝓶✧"
# - id: "Anime/Touhou & Modern"
- id: "test/awkward"
# - id: "wizardposting"
# - id: Room163249719601

5
config/permissions.yml Normal file
View File

@ -0,0 +1,5 @@
user:
moderator:
admin:

View File

@ -1,4 +1,4 @@
enableMPP: false
enableMPP: true
enableDiscord: false
enableConsole: true
enableSwitchChat: true
enableSwitchChat: false

View File

@ -16,6 +16,7 @@ model User {
platformId String
platform String
Inventory Inventory[]
role Role
}
model Inventory {
@ -24,3 +25,10 @@ model Inventory {
user User @relation(fields: [userId], references: [id])
items Json
}
enum Role {
NONE
MODERATOR
ADMINISTRATOR
OWNER
}

View File

@ -0,0 +1,25 @@
import { Item, StackableItem } from "../../../economy/Item";
import { Command } from "../../Command";
import { CommandHandler } from "../../CommandHandler";
export const inventory = new Command(
"inventory",
["inventory", "inv"],
"get bozo's inventory",
"inventory",
(msg, agent) => {
const items = msg.inventory.items as unknown as Item[];
const list = items
.map(
i =>
`${i.name}${
(i as StackableItem).count
? " " + (i as StackableItem).count
: ""
}`
)
.join(" | ");
return `Items: ${list ? list : "(none)"}`;
}
);

View File

@ -0,0 +1,51 @@
import { MPPAgent } from "../../../services/mpp";
import { CosmicColor } from "../../../util/CosmicColor";
import { Command } from "../../Command";
export const color = new Command(
"color",
["color"],
"colors, bozo",
"color [<r> <g> <b> | <hex>]",
(msg, agent) => {
if (msg.argv[3]) {
// test for rgb
try {
let rstr = msg.argv[1];
let gstr = msg.argv[2];
let bstr = msg.argv[3];
let r = parseInt(rstr);
let g = parseInt(gstr);
let b = parseInt(bstr);
if (r > 255 || g > 255 || b > 255) throw "too large";
if (r < 0 || g < 0 || b < 0) throw "too small";
let c = new CosmicColor(r, g, b);
let outc = `${c.getName().replace("A", "a")} [${c.toHexa()}]`;
return `The RGB color ${r}, ${g}, ${b} is ${outc}`;
} catch (e) {
return `The color '${msg.argv[1]}, ${msg.argv[2]}, ${msg.argv[3]}' is not a valid RGB color. Reason: ${e}`;
}
} else if (msg.argv[1]) {
if (msg.argv[1].match(/#[0-9a-f]{6}/gi) !== null) {
// definitely a hex string
let c = new CosmicColor(msg.argv[1]);
let outc = `${c.getName().replace("A", "a")} [${c.toHexa()}]`;
return `The hex color '${msg.argv[1]}' is ${outc}`;
} else {
return `I don't think '${msg.argv[1]}' is a hex color.`;
}
} else {
if (msg.p.color) {
let c = new CosmicColor(msg.p.color);
let outc = `${c.getName().replace("A", "a")} [${c.toHexa()}]`;
return `${msg.p.name}, your color is ${outc}`;
} else {
return `You... have no color property or something? I guess just look at the command usage and manually choose a color so this doesn't happen.`;
}
}
},
false
);

View File

@ -0,0 +1,17 @@
import { MPPAgent } from "../../../services/mpp";
import { Command } from "../../Command";
export const cursor = new Command(
"cursor",
["cursor"],
"set the cursor bozo",
"cursor",
(msg, agent) => {
if (!(agent as MPPAgent).client.isConnected) return;
if (!msg.argv[1]) return "Specify a mode.";
const cursor = (agent as MPPAgent).cursor;
cursor.props.currentAnimation = msg.argv[1];
},
false
);

View File

@ -8,7 +8,9 @@ export const id = new Command(
"id",
(msg, agent) => {
if (!(agent as MPPAgent).client.isConnected) return;
return `ID: \`${(msg.originalMessage as any).p._id}\``;
return `ID: \`${(msg.originalMessage as any).p._id}\` Cosmic ID: \`${
msg.p._id
}\``;
},
false
);

View File

@ -7,6 +7,9 @@ import { msg } from "./commands/utility/msg";
import { math } from "./commands/utility/math";
import { memory } from "./commands/utility/memory";
import { magic8ball } from "./commands/fun/magic8ball";
import { cursor } from "./commands/utility/cursor";
import { inventory } from "./commands/economy/inventory";
import { color } from "./commands/utility/color";
export function loadCommands() {
// cringe
@ -14,11 +17,15 @@ export function loadCommands() {
general.addCommands([help, about]);
CommandHandler.addCommandGroup(general);
const economy = new CommandGroup("economy", "💸 Economy");
economy.addCommands([inventory]);
CommandHandler.addCommandGroup(economy);
const fun = new CommandGroup("fun", "✨ Fun");
fun.addCommands([magic8ball]);
CommandHandler.addCommandGroup(fun);
const utility = new CommandGroup("utility", "🔨 Utility");
utility.addCommands([math, memory, id, msg]);
utility.addCommands([math, memory, id, msg, cursor, color]);
CommandHandler.addCommandGroup(utility);
}

8
src/economy/Item.ts Normal file
View File

@ -0,0 +1,8 @@
export interface Item {
id: string;
name: string;
}
export interface StackableItem extends Item {
count: number;
}

View File

@ -3,3 +3,7 @@ import { ServiceLoader } from "./services";
loadCommands();
ServiceLoader.loadServices();
export function scopedEval(code: string) {
return eval(code);
}

View File

@ -1,8 +1,12 @@
import EventEmitter from "events";
import { Logger } from "../util/Logger";
export abstract class ServiceAgent<T> extends EventEmitter {
public logger: Logger;
constructor(public platform: string, public client: T) {
super();
this.logger = new Logger(platform);
this.bindEventListeners();
}
@ -10,6 +14,6 @@ export abstract class ServiceAgent<T> extends EventEmitter {
public abstract stop(): void;
protected bindEventListeners() {
this.on("log", txt => console.log(txt));
this.on("log", txt => this.logger.info(txt));
}
}

View File

@ -0,0 +1,161 @@
import { ConsoleAgent } from ".";
import { ServiceLoader } from "..";
import { scopedEval } from "../..";
import { BaseCommandMessage } from "../../commands/CommandHandler";
import { CosmicColor } from "../../util/CosmicColor";
import { ServiceAgent } from "../ServiceAgent";
import { MPPAgent } from "../mpp";
export interface ChatMessage<T = unknown> {
m: "a";
a: string;
p: {
_id: string;
platformId: string;
name: string;
color: string;
};
originalMessage: T;
}
function onChildMessage(msg: ChatMessage) {
const consoleAgent = ServiceLoader.agents.find(
ag => ag.platform == "console"
) as ConsoleAgent | undefined;
if (!consoleAgent) return;
consoleAgent.logger.info(
`[${msg.p.platformId.substring(0, 6)}] ${msg.p.name}: ${msg.a}`
);
}
function onConsoleMessage(text: string) {
const consoleAgent = ServiceLoader.agents.find(
ag => ag.platform == "console"
) as ConsoleAgent | undefined;
if (!consoleAgent) return;
if (!consoleAgent.viewAgent) return;
consoleAgent.viewAgent.emit("send chat", `[Console] ${text}`);
}
export class MicroHandler {
public static async handleMicroCommand(
command: BaseCommandMessage,
agent: ServiceAgent<unknown>
) {
let microcommand = command.argv[0].substring(1);
switch (microcommand) {
case "help":
case "commands":
case "cmds":
default:
return "Microcommands: /help | /js <expr> | /exit | /list | /view <index> | /unview";
break;
case "js":
case "eval":
if (!command.argv[1]) return "Error: No arguments provided";
try {
const out = scopedEval(command.argv.slice(1).join(" "));
return `(${typeof out}) ${out}`;
} catch (err) {
return err;
}
break;
case "exit":
case "stop":
process.exit();
break;
case "list":
if (agent.platform !== "console")
return "This command is only for console agents.";
for (let i in ServiceLoader.agents) {
const agent2 = ServiceLoader.agents[i];
if (agent2.platform == "mpp") {
agent.emit(
"log",
`${i} - ${agent2.platform} - ${
(agent2 as MPPAgent).desiredChannel
}`
);
} else {
agent.emit("log", `${i} - ${agent2.platform}`);
}
}
break;
case "view":
case "connect":
if (agent.platform !== "console")
return "This command is only for console agents.";
try {
let index = parseInt(command.argv[1]);
if (typeof index !== "number")
return "Please provide an index. (check /list)";
let walkie = agent as ConsoleAgent;
let talky = ServiceLoader.agents[index];
if (index == ServiceLoader.agents.indexOf(walkie))
return "Why would you want to chat with yourself?";
// Remove old listeners
if (walkie.viewAgent) {
walkie.viewAgent.off("chat", onChildMessage);
walkie.off("send chat", onConsoleMessage);
}
// Add new listeners
walkie.viewAgent = talky;
walkie.viewAgent.on("chat", onChildMessage);
walkie.on("send chat", onConsoleMessage);
return `Now veiwing agent ${index}`;
} catch (err) {
agent.logger.error(err);
}
break;
case "unview":
case "stopview":
case "stopviewing":
if (agent.platform !== "console")
return "This command is only for console agents.";
try {
let walkie = agent as ConsoleAgent;
// Remove old listeners
if (walkie.viewAgent) {
walkie.viewAgent.off("chat", onChildMessage);
walkie.off("send chat", onConsoleMessage);
}
delete walkie.viewAgent;
} catch (err) {
agent.logger.error(err);
}
break;
case "ppl":
if (agent.platform !== "console")
return "This command is only for console agents.";
let conAg = agent as ConsoleAgent;
if (!conAg.viewAgent) return "There is no agent being viewed.";
if (conAg.viewAgent.platform !== "mpp")
return "The view agent is not on MPP.";
const ppl = (conAg.viewAgent as MPPAgent).client.ppl;
return `MPP Users: ${Object.values(ppl).map(
p =>
`\n - ${p._id} (user) / ${p.id} (part): ${p.name} (${
p.color
}, ${new CosmicColor(p.color).getName()})`
)}`;
break;
}
}
}

View File

@ -1,25 +1,33 @@
import { CommandHandler, CommandMessage } from "../../commands/CommandHandler";
import {
BaseCommandMessage,
CommandHandler
} from "../../commands/CommandHandler";
import { loadConfig } from "../../util/config";
import { ServiceAgent } from "../ServiceAgent";
import readline from "readline";
import { MicroHandler } from "./MicroHandler";
import { Logger } from "../../util/Logger";
const config = loadConfig("config/switchchat.yml", {
ownerOnly: false
});
export class SwitchChatAgent extends ServiceAgent<readline.ReadLine> {
export class ConsoleAgent extends ServiceAgent<readline.ReadLine> {
public desiredUser = {
name: "🟇 𝙎𝙪𝙥𝙚𝙧 Cosmic",
color: "#1d0054"
};
constructor(token: string) {
public logger = new Logger("Console");
public viewAgent: ServiceAgent<unknown> | undefined;
constructor() {
const cl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
super(cl);
super("console", cl);
}
public started = false;
@ -27,7 +35,7 @@ export class SwitchChatAgent extends ServiceAgent<readline.ReadLine> {
public start() {
if (this.started) return;
this.started = true;
this.client.setPrompt(">");
this.client.setPrompt("> ");
this.client.prompt(true);
}
@ -40,26 +48,37 @@ export class SwitchChatAgent extends ServiceAgent<readline.ReadLine> {
protected bindEventListeners(): void {
super.bindEventListeners();
this.client.on("command", async cmd => {
if (config.ownerOnly && !cmd.ownerOnly) return;
this.client.on("line", async text => {
const args = text.split(" ");
console.log(
`${cmd.user.displayName}: ${cmd.ownerOnly ? "^" : "\\"}${
cmd.command
} ${cmd.args.join(" ")}`
);
const message: CommandMessage = {
const message: BaseCommandMessage = {
m: "command",
a: `${cmd.command} ${cmd.args.join(" ")}`,
argc: cmd.args.length + 1,
argv: [cmd.command, ...cmd.args],
originalMessage: cmd
a: text,
argc: args.length,
argv: args,
originalMessage: text,
p: {
platformId: "console",
_id: "console",
name: "Console",
color: "#ffffff"
}
};
const out = await CommandHandler.handleCommand(message, this);
console.log(out);
if (out) this.client.tell(cmd.user.name, out);
let out;
if (text.startsWith("/")) {
out = await MicroHandler.handleMicroCommand(message, this);
} else {
out = await CommandHandler.handleCommand(message, this);
}
if (out) {
this.logger.info(out);
} else {
this.emit("send chat", message.a);
}
this.client.prompt();
});
}
}

View File

@ -5,6 +5,7 @@ import { ServiceAgent } from "./ServiceAgent";
import { loadConfig } from "../util/config";
import { z } from "zod";
import { SwitchChatAgent } from "./switchchat";
import { ConsoleAgent } from "./console";
/**
* Services are anything (any platforms or environments) that the bot will directly communicate to users with
@ -79,5 +80,12 @@ export class ServiceLoader {
switchChatAgent.start();
this.addAgent(switchChatAgent);
}
if (config.enableConsole) {
const consoleAgent = new ConsoleAgent();
consoleAgent.start();
this.addAgent(consoleAgent);
}
}
}

View File

@ -25,7 +25,7 @@ export class Cursor {
public updateInterval: NodeJS.Timeout;
public props: CursorProps = {
currentAnimation: "lemniscate",
currentAnimation: "test2",
position: {
x: 50,
y: 50
@ -35,8 +35,8 @@ export class Cursor {
y: 0
},
velocity: {
x: 0,
y: 0
x: 2 / 5,
y: 2 / 7
},
acceleration: {
x: 0,
@ -112,6 +112,7 @@ export class Cursor {
this.props.position.x >= 105
) {
this.props.position.x = 50;
this.props.velocity.x = 0;
}
if (
@ -119,6 +120,64 @@ export class Cursor {
this.props.position.y >= 105
) {
this.props.position.y = 50;
this.props.velocity.y = 0;
}
this.props.ot = Date.now();
break;
case "bounce2":
this.props.oldPosition.x = this.props.position.x;
this.props.oldPosition.y = this.props.position.y;
this.props.t = Date.now();
this.props.dt = (this.props.t - this.props.ot) / 1000;
this.props.acceleration.x = Math.random() * 100 - 50;
if (this.props.position.y < 75) {
this.props.acceleration.y =
Math.random() * 100 - 50 - this.props.gravity;
} else {
this.props.acceleration.y = -(Math.random() * 50);
}
this.props.velocity.x +=
this.props.acceleration.x * this.props.dt;
this.props.velocity.y +=
this.props.acceleration.y * this.props.dt;
this.props.position.x +=
this.props.velocity.x * this.props.dt;
this.props.position.y +=
this.props.velocity.y * this.props.dt;
if (
this.props.position.x >= 100 ||
this.props.position.x <= 0
) {
this.props.velocity.x = -this.props.velocity.x;
}
if (
this.props.position.y >= 100 ||
this.props.position.y <= 0
) {
this.props.velocity.y = -this.props.velocity.y;
}
if (
this.props.position.x <= -5 ||
this.props.position.x >= 105
) {
this.props.position.x = 50;
this.props.velocity.x = 0;
}
if (
this.props.position.y <= -5 ||
this.props.position.y >= 105
) {
this.props.position.y = 50;
this.props.velocity.y = 0;
}
this.props.ot = Date.now();
@ -156,6 +215,7 @@ export class Cursor {
this.props.position.x >= 105
) {
this.props.position.x = 50;
this.props.velocity.x = 0;
}
if (
@ -163,6 +223,7 @@ export class Cursor {
this.props.position.y >= 105
) {
this.props.position.y = 50;
this.props.velocity.y = 0;
}
this.props.ot = Date.now();
@ -181,6 +242,58 @@ export class Cursor {
10 +
50;
break;
case "test":
if (!this.props.angles[0]) this.props.angles[0] = 0;
this.props.angles[0] += 2;
if (this.props.angles[0] > 360) this.props.angles[0] = 0;
this.props.position.x =
Math.cos(this.props.angles[0] * (Math.PI / 180)) * 10 +
50;
this.props.position.y =
Math.sin(this.props.angles[0] * (Math.PI / 180) * 2) *
10 +
50;
break;
case "test2":
this.props.oldPosition.x = this.props.position.x;
this.props.oldPosition.y = this.props.position.y;
this.props.t = Date.now();
this.props.dt = (this.props.t - this.props.ot) / 1000;
if (this.props.velocity.x > 10)
this.props.velocity.x = 2 / 5;
if (this.props.velocity.x < -10)
this.props.velocity.x = -(2 / 5);
if (this.props.velocity.y > 10)
this.props.velocity.y = 2 / 7;
if (this.props.velocity.y < -10)
this.props.velocity.y = -(2 / 7);
this.props.position.x +=
this.props.velocity.x * this.props.dt * 10;
this.props.position.y +=
this.props.velocity.y * this.props.dt * 10;
if (
this.props.position.x >= 100 ||
this.props.position.x <= 0
) {
this.props.velocity.x = -this.props.velocity.x;
}
if (
this.props.position.y >= 100 ||
this.props.position.y <= 0
) {
this.props.velocity.y = -this.props.velocity.y;
}
this.props.ot = Date.now();
break;
}
}, 1000 / 60);

View File

@ -2,6 +2,7 @@ import Client from "mpp-client-net";
import { ServiceAgent } from "../ServiceAgent";
import { CommandHandler } from "../../commands/CommandHandler";
import { Cursor } from "./Cursor";
import { ChatMessage } from "../console/MicroHandler";
export class MPPAgent extends ServiceAgent<Client> {
public cursor: Cursor;
@ -14,7 +15,6 @@ export class MPPAgent extends ServiceAgent<Client> {
) {
const cl = new Client(uri, token);
super("mpp", cl);
this.emit("log", desiredChannel);
this.cursor = new Cursor(this);
}
@ -30,7 +30,6 @@ export class MPPAgent extends ServiceAgent<Client> {
super.bindEventListeners();
this.client.on("hi", msg => {
this.emit("log", msg.u);
this.client.setChannel(this.desiredChannel);
this.fixUser();
});
@ -40,7 +39,20 @@ export class MPPAgent extends ServiceAgent<Client> {
});
this.client.on("a", async msg => {
console.log(`${msg.p.name}: ${msg.a}`);
const _id = "MPP_" + this.client.uri + "_" + msg.p._id;
this.emit("chat", {
m: "a",
a: msg.a,
p: {
_id,
name: msg.p.name,
color: msg.p.color,
platformId: msg.p._id
},
originalMessage: msg
} as ChatMessage);
let args = msg.a.split(" ");
const str = await CommandHandler.handleCommand(
@ -50,7 +62,7 @@ export class MPPAgent extends ServiceAgent<Client> {
argc: args.length,
argv: args,
p: {
_id: "MPP_" + this.client.uri + "_" + msg.p._id,
_id,
name: msg.p.name,
color: msg.p.color,
platformId: msg.p._id
@ -73,15 +85,19 @@ export class MPPAgent extends ServiceAgent<Client> {
]);
}
} else {
this.client.sendArray([
{
m: "a",
message: `\u034f${str}`
}
]);
this.emit("send chat", str);
}
}
});
this.on("send chat", text => {
this.client.sendArray([
{
m: "a",
message: `\u034f${text}`
}
]);
});
}
public fixUser() {

1085
src/util/CosmicColor.ts Normal file

File diff suppressed because it is too large Load Diff

0
src/util/permission.ts Normal file
View File