Add talkomatic
This commit is contained in:
parent
39d95665d4
commit
2d0fb07da2
|
@ -6,3 +6,6 @@ DISCORD_TOKEN=
|
||||||
DISCORD_FISHING_TOKEN=
|
DISCORD_FISHING_TOKEN=
|
||||||
|
|
||||||
CLI_FISHING_TOKEN=
|
CLI_FISHING_TOKEN=
|
||||||
|
|
||||||
|
TALKOMATIC_SID=
|
||||||
|
TALKOMATIC_FISHING_TOKEN=
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,2 @@
|
||||||
|
- channel:
|
||||||
|
id: "369310"
|
12
package.json
12
package.json
|
@ -1,17 +1,19 @@
|
||||||
{
|
{
|
||||||
"name": "fishing-api",
|
"name": "fishing-api",
|
||||||
"module": "src/api/index.ts",
|
"module": "src/api/index.ts",
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "bun .",
|
"start": "bun .",
|
||||||
"start-bot": "bun src/mpp/index.ts",
|
"start-bot": "bun src/mpp/index.ts",
|
||||||
"start-discord": "bun src/discord/index.ts"
|
"start-discord": "bun src/discord/index.ts",
|
||||||
|
"build-talko": "bunx tsc --build tsconfig.talko.json"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "^1.1.9"
|
"@types/bun": "^1.1.9",
|
||||||
|
"@types/dotenv": "^8.2.0",
|
||||||
|
"esbuild": "^0.24.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.6.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@prisma/client": "^5.19.1",
|
"@prisma/client": "^5.19.1",
|
||||||
|
@ -20,8 +22,10 @@
|
||||||
"@types/node": "^20.16.5",
|
"@types/node": "^20.16.5",
|
||||||
"cli-markdown": "^3.4.0",
|
"cli-markdown": "^3.4.0",
|
||||||
"discord.js": "^14.16.2",
|
"discord.js": "^14.16.2",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
"mpp-client-net": "^1.2.3",
|
"mpp-client-net": "^1.2.3",
|
||||||
"prisma": "^5.19.1",
|
"prisma": "^5.19.1",
|
||||||
|
"socket.io-client": "^4.8.0",
|
||||||
"trpc-bun-adapter": "^1.1.2",
|
"trpc-bun-adapter": "^1.1.2",
|
||||||
"yaml": "^2.5.1",
|
"yaml": "^2.5.1",
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
import esbuild from "esbuild";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log("Making build directory...");
|
||||||
|
fs.mkdirSync("./build");
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Directory already exists");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Creating script bundle...");
|
||||||
|
const result = await esbuild.build({
|
||||||
|
entryPoints: ["src/talkomatic/index.ts"],
|
||||||
|
bundle: true,
|
||||||
|
target: "node22.9",
|
||||||
|
platform: "node",
|
||||||
|
format: "cjs",
|
||||||
|
tsconfig: "./tsconfig.talko.json",
|
||||||
|
outdir: "./build/"
|
||||||
|
});
|
||||||
|
|
||||||
|
// console.log(result);
|
||||||
|
console.log("Done!");
|
|
@ -7,10 +7,10 @@ export const reel = new Command(
|
||||||
"Reel in and stop fishing",
|
"Reel in and stop fishing",
|
||||||
"reel",
|
"reel",
|
||||||
"command.fishing.reel",
|
"command.fishing.reel",
|
||||||
async ({ id, command, args, prefix, part, user }) => {
|
async ({ id, channel, command, args, prefix, part, user, isDM }) => {
|
||||||
const fishing = getFishing(id, part.id);
|
const fishing = getFishing(id, part.id);
|
||||||
if (fishing) {
|
if (fishing) {
|
||||||
stopFishing(id, part.id);
|
stopFishing(id, part.id, channel, isDM);
|
||||||
return `Our friend ${part.name} reel his/her lure back inside, temporarily decreasing his/her chances of catching a fish by 100%.`;
|
return `Our friend ${part.name} reel his/her lure back inside, temporarily decreasing his/her chances of catching a fish by 100%.`;
|
||||||
} else {
|
} else {
|
||||||
return `Friend ${part.name}: You haven't ${prefix}casted it.`;
|
return `Friend ${part.name}: You haven't ${prefix}casted it.`;
|
||||||
|
|
|
@ -26,6 +26,7 @@ import { chance } from "./util/chance";
|
||||||
import { info } from "./general/info";
|
import { info } from "./general/info";
|
||||||
import { burger } from "./util/burger";
|
import { burger } from "./util/burger";
|
||||||
import { daily } from "./pokemon/daily";
|
import { daily } from "./pokemon/daily";
|
||||||
|
import { give } from "./inventory/give";
|
||||||
// import { give } from "./inventory/give";
|
// import { give } from "./inventory/give";
|
||||||
|
|
||||||
interface ICommandGroup {
|
interface ICommandGroup {
|
||||||
|
@ -55,7 +56,7 @@ commandGroups.push(fishingGroup);
|
||||||
const inventoryGroup: ICommandGroup = {
|
const inventoryGroup: ICommandGroup = {
|
||||||
id: "inventory",
|
id: "inventory",
|
||||||
displayName: "Inventory",
|
displayName: "Inventory",
|
||||||
commands: [inventory, sack, pokemon, take, eat, yeet, burger /* give */]
|
commands: [inventory, sack, pokemon, take, eat, yeet, burger, give]
|
||||||
};
|
};
|
||||||
|
|
||||||
commandGroups.push(inventoryGroup);
|
commandGroups.push(inventoryGroup);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Command from "@server/commands/Command";
|
import Command from "@server/commands/Command";
|
||||||
import { logger } from "@server/commands/handler";
|
import { logger } from "@server/commands/handler";
|
||||||
import { getInventory, updateInventory } from "@server/data/inventory";
|
import { getInventory, updateInventory } from "@server/data/inventory";
|
||||||
import { removeItem } from "@server/items";
|
import { findItemByNameFuzzy, removeItem } from "@server/items";
|
||||||
import { itemBehaviorMap, runBehavior } from "@server/items/behavior";
|
import { itemBehaviorMap, runBehavior } from "@server/items/behavior";
|
||||||
|
|
||||||
export const eat = new Command(
|
export const eat = new Command(
|
||||||
|
@ -22,27 +22,9 @@ export const eat = new Command(
|
||||||
let i = 0;
|
let i = 0;
|
||||||
let shouldRemove = false;
|
let shouldRemove = false;
|
||||||
|
|
||||||
for (const item of inventory.items as unknown as IItem[]) {
|
foundObject =
|
||||||
if (!item.name.toLowerCase().includes(eating.toLowerCase())) {
|
findItemByNameFuzzy(inventory.items, eating) ||
|
||||||
i++;
|
findItemByNameFuzzy(inventory.fishSack, eating);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foundObject = item;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (const fish of inventory.fishSack as TFishSack) {
|
|
||||||
if (!fish.name.toLowerCase().includes(eating.toLowerCase())) {
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foundObject = fish;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundObject) return `You don't have "${eating}" to eat.`;
|
if (!foundObject) return `You don't have "${eating}" to eat.`;
|
||||||
|
|
||||||
|
@ -73,25 +55,17 @@ export const eat = new Command(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundObject.id == "sand") {
|
if (foundObject.id == "sand") {
|
||||||
if (res) {
|
if (res && res.and) {
|
||||||
if (res.and) {
|
|
||||||
return `Our friend ${part.name} ate of his/her ${foundObject.name} ${res.and}`;
|
return `Our friend ${part.name} ate of his/her ${foundObject.name} ${res.and}`;
|
||||||
} else {
|
} else {
|
||||||
return `Our friend ${part.name} ate of his/her ${foundObject.name}.`;
|
return `Our friend ${part.name} ate of his/her ${foundObject.name}.`;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return `Our friend ${part.name} ate of his/her ${foundObject.name}.`;
|
if (res && res.and) {
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (res) {
|
|
||||||
if (res.and) {
|
|
||||||
return `Our friend ${part.name} ate his/her ${foundObject.name} ${res.and}`;
|
return `Our friend ${part.name} ate his/her ${foundObject.name} ${res.and}`;
|
||||||
} else {
|
} else {
|
||||||
return `Our friend ${part.name} ate his/her ${foundObject.name}.`;
|
return `Our friend ${part.name} ate his/her ${foundObject.name}.`;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return `Our friend ${part.name} ate his/her ${foundObject.name}.`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import type { User } from "@prisma/client";
|
||||||
import Command from "@server/commands/Command";
|
import Command from "@server/commands/Command";
|
||||||
import { getInventory, updateInventory } from "@server/data/inventory";
|
import { getInventory, updateInventory } from "@server/data/inventory";
|
||||||
import prisma from "@server/data/prisma";
|
import prisma from "@server/data/prisma";
|
||||||
import { addItem } from "@server/items";
|
import { addItem, findItemByNameFuzzy, removeItem } from "@server/items";
|
||||||
|
|
||||||
export const give = new Command(
|
export const give = new Command(
|
||||||
"give",
|
"give",
|
||||||
|
@ -37,87 +37,28 @@ export const give = new Command(
|
||||||
const argcat = args.slice(1).join(" ");
|
const argcat = args.slice(1).join(" ");
|
||||||
let foundObject: IObject | undefined;
|
let foundObject: IObject | undefined;
|
||||||
|
|
||||||
let i = 0;
|
foundObject =
|
||||||
|
findItemByNameFuzzy(inventory.items, argcat) ||
|
||||||
for (const item of inventory.items as unknown as IItem[]) {
|
findItemByNameFuzzy(inventory.fishSack, argcat);
|
||||||
if (!item.name.toLowerCase().includes(argcat.toLowerCase())) {
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foundObject = item;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
for (const fish of inventory.fishSack as TFishSack) {
|
|
||||||
if (!fish.name.toLowerCase().includes(argcat.toLowerCase())) {
|
|
||||||
i++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foundObject = fish;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!foundObject) return `You don't have any "${argcat}" to give.`;
|
if (!foundObject) return `You don't have any "${argcat}" to give.`;
|
||||||
|
|
||||||
let updated = false;
|
let updated = false;
|
||||||
|
if (foundObject.objtype == "fish") {
|
||||||
if (foundObject.objtype == "item") {
|
|
||||||
addItem(foundInventory.items as unknown as IItem[], foundObject);
|
addItem(foundInventory.items as unknown as IItem[], foundObject);
|
||||||
updated = true;
|
updated = true;
|
||||||
} else if (foundObject.objtype == "fish") {
|
} else if (foundObject.objtype == "item") {
|
||||||
addItem(foundInventory.items as unknown as IItem[], foundObject);
|
addItem(foundInventory.items as unknown as IItem[], foundObject);
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let shouldRemove = false;
|
|
||||||
|
|
||||||
if (updated) {
|
if (updated) {
|
||||||
await updateInventory(foundInventory);
|
await updateInventory(foundInventory);
|
||||||
|
|
||||||
if (foundObject.objtype == "fish") {
|
if (foundObject.objtype == "fish") {
|
||||||
i = 0;
|
removeItem(inventory.fishSack, foundObject, 1);
|
||||||
|
|
||||||
for (const fish of inventory.fishSack as TFishSack) {
|
|
||||||
if (typeof fish.count !== "undefined") {
|
|
||||||
if (fish.count > 1) {
|
|
||||||
shouldRemove = false;
|
|
||||||
((inventory.fishSack as TFishSack)[i]
|
|
||||||
.count as number)--;
|
|
||||||
} else {
|
|
||||||
shouldRemove = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
shouldRemove = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldRemove)
|
|
||||||
(inventory.fishSack as TFishSack).splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else if (foundObject.objtype == "item") {
|
} else if (foundObject.objtype == "item") {
|
||||||
i = 0;
|
removeItem(inventory.items, foundObject, 1);
|
||||||
|
|
||||||
for (const item of inventory.items as unknown as IItem[]) {
|
|
||||||
if (typeof item.count == "number") {
|
|
||||||
if (item.count > 1) {
|
|
||||||
shouldRemove = false;
|
|
||||||
((inventory.items as TInventoryItems)[i]
|
|
||||||
.count as number)--;
|
|
||||||
} else {
|
|
||||||
shouldRemove = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
shouldRemove = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldRemove)
|
|
||||||
(inventory.items as TInventoryItems).splice(i, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return `You ${
|
return `You ${
|
||||||
|
|
|
@ -46,3 +46,20 @@ export function removeItem(arr: IObject[], item: IObject, count = 1) {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function findItemByNameFuzzy(arr: IObject[], name: string) {
|
||||||
|
let foundObject: IObject | undefined;
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
for (const item of arr as unknown as IItem[]) {
|
||||||
|
if (!item.name.toLowerCase().includes(name.toLowerCase())) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foundObject = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return foundObject;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,283 @@
|
||||||
|
import { Logger } from "@util/Logger";
|
||||||
|
import { io, type Socket } from "socket.io-client";
|
||||||
|
import { EventEmitter } from "node:events";
|
||||||
|
import gettRPC from "@util/api/trpc";
|
||||||
|
|
||||||
|
require("dotenv").config();
|
||||||
|
|
||||||
|
export interface TalkomaticBotConfig {
|
||||||
|
channel: {
|
||||||
|
id: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TalkomaticParticipant {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
color: string;
|
||||||
|
typingTimeout: Timer | undefined;
|
||||||
|
typingFlag: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ppl: Record<string, TalkomaticParticipant> = {};
|
||||||
|
|
||||||
|
export class TalkomaticBot extends EventEmitter {
|
||||||
|
public client: Socket;
|
||||||
|
public b = new EventEmitter();
|
||||||
|
public logger: Logger;
|
||||||
|
public trpc = gettRPC(process.env.TALKOMATIC_FISHING_TOKEN as string);
|
||||||
|
public started = false;
|
||||||
|
public textColor = "#abe3d6";
|
||||||
|
|
||||||
|
constructor(public config: TalkomaticBotConfig) {
|
||||||
|
super();
|
||||||
|
this.logger = new Logger("Talkomatic - " + config.channel.id);
|
||||||
|
// this.client = new Client(config.uri, token);
|
||||||
|
// this.client = io(
|
||||||
|
// "wss://talkomatic.co/socket.io/?EIO=4&transport=websocket&sid=f_X4Z5LB8lKBlybNAdj8"
|
||||||
|
// );
|
||||||
|
|
||||||
|
// this.logger.debug(process.env.TALKOMATIC_SID);
|
||||||
|
|
||||||
|
this.client = io("https://talkomatic.co/", {
|
||||||
|
extraHeaders: {
|
||||||
|
Cookie: "connect.sid=" + process.env.TALKOMATIC_SID
|
||||||
|
},
|
||||||
|
autoConnect: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public start() {
|
||||||
|
this.logger.debug("Starting");
|
||||||
|
this.client.connect();
|
||||||
|
// this.client.io.engine.on("packetCreate", this.logger.debug);
|
||||||
|
this.bindEventListeners();
|
||||||
|
this.setChannel(this.config.channel.id);
|
||||||
|
this.started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public stop() {
|
||||||
|
this.client.disconnect();
|
||||||
|
this.started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public connected = false;
|
||||||
|
|
||||||
|
public bindEventListeners() {
|
||||||
|
this.client.onAny(msg => {
|
||||||
|
if (this.connected) return;
|
||||||
|
this.connected = true;
|
||||||
|
this.logger.info("Connected to server");
|
||||||
|
});
|
||||||
|
|
||||||
|
this.client.on(
|
||||||
|
"userTyping",
|
||||||
|
(msg: { userId: string; text: string; color: string }) => {
|
||||||
|
const p = ppl[msg.userId] || {
|
||||||
|
name: "<unknown user>",
|
||||||
|
id: msg.userId,
|
||||||
|
color: msg.color,
|
||||||
|
typingFlag: false
|
||||||
|
};
|
||||||
|
|
||||||
|
// p.color = msg.color;
|
||||||
|
|
||||||
|
if (p.typingTimeout) clearTimeout(p.typingTimeout);
|
||||||
|
|
||||||
|
p.typingTimeout = setTimeout(() => {
|
||||||
|
p.typingFlag = true;
|
||||||
|
ppl[msg.userId] = p;
|
||||||
|
if (msg.text.length <= 0) return;
|
||||||
|
this.emit("command", msg);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
ppl[msg.userId] = p;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.client.on(
|
||||||
|
"udpateRoom",
|
||||||
|
(msg: {
|
||||||
|
users: {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
location: string;
|
||||||
|
is_moderator: boolean;
|
||||||
|
avatar: string;
|
||||||
|
}[];
|
||||||
|
}) => {
|
||||||
|
if (!Array.isArray(msg.users)) return;
|
||||||
|
try {
|
||||||
|
for (const user of msg.users) {
|
||||||
|
const p = ppl[user.id] || {
|
||||||
|
name: user.username,
|
||||||
|
id: user.id,
|
||||||
|
color: "#abe3d6",
|
||||||
|
typingFlag: false
|
||||||
|
};
|
||||||
|
|
||||||
|
ppl[user.id] = p;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.client.on(
|
||||||
|
"roomUsers",
|
||||||
|
(msg: {
|
||||||
|
users: {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
location: string;
|
||||||
|
is_moderator: boolean;
|
||||||
|
avatar: string;
|
||||||
|
}[];
|
||||||
|
currentUserId: string;
|
||||||
|
}) => {
|
||||||
|
if (!Array.isArray(msg.users)) return;
|
||||||
|
try {
|
||||||
|
for (const user of msg.users) {
|
||||||
|
const p = ppl[user.id] || {
|
||||||
|
name: user.username,
|
||||||
|
id: user.id,
|
||||||
|
color: "#abe3d6",
|
||||||
|
typingFlag: false
|
||||||
|
};
|
||||||
|
|
||||||
|
ppl[user.id] = p;
|
||||||
|
}
|
||||||
|
} catch (err) {}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.on(
|
||||||
|
"command",
|
||||||
|
async (msg: { userId: string; text: string; color: string }) => {
|
||||||
|
let prefixes: string[];
|
||||||
|
|
||||||
|
try {
|
||||||
|
prefixes = await this.trpc.prefixes.query();
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.error(err);
|
||||||
|
this.logger.warn("Unable to contact server");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let usedPrefix: string | undefined = prefixes.find(pr =>
|
||||||
|
msg.text.startsWith(pr)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!usedPrefix) return;
|
||||||
|
|
||||||
|
const args = msg.text.split(" ");
|
||||||
|
|
||||||
|
let part: TalkomaticParticipant = ppl[msg.userId] || {
|
||||||
|
name: "<unknown user>",
|
||||||
|
id: msg.userId,
|
||||||
|
color: msg.color,
|
||||||
|
typingFlag: false
|
||||||
|
};
|
||||||
|
|
||||||
|
this.logger.info(`${part.name}: ${msg.text}`);
|
||||||
|
|
||||||
|
const command = await this.trpc.command.query({
|
||||||
|
channel: this.config.channel.id,
|
||||||
|
args: args.slice(1, args.length),
|
||||||
|
command: args[0].substring(usedPrefix.length),
|
||||||
|
prefix: usedPrefix,
|
||||||
|
user: part
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!command) return;
|
||||||
|
if (command.response)
|
||||||
|
this.sendChat(command.response, undefined, msg.userId);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.client.on(
|
||||||
|
"userJoined",
|
||||||
|
(msg: {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
location: string;
|
||||||
|
avatar: string;
|
||||||
|
}) => {
|
||||||
|
const p = ppl[msg.id] || {
|
||||||
|
name: "<unknown user>",
|
||||||
|
id: msg.id,
|
||||||
|
color: "#ffffff",
|
||||||
|
typingFlag: false
|
||||||
|
};
|
||||||
|
|
||||||
|
ppl[msg.id] = p;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const backs = (await this.trpc.backs.query()) as any;
|
||||||
|
if (backs.length > 0) {
|
||||||
|
// this.logger.debug(backs);
|
||||||
|
for (const back of backs) {
|
||||||
|
if (typeof back.m !== "string") return;
|
||||||
|
this.b.emit(back.m, back);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, 1000 / 20);
|
||||||
|
|
||||||
|
this.b.on("color", msg => {
|
||||||
|
if (typeof msg.color !== "string" || typeof msg.id !== "string")
|
||||||
|
return;
|
||||||
|
// this.textColor = msg.color;
|
||||||
|
try {
|
||||||
|
ppl[msg.id].color = msg.color;
|
||||||
|
} catch (err) {}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.b.on("sendchat", msg => {
|
||||||
|
// this.logger.debug("sendchat message:", msg);
|
||||||
|
|
||||||
|
if (typeof msg.channel === "string") {
|
||||||
|
if (msg.channel !== this.config.channel) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendChat(msg.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public sendChat(text: string, reply?: string, id?: string) {
|
||||||
|
// let lines = text.split("\n");
|
||||||
|
|
||||||
|
// for (const line of lines) {
|
||||||
|
// const splits = line.match(/.{510}|.{1,509}/gi);
|
||||||
|
// if (!splits) continue;
|
||||||
|
|
||||||
|
// for (const split of splits) {
|
||||||
|
// if (split.length <= 510) {
|
||||||
|
// const text = `\u034f${split
|
||||||
|
// .split("\t")
|
||||||
|
// .join("")
|
||||||
|
// .split("\r")
|
||||||
|
// .join("")}`;
|
||||||
|
|
||||||
|
const msg = {
|
||||||
|
roomId: this.config.channel.id,
|
||||||
|
text,
|
||||||
|
color: id ? ppl[id].color : "#ffffff"
|
||||||
|
};
|
||||||
|
|
||||||
|
this.client.emit("typing", msg);
|
||||||
|
// } else {
|
||||||
|
// this.sendChat(split);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public setChannel(roomId: string) {
|
||||||
|
this.client.emit("joinRoom", { roomId });
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { loadConfig } from "../../util/config";
|
||||||
|
import { TalkomaticBot, type TalkomaticBotConfig } from "./TalkomaticBot";
|
||||||
|
|
||||||
|
const bots: TalkomaticBot[] = [];
|
||||||
|
|
||||||
|
const defaults = loadConfig("config/talkomatic_bots.yml", [
|
||||||
|
{
|
||||||
|
channel: {
|
||||||
|
id: "116955"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
] as TalkomaticBotConfig[]);
|
||||||
|
|
||||||
|
export function connectDefaultBots() {
|
||||||
|
defaults.forEach(conf => {
|
||||||
|
initBot(conf);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initBot(conf: TalkomaticBotConfig) {
|
||||||
|
const bot = new TalkomaticBot(conf);
|
||||||
|
bot.start();
|
||||||
|
bots.push(bot);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { TalkomaticBot as Bot };
|
||||||
|
export default TalkomaticBot;
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { startAutorestart } from "@util/autorestart";
|
||||||
|
import { connectDefaultBots } from "./bot/index";
|
||||||
|
|
||||||
|
connectDefaultBots();
|
||||||
|
startAutorestart();
|
|
@ -1,5 +1,5 @@
|
||||||
import { getHHMMSS } from "./time";
|
import { getHHMMSS } from "./time";
|
||||||
import type { ReadLine } from "readline";
|
import type { ReadLine } from "node:readline";
|
||||||
|
|
||||||
export class Logger {
|
export class Logger {
|
||||||
private static log(...args: any[]) {
|
private static log(...args: any[]) {
|
||||||
|
|
|
@ -1,29 +1,30 @@
|
||||||
import { createTRPCClient, httpBatchLink } from "@trpc/client";
|
import { createTRPCClient, httpBatchLink } from "@trpc/client";
|
||||||
import type { AppRouter } from "@server/api/trpc";
|
import type { AppRouter } from "@server/api/trpc";
|
||||||
|
|
||||||
// const apiToken = process.env.FISHING_TOKEN as string;
|
require("dotenv").config();
|
||||||
|
|
||||||
export function gettRPC(token: string) {
|
export function gettRPC(token: string) {
|
||||||
return createTRPCClient<AppRouter>({
|
const fishingURL = process.env.FISHING_API_URL as string;
|
||||||
links: [
|
|
||||||
/*httpBatchLink({
|
const firstLink = httpBatchLink({
|
||||||
url: "http://localhost:3000",
|
url: fishingURL,
|
||||||
headers() {
|
headers() {
|
||||||
return {
|
return {
|
||||||
Authorization: token
|
Authorization: token
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}),*/
|
});
|
||||||
httpBatchLink({
|
|
||||||
|
const secondLink = httpBatchLink({
|
||||||
url: "https://fishing.hri7566.info/api",
|
url: "https://fishing.hri7566.info/api",
|
||||||
headers() {
|
headers() {
|
||||||
return {
|
return {
|
||||||
Authorization: token
|
Authorization: token
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
})
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const links = firstLink ? [firstLink, secondLink] : [secondLink];
|
||||||
|
return createTRPCClient<AppRouter>({ links });
|
||||||
}
|
}
|
||||||
|
|
||||||
export default gettRPC;
|
export default gettRPC;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
||||||
import YAML from "yaml";
|
import * as YAML from "yaml";
|
||||||
import { parse } from "path/posix";
|
import { parse } from "node:path/posix";
|
||||||
|
|
||||||
export function loadConfig<T>(path: string, defaultConfig: T) {
|
export function loadConfig<T>(path: string, defaultConfig: T) {
|
||||||
const parsed = parse(path);
|
const parsed = parse(path);
|
||||||
|
|
|
@ -23,6 +23,6 @@
|
||||||
"@server/*": ["./src/api/*"],
|
"@server/*": ["./src/api/*"],
|
||||||
"@client/*": ["./src/mpp/*"],
|
"@client/*": ["./src/mpp/*"],
|
||||||
"@util/*": ["./src/util/*"]
|
"@util/*": ["./src/util/*"]
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["ESNext"],
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
"allowJs": true,
|
||||||
|
|
||||||
|
/* Bundler mode */
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"verbatimModuleSyntax": true,
|
||||||
|
"noEmit": true,
|
||||||
|
|
||||||
|
/* Linting */
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
|
||||||
|
"paths": {
|
||||||
|
"@server/*": ["./src/api/*"],
|
||||||
|
"@client/*": ["./src/mpp/*"],
|
||||||
|
"@util/*": ["./src/util/*"]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/talkomatic",
|
||||||
|
"src/api/api/trpc.ts",
|
||||||
|
"src/util"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue